diff --git a/README.md b/README.md index 312bb8171afffe8430b8c25990faf09b2bfeb117..9e5b9cb8291a4d1c71abd536365a9d8590045d78 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,13 @@ uCoin Java API. Install required dependencies: - - Install [libsoidum](http://doc.libsodium.org/installation/README.html) + - Install [libsodium](http://doc.libsodium.org/installation/index.html) + + - Linux: after [installation](http://doc.libsodium.org/installation/index.html), make sure the file 'libsodium.so' exists on: /usr/local/lib or /opt/local/lib. + If not, create a symbolic link. + + - Windows: copy the file 'sodium.dll' into directory 'ucoinj-core/lib/' + - Install [Maven 3](http://maven.apache.org/). Get the source code, then compile using Maven: diff --git a/pom.xml b/pom.xml index 246a4e95055b1bd5f8cdf3a8bab69d7029dce489..d104990d98b39b60d812d087a4cc6774bdeda5e4 100644 --- a/pom.xml +++ b/pom.xml @@ -20,14 +20,15 @@ <file.encoding>UTF-8</file.encoding> <log4j.version>1.2.16</log4j.version> <slf4j.version>1.7.5</slf4j.version> - <guava.version>14.0.1</guava.version> + <guava.version>19.0</guava.version> <xalan.version>2.7.1</xalan.version> <xerces.version>2.9.0</xerces.version> <xml-apis.version>2.0.2</xml-apis.version> <gson.version>2.2.2</gson.version> - <kalium.version>0.3.1-SNAPSHOT</kalium.version> + <kalium.version>0.4.0</kalium.version> <scrypt.version>1.4.0</scrypt.version> - <elasticsearch.version>1.4.4</elasticsearch.version> + <elasticsearch.version>2.1.1</elasticsearch.version> + <jna.version>4.2.1</jna.version> <nuitonConfigVersion>3.0-rc-2</nuitonConfigVersion> <nuitonI18nVersion>3.3</nuitonI18nVersion> @@ -36,6 +37,10 @@ <wicket.version>7.0.0-M5</wicket.version> <wicketstuff.version>7.0.0-M5</wicketstuff.version> <jquery-ui.version>7.0.0-M5</jquery-ui.version> + <spring.version>4.2.1.RELEASE</spring.version> + <spring-security.version>4.0.2.RELEASE</spring-security.version> + <aspectj.version>1.8.7</aspectj.version> + <yuicompressor-maven-plugin.version>1.3.0</yuicompressor-maven-plugin.version> <htmlcompressor-maven-plugin.version>1.3</htmlcompressor-maven-plugin.version> @@ -60,6 +65,9 @@ <goals>deploy</goals> <arguments></arguments> <preparationGoals>verify</preparationGoals> + <projectInfoReportsPluginVersion>2.7</projectInfoReportsPluginVersion> + + <jarPluginVersion>2.5</jarPluginVersion> <locales>en,fr</locales> @@ -86,8 +94,10 @@ <inceptionYear>2014</inceptionYear> <modules> - <module>ucoinj-core</module> - <module>ucoinj-web</module> + <module>ucoinj-core-shared</module> + <module>ucoinj-core-client</module> + <module>ucoinj-elasticsearch</module> + <module>ucoinj-ui-wicket</module> </modules> <scm> @@ -201,14 +211,51 @@ <version>${wicket.version}</version> </dependency> <dependency> - <groupId>org.wicketstuff</groupId> - <artifactId>wicketstuff-restannotations-json</artifactId> - <version>${wicketstuff.version}</version> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-core</artifactId> + <version>${spring-security.version}</version> </dependency> <dependency> - <groupId>org.apache.wicket</groupId> - <artifactId>wicket-spring-annot</artifactId> - <version>1.3.7</version> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-config</artifactId> + <version>${spring-security.version}</version> + <scope>compile</scope> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-web</artifactId> + <version>${spring-security.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webmvc</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.aspectj</groupId> + <artifactId>aspectjweaver</artifactId> + <version>${aspectj.version}</version> + <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> @@ -290,11 +337,22 @@ <artifactId>elasticsearch</artifactId> <version>${elasticsearch.version}</version> </dependency> + <!-- JNA (need for OS shutdown hook) --> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna</artifactId> + <version>${jna.version}</version> + </dependency> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna-platform</artifactId> + <version>${jna.version}</version> + </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> - <version>2.5.1</version> + <version>2.6.4</version> </dependency> </dependencies> </dependencyManagement> @@ -343,7 +401,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> - <version>1.2.1</version> + <version>1.3</version> </plugin> <plugin> @@ -352,6 +410,11 @@ <version>1.4</version> </plugin> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <version>1.3.1</version> + </plugin> + <plugin> <artifactId>maven-source-plugin</artifactId> <version>2.2.1</version> @@ -375,9 +438,21 @@ </configuration> </plugin> + <plugin> + <artifactId>maven-changes-plugin</artifactId> + <version>2.11</version> + <configuration> + <escapeHTML>false</escapeHTML> + <feedType>rss_2.0</feedType> + <issueLinkTemplatePerSystem> + <default>${project.url}/issues/%ISSUE%</default> + </issueLinkTemplatePerSystem> + </configuration> + </plugin> + <plugin> <artifactId>maven-compiler-plugin</artifactId> - <!-- <version>3.0</version> --> + <version>3.2</version> <configuration> <source>1.7</source> <target>1.7</target> @@ -397,14 +472,22 @@ <plugin> <artifactId>maven-jar-plugin</artifactId> - <version>2.2</version> + <version>${jarPluginVersion}</version> + <configuration> <archive> + <!-- cela fait bugger le chargement des service via ServiceLoader donc on desactive --> + <!--index>true</index --> <manifest> <!-- This is need to override the option version, in configuration classes --> <addDefaultImplementationEntries>true</addDefaultImplementationEntries> <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries> + <!-- Main class, configured in sub-modules --> + <mainClass>${maven.jar.main.class}</mainClass> </manifest> + <manifestEntries> + <url>${project.url}</url> + </manifestEntries> </archive> </configuration> </plugin> @@ -447,6 +530,70 @@ </distributionManagement> <profiles> + + <!-- use this profile to run the main class --> + <profile> + <id>run</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <build> + <defaultGoal>package</defaultGoal> + <plugins> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <executions> + <execution> + <id>check-run</id> + <goals> + <goal>enforce</goal> + </goals> + <phase>initialize</phase> + <configuration> + <rules> + <requireProperty> + <property>maven.jar.main.class</property> + <message>Could not find the "maven.jar.main.class" + required property, use + -Dmaven.jar.main.class=your.main.class.fqn + </message> + </requireProperty> + </rules> + <ignoreCache>true</ignoreCache> + <failFast>true</failFast> + <fail>true</fail> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <id>run</id> + <goals> + <goal>java</goal> + </goals> + <phase>compile</phase> + <configuration> + <mainClass>${exec.mainClass}</mainClass> + <classpathScope>${exec.classpathScope}</classpathScope> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <properties> + <exec.mainClass>${maven.jar.main.class}</exec.mainClass> + <exec.classpathScope>runtime</exec.classpathScope> + <adagio.log.file>${project.build.directory}/exec.log</adagio.log.file> + </properties> + </profile> + <!-- perform only on a release stage when using the maven-release-plugin --> <profile> <id>license-profile</id> diff --git a/ucoinj-core/.gitignore b/ucoinj-core-client/.gitignore similarity index 100% rename from ucoinj-core/.gitignore rename to ucoinj-core-client/.gitignore diff --git a/ucoinj-core-client/LICENSE b/ucoinj-core-client/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/ucoinj-core-client/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ucoinj-core-client/i18n/ucoinj-core-client-i18n-definition.properties b/ucoinj-core-client/i18n/ucoinj-core-client-i18n-definition.properties new file mode 100644 index 0000000000000000000000000000000000000000..98837564c8b794dd144203f64797151e9d8b142b --- /dev/null +++ b/ucoinj-core-client/i18n/ucoinj-core-client-i18n-definition.properties @@ -0,0 +1,7 @@ +#Generated by org.nuiton.i18n.init.UserI18nInitializer +#Tue Dec 29 10:46:20 CET 2015 +locales=fr_FR,en_GB +bundles.en_GB=i18n/nuiton-utils_en_GB.properties,i18n/ucoinj-core-client_en_GB.properties +version=1.0 +encoding=UTF-8 +bundles.fr_FR=i18n/nuiton-utils_fr_FR.properties,i18n/ucoinj-core-client_fr_FR.properties diff --git a/ucoinj-core-client/i18n/ucoinj-core-client-i18n_en_GB.properties b/ucoinj-core-client/i18n/ucoinj-core-client-i18n_en_GB.properties new file mode 100644 index 0000000000000000000000000000000000000000..70412fbc38b57ace633acac5e9ff884b0f7a6c76 --- /dev/null +++ b/ucoinj-core-client/i18n/ucoinj-core-client-i18n_en_GB.properties @@ -0,0 +1,69 @@ +#Tue Dec 29 10:39:49 CET 2015 +nuitonutil.config.moving.conf=Moving old configuration file from %s to %s +nuitonutil.debug.objectutil.create=Try to create %s with %s +nuitonutil.debug.objectutil.instantiate=Can't instantiate %s with params %s +nuitonutil.debug.objectutil.invoke=Invoke %s with %s +nuitonutil.error.add.url.in.classloader=Can't add url in classloader %1$s for reason %2$s +nuitonutil.error.applicationconfig.save=Can't save config in file %s +nuitonutil.error.cant.instanciate.class=Class %s can't be instanciated with %s +nuitonutil.error.class.with.more.than.one.constructor=Your class %s has more than one constructor +nuitonutil.error.convert.file.to.url=Can't convert %s for reason %s +nuitonutil.error.convertor.noValue=No value specified for converter %s +nuitonutil.error.could.not.addPCL=Could not add the PropertychangeListener %1$s on object %2$s for following reason \: %3$s +nuitonutil.error.could.not.find.MD5=Could not find MD5 algorithm +nuitonutil.error.could.not.removePCL=Could remove the PropertychangeListener %1$s from object %2$s for following reason \: %3$s +nuitonutil.error.get.url.from.zip=Error while reading %s \: %s +nuitonutil.error.no.convertor=no convertor found for type %2$s and objet '%1$s' +nuitonutil.error.not.an.enum=The type %1$s ins not an Enum type +nuitonutil.error.null.parameter=The parameter %1$s is null\! +nuitonutil.error.resource.not.found=Can't find resource \: %s +nuitonutil.error.unfound.assignable.argument=Can't find assignable argument for %s in %s +nuitonutil.error.unfound.month=could not found month from '%s', use default month '%s' +nuitonutil.error.unknown.url.type=could not treate unknown type of url %1$s +nuitonutil.error.url.convertor=a problem occurs while converting value '%s' with url convertor %s for reason %s +nuitonutil.error.version.convertor=Could not convert version %1$s with converter %2$s for reason \: %3$s +nuitonutil.error.version.pattern=Pattern of version not found for %1$s +nuitonutil.fileCompletion.cancel=.. to cancel or return to parent directory +nuitonutil.fileCompletion.enter=Enter to display file list, or to complete path +nuitonutil.fileCompletion.exit=Enter "\!q" to exit +nuitonutil.fileCompletion.save=Enter "\!s" in the end of the file name to save +nuitonutil.month.april=april +nuitonutil.month.august=august +nuitonutil.month.december=december +nuitonutil.month.february=february +nuitonutil.month.january=january +nuitonutil.month.july=july +nuitonutil.month.june=june +nuitonutil.month.march=march +nuitonutil.month.may=may +nuitonutil.month.november=november +nuitonutil.month.october=october +nuitonutil.month.september=september +ucoinj.config= +ucoinj.config.option.basedir.description= +ucoinj.config.option.cache.directory.description= +ucoinj.config.option.data.directory.description= +ucoinj.config.option.i18n.directory.description= +ucoinj.config.option.i18n.locale.description= +ucoinj.config.option.inceptionYear.description= +ucoinj.config.option.node.currency.description= +ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= +ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.host.description= +ucoinj.config.option.node.port.description= +ucoinj.config.option.node.protocol.description= +ucoinj.config.option.node.timeout.description= +ucoinj.config.option.organizationName.description= +ucoinj.config.option.passwd.description= +ucoinj.config.option.salt.description= +ucoinj.config.option.site.url.description= +ucoinj.config.option.tmp.directory.description= +ucoinj.config.option.version.description= +ucoinj.config.parse.error= diff --git a/ucoinj-core-client/i18n/ucoinj-core-client-i18n_fr_FR.properties b/ucoinj-core-client/i18n/ucoinj-core-client-i18n_fr_FR.properties new file mode 100644 index 0000000000000000000000000000000000000000..0a11a60c86e5e24afa6213e94fff77e1fbad1d9f --- /dev/null +++ b/ucoinj-core-client/i18n/ucoinj-core-client-i18n_fr_FR.properties @@ -0,0 +1,70 @@ +#Tue Dec 29 10:39:49 CET 2015 +nuitonutil.config.moving.conf=Déplacement du fichier de configuration depuis %s vers %s +nuitonutil.debug.objectutil.create=Essaye de créer %s avec %s +nuitonutil.debug.objectutil.instantiate=Ne peut pas instancier %s avec les paramêtres %s +nuitonutil.debug.objectutil.invoke=Invocation de %s avec %s +nuitonutil.error.add.url.in.classloader=Impossible d'ajouter une url dans le classloader %s pour la raison \: %s +nuitonutil.error.applicationconfig.save=Impossible de sauvegarder le fichier de configuration dans %s +nuitonutil.error.cant.instanciate.class=La Classe %s n'a pas pu être instanciée avec %s +nuitonutil.error.class.with.more.than.one.constructor=Votre classe %s a plus d'un constructeur +nuitonutil.error.convert.file.to.url=Le fichier '%1$s' n'a pas pu être converti en URL pour la raison suivante \: %2$S +nuitonutil.error.convertor.noValue=Aucune valeur à convertir pour le convertisseur %s +nuitonutil.error.could.not.addPCL=N'a pas pu ajouté le PropertychangeListener %1$s sur l'objet %2$s pour la raison suivante \: %3$s +nuitonutil.error.could.not.find.MD5=L'algorithme MD5 n'a pas été trouvé\! +nuitonutil.error.could.not.removePCL=N'a pas pu enlevé le PropertychangeListener %1$s sur l'objet %2$s pour la raison suivante \: %3$s +nuitonutil.error.get.url.from.zip=Erreur lors de la lecture du fichier compressé %1$s \: %2$s +nuitonutil.error.no.convertor=Aucun convertisseur trouvé pour le type %2$s et l''objet '%1$s' +nuitonutil.error.not.an.enum=Le type %1$s n'est pas une enumeration java +nuitonutil.error.null.parameter=Le paramètre '%1$s' est null\! +nuitonutil.error.resource.not.found=Impossible de trouver la ressource \: %s +nuitonutil.error.unfound.assignable.argument=N'a pas pu trouver un argument assignable pour %s dans %s +nuitonutil.error.unfound.month=n'a pas pu trouvé le mois à partir de '%s', utilise le mois par défaut '%s' +nuitonutil.error.unknown.url.type=could not treate unknown type of url %1$s +nuitonutil.error.url.convertor=Un problème est apparu lors de la convertion en url de '%s' avec le convertisseur %s pour la raison suivante \: %s +nuitonutil.error.version.convertor=N'a pas pu convertir la valeur %1$s avec le converter %2$s pour la raison suivante \: %3$s +nuitonutil.error.version.pattern=Pattern de version non connu pour %1$s +nuitonutil.fileCompletion.cancel=.. pour annuler ou pour revenir au repertoire précédent +nuitonutil.fileCompletion.enter=Entrer pour afficher la liste des fichiers, ou pour compléter le chemin +nuitonutil.fileCompletion.exit=Saisir "\!q" pour quitter +nuitonutil.fileCompletion.save=Saisir "\!s" a la fin du nom de fichier pour l'enregistrer +nuitonutil.month.april=avril +nuitonutil.month.august=août +nuitonutil.month.december=décembre +nuitonutil.month.february=février +nuitonutil.month.january=janvier +nuitonutil.month.july=juillet +nuitonutil.month.june=juin +nuitonutil.month.march=mars +nuitonutil.month.may=mai +nuitonutil.month.november=novembre +nuitonutil.month.october=octobre +nuitonutil.month.september=septembre +quadrige2.config.parse.error=Erreur lors de la lecture de la ligne de commande +ucoinj.config= +ucoinj.config.option.basedir.description= +ucoinj.config.option.cache.directory.description= +ucoinj.config.option.data.directory.description= +ucoinj.config.option.i18n.directory.description= +ucoinj.config.option.i18n.locale.description= +ucoinj.config.option.inceptionYear.description= +ucoinj.config.option.node.currency.description= +ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= +ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.host.description= +ucoinj.config.option.node.port.description= +ucoinj.config.option.node.protocol.description= +ucoinj.config.option.node.timeout.description= +ucoinj.config.option.organizationName.description= +ucoinj.config.option.passwd.description= +ucoinj.config.option.salt.description= +ucoinj.config.option.site.url.description= +ucoinj.config.option.tmp.directory.description= +ucoinj.config.option.version.description= +ucoinj.config.parse.error= diff --git a/ucoinj-core-client/pom.xml b/ucoinj-core-client/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2acbd76f7d11e090bf46f66277a7f6282b98e190 --- /dev/null +++ b/ucoinj-core-client/pom.xml @@ -0,0 +1,130 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj</artifactId> + <version>1.0-SNAPSHOT</version> + </parent> + + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-core-client</artifactId> + <packaging>jar</packaging> + <name>UCoin Java :: Core Client API</name> + + <properties> + <i18n.bundleOutputName>ucoinj-core-client-i18n</i18n.bundleOutputName> + <i18n.generateCsvFile>true</i18n.generateCsvFile> + <i18n.bundleCsvFile> + ${maven.gen.dir}/resources/META-INF/${i18n.bundleOutputName}.csv + </i18n.bundleCsvFile> + <config.i18nBundleName>${i18n.bundleOutputName}</config.i18nBundleName> + + </properties> + <dependencies> + <dependency> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-core-shared</artifactId> + <version>${project.version}</version> + </dependency> + <!-- LOGGING DEPENDENCIES - SLF4J --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-collections4</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore</artifactId> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpmime</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-config</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + + <!-- Unit test --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <testResources> + <testResource> + <directory>src/test/resources</directory> + <filtering>false</filtering> + </testResource> + </testResources> + <plugins> + <plugin> + <groupId>org.nuiton.i18n</groupId> + <artifactId>i18n-maven-plugin</artifactId> + + <executions> + <execution> + <id>scan-sources</id> + <configuration> + <entries> + <entry> + <specificGoal>parserValidation</specificGoal> + <basedir>${maven.src.dir}/main/java/</basedir> + <includes> + <param>**/**-validation.xml</param> + </includes> + </entry> + </entries> + </configuration> + <goals> + <goal>parserJava</goal> + <goal>parserValidation</goal> + <goal>gen</goal> + </goals> + </execution> + <execution> + <id>make-bundle</id> + <goals> + <goal>bundle</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/Configuration.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/Configuration.java new file mode 100644 index 0000000000000000000000000000000000000000..abec2fde55642dde80365efa31776a0b96ba95ef --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/Configuration.java @@ -0,0 +1,269 @@ +package io.ucoin.ucoinj.core.client.config; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.base.Charsets; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.nuiton.config.ApplicationConfig; +import org.nuiton.config.ApplicationConfigHelper; +import org.nuiton.config.ApplicationConfigProvider; +import org.nuiton.config.ArgumentsParserException; +import org.nuiton.util.version.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URL; +import java.util.Locale; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * Access to configuration options + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public class Configuration { + /** Logger. */ + private static final Logger log = LoggerFactory.getLogger(Configuration.class); + + /** + * Delegate application config. + */ + protected final ApplicationConfig applicationConfig; + + private static Configuration instance; + + public static Configuration instance() { + return instance; + } + + public static void setInstance(Configuration instance) { + Configuration.instance = instance; + } + + protected final String[] optionKeyToNotSave; + + protected File configFile; + + public Configuration(ApplicationConfig applicationConfig) { + super(); + this.applicationConfig = applicationConfig; + this.optionKeyToNotSave = null; + + // Override application version + initVersion(applicationConfig); + } + + public Configuration(String file, String... args) { + super(); + this.applicationConfig = new ApplicationConfig(); + this.applicationConfig.setEncoding(Charsets.UTF_8.name()); + this.applicationConfig.setConfigFileName(file); + + // get all config providers + Set<ApplicationConfigProvider> providers = + ApplicationConfigHelper.getProviders(null, + null, + null, + true); + + // load all default options + ApplicationConfigHelper.loadAllDefaultOption(applicationConfig, + providers); + + // Load actions + for (ApplicationConfigProvider provider : providers) { + applicationConfig.loadActions(provider.getActions()); + } + + // Define Alias + addAlias(applicationConfig); + + // Override application version + initVersion(applicationConfig); + + // get all transient and final option keys + Set<String> optionToSkip = + ApplicationConfigHelper.getTransientOptionKeys(providers); + + if (log.isDebugEnabled()) { + log.debug("Option that won't be saved: " + optionToSkip); + } + optionKeyToNotSave = optionToSkip.toArray(new String[optionToSkip.size()]); + + try { + applicationConfig.parse(args); + + } catch (ArgumentsParserException e) { + throw new TechnicalException(t("ucoinj.config.parse.error"), e); + } + + // TODO Review this, this is very dirty to do this... + File appBasedir = applicationConfig.getOptionAsFile( + ConfigurationOption.BASEDIR.getKey()); + + if (appBasedir == null) { + appBasedir = new File(""); + } + if (!appBasedir.isAbsolute()) { + appBasedir = new File(appBasedir.getAbsolutePath()); + } + if (appBasedir.getName().equals("..")) { + appBasedir = appBasedir.getParentFile().getParentFile(); + } + if (appBasedir.getName().equals(".")) { + appBasedir = appBasedir.getParentFile(); + } + if (log.isInfoEnabled()) { + log.info("Application basedir: " + appBasedir); + } + applicationConfig.setOption( + ConfigurationOption.BASEDIR.getKey(), + appBasedir.getAbsolutePath()); + } + + /** + * Override the version default option, from the MANIFEST implementation version (if any) + * @param applicationConfig + */ + protected void initVersion(ApplicationConfig applicationConfig) { + // Override application version + String implementationVersion = this.getClass().getPackage().getSpecificationVersion(); + if (implementationVersion != null) { + applicationConfig.setDefaultOption( + ConfigurationOption.VERSION.getKey(), + implementationVersion); + } + } + + /** + * Add alias to the given ApplicationConfig. <p/> + * This method could be override to add specific alias + * + * @param applicationConfig + */ + protected void addAlias(ApplicationConfig applicationConfig) { + applicationConfig.addAlias("-h", "--option", ConfigurationOption.NODE_HOST.getKey()); + applicationConfig.addAlias("--host", "--option", ConfigurationOption.NODE_HOST.getKey()); + applicationConfig.addAlias("-p", "--option", ConfigurationOption.NODE_PORT.getKey()); + applicationConfig.addAlias("--port", "--option", ConfigurationOption.NODE_PORT.getKey()); + applicationConfig.addAlias("-c", "--option", ConfigurationOption.NODE_CURRENCY.getKey()); + applicationConfig.addAlias("--salt", "--option", ConfigurationOption.USER_SALT.getKey()); + applicationConfig.addAlias("--passwd", "--option", ConfigurationOption.USER_PASSWD.getKey()); + } + + public File getConfigFile() { + if (configFile == null) { + File dir = getBasedir(); + if (dir == null || !dir.exists()) { + dir = new File(applicationConfig.getUserConfigDirectory()); + } + configFile = new File(dir, applicationConfig.getConfigFileName()); + } + return configFile; + } + + /** @return {@link ConfigurationOption#BASEDIR} value */ + public File getBasedir() { + File result = applicationConfig.getOptionAsFile(ConfigurationOption.BASEDIR.getKey()); + return result; + } + + /** @return {@link ConfigurationOption#DATA_DIRECTORY} value */ + public File getDataDirectory() { + File result = applicationConfig.getOptionAsFile(ConfigurationOption.DATA_DIRECTORY.getKey()); + return result; + } + + public ApplicationConfig getApplicationConfig() { + return applicationConfig; + } + + public File getTempDirectory() { + return applicationConfig.getOptionAsFile(ConfigurationOption.TMP_DIRECTORY.getKey()); + } + + public File getCacheDirectory() { + return applicationConfig.getOptionAsFile(ConfigurationOption.CACHE_DIRECTORY.getKey()); + } + + public Version getVersion() { + return applicationConfig.getOptionAsVersion(ConfigurationOption.VERSION.getKey()); + } + + public File getI18nDirectory() { + return applicationConfig.getOptionAsFile( + ConfigurationOption.I18N_DIRECTORY.getKey()); + } + + public Locale getI18nLocale() { + return applicationConfig.getOptionAsLocale( + ConfigurationOption.I18N_LOCALE.getKey()); + } + + public void setI18nLocale(Locale locale) { + applicationConfig.setOption(ConfigurationOption.I18N_LOCALE.getKey(), locale.toString()); + } + + public String getNodeCurrency() { + return applicationConfig.getOption(ConfigurationOption.NODE_CURRENCY.getKey()); + } + + public String getNodeProtocol() { + return applicationConfig.getOption(ConfigurationOption.NODE_PROTOCOL.getKey()); + } + + public String getNodeHost() { + return applicationConfig.getOption(ConfigurationOption.NODE_HOST.getKey()); + } + + public int getNodePort() { + return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_PORT.getKey()); + } + + public URL getNodeUrl() { + return applicationConfig.getOptionAsURL(ConfigurationOption.NODE_URL.getKey()); + } + + public int getNetworkTimeout() { + return applicationConfig.getOptionAsInt(ConfigurationOption.NETWORK_TIMEOUT.getKey()); + } + + public int getNetworkCacheTimeInMillis() { + return Integer.parseInt(ConfigurationOption.NETWORK_CACHE_TIME_IN_MILLIS.getDefaultValue()); + } + + public String getNodeElasticSearchHost() { + return applicationConfig.getOption(ConfigurationOption.NODE_ELASTICSEARCH_HOST.getKey()); + } + public int getNodeElasticSearchPort() { + return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_ELASTICSEARCH_PORT.getKey()); + } + + public URL getNodeElasticSearchUrl() { + return applicationConfig.getOptionAsURL(ConfigurationOption.NODE_ELASTICSEARCH_URL.getKey()); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationOption.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationOption.java new file mode 100644 index 0000000000000000000000000000000000000000..ce0f0dd596438e7639465814662ac9da12699fef --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationOption.java @@ -0,0 +1,289 @@ +package io.ucoin.ucoinj.core.client.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationOption.java 1441 2013-12-09 20:13:47Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ConfigOptionDef; +import org.nuiton.util.Version; + +import java.io.File; +import java.net.URL; +import java.util.Locale; + +import static org.nuiton.i18n.I18n.n; + +/** + * All application configuration options. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public enum ConfigurationOption implements ConfigOptionDef { + + // ------------------------------------------------------------------------// + // -- READ-ONLY OPTIONS ---------------------------------------------------// + // ------------------------------------------------------------------------// + + BASEDIR( + "ucoinj.basedir", + n("ucoinj.config.option.basedir.description"), + "${user.home}/.ucoinj", + File.class), + + DATA_DIRECTORY( + "ucoinj.data.directory", + n("ucoinj.config.option.data.directory.description"), + "${ucoinj.basedir}/data", + File.class), + + I18N_DIRECTORY( + "ucoinj.i18n.directory", + n("ucoinj.config.option.i18n.directory.description"), + "${ucoinj.basedir}/i18n", + File.class), + + TMP_DIRECTORY( + "ucoinj.tmp.directory", + n("ucoinj.config.option.tmp.directory.description"), + "${ucoinj.data.directory}/temp", + File.class), + + CACHE_DIRECTORY( + "ucoinj.cache.directory", + n("ucoinj.config.option.cache.directory.description"), + "${ucoinj.data.directory}/cache", + File.class), + + VERSION( + "ucoinj.version", + n("ucoinj.config.option.version.description"), + "1.0", + Version.class), + + SITE_URL( + "ucoinj.site.url", + n("ucoinj.config.option.site.url.description"), + "http://ucoin.io/ucoinj", + URL.class), + + ORGANIZATION_NAME( + "ucoinj.organizationName", + n("ucoinj.config.option.organizationName.description"), + "e-is.pro", + String.class), + + INCEPTION_YEAR( + "ucoinj.inceptionYear", + n("ucoinj.config.option.inceptionYear.description"), + "2011", + Integer.class), + + USER_SALT( + "ucoinj.salt", + n("ucoinj.config.option.salt.description"), + "", + String.class), + + USER_PASSWD( + "ucoinj.passwd", + n("ucoinj.config.option.passwd.description"), + "", + String.class), + + // ------------------------------------------------------------------------// + // -- DATA CONSTANTS --------------------------------------------------// + // ------------------------------------------------------------------------// + + // ------------------------------------------------------------------------// + // -- READ-WRITE OPTIONS --------------------------------------------------// + // ------------------------------------------------------------------------// + + I18N_LOCALE( + "ucoinj.i18n.locale", + n("ucoinj.config.option.i18n.locale.description"), + Locale.FRANCE.getCountry(), + Locale.class, + false), + + NODE_CURRENCY( + "ucoinj.node.currency", + n("ucoinj.config.option.node.currency.description"), + "meta_brouzouf", + String.class, + false), + + NODE_PROTOCOL( + "ucoinj.node.protocol", + n("ucoinj.config.option.node.protocol.description"), + "http", + String.class, + false), + + NODE_HOST( + "ucoinj.node.host", + n("ucoinj.config.option.node.host.description"), + "metab.ucoin.io", + String.class, + false), + + NODE_PORT( + "ucoinj.node.port", + n("ucoinj.config.option.node.port.description"), + "9201", + Integer.class, + false), + + NODE_URL( + "ucoinj.node.url", + n("ucoinj.config.option.node.port.description"), + "${ucoinj.node.protocol}://${ucoinj.node.host}:${ucoinj.node.port}", + URL.class, + false), + + NETWORK_TIMEOUT( + "ucoinj.network.timeout", + n("ucoinj.config.option.network.timeout.description"), + "100000", // = 10 s + Integer.class, + false), + + NETWORK_CACHE_TIME_IN_MILLIS ( + "ucoin.network.cacheTimeInMillis", + "ucoin.config.option.network.cacheTimeInMillis.description", + "10000", // = 10 s + Integer.class, + false), + + NODE_ELASTICSEARCH_PROTOCOL( + "ucoinj.node.elasticsearch.protocol", + n("ucoinj.config.option.node.elasticsearch.protocol.description"), + "http", + String.class, + false), + + NODE_ELASTICSEARCH_HOST( + "ucoinj.node.elasticsearch.host", + n("ucoinj.config.option.node.elasticsearch.host.description"), + "localhost", + String.class, + false), + + NODE_ELASTICSEARCH_PORT( + "ucoinj.node.elasticsearch.port", + n("ucoinj.config.option.node.elasticsearch.port.description"), + "9200", + Integer.class, + false), + + NODE_ELASTICSEARCH_URL( + "ucoinj.node.elasticsearch.url", + n("ucoinj.config.option.node.elasticsearch.url.description"), + "${ucoinj.node.elasticsearch.protocol}://${ucoinj.node.elasticsearch.host}:${ucoinj.node.elasticsearch.port}", + URL.class, + false) + ; + + /** Configuration key. */ + private final String key; + + /** I18n key of option description */ + private final String description; + + /** Type of option */ + private final Class<?> type; + + /** Default value of option. */ + private String defaultValue; + + /** Flag to not keep option value on disk */ + private boolean isTransient; + + /** Flag to not allow option value modification */ + private boolean isFinal; + + ConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type, + boolean isTransient) { + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + this.type = type; + this.isTransient = isTransient; + this.isFinal = isTransient; + } + + ConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type) { + this(key, description, defaultValue, type, true); + } + + @Override + public String getKey() { + return key; + } + + @Override + public Class<?> getType() { + return type; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } + + @Override + public boolean isTransient() { + return isTransient; + } + + @Override + public boolean isFinal() { + return isFinal; + } + + @Override + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public void setTransient(boolean newValue) { + // not used + } + + @Override + public void setFinal(boolean newValue) { + // not used + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationProvider.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..05482713120bdd707ec7bd35d8acee3e3f0743eb --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/config/ConfigurationProvider.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.core.client.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationProvider.java 1418 2013-12-01 21:18:22Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationProvider.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ApplicationConfigProvider; +import org.nuiton.config.ConfigActionDef; +import org.nuiton.config.ConfigOptionDef; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l; + +/** + * Config provider (for site generation). + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + */ +public class ConfigurationProvider implements ApplicationConfigProvider { + + @Override + public String getName() { + return "ucoinj"; + } + + @Override + public String getDescription(Locale locale) { + return l(locale, "ucoinj.config"); + } + + @Override + public ConfigOptionDef[] getOptions() { + return ConfigurationOption.values(); + } + + @Override + public ConfigActionDef[] getActions() { + return new ConfigActionDef[0]; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/CurrencyDao.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/CurrencyDao.java new file mode 100644 index 0000000000000000000000000000000000000000..d8d0d560823c46e3f9f140f37b486f44e935d29c --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/CurrencyDao.java @@ -0,0 +1,63 @@ +package io.ucoin.ucoinj.core.client.dao; + +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.client.model.local.Currency; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created by eis on 07/02/15. + */ +public interface CurrencyDao extends Bean, EntityDao<Currency> { + + Currency create(final Currency currency); + + Currency update(final Currency currency); + + void remove(final Currency currency); + + List<Currency> getCurrencies(long accountId); + + /** + * Return a (cached) currency name, by id + * @param currencyId + * @return + */ + String getCurrencyNameById(long currencyId); + + /** + * Return a currency id, by name + * @param currencyName + * @return + */ + Long getCurrencyIdByName(String currencyName); + + /** + * Return a (cached) list of currency ids + * @return + */ + Set<Long> getCurrencyIds(); + + /** + * Return a (cached) number of registered currencies + * @return + */ + int getCurrencyCount(); + + /** + * Return the value of the last universal dividend + * @param currencyId + * @return + */ + long getLastUD(long currencyId); + + /** + * Return a map of UD (key=blockNumber, value=amount) + * @return + */ + Map<Integer, Long> getAllUD(long currencyId); + + void insertUDs(Long currencyId, Map<Integer, Long> newUDs); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/EntityDao.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/EntityDao.java new file mode 100644 index 0000000000000000000000000000000000000000..3dc4fd496440b4a46d334fdca43d5c55c63e763f --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/EntityDao.java @@ -0,0 +1,19 @@ +package io.ucoin.ucoinj.core.client.dao; + +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.client.model.local.LocalEntity; + +/** + * Created by blavenie on 29/12/15. + */ +public interface EntityDao<B extends LocalEntity> extends Bean{ + + B create(B entity); + + B update(B entity); + + B getById(long id); + + void remove(B entity); + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/PeerDao.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/PeerDao.java new file mode 100644 index 0000000000000000000000000000000000000000..c65a197ea3b2bf9270f5aada4e103ee081584fe1 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/PeerDao.java @@ -0,0 +1,13 @@ +package io.ucoin.ucoinj.core.client.dao; + +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.util.List; + +/** + * Created by blavenie on 29/12/15. + */ +public interface PeerDao extends EntityDao<Peer> { + + List<Peer> getPeersByCurrencyId(long currencyId); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryCurrencyDaoImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryCurrencyDaoImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..c749e9eb781e580b902960f525e2e8e5910453ab --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryCurrencyDaoImpl.java @@ -0,0 +1,119 @@ +package io.ucoin.ucoinj.core.client.dao.mem; + +import io.ucoin.ucoinj.core.client.dao.CurrencyDao; +import io.ucoin.ucoinj.core.client.model.local.Currency; +import io.ucoin.ucoinj.core.util.CollectionUtils; + +import java.util.*; + +/** + * Created by blavenie on 29/12/15. + */ +public class MemoryCurrencyDaoImpl implements CurrencyDao { + + + private Map<Long, Currency> currencies = new HashMap<>(); + + private Map<Long, Map<Integer, Long>> currencyUDsByBlock = new HashMap<>(); + + @Override + public Currency create(final Currency entity) { + + long id = getMaxId() + 1; + entity.setId(id); + + currencies.put(id, entity); + + return entity; + } + + @Override + public Currency update(final Currency currency) { + currencies.put(currency.getId(), currency); + return currency; + } + + @Override + public void remove(final Currency currency) { + currencies.remove(currency.getId()); + } + + @Override + public List<Currency> getCurrencies(long accountId) { + List<Currency> result = new ArrayList<>(); + result.addAll(currencies.values()); + return result; + } + + @Override + public Currency getById(long currencyId) { + return currencies.get(currencyId); + } + + @Override + public String getCurrencyNameById(long currencyId) { + Currency currency = getById(currencyId); + if (currency == null) { + return null; + } + return currency.getCurrencyName(); + } + + @Override + public Long getCurrencyIdByName(String currencyName) { + for(Currency currency: currencies.values()) { + if (currencyName.equalsIgnoreCase(currency.getCurrencyName())) { + return currency.getId(); + } + } + return null; + } + + @Override + public Set<Long> getCurrencyIds() { + return currencies.keySet(); + } + + @Override + public int getCurrencyCount() { + return currencies.size(); + } + + @Override + public long getLastUD(long currencyId) { + Currency currency = getById(currencyId); + if (currency == null) { + return -1; + } + return currency.getLastUD(); + } + + @Override + public Map<Integer, Long> getAllUD(long currencyId) { + + return currencyUDsByBlock.get(currencyId); + } + + @Override + public void insertUDs(Long currencyId, Map<Integer, Long> newUDs) { + Map<Integer, Long> udsByBlock = currencyUDsByBlock.get(currencyId); + if (udsByBlock == null) { + udsByBlock = new HashMap<>(); + currencyUDsByBlock.put(currencyId, udsByBlock); + } + udsByBlock.putAll(newUDs); + } + + /* -- internal methods -- */ + + protected long getMaxId() { + long currencyId = -1; + for (Long anId : currencies.keySet()) { + if (anId > currencyId) { + currencyId = anId; + } + } + + return currencyId; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryPeerDaoImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryPeerDaoImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6963f67e368b61f325e0499221c811fe07e556af --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/dao/mem/MemoryPeerDaoImpl.java @@ -0,0 +1,71 @@ +package io.ucoin.ucoinj.core.client.dao.mem; + +import io.ucoin.ucoinj.core.client.dao.PeerDao; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeers; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created by blavenie on 29/12/15. + */ +public class MemoryPeerDaoImpl implements PeerDao { + + private Map<Long, Peer> peersByCurrencyId = new HashMap<>(); + + @Override + public Peer create(Peer entity) { + long id = getMaxId() + 1; + entity.setId(id); + + peersByCurrencyId.put(id, entity); + + return entity; + } + + @Override + public Peer update(Peer entity) { + peersByCurrencyId.put(entity.getId(), entity); + return entity; + } + + @Override + public Peer getById(long id) { + return peersByCurrencyId.get(id); + } + + @Override + public void remove(Peer entity) { + peersByCurrencyId.remove(entity.getId()); + } + + @Override + public List<Peer> getPeersByCurrencyId(long currencyId) { + + List<Peer> result = new ArrayList<>(); + + for(Peer peer: peersByCurrencyId.values()) { + if (peer.getCurrencyId() == currencyId) { + result.add(peer); + } + } + + return result; + } + + /* -- internal methods -- */ + + protected long getMaxId() { + long currencyId = -1; + for (Long anId : peersByCurrencyId.keySet()) { + if (anId > currencyId) { + currencyId = anId; + } + } + + return currencyId; + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupSignature.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Account.java similarity index 54% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupSignature.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Account.java index 37e2bdcff2d50f058bf0389eb3fe08e8db9ffe8a..7b104c13ddae0d6e074fd8c4edfd68d27ace0a78 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupSignature.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Account.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model; /* * #%L @@ -22,38 +22,60 @@ package io.ucoin.client.core.model; * #L% */ - -import java.util.Map; - -public class WotLookupSignature { - - private String pubkey; - - private Map<String, String> meta; - - private String signature; - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public Map<String, String> getMeta() { - return meta; - } - - public void setMeta(Map<String, String> meta) { - this.meta = meta; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } -} + +import io.ucoin.ucoinj.core.client.model.local.LocalEntity; + +/** + * Created by eis on 07/02/15. + */ +public class Account implements LocalEntity { + + private Long id; + private String uid; + private String pubkey; + private String salt; + private String cryptPin; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getSalt() { + return salt; + } + + public void setSalt(String salt) { + this.salt = salt; + } + + public String getCryptPin() { + return cryptPin; + } + + public void setCryptPin(String cryptPin) { + this.cryptPin = cryptPin; + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BasicIdentity.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/BasicIdentity.java similarity index 90% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/BasicIdentity.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/BasicIdentity.java index 0e58c49bd0a4ef4e68c50da813eb2a9f7a3614d9..aeeaa5b03d88f21ef08bb75a9f4c9a4f285a87a4 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BasicIdentity.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/BasicIdentity.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model; /* * #%L @@ -22,57 +22,65 @@ package io.ucoin.client.core.model; * #L% */ - -import java.io.Serializable; - -/** - * Basic information on a identity. - * - * @author Benoit Lavenier <benoit.lavenier@e-is.pro> - * @since 1.0 - * - */ -public class BasicIdentity implements Serializable { - - private static final long serialVersionUID = 8080689271400316984L; - - private String pubkey; - - private String signature; - - private String uid; - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public String getSignature() { - return signature; - } - - public void setSignature(String signature) { - this.signature = signature; - } - - public String getUid() { - return uid; - } - - public void setUid(String uid) { - this.uid = uid; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder() - .append("uid=").append(uid) - .append(",pubkey=").append(pubkey) - .append(",signature").append(signature); - - return sb.toString(); - } -} + +import java.io.Serializable; + +/** + * Basic information on a identity. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + * + */ +public class BasicIdentity implements Serializable { + + private static final long serialVersionUID = 8080689271400316984L; + + private String pubkey; + + private String signature; + + private String uid; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getSelf() { + return signature; + } + + public void setSelf(String signature) { + this.signature = signature; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder() + .append("uid=").append(uid) + .append(",pubkey=").append(pubkey) + .append(",signature").append(signature); + + return sb.toString(); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Currency.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Currency.java new file mode 100644 index 0000000000000000000000000000000000000000..19d5f1f51fa58cccc17e710bc5eaf7da159eb484 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Currency.java @@ -0,0 +1,151 @@ +package io.ucoin.ucoinj.core.client.model; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by eis on 05/02/15. + */ +public class Currency implements Serializable { + + private List<Peer> peers = new ArrayList<Peer>(); + + private Long id; + private String currencyName; + private Integer membersCount; + private String firstBlockSignature; + private Account account; + private Long accountId; + private String[] tags; + private String senderPubkey; + private Long lastUD; + + public Currency() { + } + + public Currency(String currencyName, + String firstBlockSignature, + int membersCount, + List<Peer> peers) { + this.currencyName = currencyName; + this.firstBlockSignature = firstBlockSignature; + this.membersCount = membersCount; + this.peers = peers; + } + + public Currency(String currencyName, + String firstBlockSignature, + List<Peer> peers) { + this.currencyName = currencyName; + this.firstBlockSignature = firstBlockSignature; + this.membersCount = null; + this.peers = peers; + } + + public Long getId() { + return id; + } + + public String getCurrencyName() + { + return currencyName; + } + + public Integer getMembersCount() { + return membersCount; + } + + public String getFirstBlockSignature() { + return firstBlockSignature; + } + + public List<Peer> getPeers() { + return peers; + } + + public void addPeer(Peer peer) { + this.peers.add(peer); + } + + public void setPeers(List<Peer> peers) { + this.peers = peers; + } + + public void setId(Long id) { + this.id = id; + } + + public void setCurrencyName(String currencyName) { + this.currencyName = currencyName; + } + + public void setMembersCount(Integer membersCount) { + this.membersCount = membersCount; + } + + public void setFirstBlockSignature(String firstBlockSignature) { + this.firstBlockSignature = firstBlockSignature; + } + + public Account getAccount() { + return account; + } + + public void setAccount(Account account) { + this.account = account; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String toString() { + return currencyName; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public String getSenderPubkey() { + return senderPubkey; + } + + public void setSenderPubkey(String senderPubkey) { + this.senderPubkey = senderPubkey; + } +} \ No newline at end of file diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/Member.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Member.java similarity index 89% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/Member.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Member.java index 19dec90db30d6311dc08f87dcdbcf51a1a4598b2..00dbb237fe683d3789ac8ca25b4285c2da6d0511 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/Member.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/Member.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model; /* * #%L @@ -22,28 +22,30 @@ package io.ucoin.client.core.model; * #L% */ - -public class Member extends Identity{ - - private static final long serialVersionUID = 8448049949323699700L; - - private String number; - - private String hash; - - public String getNumber() { - return number; - } - - public void setNumber(String number) { - this.number = number; - } - - public String getHash() { - return hash; - } - - public void setHash(String hash) { - this.hash = hash; - } -} + +import io.ucoin.ucoinj.core.client.model.local.Identity; + +public class Member extends Identity { + + private static final long serialVersionUID = 8448049949323699700L; + + private String number; + + private String hash; + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/ModelUtils.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/ModelUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..5ec19d4c0a7a867a18d4a91599d5509aedb27ba5 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/ModelUtils.java @@ -0,0 +1,126 @@ +package io.ucoin.ucoinj.core.client.model; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.ucoin.ucoinj.core.client.model.local.Certification; +import io.ucoin.ucoinj.core.client.model.local.Movement; + +/** + * Helper class on model entities + * Created by eis on 04/04/15. + */ +public class ModelUtils { + + /** + * Order certification by cert time (DESC), uid ASC, pubkey (ASC) + * @return a new comparator + */ + public static Comparator<Certification> newWotCertificationComparatorByDate() { + return new Comparator<Certification>() { + @Override + public int compare(Certification lhs, Certification rhs) { + int result = 0; + + // cert time (order DESC) + long lct = lhs.getTimestamp(); + long rct = rhs.getTimestamp(); + if (lct != rct) { + return lct < rct ? 1 : -1; + } + + // uid + if (lhs.getUid() != null) { + result = lhs.getUid().compareToIgnoreCase(rhs.getUid()); + if (result != 0) { + return result; + } + } + else if (rhs.getUid() != null) { + return 1; + } + + // pub key + if (lhs.getPubkey() != null) { + result = lhs.getPubkey().compareToIgnoreCase(rhs.getPubkey()); + if (result != 0) { + return result; + } + } + else if (rhs.getPubkey() != null) { + return 1; + } + return 0; + } + }; + } + + + /** + * Order certification by uid (ASC), pubkey (ASC), cert time (DESC) + * @return a new comparator + */ + public static Comparator<Certification> newWotCertificationComparatorByUid() { + return new Comparator<Certification>() { + @Override + public int compare(Certification lhs, Certification rhs) { + int result = 0; + // uid + if (lhs.getUid() != null) { + result = lhs.getUid().compareToIgnoreCase(rhs.getUid()); + if (result != 0) { + return result; + } + } + else if (rhs.getUid() != null) { + return 1; + } + + // pub key + if (lhs.getPubkey() != null) { + result = lhs.getPubkey().compareToIgnoreCase(rhs.getPubkey()); + if (result != 0) { + return result; + } + } + else if (rhs.getPubkey() != null) { + return 1; + } + + // cert time (order DESC) + long lct = lhs.getTimestamp(); + long rct = rhs.getTimestamp(); + return lct < rct ? 1 : (lct == rct ? 0 : -1); + } + }; + } + + /** + * Transform a list of sources, into a Map, using the fingerprint as key + * @param movements + * @return + */ + public static Map<String, Movement> movementsToFingerprintMap(List<Movement> movements) { + + Map<String, Movement> result = new HashMap<>(); + for(Movement movement: movements) { + result.put(movement.getFingerprint(), movement); + } + + return result; + } + + /** + * Return a small string, for the given pubkey. + * @param pubkey + * @return + */ + public static String minifyPubkey(String pubkey) { + if (pubkey == null || pubkey.length() < 6) { + return pubkey; + } + return pubkey.substring(0, 6); + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertificationTime.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/TxOutput.java similarity index 59% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertificationTime.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/TxOutput.java index ab252203b985cd73c4f21a7e213598569b8197d7..13f9d1ff19f23784952f87ce4c355583fe152794 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertificationTime.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/TxOutput.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model; /* * #%L @@ -22,31 +22,30 @@ package io.ucoin.client.core.model; * #L% */ - -import java.io.Serializable; - -public class WotCertificationTime implements Serializable{ - - private static final long serialVersionUID = -358639516878884523L; - - private int block = -1; - - private int medianTime = -1; - - public int getBlock() { - return block; - } - - public void setBlock(int block) { - this.block = block; - } - - public int getMedianTime() { - return medianTime; - } - - public void setMedianTime(int medianTime) { - this.medianTime = medianTime; - } - -} + +import java.io.Serializable; + +public class TxOutput implements Serializable { + + private static final long serialVersionUID = 8084087351543574142L; + + private String pubKey; + + private long amount; + + public String getPubKey() { + return pubKey; + } + + public void setPubKey(String pubKey) { + this.pubKey = pubKey; + } + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java new file mode 100644 index 0000000000000000000000000000000000000000..4e15b92dbe6a4442e0772dc03fc47700e06d74af --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainBlock.java @@ -0,0 +1,373 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + + +import java.io.Serializable; + +/** + * A block from the blockchain. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public class BlockchainBlock implements Serializable { + + private static final long serialVersionUID = -5598140972293452669L; + + private String version; + private Integer nonce; + private Integer powMin; + private Integer number; + private Integer time; + private Integer medianTime; + private Integer membersCount; + private Long monetaryMass; + private String currency; + private String issuer; + private String signature; + private String hash; + private String parameters; + private String previousHash; + private String previousIssuer; + private Integer dividend; + private String[] membersChanges; + private Identity[] identities; + private Joiner[] joiners; + private String[] actives; + private String[] leavers; + private String[] excluded; + private String[] certifications; +// private int actives": [], +// private int transactions": [], + +// raw": "Version: 1\nType: Block\nCurrency: zeta_brouzouf\nNonce: 8233\nNumber: 1\nDate: 1416589860\nConfirmedDate: 1416589860\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nPreviousHash: 00006CD96A01378465318E48310118AC6B2F3625\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 4\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" + //private String raw; + + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public Integer getNonce() { + return nonce; + } + public void setNonce(Integer nonce) { + this.nonce = nonce; + } + + public Integer getPowMin() { + return powMin; + } + + public void setPowMin(Integer powMin) { + this.powMin = powMin; + } + + public Integer getNumber() { + return number; + } + public void setNumber(Integer number) { + this.number = number; + } + public Integer getTime() { + return time; + } + public void setTime(Integer time) { + this.time = time; + } + public Integer getMedianTime() { + return medianTime; + } + public void setMedianTime(Integer medianTime) { + this.medianTime = medianTime; + } + public Integer getMembersCount() { + return membersCount; + } + public void setMembersCount(Integer membersCount) { + this.membersCount = membersCount; + } + + public Long getMonetaryMass() { + return monetaryMass; + } + + public void setMonetaryMass(Long monetaryMass) { + this.monetaryMass = monetaryMass; + } + + public String getCurrency() { + return currency; + } + public void setCurrency(String currency) { + this.currency = currency; + } + public String getIssuer() { + return issuer; + } + public void setIssuer(String issuer) { + this.issuer = issuer; + } + public String getSignature() { + return signature; + } + public void setSignature(String signature) { + this.signature = signature; + } + public String getHash() { + return hash; + } + public void setHash(String hash) { + this.hash = hash; + } + public String getParameters() { + return parameters; + } + public void setParameters(String parameters) { + this.parameters = parameters; + } + public String getPreviousHash() { + return previousHash; + } + public void setPreviousHash(String previousHash) { + this.previousHash = previousHash; + } + public String getPreviousIssuer() { + return previousIssuer; + } + public void setPreviousIssuer(String previousIssuer) { + this.previousIssuer = previousIssuer; + } + public Integer getDividend() { + return dividend; + } + public void setDividend(Integer dividend) { + this.dividend = dividend; + } + public Identity[] getIdentities() { + return identities; + } + public void setIdentities(Identity[] identities) { + this.identities = identities; + } + public Joiner[] getJoiners() { + return joiners; + } + public void setJoiners(Joiner[] joiners) { + this.joiners = joiners; + } + + public String toString() { + String s = "version=" + version; + s += "\nnonce=" + nonce; + s += "\nnumber=" + number; + s += "\npowMin" + powMin; + s += "\ntime=" + time; + s += "\nmedianTime=" + medianTime; + s += "\nmembersCount=" + membersCount; + s += "\nmonetaryMass=" + monetaryMass; + s += "\ncurrency=" + currency; + s += "\nissuer=" + issuer; + s += "\nsignature=" + signature; + s += "\nhash=" + hash; + s += "\nparameters=" + parameters; + s += "\npreviousHash=" + previousHash; + s += "\npreviousIssuer=" + previousIssuer; + s += "\ndividend=" + dividend; + s += "\nmembersChanges:"; + if (membersChanges != null) { + for (String m : membersChanges) { + s += "\n\t" + m; + } + } + s += "\nidentities:"; + if (identities != null) { + for (Identity i : identities) { + s += "\n\t" + i.toString(); + } + } + s += "\njoiners:"; + if (joiners != null) { + for (Joiner j : joiners) { + s += "\n\t" + j.toString(); + } + } + s += "\nleavers:"; + if (leavers != null) { + for (String l : leavers) { + s += "\n\t" + l; + } + } + s += "\nexcluded:"; + if (excluded != null) { + for (String e : excluded) { + s += "\n\t" + e; + } + } + s += "\ncertifications:"; + if (certifications != null) { + for (String c : certifications) { + s += "\n\t" + c; + } + } + + return s; + } + + public static class Identity implements Serializable { + + private static final long serialVersionUID = 8080689271400316984L; + + private String pubkey; + + private String signature; + + private String uid; + + private long timestamp = -1; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder() + .append(":").append(pubkey) + .append(":").append(signature) + .append(":").append(timestamp) + .append("").append(uid); + + return sb.toString(); + } + } + + public static class Joiner extends Identity { + + private static final long serialVersionUID = 8448049949323699700L; + private String pubkey; + + private String signature; + + private String uid; + + private long timestamp = -1; + + private String number; + + private String hash; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + @Override + public String toString() { + + StringBuilder sb = new StringBuilder() + .append(":").append(pubkey) + .append(":").append(signature) + .append(":").append(number) + .append(":").append(hash) + .append(":").append(timestamp) + .append(":").append(uid); + + return sb.toString(); + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainMemberships.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainMemberships.java new file mode 100644 index 0000000000000000000000000000000000000000..1b969d2b38524aeb6dff26edf36c3a281b0a5195 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainMemberships.java @@ -0,0 +1,66 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +import io.ucoin.ucoinj.core.client.model.BasicIdentity; + +import java.io.Serializable; + +public class BlockchainMemberships extends BasicIdentity { + private static final long serialVersionUID = -5631089862725952431L; + + private long sigDate; + private Membership[] memberships; + + public long getSigDate() { + return sigDate; + } + public void setSigDate(long sigDate) { + this.sigDate = sigDate; + } + public Membership[] getMemberships() { + return memberships; + } + public void setMemberships(Membership[] memberships) { + this.memberships = memberships; + } + + public class Membership implements Serializable { + private static final long serialVersionUID = 1L; + + private String version; + private String currency; + private String membership; + private long blockNumber; + private String blockHash; + + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getCurrency() { + return currency; + } + public void setCurrency(String currency) { + this.currency = currency; + } + public String getMembership() { + return membership; + } + public void setMembership(String membership) { + this.membership = membership; + } + public long getBlockNumber() { + return blockNumber; + } + public void setBlockNumber(long blockNumber) { + this.blockNumber = blockNumber; + } + public String getBlockHash() { + return blockHash; + } + public void setBlockHash(String blockHash) { + this.blockHash = blockHash; + } + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainParameter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java similarity index 79% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainParameter.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java index 303108b2aa45579e12a0e3be723960b02e58e1ce..de3b0a8571dc9ab027989dfb1b5b98a9e2f68d87 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainParameter.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/BlockchainParameters.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model.bma; /* * #%L @@ -22,223 +22,229 @@ package io.ucoin.client.core.model; * #L% */ - -import java.io.Serializable; - -/** - * Blockwhain parameters. - * - * @author Benoit Lavenier <benoit.lavenier@e-is.pro> - * @since 1.0 - */ -public class BlockchainParameter implements Serializable { - - private static final long serialVersionUID = 929951447031659549L; - - private String currency; - - /** - * The %growth of the UD every [dt] period - */ - private Double c; - - /** - * Time period between two UD - */ - private Integer dt; - - /** - * UD(0), i.e. initial Universal Dividend - */ - private Integer ud0; - - /** - * Minimum delay between 2 identical certifications (same pubkeys) - */ - private Integer sigDelay; - - - /** - * Maximum age of a valid signature (in seconds) (e.g. 2629800) - */ - private Integer sigValidity; - - /** - * Minimum quantity of signatures to be part of the WoT (e.g. 3) - */ - private Integer sigQty; - - /** - * Minimum quantity of valid made certifications to be part of the WoT for distance rule - */ - private Integer sigWoT; - - /** - * Maximum age of a valid membership (in seconds) - */ - private Integer msValidity; - - /** - * Maximum distance between each WoT member and a newcomer - */ - private Integer stepMax; - - - /** - * Number of blocks used for calculating median time. - */ - private Integer medianTimeBlocks; - - /** - * The average time for writing 1 block (wished time) - */ - private Integer avgGenTime; - - /** - * The number of blocks required to evaluate again PoWMin value - */ - private Integer dtDiffEval; - - /** - * The number of previous blocks to check for personalized difficulty - */ - private Integer blocksRot; - - /** - * The percent of previous issuers to reach for personalized difficulty - */ - private Double percentRot; - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("currency: ").append(currency).append("\n") - .append("c: ").append(c).append("\n") - .append("dt: ").append(dt).append("\n") - .append("ud0: ").append(ud0).append("\n") - .append("sigDelay: ").append(sigDelay); - // TODO : display missing fields - return sb.toString(); - } - - public String getCurrency() { - return currency; - } - - public void setCurrency(String currency) { - this.currency = currency; - } - - public Double getC() { - return c; - } - - public void setC(Double c) { - this.c = c; - } - - public Integer getDt() { - return dt; - } - - public void setDt(Integer dt) { - this.dt = dt; - } - - public Integer getUd0() { - return ud0; - } - - public void setUd0(Integer ud0) { - this.ud0 = ud0; - } - - public Integer getSigDelay() { - return sigDelay; - } - - public void setSigDelay(Integer sigDelay) { - this.sigDelay = sigDelay; - } - - public Integer getSigValidity() { - return sigValidity; - } - - public void setSigValidity(Integer sigValidity) { - this.sigValidity = sigValidity; - } - - public Integer getSigQty() { - return sigQty; - } - - public void setSigQty(Integer sigQty) { - this.sigQty = sigQty; - } - - public Integer getSigWoT() { - return sigWoT; - } - - public void setSigWoT(Integer sigWoT) { - this.sigWoT = sigWoT; - } - - public Integer getMsValidity() { - return msValidity; - } - - public void setMsValidity(Integer msValidity) { - this.msValidity = msValidity; - } - - public Integer getStepMax() { - return stepMax; - } - - public void setStepMax(Integer stepMax) { - this.stepMax = stepMax; - } - - public Integer getMedianTimeBlocks() { - return medianTimeBlocks; - } - - public void setMedianTimeBlocks(Integer medianTimeBlocks) { - this.medianTimeBlocks = medianTimeBlocks; - } - - public Integer getAvgGenTime() { - return avgGenTime; - } - - public void setAvgGenTime(Integer avgGenTime) { - this.avgGenTime = avgGenTime; - } - - public Integer getDtDiffEval() { - return dtDiffEval; - } - - public void setDtDiffEval(Integer dtDiffEval) { - this.dtDiffEval = dtDiffEval; - } - - public Integer getBlocksRot() { - return blocksRot; - } - - public void setBlocksRot(Integer blocksRot) { - this.blocksRot = blocksRot; - } - - public Double getPercentRot() { - return percentRot; - } - - public void setPercentRot(Double percentRot) { - this.percentRot = percentRot; - } -} + +import java.io.Serializable; + +/** + * Blockwhain parameters. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public class BlockchainParameters implements Serializable{ + + private static final long serialVersionUID = 929951447031659549L; + + private String currency; + + /** + * The %growth of the UD every [dt] period + */ + private Double c; + + /** + * Time period between two UD + */ + private Integer dt; + + /** + * UD(0), i.e. initial Universal Dividend + */ + private Long ud0; + + /** + * Minimum delay between 2 identical certifications (same pubkeys) + */ + private Integer sigDelay; + + /** + * Maximum age of a valid signature (in seconds) (e.g. 2629800) + */ + private Integer sigValidity; + + /** + * Minimum quantity of signatures to be part of the WoT (e.g. 3) + */ + private Integer sigQty; + + /** + * Minimum quantity of valid made certifications to be part of the WoT for distance rule + */ + private Integer sigWoT; + + /** + * Maximum age of a valid membership (in seconds) + */ + private Integer msValidity; + + /** + * Maximum distance between each WoT member and a newcomer + */ + private Integer stepMax; + + /** + * Number of blocks used for calculating median time. + */ + private Integer medianTimeBlocks; + + /** + * The average time for writing 1 block (wished time) + */ + private Integer avgGenTime; + + /** + * The number of blocks required to evaluate again PoWMin value + */ + private Integer dtDiffEval; + + /** + * The number of previous blocks to check for personalized difficulty + */ + private Integer blocksRot; + + /** + * The percent of previous issuers to reach for personalized difficulty + */ + private Double percentRot; + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public Double getC() { + return c; + } + + public void setC(Double c) { + this.c = c; + } + + public Integer getDt() { + return dt; + } + + public void setDt(Integer dt) { + this.dt = dt; + } + + public Long getUd0() { + return ud0; + } + + public void setUd0(Long ud0) { + this.ud0 = ud0; + } + + public Integer getSigDelay() { + return sigDelay; + } + + public void setSigDelay(Integer sigDelay) { + this.sigDelay = sigDelay; + } + + public Integer getSigValidity() { + return sigValidity; + } + + public void setSigValidity(Integer sigValidity) { + this.sigValidity = sigValidity; + } + + public Integer getSigQty() { + return sigQty; + } + + public void setSigQty(Integer sigQty) { + this.sigQty = sigQty; + } + + public Integer getSigWoT() { + return sigWoT; + } + + public void setSigWoT(Integer sigWoT) { + this.sigWoT = sigWoT; + } + + public Integer getMsValidity() { + return msValidity; + } + + public void setMsValidity(Integer msValidity) { + this.msValidity = msValidity; + } + + public Integer getStepMax() { + return stepMax; + } + + public void setStepMax(Integer stepMax) { + this.stepMax = stepMax; + } + + public Integer getMedianTimeBlocks() { + return medianTimeBlocks; + } + + public void setMedianTimeBlocks(Integer medianTimeBlocks) { + this.medianTimeBlocks = medianTimeBlocks; + } + + public Integer getAvgGenTime() { + return avgGenTime; + } + + public void setAvgGenTime(Integer avgGenTime) { + this.avgGenTime = avgGenTime; + } + + public Integer getDtDiffEval() { + return dtDiffEval; + } + + public void setDtDiffEval(Integer dtDiffEval) { + this.dtDiffEval = dtDiffEval; + } + + public Integer getBlocksRot() { + return blocksRot; + } + + public void setBlocksRot(Integer blocksRot) { + this.blocksRot = blocksRot; + } + + public Double getPercentRot() { + return percentRot; + } + + public void setPercentRot(Double percentRot) { + this.percentRot = percentRot; + } + + @Override + public String toString() { + return new StringBuilder() + .append("currency=" ).append(currency) + .append("\nc=").append(c) + .append("\ndt=").append(dt) + .append("\nud0=").append(ud0) + .append("\nsigDelay=").append(sigDelay) + .append("\nsigValidity=").append(sigValidity) + .append("\nsigQty=").append(sigQty) + .append("\nsigWoT=").append(sigWoT) + .append("\nmsValidity=").append(msValidity) + .append("\nstepMax=").append(stepMax) + .append("\nmedianTimeBlocks=").append(medianTimeBlocks) + .append("\navgGenTime=").append(avgGenTime) + .append("\ndtDiffEval=").append(dtDiffEval) + .append("\nblocksRot=").append(blocksRot) + .append("\npercentRot=").append(percentRot) + .toString(); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/EndpointProtocol.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/EndpointProtocol.java new file mode 100644 index 0000000000000000000000000000000000000000..6ca68b783c45130bdeff15c954f7f768adca0f00 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/EndpointProtocol.java @@ -0,0 +1,7 @@ +package io.ucoin.ucoinj.core.client.model.bma; + + +public enum EndpointProtocol { + BASIC_MERKLED_API, + UNDEFINED +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java new file mode 100644 index 0000000000000000000000000000000000000000..5da32e752ad8594af27a46be90bb53108610bdbe --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeering.java @@ -0,0 +1,98 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +import java.io.Serializable; + +/** + * Created by eis on 05/02/15. + */ +public class NetworkPeering implements Serializable { + private String version; + private String currency; + private String status; + private String block; + private String signature; + // not need : private String raw + private String pubkey; + + public Endpoint[] endpoints; + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getBlock() { + return block; + } + + public void setBlock(String block) { + this.block = block; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String toString() { + String s = "currency=" + currency + "\n" + + "pubkey=" + pubkey + "\n" + + "signature=" + signature + "\n" + + "block=" + block + "\n"; + for(Endpoint endpoint : endpoints) { + s += endpoint.toString() + "\n"; + } + return s; + + } + + public static class Endpoint implements Serializable { + public EndpointProtocol protocol; + public String url; + public String ipv4; + public String ipv6; + public Integer port; + + @Override + public String toString() { + String s = "protocol=" + protocol.name() + "\n" + + "url=" + url + "\n" + + "ipv4=" + ipv4 + "\n" + + "ipv6=" + ipv6 + "\n" + + "port=" + port + "\n"; + return s; + } + } + + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeers.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeers.java new file mode 100644 index 0000000000000000000000000000000000000000..e50336b598aafb928da67396bb8ef0e3fa495829 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/NetworkPeers.java @@ -0,0 +1,42 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +import java.io.Serializable; + +/** + * Created by eis on 05/02/15. + */ +public class NetworkPeers implements Serializable { + + public Peer[] peers; + + public String toString() { + String s = ""; + for(Peer peer : peers) { + s += peer.toString() + "\n"; + } + return s; + } + + public static class Peer implements Serializable { + public String version; + public String currency; + public String status; + public String block; + public String signature; + public String pubkey; + public NetworkPeering.Endpoint[] endpoints; + + @Override + public String toString() { + String s = "version=" + version + "\n" + + "currency=" + currency + "\n" + + "pubkey=" + pubkey + "\n" + + "status=" + status + "\n" + + "block=" + block + "\n"; + for(NetworkPeering.Endpoint endpoint: endpoints) { + s += endpoint.toString() + "\n"; + } + return s; + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxHistory.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..012e5aa157e66c9bf27bbca78e80355c0ca72b0a --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxHistory.java @@ -0,0 +1,192 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +public class TxHistory { + + private String currency; + + private String pubkey; + + private History history; + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public History getHistory() { + return history; + } + + public void setHistory(History history) { + this.history = history; + } + + public class History { + + private Movement[] sent; + + private Movement[] received; + + private Movement[] sending; + + private Movement[] receiving; + + public Movement[] getSent() { + return sent; + } + + public void setSent(Movement[] sent) { + this.sent = sent; + } + + public Movement[] getReceived() { + return received; + } + + public void setReceived(Movement[] received) { + this.received = received; + } + + public Movement[] getSending() { + return sending; + } + + public void setSending(Movement[] sending) { + this.sending = sending; + } + + public Movement[] getReceiving() { + return receiving; + } + + public void setReceiving(Movement[] receiving) { + this.receiving = receiving; + } + } + + public static class Movement { + + private String version; + + private String[] issuers; + + private String[] inputs; + + private String[] outputs; + + private String comment; + + private String[] signatures; + + private String hash; + + private int block_number; + + private long time; + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String[] getIssuers() { + return issuers; + } + + public void setIssuers(String[] issuers) { + this.issuers = issuers; + } + + public String[] getInputs() { + return inputs; + } + + public void setInputs(String[] inputs) { + this.inputs = inputs; + } + + public String[] getOutputs() { + return outputs; + } + + public void setOutputs(String[] outputs) { + this.outputs = outputs; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String[] getSignatures() { + return signatures; + } + + public void setSignatures(String[] signatures) { + this.signatures = signatures; + } + + public String getHash() { + return hash; + } + + public String getFingerprint() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + /** + * @deprecated use getBlockNumber() instead + * @return + */ + @Deprecated + public int getBlock_number() { + return block_number; + } + + /** + * @deprecated use setBlockNumber() instead + * @return + */ + @Deprecated + public void setBlock_number(int block_number) { + this.block_number = block_number; + } + + public int getBlockNumber() { + return block_number; + } + + public void setNumber(int block_number) { + this.block_number = block_number; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxSource.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxSource.java new file mode 100644 index 0000000000000000000000000000000000000000..6ebac959464254978690a71a4309b4a5be0a549a --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/TxSource.java @@ -0,0 +1,127 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import java.io.Serializable; +import java.util.List; + +public class TxSource { + + private String currency; + + private String pubkey; + + private Source[] sources; + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public Source[] getSources() { + return sources; + } + + public void setSources(Source[] sources) { + this.sources = sources; + } + + public class Source implements Serializable, Cloneable { + + private static final long serialVersionUID = 8084087351543574142L; + + private String type; + private int number; + private String fingerprint; + private long amount; + + + @Override + public Object clone() throws CloneNotSupportedException { + + Source clone = (Source)super.clone(); + clone.type = type; + clone.number = number; + clone.fingerprint = fingerprint; + clone.amount = amount; + return clone; + } + + /** + * Source type : <ul> + * <li><code>D</code> : Universal Dividend</li> + * <li><code>T</code> : Transaction</li> + * </ul> + * @return + */ + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + /** + * The block number where the source has been written + * @return + */ + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public String getFingerprint() { + return fingerprint; + } + + public void setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + } + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } + } + + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotCertification.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotCertification.java new file mode 100644 index 0000000000000000000000000000000000000000..f319dc91a3e317d56ec47f455a85ec7be83d645e --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotCertification.java @@ -0,0 +1,152 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.bma.WotCertification; +import io.ucoin.ucoinj.core.client.model.local.Identity; + +import java.io.Serializable; +import java.util.List; + +/** + * A list of certifications done to user, or by user + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + * + */ +public class WotCertification implements Serializable{ + + private static final long serialVersionUID = 8568496827055074607L; + + private String pubkey; + + private String uid; + + private Certification[] certifications; + + public Certification[] getCertifications() { + return certifications; + } + + public void setCertifications(Certification[] certifications) { + this.certifications = certifications; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public class Certification extends Identity { + + private static final long serialVersionUID = 2204517069552693026L; + + public CertTime cert_time; + + /** + * Indicate whether the certification is written in the blockchain or not. + */ + private Written written; + + public CertTime getCert_time() { + return cert_time; + } + + public void setCert_time(CertTime cert_time) { + this.cert_time = cert_time; + } + + /** + * Indicate whether the certification is written in the blockchain or not. + */ + public Written getWritten() { + return written; + } + + public void setWritten(Written written) { + this.written = written; + } + + } + + public class CertTime implements Serializable { + + private static final long serialVersionUID = -358639516878884523L; + + private int block = -1; + + private long medianTime = -1; + + public int getBlock() { + return block; + } + + public void setBlock(int block) { + this.block = block; + } + + public long getMedianTime() { + return medianTime; + } + + public void setMedianTime(long medianTime) { + this.medianTime = medianTime; + } + + } + + public class Written implements Serializable{ + + private long number = -1; + + private String hash = ""; + + public long getNumber() { + return number; + } + + public void setNumber(long number) { + this.number = number; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java new file mode 100644 index 0000000000000000000000000000000000000000..8d1f97201842658fc23a54e3b3e5c400ff7d47f2 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/WotLookup.java @@ -0,0 +1,257 @@ +package io.ucoin.ucoinj.core.client.model.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import java.io.Serializable; + +public class WotLookup { + + public boolean partial; + public Result[] results; + + public boolean isPartial() { + return partial; + } + + public void setPartial(boolean partial) { + this.partial = partial; + } + + public Result[] getResults() { + return results; + } + + public void setResults(Result[] results) { + this.results = results; + } + + public String toString() { + String s = ""; + for (Result result : results) { + s = "pubkey=" + result.pubkey; + for (Uid uid : result.uids) { + s += "\nuid=" + uid.uid; + s += "\ntimestamp=" + uid.meta.timestamp; + s += "self=" + uid.self; + } + } + return s; + } + + public static class Result implements Serializable { + + private static final long serialVersionUID = -39452685440482106L; + + public String pubkey; + public Uid[] uids; + public SignedSignature[] signed; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public Uid[] getUids() { + return uids; + } + + public void setUids(Uid[] uids) { + this.uids = uids; + } + + public SignedSignature[] getSigned() { + return signed; + } + + public void setSigned(SignedSignature[] signed) { + this.signed = signed; + } + } + + public class Uid { + + public String uid; + public Meta meta; + public String self; + public OtherSignature[] others; + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public Meta getMeta() { + return meta; + } + + public void setMeta(Meta meta) { + this.meta = meta; + } + + public String getSelf() { + return self; + } + + public void setSelf(String self) { + this.self = self; + } + + public OtherSignature[] getOthers() { + return others; + } + + public void setOthers(OtherSignature[] others) { + this.others = others; + } + } + + + public class Meta implements Serializable { + public Long timestamp; + public Long block_number; + } + + public class OtherSignature { + + public String pubkey; + public Meta meta; + public String signature; + public String[] uids; + public boolean isMember; + public boolean wasMember; + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public Meta getMeta() { + return meta; + } + + public void setMeta(Meta meta) { + this.meta = meta; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public String[] getUids() { + return uids; + } + + public void setUids(String[] uids) { + this.uids = uids; + } + + public boolean isMember() { + return isMember; + } + + public void setMember(boolean member) { + isMember = member; + } + + public boolean isWasMember() { + return wasMember; + } + + public void setWasMember(boolean wasMember) { + this.wasMember = wasMember; + } + } + + public class SignedSignature { + + public String uid; + public String pubkey; + public Meta meta; + public String signature; + public boolean isMember; + public boolean wasMember; + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public Meta getMeta() { + return meta; + } + + public void setMeta(Meta meta) { + this.meta = meta; + } + + public String getSignature() { + return signature; + } + + public void setSignature(String signature) { + this.signature = signature; + } + + public boolean isMember() { + return isMember; + } + + public void setMember(boolean member) { + isMember = member; + } + + public boolean isWasMember() { + return wasMember; + } + + public void setWasMember(boolean wasMember) { + this.wasMember = wasMember; + } + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/EndpointAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/EndpointAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..492d55644a2432cf27f1c47e71acca9cce9db56b --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/EndpointAdapter.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import io.ucoin.ucoinj.core.client.model.bma.EndpointProtocol; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeering; +import org.apache.http.conn.util.InetAddressUtils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +public class EndpointAdapter extends TypeAdapter<NetworkPeering.Endpoint> { + + @Override + public NetworkPeering.Endpoint read(JsonReader reader) throws IOException { + if (reader.peek() == com.google.gson.stream.JsonToken.NULL) { + reader.nextNull(); + return null; + } + + String ept = reader.nextString(); + ArrayList<String> parts = new ArrayList<>(Arrays.asList(ept.split(" "))); + NetworkPeering.Endpoint endpoint = new NetworkPeering.Endpoint(); + endpoint.port = Integer.parseInt(parts.remove(parts.size() - 1)); + for (String word : parts) { + if (InetAddressUtils.isIPv4Address(word)) { + endpoint.ipv4 = word; + } else if (InetAddressUtils.isIPv6Address(word)) { + endpoint.ipv6 = word; + } else if (word.startsWith("http")) { + endpoint.url = word; + } else { + try { + endpoint.protocol = EndpointProtocol.valueOf(word); + } catch (IllegalArgumentException e) { + // skip this part + } + } + } + + if (endpoint.protocol == null) { + endpoint.protocol = EndpointProtocol.UNDEFINED; + } + + return endpoint; + } + + public void write(JsonWriter writer, NetworkPeering.Endpoint endpoint) throws IOException { + if (endpoint == null) { + writer.nullValue(); + return; + } + writer.value(endpoint.protocol.name() + " " + + endpoint.url + " " + + endpoint.ipv4 + " " + + endpoint.ipv6 + " " + + endpoint.port); + } + } \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..3b25dc9b8f2a5780f6d4c7a5261f25c512648254 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/GsonUtils.java @@ -0,0 +1,74 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.collect.Multimap; +import com.google.gson.GsonBuilder; +import io.ucoin.ucoinj.core.client.model.Member; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeering; +import io.ucoin.ucoinj.core.client.model.local.Identity; + +import java.util.List; + +public class GsonUtils { + + public static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public static GsonBuilder newBuilder() { + return new GsonBuilder() + // make sure date will be serialized + .setDateFormat(DATE_PATTERN) + // Register Multimap adapter + .registerTypeAdapter(Multimap.class, new MultimapTypeAdapter()) + // Register Blockchain.identity adapter + .registerTypeAdapter(BlockchainBlock.Identity.class, new IdentityTypeAdapter()) + // Register Blockchain.joiner adapter + .registerTypeAdapter(BlockchainBlock.Joiner.class, new JoinerTypeAdapter()) + // Register endpoint adpater + .registerTypeAdapter(NetworkPeering.Endpoint.class, new EndpointAdapter()) + ; + } + + public static List<String> getValuesFromJSONAsString(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValues(jsonString); + } + + public static String getValueFromJSONAsString(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsString(jsonString); + } + + public static Number getValueFromJSONAsNumber(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsNumber(jsonString); + } + + public static int getValueFromJSONAsInt(String jsonString, String attributeName) { + return new JsonAttributeParser(attributeName).getValueAsInt(jsonString); + } + + public static List<String> getArrayValuesFromJSONAsInt(String jsonString) { + return new JsonArrayParser().getValuesAsList(jsonString); + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..0f5c12c8a2a134655bea90642c40400749f0dce1 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/IdentityTypeAdapter.java @@ -0,0 +1,67 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.gson.*; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Type; + +public class IdentityTypeAdapter implements JsonDeserializer<BlockchainBlock.Identity>, JsonSerializer<BlockchainBlock.Identity>{ + + @Override + public BlockchainBlock.Identity deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + String identityStr = json.getAsString(); + if (StringUtils.isBlank(identityStr)) { + return null; + } + + String[] identityParts = identityStr.split(":"); + if (identityParts.length != 4) { + throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 4 parts, but found %s.", identityParts.length)); + } + + BlockchainBlock.Identity result = new BlockchainBlock.Identity(); + int i = 0; + + result.setPubkey(identityParts[i++]); + result.setSignature(identityParts[i++]); + result.setTimestamp(Integer.parseInt(identityParts[i++])); + result.setUid(identityParts[i++]); + + return result; + } + + @Override + public JsonElement serialize(BlockchainBlock.Identity identity, Type type, JsonSerializationContext context) { + String result = new StringBuilder() + .append(identity.getPubkey()).append(":") + .append(identity.getSignature()).append(":") + .append(identity.getTimestamp()).append(":") + .append(identity.getUid()).toString(); + + return context.serialize(result.toString(), String.class); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..f1a0582a089ed9b33746adf0cb650eacff473bc2 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JoinerTypeAdapter.java @@ -0,0 +1,72 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.gson.*; +import io.ucoin.ucoinj.core.client.model.Member; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Type; + +public class JoinerTypeAdapter implements JsonDeserializer<BlockchainBlock.Joiner>, JsonSerializer<BlockchainBlock.Joiner>{ + + @Override + public BlockchainBlock.Joiner deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + String identityStr = json.getAsString(); + if (StringUtils.isBlank(identityStr)) { + return null; + } + + String[] identityParts = identityStr.split(":"); + if (identityParts.length != 6) { + throw new JsonParseException(String.format("Bad format for BlockchainBlock.Identity. Should have 6 parts, but found %s.", identityParts.length)); + } + + BlockchainBlock.Joiner result = new BlockchainBlock.Joiner(); + int i = 0; + + result.setPubkey(identityParts[i++]); + result.setSignature(identityParts[i++]); + result.setNumber(identityParts[i++]); + result.setHash(identityParts[i++]); + result.setTimestamp(Integer.parseInt(identityParts[i++])); + result.setUid(identityParts[i++]); + + return result; + } + + @Override + public JsonElement serialize(BlockchainBlock.Joiner member, Type type, JsonSerializationContext context) { + String result = new StringBuilder() + .append(member.getPubkey()).append(":") + .append(member.getSignature()).append(":") + .append(member.getNumber()).append(":") + .append(member.getHash()).append(":") + .append(member.getTimestamp()).append(":") + .append(member.getUid()).toString(); + + return context.serialize(result.toString(), String.class); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParser.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParser.java new file mode 100644 index 0000000000000000000000000000000000000000..6d580572c0d51a24d6728c0dd8f1b5a405221879 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParser.java @@ -0,0 +1,69 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +import com.google.gson.JsonParseException; +import io.ucoin.ucoinj.core.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Parse JSON array content, without deserialize each item. + * + * Created by blavenie on 05/01/16. + */ +public class JsonArrayParser { + + enum ParserState { + READING_OBJECT, + READING_ARRAY + } + + public String[] getValuesAsArray(String jsonArray) throws JsonParseException { + List<String> result = getValuesAsList(jsonArray); + if (CollectionUtils.isEmpty(result)) { + return null; + } + return result.toArray(new String[result.size()]); + } + + public List<String> getValuesAsList(String jsonArray) throws JsonParseException { + ParserState state = ParserState.READING_ARRAY; + List<String> result = new ArrayList<String>(); + StringBuilder currentObject = null; + int i = 0; + int parenthesisBalance = 0; + for (char c : jsonArray.toCharArray()) { + switch (c) { + case '{': { + if (state == ParserState.READING_ARRAY) { + state = ParserState.READING_OBJECT; + currentObject = new StringBuilder(); + } + parenthesisBalance++; + currentObject.append(c); + break; + } + case '}': { + if (state == ParserState.READING_ARRAY) { + throw new JsonParseException("unexpected '}' at " + i); + } else { + currentObject.append(c); + parenthesisBalance--; + if (parenthesisBalance == 0) { + state = ParserState.READING_ARRAY; + result.add(currentObject.toString()); + } + } + break; + } + default: { + if (state == ParserState.READING_OBJECT) { + currentObject.append(c); + } + } + } + i++; + } + return result; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonAttributeParser.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonAttributeParser.java new file mode 100644 index 0000000000000000000000000000000000000000..a63a75c402caa1c0f542dac99e4619b1e681f5ee --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonAttributeParser.java @@ -0,0 +1,78 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.ObjectUtils; + +import java.text.DecimalFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JsonAttributeParser { + + public static final String REGEX_ATTRIBUTE_STRING_VALUE = "\\\"%s\\\"\\s*:\\s*\"([^\"]+)\\\""; + public static final String REGEX_ATTRIBUTE_NUMERIC_VALUE = "\\\"%s\\\"\\s*:\\s*([\\d]+(?:[.][\\d]+)?)"; + + private Pattern pattern; + private Pattern numericPattern; + private DecimalFormat decimalFormat; + private String attributeName; + + public JsonAttributeParser(String attributeName) { + ObjectUtils.checkNotNull(attributeName); + + this.attributeName = attributeName; + this.numericPattern = Pattern.compile(String.format(REGEX_ATTRIBUTE_NUMERIC_VALUE, attributeName)); + this.pattern = Pattern.compile(String.format(REGEX_ATTRIBUTE_STRING_VALUE, attributeName)); + this.decimalFormat = new DecimalFormat(); + this.decimalFormat.getDecimalFormatSymbols().setDecimalSeparator('.'); + } + + public Number getValueAsNumber(String jsonString) { + ObjectUtils.checkNotNull(jsonString); + + Matcher matcher = numericPattern.matcher(jsonString); + + if (!matcher.find()) { + return null; + } + String group = matcher.group(1); + try { + Number result = decimalFormat.parse(group); + return result; + } catch (ParseException e) { + throw new TechnicalException(String.format("Error while parsing json numeric value, for attribute [%s]: %s", attributeName,e.getMessage()), e); + } + } + + public int getValueAsInt(String jsonString) { + Number numberValue = getValueAsNumber(jsonString); + if (numberValue == null) { + return 0; + } + return numberValue.intValue(); + } + + public String getValueAsString(String jsonString) { + Matcher matcher = pattern.matcher(jsonString); + if (!matcher.find()) { + return null; + } + + return matcher.group(1); + } + + public List<String> getValues(String jsonString) { + Matcher matcher = pattern.matcher(jsonString); + List<String> result = new ArrayList<>(); + while (matcher.find()) { + String group = matcher.group(1); + result.add(group); + } + + return result; + } + + } \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/MultimapTypeAdapter.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/MultimapTypeAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..9c705572b4c7388f6bb88a6919e1c9c066f70b25 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/MultimapTypeAdapter.java @@ -0,0 +1,68 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.gson.*; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Map; + +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class MultimapTypeAdapter implements JsonSerializer<Multimap>, JsonDeserializer<Multimap> { + + @Override + public JsonElement serialize(final Multimap src, final Type typeOfSrc, final JsonSerializationContext context) { + return context.serialize(src.asMap(), createMapType(typeOfSrc)); + } + + @Override + public Multimap deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) + throws JsonParseException { + final Multimap multimap = HashMultimap.create(); + final Map map = context.deserialize(json, createMapType(typeOfT)); + for (final Object key : map.keySet()) { + final Collection values = (Collection) map.get(key); + multimap.putAll(key, values); + } + + return multimap; + } + + private Type createMapType(final Type multimapType) { + Preconditions.checkArgument(multimapType instanceof ParameterizedType); + final ParameterizedType paramType = (ParameterizedType)multimapType; + final Type[] typeArguments = paramType.getActualTypeArguments(); + Preconditions.checkArgument(2 == typeArguments.length, "Type must contain exactly 2 type arguments."); + + final ParameterizedTypeImpl valueType = new ParameterizedTypeImpl(Collection.class, null, typeArguments[1]); + final ParameterizedTypeImpl mapType = new ParameterizedTypeImpl(Map.class, null, typeArguments[0], valueType); + return mapType; + } + +} \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/ParameterizedTypeImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/ParameterizedTypeImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6efce1000d23f1afa8fd781c2636310cab3f4d9c --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/bma/gson/ParameterizedTypeImpl.java @@ -0,0 +1,57 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +public class ParameterizedTypeImpl implements ParameterizedType { + + private final Type rawType; + private final Type ownerType; + private final Type[] typeArguments; + + public ParameterizedTypeImpl(final Type rawType, final Type ownerType, final Type... typeArguments) { + this.rawType = rawType; + this.ownerType = ownerType; + this.typeArguments = typeArguments; + } + + @Override + public Type[] getActualTypeArguments() { + return typeArguments; + } + + @Override + public Type getRawType() { + return rawType; + } + + @Override + public Type getOwnerType() { + return ownerType; + } + +} \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/elasticsearch/Currency.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/elasticsearch/Currency.java new file mode 100644 index 0000000000000000000000000000000000000000..bc9a7c5f59731fb0df6530e38349c4571ed9640f --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/elasticsearch/Currency.java @@ -0,0 +1,109 @@ +package io.ucoin.ucoinj.core.client.model.elasticsearch; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.io.Serializable; + +/** + * Created by eis on 05/02/15. + */ +public class Currency implements Serializable { + + private String currencyName; + private Integer membersCount; + private String firstBlockSignature; + private Long lastUD; + private BlockchainParameters parameters; + private Peer peers[]; + + private String[] tags; + private String senderPubkey; + + public String getCurrencyName() { + return currencyName; + } + + public void setCurrencyName(String currencyName) { + this.currencyName = currencyName; + } + + public Integer getMembersCount() { + return membersCount; + } + + public void setMembersCount(Integer membersCount) { + this.membersCount = membersCount; + } + + public String getFirstBlockSignature() { + return firstBlockSignature; + } + + public void setFirstBlockSignature(String firstBlockSignature) { + this.firstBlockSignature = firstBlockSignature; + } + + public Long getLastUD() { + return lastUD; + } + + public void setLastUD(Long lastUD) { + this.lastUD = lastUD; + } + + public BlockchainParameters getParameters() { + return parameters; + } + + public void setParameters(BlockchainParameters parameters) { + this.parameters = parameters; + } + + public Peer[] getPeers() { + return peers; + } + + public void setPeers(Peer[] peers) { + this.peers = peers; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public String getSenderPubkey() { + return senderPubkey; + } + + public void setSenderPubkey(String senderPubkey) { + this.senderPubkey = senderPubkey; + } +} \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Certification.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Certification.java new file mode 100644 index 0000000000000000000000000000000000000000..65237b2fd015df831c47d261b5563b4da8a5b131 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Certification.java @@ -0,0 +1,124 @@ +package io.ucoin.ucoinj.core.client.model.local; + + +import io.ucoin.ucoinj.core.util.ObjectUtils; + +/** + * A certification, return by <code>/wot/certified-by/[uid]</code> or <code>/wot/certifiers-of/[uid]</code> + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + * + */ +public class Certification { + + private static final long serialVersionUID = 2204517069552693026L; + + private long currencyId; + + private String uid; + + private String pubkey; + + private long timestamp; + + /** + * Give the other side certicication + * (not in protocol: fill by the service) + */ + private Certification otherEnd; + + + /** + * Indicate whether the certification is valid for membership request. + * (not in protocol: fill by the service) + */ + private boolean valid = false; + + /** + * Given the certification side. If true, certified-by, + * if false, certifier of + */ + private boolean isCertifiedBy; + + private boolean isMember; + + public Certification() { + super(); + } + + public long getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(long currencyId) { + this.currencyId = currencyId; + } + + public Certification getOtherEnd() { + return otherEnd; + } + + public void setOtherEnd(Certification otherEnd) { + this.otherEnd = otherEnd; + } + + public boolean isCertifiedBy() { + return isCertifiedBy; + } + + public void setCertifiedBy(boolean isCertifiedBy) { + this.isCertifiedBy = isCertifiedBy; + } + + public boolean isValid() { + return valid; + } + + public void setValid(boolean valid) { + this.valid = valid; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long certTime) { + this.timestamp = timestamp; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getPubkey() { + return pubkey; + } + + public void setPubkey(String pubkey) { + this.pubkey = pubkey; + } + + public boolean isMember() { + return isMember; + } + + public void setMember(boolean member) { + isMember = member; + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (o instanceof Certification) { + Certification wc = (Certification)o; + return ObjectUtils.equals(timestamp, wc.timestamp); + } + return false; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Contact.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Contact.java new file mode 100644 index 0000000000000000000000000000000000000000..4274e8ba876ef031011e19c56f9f36245cf64a51 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Contact.java @@ -0,0 +1,100 @@ +package io.ucoin.ucoinj.core.client.model.local; + +import io.ucoin.ucoinj.core.util.ObjectUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * A wallet is a user account + * Created by eis on 13/01/15. + */ +public class Contact implements LocalEntity, Serializable { + + private long id; + private long accountId; + private String name; + private long phoneContactId = 0; + private List<Identity> identities = new ArrayList<Identity>(); + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List<Identity> getIdentities() { + return identities; + } + + public void setIdentities(List<Identity> identities) { + this.identities = identities; + } + + public void addIdentity(Identity identity) { + this.identities.add(identity); + } + + public Long getPhoneContactId() { + return phoneContactId; + } + + public void setPhoneContactId(Long phoneContactId) { + this.phoneContactId = phoneContactId; + } + + @Override + public String toString() { + return name; + } + + public void copy(Contact contact) { + this.id = contact.id; + this.accountId = contact.accountId; + this.name = contact.name; + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (o instanceof Contact) { + Contact bi = (Contact)o; + return ObjectUtils.equals(this.id, bi.id) + && ObjectUtils.equals(this.accountId, bi.accountId) + && ObjectUtils.equals(this.name, bi.name); + } + return false; + } + + public boolean hasIdentityForCurrency(long currencyId) { + for(Identity identity:identities) { + if (identity.getCurrencyId() != null && identity.getCurrencyId().longValue() == currencyId) { + return true; + } + } + return false; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Currency.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Currency.java new file mode 100644 index 0000000000000000000000000000000000000000..ca92c6af95bff66f73609274d1b9f35e8ffb04d7 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Currency.java @@ -0,0 +1,115 @@ +package io.ucoin.ucoinj.core.client.model.local; + +import java.io.Serializable; + +import io.ucoin.ucoinj.core.client.model.Account; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; + +/** + * Created by eis on 05/02/15. + */ +public class Currency implements LocalEntity, Serializable { + + private Peer peers[]; + + private Long id; + private String currencyName; + private Integer membersCount; + private String firstBlockSignature; + private Account account; + private Long accountId; + private Long lastUD; + private BlockchainParameters parameters; + + public Currency() { + } + + public Currency(String currencyName, + String firstBlockSignature, + int membersCount, + Peer[] peers, + BlockchainParameters parameters) { + this.currencyName = currencyName; + this.firstBlockSignature = firstBlockSignature; + this.membersCount = membersCount; + this.peers = peers; + this.parameters = parameters; + } + + public Long getId() { + return id; + } + + public String getCurrencyName() + { + return currencyName; + } + + public Integer getMembersCount() { + return membersCount; + } + + public String getFirstBlockSignature() { + return firstBlockSignature; + } + + public Peer[] getPeers() { + return peers; + } + + public void setPeers(Peer[] peers) { + this.peers = peers; + } + + public void setId(Long id) { + this.id = id; + } + + public void setCurrencyName(String currencyName) { + this.currencyName = currencyName; + } + + public void setMembersCount(Integer membersCount) { + this.membersCount = membersCount; + } + + public void setFirstBlockSignature(String firstBlockSignature) { + this.firstBlockSignature = firstBlockSignature; + } + + public Account getAccount() { + return account; + } + + public void setAccount(Account account) { + this.account = account; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public Long getLastUD() { + return lastUD; + } + + public void setLastUD(Long lastUD) { + this.lastUD = lastUD; + } + + public BlockchainParameters getParameters() { + return parameters; + } + + public void setParameters(BlockchainParameters parameters) { + this.parameters = parameters; + } + + public String toString() { + return currencyName; + } +} \ No newline at end of file diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertification.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java similarity index 51% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertification.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java index be425b80f62087cad318f770c38a28371dffdf8e..e9c326c62bc3885a2d74306f0b5db637d631670a 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotCertification.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Identity.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.model.local; /* * #%L @@ -22,42 +22,47 @@ package io.ucoin.client.core.model; * #L% */ - - -/** - * A certification, return by <code>/wot/certified-by/[uid]</code> or <code>/wot/certifiers-of/[uid]</code> - * @author Benoit Lavenier <benoit.lavenier@e-is.pro> - * @since 1.0 - * - */ -public class WotCertification extends BasicIdentity{ - - private static final long serialVersionUID = 2204517069552693026L; - - public WotCertificationTime cert_time; - - /** - * Indicate whether the certification is written in the blockchain or not. - */ - public boolean written; - - public WotCertificationTime getCert_time() { - return cert_time; - } - - public void setCert_time(WotCertificationTime cert_time) { - this.cert_time = cert_time; - } - - /** - * Indicate whether the certification is written in the blockchain or not. - */ - public boolean isWritten() { - return written; - } - - public void setWritten(boolean written) { - this.written = written; - } - -} + +import io.ucoin.ucoinj.core.client.model.BasicIdentity; + +public class Identity extends BasicIdentity { + + private static final long serialVersionUID = -7451079677730158794L; + + private long timestamp = -1; + + private Boolean isMember = null; + + private Long currencyId; + + /** + * The timestamp value of the signature date + * @return + */ + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /** + * Indicate whether the certification is written in the blockchain or not. + */ + public Boolean getIsMember() { + return isMember; + } + + public void setMember(Boolean isMember) { + this.isMember = isMember; + } + + public Long getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(Long currencyId) { + this.currencyId = currencyId; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/LocalEntity.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/LocalEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..79092c42d29264d281b9148b84904c0f9b70515a --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/LocalEntity.java @@ -0,0 +1,33 @@ +package io.ucoin.ucoinj.core.client.model.local; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +/** + * Created by eis on 07/02/15. + */ +public interface LocalEntity { + + Long getId(); + void setId(Long id); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Movement.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Movement.java new file mode 100644 index 0000000000000000000000000000000000000000..456fe33aefde2bac05e5b3fa058b24dac1fd3e3a --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Movement.java @@ -0,0 +1,116 @@ +package io.ucoin.ucoinj.core.client.model.local; + +import java.io.Serializable; + +/** + * A wallet's movement (DU or transfer) + * @author + */ +public class Movement implements LocalEntity, Serializable { + + private Long id; + private long walletId; + private long amount; + private Long time; + private Integer blockNumber; + private long dividend; + private boolean isUD = false; + private String fingerprint; + private String comment; + private String issuers; + private String receivers; + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public long getWalletId() { + return walletId; + } + + public void setWalletId(long walletId) { + this.walletId = walletId; + } + + public long getAmount() { + return amount; + } + + public void setAmount(long amount) { + this.amount = amount; + } + + public Long getTime() { + return time; + } + + public void setTime(Long time) { + this.time = time; + } + + public Integer getBlockNumber() { + return blockNumber; + } + + public void setBlockNumber(Integer blockNumber) { + this.blockNumber = blockNumber; + } + + public boolean isUD() { + return isUD; + } + + public void setUD(boolean isUD) { + this.isUD = isUD; + } + + public String getFingerprint() { + return fingerprint; + } + + public void setFingerprint(String fingerprint) { + this.fingerprint = fingerprint; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public boolean isValidate() { + return blockNumber != null; + } + + public String getIssuers() { + return issuers; + } + + public void setIssuers(String issuers) { + this.issuers = issuers; + } + + public void setReceivers(String receivers) { + this.receivers = receivers; + } + + public String getReceivers() { + return receivers; + } + + public long getDividend() { + return dividend; + } + + public void setDividend(long dividend) { + this.dividend = dividend; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Peer.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Peer.java new file mode 100644 index 0000000000000000000000000000000000000000..ea69c7570ebf20018fe25085f8388c47eaedc019 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Peer.java @@ -0,0 +1,107 @@ +package io.ucoin.ucoinj.core.client.model.local; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import java.io.Serializable; + +public class Peer implements LocalEntity, Serializable { + + private Long id; + private Long currencyId; + private String host; + private int port; + private String url; + + public Peer() { + // default constructor, need for de-serialization + } + + public Peer(String host, int port) { + this.host = host; + this.port = port; + this.url = initUrl(host, port); + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public String getUrl() { + return url; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(Long currencyId) { + this.currencyId = currencyId; + } + + public void setPort(int port) { + this.port = port; + this.url = initUrl(host, port); + } + + public void setHost(String host) { + this.host = host; + this.url = initUrl(host, port); + } + + public String toString() { + return new StringBuilder().append("url=").append(url).append(",") + .append("host=").append(host).append(",") + .append("port=").append(port) + .toString(); + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (id != null && o instanceof Peer) { + return id.equals(((Peer)o).getId()); + } + return super.equals(o); + } + + /* -- Internal methods -- */ + + protected String initUrl(String host, int port) { + return String.format("http://%s:%s", host, port); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java new file mode 100644 index 0000000000000000000000000000000000000000..3581aef57e5c7403ce23f059fc793fd2f3a14b44 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/model/local/Wallet.java @@ -0,0 +1,220 @@ +package io.ucoin.ucoinj.core.client.model.local; + +import java.io.Serializable; +import java.util.Collection; + +import io.ucoin.ucoinj.core.client.model.bma.WotCertification; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import io.ucoin.ucoinj.core.util.crypto.KeyPair; + +/** + * A wallet is a user account + * Created by eis on 13/01/15. + */ +public class Wallet extends KeyPair implements LocalEntity, Serializable { + + + private Long id; + private Long currencyId; + private Long accountId; + private String name; + private Long credit; + private Identity identity; + private Double creditAsUD; + private long blockNumber = -1; + private long txBlockNumber = -1; + private Collection<WotCertification> certifications; + + /** + * Use for UI, when some properties has not been displayed yet + */ + private boolean isDirty = false; + + // TODO : voir si besoin de les garder ou pas + private String salt; + private String currency; + + public Wallet() { + super(null, null); + this.identity = new Identity(); + } + + public Wallet(String currency, String uid, byte[] pubKey, byte[] secKey) { + super(pubKey, secKey); + this.currency = currency; + this.identity = new Identity(); + this.identity.setPubkey(pubKey == null ? null : CryptoUtils.encodeBase58(pubKey)); + this.identity.setUid(uid); + } + + public Wallet(String currency, String uid, String pubKey, String secKey) { + super(CryptoUtils.decodeBase58(pubKey), secKey == null ? null : CryptoUtils.decodeBase58(secKey)); + this.currency = currency; + this.identity = new Identity(); + this.identity.setPubkey(pubKey); + this.identity.setUid(uid); + } + + public Wallet(String currency, byte[] secKey, Identity identity) { + super(CryptoUtils.decodeBase58(identity.getPubkey()), secKey); + this.currency = currency; + this.identity = identity; + } + + public Identity getIdentity() { + return identity; + } + + public void setIdentity(Identity identity) { + this.identity = identity; + } + + public String getPubKeyHash() { + return identity.getPubkey(); + } + + public String getSalt(){ + return salt; + } + + public void setSalt(String salt){ + this.salt = salt; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } + + public boolean isAuthenticate() { + return secretKey != null && identity != null && identity.getPubkey() != null; + } + + public boolean isSelfSend() { + return identity.getTimestamp() != -1; + } + + public Long getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(Long currencyId) { + this.currencyId = currencyId; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getCredit() { + return credit; + } + + public void setCredit(Long credit) { + this.credit = credit; + } + + @Override + public Long getId() { + return id; + } + + @Override + public void setId(Long id) { + this.id = id; + } + + public String toString() { + return name; + } + + public String getUid() { + return identity.getUid(); + } + + public void setUid(String uid) { + identity.setUid(uid); + } + + public long getCertTimestamp() { + return identity.getTimestamp(); + } + + public void setCertTimestamp(long timestamp) { + identity.setTimestamp(timestamp); + } + + public void setMember(Boolean isMember) { + identity.setMember(isMember); + } + + public Boolean getIsMember() { + return identity.getIsMember(); + } + + public boolean isDirty() { + return isDirty; + } + + public void setDirty(boolean isDirty) { + this.isDirty = isDirty; + } + + public Double getCreditAsUD() { + return creditAsUD; + } + + public void setCreditAsUD(Double creditAsUD) { + this.creditAsUD = creditAsUD; + } + + public Collection<WotCertification> getCertifications() { + return certifications; + } + + public void setCertifications(Collection<WotCertification> certifications) { + this.certifications = certifications; + } + + public long getBlockNumber() { + return blockNumber; + } + + public void setBlockNumber(long blockNumber) { + this.blockNumber = blockNumber; + } + + public long getTxBlockNumber() { + return txBlockNumber; + } + + public void setTxBlockNumber(long txBlockNumber) { + this.txBlockNumber = txBlockNumber; + } + + @Override + public boolean equals(Object o) { + if (o instanceof Wallet) { + return ObjectUtils.equals(id, ((Wallet)o).id) + && ObjectUtils.equals(getPubKeyHash(), ((Wallet)o).getPubKeyHash()) + && ObjectUtils.equals(currencyId, ((Wallet)o).currencyId); + } + return super.equals(o); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/DataContext.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/DataContext.java new file mode 100644 index 0000000000000000000000000000000000000000..379e38d6285beca700a72ddb1873b76ce1b27889 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/DataContext.java @@ -0,0 +1,40 @@ +package io.ucoin.ucoinj.core.client.service; + +import io.ucoin.ucoinj.core.beans.Bean; + +import java.io.Closeable; +import java.io.IOException; + +/** + * Hold some contextual data, such as account id + * Created by blavenie on 29/12/15. + */ +public class DataContext implements Bean, Closeable{ + + private long accountId = -1; + + public DataContext() { + + } + + @Override + public void close() throws IOException { + clear(); + } + + public void clear() { + accountId = -1; + } + + /* -- getter/setter-- */ + + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + /* -- protected methods -- */ +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpService.java new file mode 100644 index 0000000000000000000000000000000000000000..b2ae1202fc50f8075def2bfd5685e073b142bf02 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpService.java @@ -0,0 +1,26 @@ +package io.ucoin.ucoinj.core.client.service; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.exception.PeerConnectionException; +import org.apache.http.client.methods.HttpUriRequest; + +/** + * Created by blavenie on 29/12/15. + */ +public interface HttpService extends Service { + + void connect(Peer peer) throws PeerConnectionException; + + boolean isConnected(); + + <T> T executeRequest(HttpUriRequest request, Class<? extends T> resultClass) ; + + <T> T executeRequest(String absolutePath, Class<? extends T> resultClass) ; + + <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass); + + String getPath(Peer peer, String absolutePath); + + String getPath(String absolutePath); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..be0a7e47105b54449e64a5b715d7ec40a0236a9c --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/HttpServiceImpl.java @@ -0,0 +1,305 @@ +package io.ucoin.ucoinj.core.client.service; + +import com.google.gson.Gson; +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; +import io.ucoin.ucoinj.core.client.service.exception.JsonSyntaxException; +import io.ucoin.ucoinj.core.client.service.exception.PeerConnectionException; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.nio.charset.StandardCharsets; + +/** + * Created by eis on 05/02/15. + */ +public class HttpServiceImpl implements HttpService, Closeable, InitializingBean{ + + private static final Logger log = LoggerFactory.getLogger(HttpServiceImpl.class); + + private static final String USER_AGENT = "Android"; + + public static final String URL_PEER_ALIVE = "/blockchain/parameters"; + + protected Integer baseTimeOut; + protected Gson gson; + protected HttpClient httpClient; + protected Peer defaultPeer; + private boolean debug; + + public HttpServiceImpl() { + super(); + this.debug = log.isDebugEnabled(); + } + + @Override + public void afterPropertiesSet() throws Exception { + Configuration config = Configuration.instance(); + this.gson = GsonUtils.newBuilder().create(); + this.baseTimeOut = config.getNetworkTimeout(); + this.httpClient = createHttpClient(); + } + + public void connect(Peer peer) throws PeerConnectionException { + if (peer == null) { + throw new IllegalArgumentException("argument 'peer' must not be null"); + } + if (httpClient == null) { + httpClient = createHttpClient(); + } + if (peer == defaultPeer) { + return; + } + + HttpGet httpGet = new HttpGet(getPath(peer, URL_PEER_ALIVE)); + boolean isPeerAlive = false; + try { + isPeerAlive = executeRequest(httpClient, httpGet); + } catch(TechnicalException e) { + this.defaultPeer = null; + throw new PeerConnectionException(e); + } + if (!isPeerAlive) { + this.defaultPeer = null; + throw new PeerConnectionException("Unable to connect to peer: " + peer.toString()); + } + this.defaultPeer = peer; + } + + public boolean isConnected() { + return this.defaultPeer != null; + } + + @Override + public void close() throws IOException { + if (httpClient instanceof CloseableHttpClient) { + ((CloseableHttpClient)httpClient).close(); + } + else if (httpClient instanceof Closeable) { + ((Closeable)httpClient).close(); + } + httpClient = null; + } + + public <T> T executeRequest(HttpUriRequest request, Class<? extends T> resultClass) { + return executeRequest(httpClient, request, resultClass); + } + + public <T> T executeRequest(String absolutePath, Class<? extends T> resultClass) { + HttpGet httpGet = new HttpGet(getPath(absolutePath)); + return executeRequest(httpClient, httpGet, resultClass); + } + + public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass) { + HttpGet httpGet = new HttpGet(getPath(peer, absolutePath)); + return executeRequest(httpClient, httpGet, resultClass); + } + + public String getPath(Peer peer, String absolutePath) { + return new StringBuilder().append(peer.getUrl()).append(absolutePath).toString(); + } + + + public String getPath(String absolutePath) { + checkDefaultPeer(); + return new StringBuilder().append(defaultPeer.getUrl()).append(absolutePath).toString(); + } + + + /* -- Internal methods -- */ + + protected void checkDefaultPeer() { + if (defaultPeer == null) { + throw new IllegalStateException("No peer to connect"); + } + } + + protected HttpClient createHttpClient() { + CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(getRequestConfig()) + // .setDefaultCredentialsProvider(getCredentialsProvider()) + .build(); + return httpClient; + } + + protected RequestConfig getRequestConfig() { + // build request config for timeout + return RequestConfig.custom().setSocketTimeout(baseTimeOut).setConnectTimeout(baseTimeOut).build(); + } + + @SuppressWarnings("unchecked") + protected <T> T executeRequest(HttpClient httpClient, HttpUriRequest request, Class<? extends T> resultClass) { + T result = null; + + if (log.isDebugEnabled()) { + log.debug("Executing request : " + request.getRequestLine()); + } + + HttpResponse response = null; + try { + response = httpClient.execute(request); + + if (log.isDebugEnabled()) { + log.debug("Received response : " + response.getStatusLine()); + } + + switch (response.getStatusLine().getStatusCode()) { + case HttpStatus.SC_OK: { + result = (T) parseResponse(response, resultClass); + + response.getEntity().consumeContent(); + break; + } + case HttpStatus.SC_UNAUTHORIZED: + case HttpStatus.SC_FORBIDDEN: + throw new TechnicalException("ucoinj.client.authentication"); + case HttpStatus.SC_BAD_REQUEST: + throw new HttpBadRequestException("ucoinj.client.status" + response.getStatusLine().toString()); + default: + throw new TechnicalException("ucoinj.client.status" + response.getStatusLine().toString()); + } + } + catch (ConnectException e) { + throw new TechnicalException("ucoinj.client.core.connect", e); + } + catch (SocketTimeoutException e) { + throw new TechnicalException("ucoinj.client.core.timeout", e); + } + catch (IOException e) { + throw new TechnicalException(e.getMessage(), e); + } + finally { + // Close is need + if (response instanceof CloseableHttpResponse) { + try { + ((CloseableHttpResponse) response).close(); + } + catch(IOException e) { + // Silent is gold + } + } + } + + return result; + } + + protected Object parseResponse(HttpResponse response, Class<?> ResultClass) throws IOException { + Object result = null; + + boolean stringOutput = ResultClass != null && ResultClass.equals(String.class); + + // If trace enable, log the response before parsing + Exception error = null; + if (stringOutput) { + InputStream content = null; + try { + content = response.getEntity().getContent(); + String stringContent = getContentAsString(content); + if (log.isDebugEnabled()) { + log.debug("Parsing response:\n" + stringContent); + } + + return stringContent; + } + finally { + if (content!= null) { + content.close(); + } + } + } + + // trace not enable + else { + InputStream content = null; + try { + content = response.getEntity().getContent(); + Reader reader = new InputStreamReader(content, StandardCharsets.UTF_8); + if (ResultClass != null) { + result = gson.fromJson(reader, ResultClass); + } + else { + result = null; + } + } + catch (com.google.gson.JsonSyntaxException e) { + if (content != null) { + log.warn("Error while parsing JSON response: " + getContentAsString(content), e); + } + else { + log.warn("Error while parsing JSON response", e); + } + throw new JsonSyntaxException("ucoin.client.core.invalidResponse", e); + } + catch (Exception e) { + throw new TechnicalException("ucoin.client.core.invalidResponse", e); + } + finally { + if (content!= null) { + content.close(); + } + } + } + + if (result == null) { + throw new TechnicalException("ucoin.client.core.emptyResponse"); + } + + return result; + } + + protected String getContentAsString(InputStream content) throws IOException { + Reader reader = new InputStreamReader(content, StandardCharsets.UTF_8); + StringBuilder result = new StringBuilder(); + char[] buf = new char[64]; + int len = 0; + while((len = reader.read(buf)) != -1) { + result.append(buf, 0, len); + } + return result.toString(); + } + + protected boolean executeRequest(HttpClient httpClient, HttpUriRequest request) { + + if (log.isDebugEnabled()) { + log.debug("Executing request : " + request.getRequestLine()); + } + + try { + HttpResponse response = httpClient.execute(request); + + switch (response.getStatusLine().getStatusCode()) { + case HttpStatus.SC_OK: { + response.getEntity().consumeContent(); + return true; + } + case HttpStatus.SC_UNAUTHORIZED: + case HttpStatus.SC_FORBIDDEN: + throw new TechnicalException("ucoin.client.authentication"); + default: + throw new TechnicalException("ucoin.client.status" + response.getStatusLine().toString()); + } + + } + catch (ConnectException e) { + throw new TechnicalException("ucoin.client.core.connect", e); + } + catch (IOException e) { + throw new TechnicalException(e.getMessage(), e); + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/ServiceLocator.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/ServiceLocator.java new file mode 100644 index 0000000000000000000000000000000000000000..5762b375651d57683122ce2a89844c688c55d80e --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/ServiceLocator.java @@ -0,0 +1,151 @@ +package io.ucoin.ucoinj.core.client.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.beans.BeanFactory; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteService; +import io.ucoin.ucoinj.core.client.service.bma.TransactionRemoteService; +import io.ucoin.ucoinj.core.client.service.bma.WotRemoteService; +import io.ucoin.ucoinj.core.client.service.elasticsearch.CurrencyRegistryRemoteService; +import io.ucoin.ucoinj.core.client.service.local.CurrencyService; +import io.ucoin.ucoinj.core.client.service.local.PeerService; +import io.ucoin.ucoinj.core.service.CryptoService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; + +public class ServiceLocator implements Closeable { + + + /* Logger */ + private static final Logger log = LoggerFactory.getLogger(ServiceLocator.class); + + /** + * The shared instance of this ServiceLocator. + */ + private static ServiceLocator instance = new ServiceLocator(); + + + private BeanFactory beanFactory = null; + + protected ServiceLocator() { + } + + public void init() { + initBeanFactory(); + } + + @Override + public void close() throws IOException { + if (beanFactory != null) { + log.info("Closing ServiceLocator..."); + + try { + beanFactory.close(); + } + catch(Exception e) { + // log & continue + log.debug("Could not close bean factory: " + e.getMessage(), e); + } + } + beanFactory = null; + } + + /** + * replace the default shared instance of this Class + * + * @param newInstance the new shared service locator instance. + */ + public static void setInstance(ServiceLocator newInstance) { + instance = newInstance; + } + + /** + * Gets the shared instance of this Class + * + * @return the shared service locator instance. + */ + public static ServiceLocator instance() { + return instance; + } + + public BlockchainRemoteService getBlockchainRemoteService() { + return getBean(BlockchainRemoteService.class); + } + + public TransactionRemoteService getTransactionRemoteService() { + return getBean(TransactionRemoteService.class); + } + + public CryptoService getCryptoService() { + return getBean(CryptoService.class); + } + + public HttpService getHttpService() { + return getBean(HttpService.class); + } + public PeerService getPeerService() { + return getBean(PeerService.class); + } + + public CurrencyService getCurrencyService() { + return getBean(CurrencyService.class); + } + + public DataContext getDataContext() { + return getBean(DataContext.class); + } + + public NetworkRemoteService getNetworkRemoteService() { + return getBean(NetworkRemoteService.class); + } + public WotRemoteService getWotRemoteService() { + return getBean(WotRemoteService.class); + } + + public CurrencyRegistryRemoteService getCurrencyRegistryRemoteService() { + return getBean(CurrencyRegistryRemoteService.class); + } + + + public <S extends Bean> S getBean(Class<S> clazz) { + if (beanFactory == null) { + initBeanFactory(); + } + return beanFactory.getBean(clazz); + } + + /* -- Internal methods -- */ + + protected void initBeanFactory() { + if (beanFactory == null) { + beanFactory = new BeanFactory(); + } + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0643ce1c9aa478ecdc86a764162481fca7ad99ee --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BaseRemoteServiceImpl.java @@ -0,0 +1,56 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.HttpService; +import io.ucoin.ucoinj.core.client.service.local.PeerService; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import org.apache.http.client.methods.HttpUriRequest; + +import java.io.IOException; + +/** + * Created by eis on 05/02/15. + */ +public abstract class BaseRemoteServiceImpl implements Service, InitializingBean{ + + protected HttpService httpService; + protected PeerService peerService; + + public static final String PROTOCOL_VERSION = "1"; + + @Override + public void afterPropertiesSet() { + httpService = ServiceLocator.instance().getHttpService(); + peerService = ServiceLocator.instance().getPeerService(); + } + + @Override + public void close() throws IOException { + httpService = null; + peerService = null; + } + + public <T> T executeRequest(Peer peer, String absolutePath, Class<? extends T> resultClass) { + return httpService.executeRequest(peer, absolutePath, resultClass); + } + + public <T> T executeRequest(long currencyId, String absolutePath, Class<? extends T> resultClass) { + Peer peer = peerService.getActivePeerByCurrencyId(currencyId); + return httpService.executeRequest(peer, absolutePath, resultClass); + } + + public <T> T executeRequest(HttpUriRequest request, Class<? extends T> resultClass) { + return httpService.executeRequest(request, resultClass); + } + + public String getPath(long currencyId, String aPath) { + Peer peer = peerService.getActivePeerByCurrencyId(currencyId); + return httpService.getPath(peer, aPath); + } + + public String getPath(Peer peer, String aPath) { + return httpService.getPath(peer, aPath); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..4c7f210e69999f7835bd25894b731a7f5bbbec01 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteService.java @@ -0,0 +1,191 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.local.Identity; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainMemberships; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Currency; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.exception.PubkeyAlreadyUsedException; +import io.ucoin.ucoinj.core.client.service.exception.UidAlreadyUsedException; +import io.ucoin.ucoinj.core.client.service.exception.UidMatchAnotherPubkeyException; + +import java.util.Map; + +public interface BlockchainRemoteService extends Service { + + /** + * get the blockchain parameters (currency parameters) + * + * @param currencyId + * @param useCache + * @return + */ + BlockchainParameters getParameters(long currencyId, boolean useCache); + + /** + * get the blockchain parameters (currency parameters) + * + * @param currencyId + * @return + */ + BlockchainParameters getParameters(long currencyId); + + /** + * get the blockchain parameters (currency parameters) + * + * @param peer the peer to use for request + * @return + */ + BlockchainParameters getParameters(Peer peer); + + /** + * Retrieve a block, by id (from 0 to current) + * + * @param currencyId + * @param number + * @return + */ + BlockchainBlock getBlock(long currencyId, long number); + + /** + * Retrieve the dividend of a block, by id (from 0 to current). + * Usefull method to avoid to deserialize all the block + * + * @param currencyId + * @param number + * @return + */ + Long getBlockDividend(long currencyId, long number); + + /** + * Retrieve a block, by id (from 0 to current) + * + * @param peer the peer to use for request + * @param number the block number + * @return + */ + BlockchainBlock getBlock(Peer peer, int number); + + /** + * Retrieve a block, by id (from 0 to current) as JSON string + * + * @param peer the peer to use for request + * @param number the block number + * @return + */ + String getBlockAsJson(Peer peer, int number); + + /** + * Retrieve a block, by id (from 0 to current) as JSON string + * + * @param peer the peer to use for request + * @param number the block number + * @return + */ + String[] getBlocksAsJson(Peer peer, int count, int from); + + /** + * Retrieve the current block (with short cache) + * + * @return + */ + BlockchainBlock getCurrentBlock(long currencyId, boolean useCache); + + /** + * Retrieve the current block + * + * @return + */ + BlockchainBlock getCurrentBlock(long currencyId); + + /** + * Retrieve the current block + * + * @param peer the peer to use for request + * @return the last block + */ + BlockchainBlock getCurrentBlock(Peer peer); + + /** + * Retrieve the currency data, from peer + * + * @param peer + * @return + */ + Currency getCurrencyFromPeer(Peer peer); + + BlockchainParameters getBlockchainParametersFromPeer(Peer peer); + + /** + * Retrieve the last block with UD + * + * @param currencyId id of currency + * @return + */ + long getLastUD(long currencyId); + + /** + * Retrieve the last block with UD, from a peer + * + * @param currencyId id of currency + * @return + */ + long getLastUD(Peer peer); + + /** + * Check is a identity is not already used by a existing member + * + * @param peer + * @param identity + * @throws UidAlreadyUsedException if UID already used by another member + * @throws PubkeyAlreadyUsedException if pubkey already used by another member + */ + void checkNotMemberIdentity(Peer peer, Identity identity) throws UidAlreadyUsedException, PubkeyAlreadyUsedException; + + /** + * Check is a wallet is a member, and load its attribute isMember and certTimestamp + * + * @param peer + * @param wallet + * @throws UidMatchAnotherPubkeyException is uid already used by another pubkey + */ + void loadAndCheckMembership(Peer peer, Wallet wallet) throws UidMatchAnotherPubkeyException; + + /** + * Load identity attribute isMember and timestamp + * + * @param identity + */ + void loadMembership(long currencyId, Identity identity, boolean checkLookupForNonMember); + + + BlockchainMemberships getMembershipByUid(long currencyId, String uid); + + BlockchainMemberships getMembershipByPublicKey(long currencyId, String pubkey); + + /** + * Request to integrate the wot + */ + void requestMembership(Wallet wallet); + + BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey); + + BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey); + + String getMembership(Wallet wallet, + BlockchainBlock block, + boolean sideIn); + + /** + * Get UD, by block number + * + * @param currencyId + * @param startOffset + * @return + */ + Map<Integer, Long> getUDs(long currencyId, long startOffset); + +} \ No newline at end of file diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..6b867bd9fdb86cf9eb250fba869fb7dd9021ee5c --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceImpl.java @@ -0,0 +1,638 @@ +package io.ucoin.ucoinj.core.client.service.bma; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.gson.JsonArrayParser; +import io.ucoin.ucoinj.core.client.model.local.Currency; +import io.ucoin.ucoinj.core.client.model.local.Identity; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainMemberships; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; +import io.ucoin.ucoinj.core.client.service.exception.PubkeyAlreadyUsedException; +import io.ucoin.ucoinj.core.client.service.exception.UidAlreadyUsedException; +import io.ucoin.ucoinj.core.client.service.exception.UidMatchAnotherPubkeyException; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.core.util.cache.Cache; +import io.ucoin.ucoinj.core.util.cache.SimpleCache; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class BlockchainRemoteServiceImpl extends BaseRemoteServiceImpl implements BlockchainRemoteService { + + private static final Logger log = LoggerFactory.getLogger(BlockchainRemoteServiceImpl.class); + + private static final String JSON_DIVIDEND_ATTR = "\"dividend\":"; + + public static final String URL_BASE = "/blockchain"; + + public static final String URL_PARAMETERS = URL_BASE + "/parameters"; + + public static final String URL_BLOCK = URL_BASE + "/block/%s"; + + public static final String URL_BLOCKS_FROM = URL_BASE + "/blocks/%s/%s"; + + public static final String URL_BLOCK_CURRENT = URL_BASE + "/current"; + + public static final String URL_BLOCK_WITH_UD = URL_BASE + "/with/ud"; + + public static final String URL_MEMBERSHIP = URL_BASE + "/membership"; + + public static final String URL_MEMBERSHIP_SEARCH = URL_BASE + "/memberships/%s"; + + + private NetworkRemoteService networkRemoteService; + + private Configuration config; + + // Cache need for wallet refresh : iteration on wallet should not + // execute a download of the current block + private Cache<Long, BlockchainBlock> mCurrentBlockCache; + + // Cache on blockchain parameters + private Cache<Long, BlockchainParameters> mParametersCache; + + public BlockchainRemoteServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() { + super.afterPropertiesSet(); + networkRemoteService = ServiceLocator.instance().getNetworkRemoteService(); + config = Configuration.instance(); + + // Initialize caches + initCaches(); + } + + @Override + public BlockchainParameters getParameters(long currencyId, boolean useCache) { + if (!useCache) { + return getParameters(currencyId); + } else { + return mParametersCache.get(currencyId); + } + } + + @Override + public BlockchainParameters getParameters(long currencyId) { + // get blockchain parameter + BlockchainParameters result = executeRequest(currencyId, URL_PARAMETERS, BlockchainParameters.class); + return result; + } + + @Override + public BlockchainParameters getParameters(Peer peer) { + // get blockchain parameter + BlockchainParameters result = executeRequest(peer, URL_PARAMETERS, BlockchainParameters.class); + return result; + } + + @Override + public BlockchainBlock getBlock(long currencyId, long number) { + // get blockchain parameter + String path = String.format(URL_BLOCK, number); + BlockchainBlock result = executeRequest(currencyId, path, BlockchainBlock.class); + return result; + } + + @Override + public Long getBlockDividend(long currencyId, long number) { + // get blockchain parameter + String path = String.format(URL_BLOCK, number); + String json = executeRequest(currencyId, path, String.class); + return getDividendFromBlockJson(json); + } + + + @Override + public BlockchainBlock getBlock(Peer peer, int number) { + // get blockchain parameter + String path = String.format(URL_BLOCK, number); + BlockchainBlock result = executeRequest(peer, path, BlockchainBlock.class); + return result; + } + + @Override + public String getBlockAsJson(Peer peer, int number) { + // get blockchain parameter + String path = String.format(URL_BLOCK, number); + return executeRequest(peer, path, String.class); + } + + @Override + public String[] getBlocksAsJson(Peer peer, int count, int from) { + // get blockchain parameter + String path = String.format(URL_BLOCKS_FROM, count, from); + String jsonBlocksStr = executeRequest(peer, path, String.class); + + // Parse only array content, but deserialize array item + JsonArrayParser parser = new JsonArrayParser(); + return parser.getValuesAsArray(jsonBlocksStr); + } + + /** + * Retrieve the current block (with short cache) + * + * @return + */ + public BlockchainBlock getCurrentBlock(long currencyId, boolean useCache) { + if (!useCache) { + return getCurrentBlock(currencyId); + } else { + return mCurrentBlockCache.get(currencyId); + } + } + + @Override + public BlockchainBlock getCurrentBlock(long currencyId) { + // get blockchain parameter + BlockchainBlock result = executeRequest(currencyId, URL_BLOCK_CURRENT, BlockchainBlock.class); + return result; + } + + @Override + public BlockchainBlock getCurrentBlock(Peer peer) { + // get blockchain parameter + BlockchainBlock result = executeRequest(peer, URL_BLOCK_CURRENT, BlockchainBlock.class); + return result; + } + + @Override + public Currency getCurrencyFromPeer(Peer peer) { + BlockchainParameters parameter = getParameters(peer); + BlockchainBlock firstBlock = getBlock(peer, 0); + BlockchainBlock lastBlock = getCurrentBlock(peer); + + Currency result = new Currency(); + result.setCurrencyName(parameter.getCurrency()); + result.setFirstBlockSignature(firstBlock.getSignature()); + result.setMembersCount(lastBlock.getMembersCount()); + result.setLastUD(parameter.getUd0()); + + return result; + } + + @Override + public BlockchainParameters getBlockchainParametersFromPeer(Peer peer){ + return getParameters(peer); + } + + @Override + public long getLastUD(long currencyId) { + // get block number with UD + String blocksWithUdResponse = executeRequest(currencyId, URL_BLOCK_WITH_UD, String.class); + Integer blockNumber = getLastBlockNumberFromJson(blocksWithUdResponse); + + // If no result (this could happen when no UD has been send + if (blockNumber == null) { + // get the first UD from currency parameter + BlockchainParameters parameter = getParameters(currencyId); + return parameter.getUd0(); + } + + // Get the UD from the last block with UD + Long lastUD = getBlockDividend(currencyId, blockNumber); + + // Check not null (should never append) + if (lastUD == null) { + throw new TechnicalException("Unable to get last UD from server"); + } + return lastUD.longValue(); + } + + @Override + public long getLastUD(Peer peer) { + // get block number with UD + String blocksWithUdResponse = executeRequest(peer, URL_BLOCK_WITH_UD, String.class); + Integer blockNumber = getLastBlockNumberFromJson(blocksWithUdResponse); + + // If no result (this could happen when no UD has been send + if (blockNumber == null) { + // get the first UD from currency parameter + BlockchainParameters parameter = getParameters(peer); + return parameter.getUd0(); + } + + // Get the UD from the last block with UD + String path = String.format(URL_BLOCK, blockNumber); + String json = executeRequest(peer, path, String.class); + Long lastUD = getDividendFromBlockJson(json); + + // Check not null (should never append) + if (lastUD == null) { + throw new TechnicalException("Unable to get last UD from server"); + } + return lastUD.longValue(); + } + + /** + * Check is a identity is not already used by a existing member + * + * @param peer + * @param identity + * @throws UidAlreadyUsedException if UID already used by another member + * @throws PubkeyAlreadyUsedException if pubkey already used by another member + */ + public void checkNotMemberIdentity(Peer peer, Identity identity) throws UidAlreadyUsedException, PubkeyAlreadyUsedException { + ObjectUtils.checkNotNull(peer); + ObjectUtils.checkNotNull(identity); + ObjectUtils.checkArgument(StringUtils.isNotBlank(identity.getUid())); + ObjectUtils.checkArgument(StringUtils.isNotBlank(identity.getPubkey())); + + // Read membership data from the UID + BlockchainMemberships result = getMembershipByPubkeyOrUid(peer, identity.getUid()); + + // uid already used by another member + if (result != null) { + throw new UidAlreadyUsedException(String.format("User identifier '%s' is already used by another member", identity.getUid())); + } + + result = getMembershipByPubkeyOrUid(peer, identity.getPubkey()); + + // pubkey already used by another member + if (result != null) { + throw new PubkeyAlreadyUsedException(String.format("Pubkey key '%s' is already used by another member", identity.getPubkey())); + } + } + + /** + * Check is a wallet is a member, and load its attribute isMember and certTimestamp + * + * @param wallet + * @throws UidMatchAnotherPubkeyException is uid already used by another pubkey + */ + public void loadAndCheckMembership(Peer peer, Wallet wallet) throws UidMatchAnotherPubkeyException { + ObjectUtils.checkNotNull(wallet); + + // Load membership data + loadMembership(null, peer, wallet.getIdentity(), true); + + // Something wrong on pubkey : uid already used by another pubkey ! + if (wallet.getIdentity().getIsMember() == null) { + throw new UidMatchAnotherPubkeyException(wallet.getPubKeyHash()); + } + } + + /** + * Load identity attribute isMember and timestamp + * + * @param identity + */ + public void loadMembership(long currencyId, Identity identity, boolean checkLookupForNonMember) { + loadMembership(currencyId, null, identity, checkLookupForNonMember); + } + + + public BlockchainMemberships getMembershipByUid(long currencyId, String uid) { + ObjectUtils.checkArgument(StringUtils.isNotBlank(uid)); + + BlockchainMemberships result = getMembershipByPubkeyOrUid(currencyId, uid); + if (result == null || !uid.equals(result.getUid())) { + return null; + } + return result; + } + + public BlockchainMemberships getMembershipByPublicKey(long currencyId, String pubkey) { + ObjectUtils.checkArgument(StringUtils.isNotBlank(pubkey)); + + BlockchainMemberships result = getMembershipByPubkeyOrUid(currencyId, pubkey); + if (result == null || !pubkey.equals(result.getPubkey())) { + return null; + } + return result; + } + + /** + * Request to integrate the wot + */ + public void requestMembership(Wallet wallet) { + ObjectUtils.checkNotNull(wallet); + ObjectUtils.checkNotNull(wallet.getCurrencyId()); + + BlockchainBlock block = getCurrentBlock(wallet.getCurrencyId()); + + // Compute membership document + String membership = getMembership(wallet, + block, + true /*sideIn*/); + + if (log.isDebugEnabled()) { + log.debug(String.format( + "Will send membership document: \n------\n%s------", + membership)); + } + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("membership", membership)); + + HttpPost httpPost = new HttpPost(getPath(wallet.getCurrencyId(), URL_MEMBERSHIP)); + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } catch (UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + + String membershipResult = executeRequest(httpPost, String.class); + if (log.isDebugEnabled()) { + log.debug("received from /tx/process: " + membershipResult); + } + + executeRequest(httpPost, String.class); + } + + public BlockchainMemberships getMembershipByPubkeyOrUid(long currencyId, String uidOrPubkey) { + String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey); + + // search blockchain membership + try { + BlockchainMemberships result = executeRequest(currencyId, path, BlockchainMemberships.class); + return result; + } catch (HttpBadRequestException e) { + log.debug("No member matching this pubkey or uid: " + uidOrPubkey); + return null; + } + } + + public BlockchainMemberships getMembershipByPubkeyOrUid(Peer peer, String uidOrPubkey) { + String path = String.format(URL_MEMBERSHIP_SEARCH, uidOrPubkey); + + // search blockchain membership + try { + BlockchainMemberships result = executeRequest(peer, path, BlockchainMemberships.class); + return result; + } catch (HttpBadRequestException e) { + log.debug("No member matching this pubkey or uid: " + uidOrPubkey); + return null; + } + } + + public String getMembership(Wallet wallet, + BlockchainBlock block, + boolean sideIn + ) { + + // Create the member ship document + String membership = getMembership(wallet.getUid(), + wallet.getPubKeyHash(), + wallet.getCurrency(), + block.getNumber(), + block.getHash(), + sideIn, + wallet.getCertTimestamp() + ); + + // Add signature + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + String signature = cryptoService.sign(membership, wallet.getSecKey()); + + return new StringBuilder().append(membership).append(signature) + .append('\n').toString(); + } + + /** + * Get UD, by block number + * + * @param currencyId + * @param startOffset + * @return + */ + public Map<Integer, Long> getUDs(long currencyId, long startOffset) { + log.debug(String.format("Getting block's UD from block [%s]", startOffset)); + + int[] blockNumbersWithUD = getBlocksWithUD(currencyId); + + Map<Integer, Long> result = new LinkedHashMap<Integer,Long>(); + +// Insert the UD0 (if need) +// if (startOffset <= 0) { +// BlockchainParameters parameters = getParameters(currencyId, true/*with cache*/); +// result.put(0, parameters.getUd0()); +// } + + boolean previousBlockInsert = false; + if (blockNumbersWithUD != null && blockNumbersWithUD.length != 0) { + Integer previousBlockNumberWithUd = null; + for (Integer blockNumber : blockNumbersWithUD) { + if (blockNumber >= startOffset) { + if(!previousBlockInsert){ + Long previousUd = getParameters(currencyId, true/*with cache*/).getUd0(); + Integer previousBlockNumber = 0; + if(previousBlockNumberWithUd!=null){ + previousUd = getBlockDividend(currencyId, previousBlockNumberWithUd); + if (previousUd == null) { + throw new TechnicalException( + String.format("Unable to get UD from server block [%s]", + previousBlockNumberWithUd) + ); + } + previousBlockNumber = previousBlockNumberWithUd; + } + result.put(previousBlockNumber, previousUd); + previousBlockInsert = true; + } + Long ud = getBlockDividend(currencyId, blockNumber); + // Check not null (should never append) + if (ud == null) { + throw new TechnicalException(String.format("Unable to get UD from server block [%s]", blockNumber)); + } + result.put(blockNumber, ud); + }else{ + previousBlockNumberWithUd = blockNumber; + } + } + }else{ + result.put(0, getParameters(currencyId, true/*with cache*/).getUd0()); + } + + return result; + } + + /* -- Internal methods -- */ + + /** + * Initialize caches + */ + protected void initCaches() { + int cacheTimeInMillis = config.getNetworkCacheTimeInMillis(); + + mCurrentBlockCache = new SimpleCache<Long, BlockchainBlock>(cacheTimeInMillis) { + @Override + public BlockchainBlock load(Long currencyId) { + return getCurrentBlock(currencyId); + } + }; + + mParametersCache = new SimpleCache<Long, BlockchainParameters>(/*eternal cache*/) { + @Override + public BlockchainParameters load(Long currencyId) { + return getParameters(currencyId); + } + }; + } + + + protected void loadMembership(Long currencyId, Peer peer, Identity identity, boolean checkLookupForNonMember) { + ObjectUtils.checkNotNull(identity); + ObjectUtils.checkArgument(StringUtils.isNotBlank(identity.getUid())); + ObjectUtils.checkArgument(StringUtils.isNotBlank(identity.getPubkey())); + ObjectUtils.checkArgument(peer != null || currencyId != null); + + // Read membership data from the UID + BlockchainMemberships result = peer != null + ? getMembershipByPubkeyOrUid(peer, identity.getUid()) + : getMembershipByPubkeyOrUid(currencyId, identity.getUid()); + + // uid not used = not was member + if (result == null) { + identity.setMember(false); + + if (checkLookupForNonMember) { + WotRemoteService wotService = ServiceLocator.instance().getWotRemoteService(); + Identity lookupIdentity = peer != null + ? wotService.getIdentity(peer, identity.getUid(), identity.getPubkey()) + : wotService.getIdentity(currencyId, identity.getUid(), identity.getPubkey()); + + // Self certification exists, update the cert timestamp + if (lookupIdentity != null) { + identity.setTimestamp(lookupIdentity.getTimestamp()); + } + + // Self certification not exists: make sure the cert time is cleaning + else { + identity.setTimestamp(-1); + } + } + } + + // UID and pubkey is a member: fine + else if (identity.getPubkey().equals(result.getPubkey())) { + identity.setMember(true); + identity.setTimestamp(result.getSigDate()); + } + + // Something wrong on pubkey : uid already used by anither pubkey ! + else { + identity.setMember(null); + } + + } + + private int[] getBlocksWithUD(long currencyId) { + log.debug("Getting blocks with UD"); + + String json = executeRequest(currencyId, URL_BLOCK_WITH_UD, String.class); + + + + int startIndex = json.indexOf("["); + int endIndex = json.lastIndexOf(']'); + + if (startIndex == -1 || endIndex == -1) { + return null; + } + + String blockNumbersStr = json.substring(startIndex + 1, endIndex).trim(); + + if (StringUtils.isBlank(blockNumbersStr)) { + return null; + } + + + String[] blockNumbers = blockNumbersStr.split(","); + int[] result = new int[blockNumbers.length]; + try { + int i=0; + for (String blockNumber : blockNumbers) { + result[i++] = Integer.parseInt(blockNumber.trim()); + } + } + catch(NumberFormatException e){ + if (log.isDebugEnabled()) { + log.debug(String.format("Bad format of the response '%s'.", URL_BLOCK_WITH_UD)); + } + throw new TechnicalException("Unable to read block with UD numbers: " + e.getMessage(), e); + } + + return result; + } + + private String getMembership(String uid, + String publicKey, + String currency, + long blockNumber, + String blockHash, + boolean sideIn, + long certificationTime + ) { + StringBuilder result = new StringBuilder() + .append("Version: 1\n") + .append("Type: Membership\n") + .append("Currency: ").append(currency).append('\n') + .append("Issuer: ").append(publicKey).append('\n') + .append("Block: ").append(blockNumber).append('-').append(blockHash).append('\n') + .append("Membership: ").append(sideIn ? "IN" : "OUT").append('\n') + .append("UserID: ").append(uid).append('\n') + .append("CertTS: ").append(certificationTime).append('\n'); + + return result.toString(); + } + + private Integer getLastBlockNumberFromJson(final String json) { + + int startIndex = json.lastIndexOf(','); + int endIndex = json.lastIndexOf(']'); + if (startIndex == -1 || endIndex == -1) { + return null; + } + + String blockNumberStr = json.substring(startIndex+1,endIndex).trim(); + try { + return Integer.parseInt(blockNumberStr); + } catch(NumberFormatException e) { + if (log.isDebugEnabled()) { + log.debug("Could not parse JSON (block numbers)"); + } + throw new TechnicalException("Could not parse server response"); + } + } + + + protected Long getDividendFromBlockJson(String blockJson) { + + int startIndex = blockJson.indexOf(JSON_DIVIDEND_ATTR); + if (startIndex == -1) { + return null; + } + startIndex += JSON_DIVIDEND_ATTR.length(); + int endIndex = blockJson.indexOf(',', startIndex); + if (endIndex == -1) { + return null; + } + + String dividendStr = blockJson.substring(startIndex, endIndex).trim(); + if (dividendStr.length() == 0 + || "null".equals(dividendStr)) { + return null; + } + + return Long.parseLong(dividendStr); + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..bbe8ebbbf9f1fdc6f44a3316620456dc3ef050e4 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteService.java @@ -0,0 +1,20 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.bma.EndpointProtocol; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeering; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.util.List; + +/** + * Created by eis on 05/02/15. + */ +public interface NetworkRemoteService extends Service { + + NetworkPeering getPeering(Peer peer); + + List<Peer> getPeers(Peer peer); + + List<Peer> findPeers(Peer peer, String status, EndpointProtocol endpointProtocol, Integer currentBlockNumber, String currentBlockHash); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e587ac404772ca181c48ca585a455acbd0a09a92 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceImpl.java @@ -0,0 +1,128 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import java.util.ArrayList; +import java.util.List; + +import io.ucoin.ucoinj.core.client.model.bma.EndpointProtocol; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeering; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeers; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; + +/** + * Created by eis on 05/02/15. + */ +public class NetworkRemoteServiceImpl extends BaseRemoteServiceImpl implements NetworkRemoteService{ + + + public static final String URL_BASE = "/network"; + + public static final String URL_PEERING = URL_BASE + "/peering"; + + public static final String URL_PEERS = URL_BASE + "/peers"; + + public static final String URL_PEERING_PEERS = URL_PEERING + "/peers"; + + public static final String URL_PEERING_PEERS_LEAF = URL_PEERING + "/peers?leaf="; + + public NetworkRemoteServiceImpl() { + super(); + } + + public NetworkPeering getPeering(Peer peer) { + NetworkPeering result = httpService.executeRequest(peer, URL_PEERING, NetworkPeering.class); + return result; + } + + @Override + public List<Peer> getPeers(Peer peer) { + return findPeers(peer, null, null, null, null); + } + + @Override + public List<Peer> findPeers(Peer peer, String status, EndpointProtocol endpointProtocol, Integer currentBlockNumber, String currentBlockHash) { + ObjectUtils.checkNotNull(peer); + + List<Peer> result = new ArrayList<Peer>(); + + NetworkPeers remoteResult = httpService.executeRequest(peer, URL_PEERS, NetworkPeers.class); + + for (NetworkPeers.Peer remotePeer: remoteResult.peers) { + boolean match = (status == null || status.equalsIgnoreCase(remotePeer.status)) + && (currentBlockNumber == null || currentBlockNumber.equals(parseBlockNumber(remotePeer))) + && (currentBlockHash == null || currentBlockHash.equals(parseBlockHash(remotePeer))); + + if (match) { + + for (NetworkPeering.Endpoint endpoint : remotePeer.endpoints) { + + match = endpointProtocol == null || endpointProtocol == endpoint.protocol; + + if (match) { + Peer childPeer = toPeer(endpoint); + if (childPeer != null) { + result.add(childPeer); + } + } + + } + } + } + + return result; + } + + /* -- Internal methods -- */ + + protected Peer toPeer(NetworkPeering.Endpoint source) { + Peer target = new Peer(); + if (StringUtils.isNotBlank(source.ipv4)) { + target.setHost(source.ipv4); + } else if (StringUtils.isNotBlank(source.ipv6)) { + target.setHost(source.ipv6); + } else if (StringUtils.isNotBlank(source.url)) { + target.setHost(source.url); + } else { + target = null; + } + if (target != null && source.port != null) { + target.setPort(source.port); + } + return target; + } + + protected Integer parseBlockNumber(NetworkPeers.Peer remotePeer) { + ObjectUtils.checkNotNull(remotePeer); + + if (remotePeer.block == null) { + return null; + } + int index = remotePeer.block.indexOf("-"); + if (index == -1) { + return null; + } + + String str = remotePeer.block.substring(0, index); + try { + return Integer.parseInt(str); + } catch(NumberFormatException e) { + return null; + } + } + + protected String parseBlockHash(NetworkPeers.Peer remotePeer) { + ObjectUtils.checkNotNull(remotePeer); + + if (remotePeer.block == null) { + return null; + } + int index = remotePeer.block.indexOf("-"); + if (index == -1) { + return null; + } + + String hash = remotePeer.block.substring(index+1); + return hash; + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..fe38d1297c4457d41e6ee63c61d53d7bb6ebcb93 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteService.java @@ -0,0 +1,30 @@ +package io.ucoin.ucoinj.core.client.service.bma; + + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.bma.TxHistory; +import io.ucoin.ucoinj.core.client.model.bma.TxSource; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.exception.InsufficientCreditException; + + +public interface TransactionRemoteService extends Service { + + String transfert(Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException; + + TxSource getSources(long currencyId, String pubKey); + + TxSource getSources(Peer peer, String pubKey); + + long getCreditOrZero(long currencyId, String pubKey); + + Long getCredit(long currencyId, String pubKey); + + Long getCredit(Peer peer, String pubKey); + + long computeCredit(TxSource.Source[] sources); + + TxHistory getTxHistory(long currencyId, String pubKey, long fromBlockNumber, long toBlockNumber); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..66c9c8ad477db93f5e5bff5f79db7fb62be088ea --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceImpl.java @@ -0,0 +1,340 @@ +package io.ucoin.ucoinj.core.client.service.bma; + + +import io.ucoin.ucoinj.core.client.model.TxOutput; +import io.ucoin.ucoinj.core.client.model.bma.TxHistory; +import io.ucoin.ucoinj.core.client.model.bma.TxSource; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.exception.InsufficientCreditException; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.core.util.crypto.DigestUtils; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; + + +public class TransactionRemoteServiceImpl extends BaseRemoteServiceImpl implements TransactionRemoteService { + + private static final Logger log = LoggerFactory.getLogger(TransactionRemoteServiceImpl.class); + + public static final String URL_TX_BASE = "/tx"; + + public static final String URL_TX_PROCESS = URL_TX_BASE + "/process"; + + public static final String URL_TX_SOURCES = URL_TX_BASE + "/sources/%s"; + + public static final String URL_TX_HISTORY = URL_TX_BASE + "/history/%s/blocks/%s/%s"; + + + private CryptoService cryptoService; + + public TransactionRemoteServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() { + super.afterPropertiesSet(); + cryptoService = ServiceLocator.instance().getCryptoService(); + } + + public String transfert(Wallet wallet, String destPubKey, long amount, + String comment) throws InsufficientCreditException { + + // http post /tx/process + HttpPost httpPost = new HttpPost( + getPath(wallet.getCurrencyId(), URL_TX_PROCESS)); + + // compute transaction + String transaction = getSignedTransaction(wallet, destPubKey, amount, + comment); + + if (log.isDebugEnabled()) { + log.debug(String.format( + "Will send transaction document: \n------\n%s------", + transaction)); + } + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("transaction", transaction)); + + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } catch (UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + + String selfResult = executeRequest(httpPost, String.class); + log.info("received from /tx/process: " + selfResult); + + + String fingerprint = DigestUtils.sha1Hex(transaction); + if (log.isDebugEnabled()) { + log.debug(String.format( + "Fingerprint: %s", + fingerprint)); + } + return fingerprint; + } + + public TxSource getSources(long currencyId, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get sources by pubKey: %s", pubKey)); + } + + // get parameter + String path = String.format(URL_TX_SOURCES, pubKey); + TxSource result = executeRequest(currencyId, path, TxSource.class); + + return result; + } + + public TxSource getSources(Peer peer, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get sources by pubKey: %s from ", pubKey, peer.toString())); + } + + // get parameter + String path = String.format(URL_TX_SOURCES, pubKey); + TxSource result = executeRequest(peer, path, TxSource.class); + + return result; + } + + public long getCreditOrZero(long currencyId, String pubKey) { + Long credit = getCredit(currencyId, pubKey); + + if (credit == null) { + return 0; + } + return credit.longValue(); + } + + public Long getCredit(long currencyId, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get credit by pubKey [%s] for currency [id=%s]", pubKey, currencyId)); + } + + // get parameter + String path = String.format(URL_TX_SOURCES, pubKey); + TxSource result = executeRequest(currencyId, path, TxSource.class); + + if (result == null) { + return null; + } + + // Compute the credit + return computeCredit(result.getSources()); + } + + public Long getCredit(Peer peer, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get credit by pubKey [%s] from peer [%s]", pubKey, peer.getUrl())); + } + + // get parameter + String path = String.format(URL_TX_SOURCES, pubKey); + TxSource result = executeRequest(peer, path, TxSource.class); + + if (result == null) { + return null; + } + + // Compute the credit + return computeCredit(result.getSources()); + } + + + public long computeCredit(TxSource.Source[] sources) { + if (CollectionUtils.isEmpty(sources)) { + return 0; + } + + long credit = 0; + for (TxSource.Source source : sources) { + credit += source.getAmount(); + } + return credit; + } + + public TxHistory getTxHistory(long currencyId, String pubKey, long fromBlockNumber, long toBlockNumber) { + ObjectUtils.checkNotNull(pubKey); + ObjectUtils.checkArgument(fromBlockNumber >= 0); + ObjectUtils.checkArgument(fromBlockNumber <= toBlockNumber); + + if (log.isDebugEnabled()) { + log.debug(String.format("Get TX history by pubKey [%s], from block [%s -> %s]", pubKey, fromBlockNumber, toBlockNumber)); + } + + // get parameter + String path = String.format(URL_TX_HISTORY, pubKey, fromBlockNumber, toBlockNumber); + TxHistory result = executeRequest(currencyId, path, TxHistory.class); + + return result; + } + + /* -- internal methods -- */ + + public String getSignedTransaction(Wallet wallet, String destPubKey, + long amount, String comment) throws InsufficientCreditException { + ObjectUtils.checkNotNull(wallet); + ObjectUtils.checkArgument(StringUtils.isNotBlank(wallet.getCurrency())); + ObjectUtils.checkArgument(StringUtils.isNotBlank(wallet.getPubKeyHash())); + + // Retrieve the wallet sources + TxSource sourceResults = getSources(wallet.getCurrencyId(), wallet.getPubKeyHash()); + if (sourceResults == null) { + throw new TechnicalException("Unable to load user sources."); + } + + TxSource.Source[] sources = sourceResults.getSources(); + if (CollectionUtils.isEmpty(sources)) { + throw new InsufficientCreditException( + "Insufficient credit : no credit found."); + } + + List<TxSource.Source> txInputs = new ArrayList<TxSource.Source>(); + List<TxOutput> txOutputs = new ArrayList<TxOutput>(); + computeTransactionInputsAndOuputs(wallet.getPubKeyHash(), destPubKey, + sources, amount, txInputs, txOutputs); + + String transaction = getTransaction(wallet.getCurrency(), + wallet.getPubKeyHash(), destPubKey, txInputs, txOutputs, + comment); + + String signature = cryptoService.sign(transaction, wallet.getSecKey()); + + return new StringBuilder().append(transaction).append(signature) + .append('\n').toString(); + } + + public String getTransaction(String currency, String srcPubKey, + String destPubKey, List<TxSource.Source> inputs, List<TxOutput> outputs, + String comments) { + + StringBuilder sb = new StringBuilder(); + sb.append("Version: 1\n").append("Type: Transaction\n") + .append("Currency: ").append(currency).append('\n') + .append("Issuers:\n") + // add issuer pubkey + .append(srcPubKey).append('\n'); + + // Inputs coins + sb.append("Inputs:\n"); + for (TxSource.Source input : inputs) { + // INDEX:SOURCE:NUMBER:FINGERPRINT:AMOUNT + sb.append(0).append(':').append(input.getType()).append(':') + .append(input.getNumber()).append(':') + .append(input.getFingerprint()).append(':') + .append(input.getAmount()).append('\n'); + } + + // Output + sb.append("Outputs:\n"); + for (TxOutput output : outputs) { + // ISSUERS:AMOUNT + sb.append(output.getPubKey()).append(':') + .append(output.getAmount()).append('\n'); + } + + // Comment + sb.append("Comment: ").append(comments).append('\n'); + + return sb.toString(); + } + + public String getCompactTransaction(String currency, String srcPubKey, + String destPubKey, List<TxSource.Source> inputs, List<TxOutput> outputs, + String comments) { + + boolean hasComment = comments != null && comments.length() > 0; + StringBuilder sb = new StringBuilder(); + sb.append("TX:") + // VERSION + .append(PROTOCOL_VERSION).append(':') + // NB_ISSUERS + .append("1:") + // NB_INPUTS + .append(inputs.size()).append(':') + // NB_OUTPUTS + .append(outputs.size()).append(':') + // HAS_COMMENT + .append(hasComment ? 1 : 0).append('\n') + // issuer pubkey + .append(srcPubKey).append('\n'); + + // Inputs coins + for (TxSource.Source input : inputs) { + // INDEX:SOURCE:NUMBER:FINGERPRINT:AMOUNT + sb.append(0).append(':').append(input.getType()).append(':') + .append(input.getNumber()).append(':') + .append(input.getFingerprint()).append(':') + .append(input.getAmount()).append('\n'); + } + + // Output + for (TxOutput output : outputs) { + // ISSUERS:AMOUNT + sb.append(output.getPubKey()).append(':') + .append(output.getAmount()).append('\n'); + } + + // Comment + if (hasComment) { + sb.append(comments).append('\n'); + } + return sb.toString(); + } + + public void computeTransactionInputsAndOuputs(String srcPubKey, + String destPubKey, TxSource.Source[] sources, long amount, + List<TxSource.Source> inputs, List<TxOutput> outputs) throws InsufficientCreditException{ + + long rest = amount; + long restForHimSelf = 0; + + for (TxSource.Source source : sources) { + long srcAmount = source.getAmount(); + inputs.add(source); + if (srcAmount >= rest) { + restForHimSelf = srcAmount - rest; + rest = 0; + break; + } + rest -= srcAmount; + } + + if (rest > 0) { + throw new InsufficientCreditException(String.format( + "Insufficient credit. Need %s more units.", rest)); + } + + // outputs + { + TxOutput output = new TxOutput(); + output.setPubKey(destPubKey); + output.setAmount(amount); + outputs.add(output); + } + if (restForHimSelf > 0) { + TxOutput output = new TxOutput(); + output.setPubKey(srcPubKey); + output.setAmount(restForHimSelf); + outputs.add(output); + } + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..2db3255b737e767fe210a14b3adc3e0930174123 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteService.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.bma.WotCertification; +import io.ucoin.ucoinj.core.client.model.bma.WotLookup; +import io.ucoin.ucoinj.core.client.model.local.Certification; +import io.ucoin.ucoinj.core.client.model.local.Identity; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +public interface WotRemoteService extends Service { + + List<Identity> findIdentities(Set<Long> currenciesIds, String uidOrPubKey); + + WotLookup.Uid find(long currencyId, String uidOrPubKey); + + void getRequirments(long currencyId, String pubKey); + + WotLookup.Uid findByUid(long currencyId, String uid); + + WotLookup.Uid findByUidAndPublicKey(long currencyId, String uid, String pubKey); + + WotLookup.Uid findByUidAndPublicKey(Peer peer, String uid, String pubKey); + + Identity getIdentity(long currencyId, String uid, String pubKey); + + Identity getIdentity(long currencyId, String pubKey); + + Identity getIdentity(Peer peer, String uid, String pubKey); + + Collection<Certification> getCertifications(long currencyId, String uid, String pubkey, boolean isMember); + + WotCertification getCertifiedBy(long currencyId, String uid); + + int countValidCertifiers(long currencyId, String pubkey); + + WotCertification getCertifiersOf(long currencyId, String uid); + + String getSelfCertification(byte[] secKey, String uid, long timestamp); + + void sendSelf(long currencyId, byte[] pubKey, byte[] secKey, String uid, long timestamp); + + String getCertification(byte[] pubKey, byte[] secKey, String userUid, + long userTimestamp, + String userSignature, + int blockNumber, + String blockHash); + + String sendCertification(Wallet wallet, Identity identity); + + String sendCertification(long currencyId, + byte[] pubKey, byte[] secKey, + String uid, long timestamp, + String userUid, String userPubKeyHash, + long userTimestamp, String userSignature); + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..00773d3cd29637c526bef8717e469df825b65d20 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceImpl.java @@ -0,0 +1,839 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +import io.ucoin.ucoinj.core.client.model.ModelUtils; +import io.ucoin.ucoinj.core.client.model.bma.WotCertification; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.bma.WotLookup; +import io.ucoin.ucoinj.core.client.model.local.Certification; +import io.ucoin.ucoinj.core.client.model.local.Identity; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.util.*; + +public class WotRemoteServiceImpl extends BaseRemoteServiceImpl implements WotRemoteService { + + private static final Logger log = LoggerFactory.getLogger(BlockchainRemoteServiceImpl.class); + + public static final String URL_BASE = "/wot"; + + public static final String URL_ADD = URL_BASE + "/add"; + + public static final String URL_LOOKUP = URL_BASE + "/lookup/%s"; + + public static final String URL_REQUIREMENT = URL_BASE+"/requirements/%s"; + + public static final String URL_CERTIFIED_BY = URL_BASE + "/certified-by/%s"; + + public static final String URL_CERTIFIERS_OF = URL_BASE + "/certifiers-of/%s"; + + /** + * See https://github.com/ucoin-io/ucoin-cli/blob/master/bin/ucoin + * > var hash = res.current ? res.current.hash : 'DA39A3EE5E6B4B0D3255BFEF95601890AFD80709'; + */ + public static final String BLOCK_ZERO_HASH = "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709"; + + private CryptoService cryptoService; + private BlockchainRemoteService bcService; + + public WotRemoteServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() { + super.afterPropertiesSet(); + cryptoService = ServiceLocator.instance().getCryptoService(); + bcService = ServiceLocator.instance().getBlockchainRemoteService(); + } + + public List<Identity> findIdentities(Set<Long> currenciesIds, String uidOrPubKey) { + List<Identity> result = new ArrayList<Identity>(); + + String path = String.format(URL_LOOKUP, uidOrPubKey); + + for (Long currencyId: currenciesIds) { + + WotLookup lookupResult = executeRequest(currencyId, path, WotLookup.class); + + addAllIdentities(result, lookupResult, currencyId); + } + + return result; + } + + public WotLookup.Uid find(long currencyId, String uidOrPubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to find user by looking up on [%s]", uidOrPubKey)); + } + + // get parameter + String path = String.format(URL_LOOKUP, uidOrPubKey); + WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + + for (WotLookup.Result result : lookupResults.getResults()) { + if (CollectionUtils.isNotEmpty(result.getUids())) { + for (WotLookup.Uid uid : result.getUids()) { + return uid; + } + } + } + return null; + + } + + public void getRequirments(long currencyId, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to find user requirements on [%s]", pubKey)); + } + // get parameter + String path = String.format(URL_REQUIREMENT, pubKey); + // TODO : managed requirements + //WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + + } + + public WotLookup.Uid findByUid(long currencyId, String uid) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to find user info by uid: %s", uid)); + } + + // call lookup + String path = String.format(URL_LOOKUP, uid); + WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + + // Retrieve the exact uid + WotLookup.Uid uniqueResult = getUid(lookupResults, uid); + if (uniqueResult == null) { + return null; + } + + return uniqueResult; + } + + public WotLookup.Uid findByUidAndPublicKey(long currencyId, String uid, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to find user info by uid [%s] and pubKey [%s]", uid, pubKey)); + } + + // call lookup + String path = String.format(URL_LOOKUP, uid); + WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + + // Retrieve the exact uid + WotLookup.Uid uniqueResult = getUidByUidAndPublicKey(lookupResults, uid, pubKey); + if (uniqueResult == null) { + return null; + } + + return uniqueResult; + } + + public WotLookup.Uid findByUidAndPublicKey(Peer peer, String uid, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to find user info by uid [%s] and pubKey [%s]", uid, pubKey)); + } + + // call lookup + String path = String.format(URL_LOOKUP, uid); + WotLookup lookupResults = executeRequest(peer, path, WotLookup.class); + + // Retrieve the exact uid + WotLookup.Uid uniqueResult = getUidByUidAndPublicKey(lookupResults, uid, pubKey); + if (uniqueResult == null) { + return null; + } + + return uniqueResult; + } + + public Identity getIdentity(long currencyId, String uid, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); + } + + WotLookup.Uid lookupUid = findByUidAndPublicKey(currencyId, uid, pubKey); + if (lookupUid == null) { + return null; + } + return toIdentity(lookupUid); + } + + public Identity getIdentity(long currencyId, String pubKey) { +// Log.d(TAG, String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); + + WotLookup.Uid lookupUid = find(currencyId, pubKey); + if (lookupUid == null) { + return null; + } + Identity result = toIdentity(lookupUid); + result.setPubkey(pubKey); + result.setCurrencyId(currencyId); + return result; + } + + public Identity getIdentity(Peer peer, String uid, String pubKey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Get identity by uid [%s] and pubKey [%s]", uid, pubKey)); + } + + WotLookup.Uid lookupUid = findByUidAndPublicKey(peer, uid, pubKey); + if (lookupUid == null) { + return null; + } + return toIdentity(lookupUid); + } + + public Collection<Certification> getCertifications(long currencyId, String uid, String pubkey, boolean isMember) { + ObjectUtils.checkNotNull(uid); + ObjectUtils.checkNotNull(pubkey); + + if (isMember) { + return getCertificationsByPubkeyForMember(currencyId, pubkey, true); + } + else { + return getCertificationsByPubkeyForNonMember(currencyId, uid, pubkey); + } + } + + + public WotCertification getCertifiedBy(long currencyId, String uid) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to get certifications done by uid: %s", uid)); + } + + // call certified-by + String path = String.format(URL_CERTIFIED_BY, uid); + WotCertification result = executeRequest(currencyId, path, WotCertification.class); + + return result; + + } + + public int countValidCertifiers(long currencyId, String pubkey) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to count valid certifications done by pubkey: %s", pubkey)); + } + + int count =0; + + // call certified-by + Collection<Certification> certifiersOf = getCertificationsByPubkeyForMember(currencyId, pubkey, false/*only certifiers of*/); + if (CollectionUtils.isEmpty(certifiersOf)) { + return 0; + } + + for(Certification certifier : certifiersOf){ + if(certifier.isValid()){ + count++; + } + } + + return count; + + } + + public WotCertification getCertifiersOf(long currencyId, String uid) { + if (log.isDebugEnabled()) { + log.debug(String.format("Try to get certifications done to uid: %s", uid)); + } + + // call certifiers-of + String path = String.format(URL_CERTIFIERS_OF, uid); + WotCertification result = executeRequest(currencyId, path, WotCertification.class); + + return result; + } + + + public void sendSelf(long currencyId, byte[] pubKey, byte[] secKey, String uid, long timestamp) { + // http post /wot/add + HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); + + // Compute the pub key hash + String pubKeyHash = CryptoUtils.encodeBase58(pubKey); + + // compute the self-certification + String selfCertification = getSelfCertification(secKey, uid, timestamp); + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("pubkey", pubKeyHash)); + urlParameters.add(new BasicNameValuePair("self", selfCertification)); + urlParameters.add(new BasicNameValuePair("other", "")); + + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } + catch(UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + + // Execute the request + executeRequest(httpPost, String.class); + } + + public String sendCertification(Wallet wallet, + Identity identity) { + return sendCertification( + wallet.getCurrencyId(), + wallet.getPubKey(), + wallet.getSecKey(), + wallet.getIdentity().getUid(), + wallet.getIdentity().getTimestamp(), + identity.getUid(), + identity.getPubkey(), + identity.getTimestamp(), + identity.getSignature()); + } + + public String sendCertification(long currencyId, + byte[] pubKey, byte[] secKey, + String uid, long timestamp, + String userUid, String userPubKeyHash, + long userTimestamp, String userSignature) { + // http post /wot/add + HttpPost httpPost = new HttpPost(getPath(currencyId, URL_ADD)); + + // Read the current block (number and hash) + BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService(); + BlockchainBlock currentBlock = blockchainService.getCurrentBlock(currencyId); + int blockNumber = currentBlock.getNumber(); + String blockHash = (blockNumber != 0) + ? currentBlock.getHash() + : BLOCK_ZERO_HASH; + + // Compute the pub key hash + String pubKeyHash = CryptoUtils.encodeBase58(pubKey); + + // compute the self-certification + String selfCertification = getSelfCertification(userUid, userTimestamp, userSignature); + + // Compute the certification + String certification = getCertification(pubKey, secKey, + userUid, userTimestamp, userSignature, + blockNumber, blockHash); + String inlineCertification = toInlineCertification(pubKeyHash, userPubKeyHash, certification); + + List<NameValuePair> urlParameters = new ArrayList<NameValuePair>(); + urlParameters.add(new BasicNameValuePair("pubkey", userPubKeyHash)); + urlParameters.add(new BasicNameValuePair("self", selfCertification)); + urlParameters.add(new BasicNameValuePair("other", inlineCertification)); + + try { + httpPost.setEntity(new UrlEncodedFormEntity(urlParameters)); + } + catch(UnsupportedEncodingException e) { + throw new TechnicalException(e); + } + String selfResult = executeRequest(httpPost, String.class); + log.debug("received from /add: " + selfResult); + + return selfResult; + } + + public void addAllIdentities(List<Identity> result, WotLookup lookupResults, Long currencyId) { + String currencyName = null; + if (currencyId != null) { + currencyName = ServiceLocator.instance().getCurrencyService().getCurrencyNameById(currencyId); + } + + for (WotLookup.Result lookupResult: lookupResults.getResults()) { + String pubKey = lookupResult.getPubkey(); + for (WotLookup.Uid source: lookupResult.getUids()) { + // Create and fill an identity, from a result row + Identity target = new Identity(); + toIdentity(source, target); + + // fill the pub key + target.setPubkey(pubKey); + + // Fill currency id and name + // TODO + //target.setCurrencyId(currencyId); + //target.setCurrency(currencyName); + + result.add(target); + } + } + } + + public Identity toIdentity(WotLookup.Uid source) { + Identity target = new Identity(); + toIdentity(source, target); + return target; + } + + public void toIdentity(WotLookup.Uid source, Identity target) { + + target.setUid(source.getUid()); + target.setSelf(source.getSelf()); + Long timestamp = source.getMeta() != null ? source.getMeta().timestamp : null; + target.setTimestamp(timestamp); + } + + public String getSelfCertification(byte[] secKey, String uid, long timestamp) { + // Create the self part to sign + StringBuilder buffer = new StringBuilder() + .append("UID:") + .append(uid) + .append("\nMETA:TS:") + .append(timestamp) + .append('\n'); + + // Compute the signature + String signature = cryptoService.sign(buffer.toString(), secKey); + + // Append the signature + return buffer.append(signature) + .append('\n') + .toString(); + } + + /* -- Internal methods -- */ + + protected Collection<Certification> getCertificationsByPubkeyForMember(long currencyId, String pubkey, boolean onlyCertifiersOf) { + + BlockchainParameters bcParameter = bcService.getParameters(currencyId, true); + BlockchainBlock currentBlock = bcService.getCurrentBlock(currencyId, true); + long medianTime = currentBlock.getMedianTime(); + int sigValidity = bcParameter.getSigValidity(); + int sigQty = bcParameter.getSigQty(); + + Collection<Certification> result = new TreeSet<Certification>(ModelUtils.newWotCertificationComparatorByUid()); + + // Certifiers of + WotCertification certifiersOfList = getCertifiersOf(currencyId, pubkey); + boolean certifiersOfIsEmpty = (certifiersOfList == null + || certifiersOfList.getCertifications() == null); + int validWrittenCertifiersCount = 0; + if (!certifiersOfIsEmpty) { + for (WotCertification.Certification certifier : certifiersOfList.getCertifications()) { + + Certification cert = toCertification(certifier, currencyId); + cert.setCertifiedBy(false); + result.add(cert); + + long certificationAge = medianTime - certifier.getTimestamp(); + if(certificationAge <= sigValidity) { + if (certifier.getIsMember() != null && certifier.getIsMember().booleanValue() + && certifier.getWritten()!=null && certifier.getWritten().getNumber()>=0) { + validWrittenCertifiersCount++; + } + cert.setValid(true); + } + else { + cert.setValid(false); + } + } + } + + if (validWrittenCertifiersCount >= sigQty) { + if (log.isDebugEnabled()) { + log.debug(String.format("pubkey [%s] has %s valid signatures: should be a member", pubkey, validWrittenCertifiersCount)); + } + } + else { + if (log.isDebugEnabled()) { + log.debug(String.format("pubkey [%s] has %s valid signatures: not a member", pubkey, validWrittenCertifiersCount)); + } + } + + if (!onlyCertifiersOf) { + + // Certified by + WotCertification certifiedByList = getCertifiedBy(currencyId, pubkey); + boolean certifiedByIsEmpty = (certifiedByList == null + || certifiedByList.getCertifications() == null); + + if (!certifiedByIsEmpty) { + for (WotCertification.Certification certifiedBy : certifiedByList.getCertifications()) { + + Certification cert = toCertification(certifiedBy, currencyId); + cert.setCertifiedBy(true); + result.add(cert); + + long certificationAge = medianTime - certifiedBy.getTimestamp(); + if (certificationAge <= sigValidity) { + cert.setValid(true); + } else { + cert.setValid(false); + } + } + } + + // Group certifications by [uid, pubKey] and keep last timestamp + result = groupByUidAndPubKey(result, true); + + } + + return result; + } + + protected Collection<Certification> getCertificationsByPubkeyForNonMember(long currencyId, final String uid, final String pubkey) { + // Ordered list, by uid/pubkey/cert time + + Collection<Certification> result = new TreeSet<Certification>(ModelUtils.newWotCertificationComparatorByUid()); + + if (log.isDebugEnabled()) { + log.debug(String.format("Get non member WOT, by uid [%s] and pubKey [%s]", uid, pubkey)); + } + + // call lookup + String path = String.format(URL_LOOKUP, pubkey); + WotLookup lookupResults = executeRequest(currencyId, path, WotLookup.class); + + // Retrieve the exact uid + WotLookup.Uid lookupUId = getUidByUidAndPublicKey(lookupResults, uid, pubkey); + + // Read certifiers, if any + Map<String, Certification> certifierByPubkeys = new HashMap<String, Certification>(); + if (lookupUId != null && lookupUId.getOthers() != null) { + for(WotLookup.OtherSignature lookupSignature: lookupUId.getOthers()) { + Collection<Certification> certifiers = toCertifierCertifications(lookupSignature, currencyId); + result.addAll(certifiers); + } + } + + // Read certified-by + if (CollectionUtils.isNotEmpty(lookupResults.getResults())) { + for (WotLookup.Result lookupResult: lookupResults.getResults()) { + if (lookupResult.signed != null) { + for(WotLookup.SignedSignature lookupSignature : lookupResult.signed) { + Certification certifiedBy = toCertifiedByCerticication(lookupSignature); + + // Set the currency Id + certifiedBy.setCurrencyId(currencyId); + + // If exists, link to other side certification + String certifiedByPubkey = certifiedBy.getPubkey(); + if (certifierByPubkeys.containsKey(certifiedByPubkey)) { + Certification certified = certifierByPubkeys.get(certifiedByPubkey); + certified.setOtherEnd(certifiedBy); + } + + // If only a certifier, just add to the list + else { + result.add(certifiedBy); + } + } + } + } + } + + // Group certifications by [uid, pubKey] and keep last timestamp + result = groupByUidAndPubKey(result, true); + + return result; + } + + protected String toInlineCertification(String pubKeyHash, + String userPubKeyHash, + String certification) { + // Read the signature + String[] parts = certification.split("\n"); + if (parts.length != 5) { + throw new TechnicalException("Bad certification document: " + certification); + } + String signature = parts[parts.length-1]; + + // Read the block number + parts = parts[parts.length-2].split(":"); + if (parts.length != 3) { + throw new TechnicalException("Bad certification document: " + certification); + } + parts = parts[2].split("-"); + if (parts.length != 2) { + throw new TechnicalException("Bad certification document: " + certification); + } + String blockNumber = parts[0]; + + return new StringBuilder() + .append(pubKeyHash) + .append(':') + .append(userPubKeyHash) + .append(':') + .append(blockNumber) + .append(':') + .append(signature) + .append('\n') + .toString(); + } + + public String getCertification(byte[] pubKey, byte[] secKey, String userUid, + long userTimestamp, + String userSignature, + int blockNumber, + String blockHash) { + // Create the self part to sign + String unsignedCertification = getCertificationUnsigned( + userUid, userTimestamp, userSignature, blockNumber, blockHash); + + // Compute the signature + String signature = cryptoService.sign(unsignedCertification, secKey); + + // Append the signature + return new StringBuilder() + .append(unsignedCertification) + .append(signature) + .append('\n') + .toString(); + } + + protected String getCertificationUnsigned(String userUid, + long userTimestamp, + String userSignature, + int blockNumber, + String blockHash) { + // Create the self part to sign + return new StringBuilder() + .append("UID:") + .append(userUid) + .append("\nMETA:TS:") + .append(userTimestamp) + .append('\n') + .append(userSignature) + .append("\nMETA:TS:") + .append(blockNumber) + .append('-') + .append(blockHash) + .append('\n').toString(); + } + + protected String getSelfCertification(String uid, + long timestamp, + String signature) { + // Create the self part to sign + return new StringBuilder() + .append("UID:") + .append(uid) + .append("\nMETA:TS:") + .append(timestamp) + .append('\n') + .append(signature) + // FIXME : in ucoin, no '\n' here - is it a bug ? + //.append('\n') + .toString(); + } + + protected WotLookup.Uid getUid(WotLookup lookupResults, String filterUid) { + if (lookupResults.getResults() == null || lookupResults.getResults().length == 0) { + return null; + } + + for (WotLookup.Result result : lookupResults.getResults()) { + if (result.getUids() != null && result.getUids().length > 0) { + for (WotLookup.Uid uid : result.getUids()) { + if (filterUid.equals(uid.getUid())) { + return uid; + } + } + } + } + + return null; + } + + protected WotLookup.Uid getUidByUidAndPublicKey(WotLookup lookupResults, + String filterUid, + String filterPublicKey) { + if (lookupResults.getResults() == null || lookupResults.getResults().length == 0) { + return null; + } + + for (WotLookup.Result result : lookupResults.getResults()) { + if (filterPublicKey.equals(result.getPubkey())) { + if (result.getUids() != null && result.getUids().length > 0) { + for (WotLookup.Uid uid : result.getUids()) { + if (filterUid.equals(uid.getUid())) { + return uid; + } + } + } + break; + } + } + + return null; + } + + private Certification toCertification(final WotCertification.Certification source, final long currencyId) { + Certification target = new Certification(); + target.setPubkey(source.getPubkey()); + target.setUid(source.getUid()); + target.setMember(source.getIsMember()); + target.setCurrencyId(currencyId); + + return target; + } + + private Collection<Certification> toCertifierCertifications(final WotLookup.OtherSignature source, final long currencyId) { + List<Certification> result = new ArrayList<Certification>(); + // If only one uid + if (source.getUids().length == 1) { + Certification target = new Certification(); + + // uid + target.setUid(source.getUids()[0]); + + // certifier + target.setCertifiedBy(false); + + // Pubkey + target.setPubkey(source.getPubkey()); + + // Is member + target.setMember(source.isMember()); + + // Set currency Id + target.setCurrencyId(currencyId); + + result.add(target); + } + else { + for(String uid: source.getUids()) { + Certification target = new Certification(); + + // uid + target.setUid(uid); + + // certified by + target.setCertifiedBy(false); + + // Pubkey + target.setPubkey(source.getPubkey()); + + // Is member + target.setMember(source.isMember()); + + // Set currency Id + target.setCurrencyId(currencyId); + + result.add(target); + } + } + return result; + } + + private Certification toCertifiedByCerticication(final WotLookup.SignedSignature source) { + + Certification target = new Certification(); + // uid + target.setUid(source.uid); + + // certifieb by + target.setCertifiedBy(true); + + if (source.meta != null) { + + // timestamp + Long timestamp = source.meta != null ? source.meta.timestamp : null; + if (timestamp != null) { + target.setTimestamp(timestamp.longValue()); + } + } + + // Pubkey + target.setPubkey(source.pubkey); + + // Is member + target.setMember(source.isMember); + + // add to result list + return target; + } + + /** + * + * @param orderedCertifications a list, ordered by uid, pubkey, timestamp (DESC) + * @return + */ + private Collection<Certification> groupByUidAndPubKey(Collection<Certification> orderedCertifications, boolean orderResultByDate) { + if (CollectionUtils.isEmpty(orderedCertifications)) { + return orderedCertifications; + } + + List<Certification> result = new ArrayList<>(); + + StringBuilder keyBuilder = new StringBuilder(); + String previousIdentityKey = null; + Certification previousCert = null; + for (Certification cert : orderedCertifications) { + String identityKey = keyBuilder.append(cert.getUid()) + .append("~~") + .append(cert.getPubkey()) + .toString(); + boolean certifiedBy = cert.isCertifiedBy(); + + // Seems to be the same identity as previous entry + if (identityKey.equals(previousIdentityKey)) { + + if (certifiedBy != previousCert.isCertifiedBy()) { + // merge with existing other End (if exists) + merge(cert, previousCert.getOtherEnd()); + + // previousCert = certifier, so keep it and link the current cert + if (!certifiedBy) { + previousCert.setOtherEnd(cert); + } + + // previousCert = certified-by, so prefer the current cert + else { + cert.setOtherEnd(previousCert); + previousCert = cert; + } + } + + // Merge + else { + merge(previousCert, cert); + } + } + + // if identity changed + else { + // So add the previous cert to result + if (previousCert != null) { + result.add(previousCert); + } + + // And prepare next iteration + previousIdentityKey = identityKey; + previousCert = cert; + } + + // prepare the next loop + keyBuilder.setLength(0); + + } + + if (previousCert != null) { + result.add(previousCert); + } + + if (orderResultByDate) { + Collections.sort(result, ModelUtils.newWotCertificationComparatorByDate()); + } + + return result; + } + + private void merge(Certification previousCert, Certification cert) { + if (cert != null && cert.getTimestamp() > previousCert.getTimestamp()) { + previousCert.setTimestamp(cert.getTimestamp()); + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteService.java new file mode 100644 index 0000000000000000000000000000000000000000..56f8fad24686422f49a2740e341cc3dad96cf850 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteService.java @@ -0,0 +1,54 @@ +package io.ucoin.ucoinj.core.client.service.elasticsearch; + +/* + * #%L + * UCoin Java Client :: ElasticSearch Indexer + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; + +import java.util.List; + +/** + * Created by Benoit on 06/05/2015. + */ +public interface CurrencyRegistryRemoteService extends Service { + + /** + * Test if elasticsearch node defined in config is alive + * @return + */ + boolean isNodeAlive(); + + /** + * Test if elasticsearch node from the given endpoint is alive + * @return + */ + boolean isNodeAlive(Peer peer); + + List<String> getAllCurrencyNames(); + + void registerNewCurrency(Wallet wallet, Currency currency); + + void registerNewCurrency(String pubkey, String jsonCurrency, String signature); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..4c452271a724776921e0cd9ff7d12b9b5eb51366 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceImpl.java @@ -0,0 +1,204 @@ +package io.ucoin.ucoinj.core.client.service.elasticsearch; + +/* + * #%L + * UCoin Java Client :: ElasticSearch Indexer + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Joiner; +import com.google.gson.Gson; +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.bma.BaseRemoteServiceImpl; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.StringUtils; +import org.apache.http.HttpStatus; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.List; + +/** + * Created by Benoit on 06/05/2015. + */ +public class CurrencyRegistryRemoteServiceImpl extends BaseRemoteServiceImpl implements CurrencyRegistryRemoteService, InitializingBean, Closeable{ + private static final Logger log = LoggerFactory.getLogger(CurrencyRegistryRemoteServiceImpl.class); + + private final static String URL_STATUS = "/"; + private final static String URL_ALL_CURRENCY_NAMES = "/currency/simple/_search?_source=currencyName"; + private final static String URL_ADD_CURRENCY = "/rest/currency/add"; + + private Configuration config; + private Peer peer; + private Gson gson; + + public CurrencyRegistryRemoteServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() { + super.afterPropertiesSet(); + config = Configuration.instance(); + peer = new Peer(config.getNodeElasticSearchHost(), config.getNodeElasticSearchPort()); + gson = GsonUtils.newBuilder().create(); + } + + @Override + public void close() throws IOException { + super.close(); + config = null; + peer = null; + gson = null; + } + + @Override + public boolean isNodeAlive() { + return isNodeAlive(peer); + } + + @Override + public boolean isNodeAlive(Peer peer) { + if (log.isDebugEnabled()) { + log.debug(String.format("Checking if elasticsearch node [%s:%s] is alive...", peer.getHost(), peer.getPort())); + } + + // get currency + String jsonResponse; + try { + String path = getPath(peer, URL_STATUS); + jsonResponse = executeRequest(peer, path, String.class); + int statusCode = GsonUtils.getValueFromJSONAsInt(jsonResponse, "status"); + return statusCode == HttpStatus.SC_OK; + } + catch(TechnicalException e) { + if (log.isDebugEnabled()) { + log.debug("Failed to get node status: " + e.getMessage(), e); + } + return false; + } + } + + @Override + public List<String> getAllCurrencyNames() { + if (log.isDebugEnabled()) { + log.debug("Getting all currency names..."); + } + + // get currency + String path = getPath(peer, URL_ALL_CURRENCY_NAMES); + String jsonResponse = executeRequest(new HttpGet(path), String.class); + + List<String> currencyNames = GsonUtils.getValuesFromJSONAsString(jsonResponse, "currencyName"); + + // Sort into alphabetical order + Collections.sort(currencyNames); + + return currencyNames; + } + + @Override + public void registerNewCurrency(Wallet wallet, Currency currency) { + if (log.isDebugEnabled()) { + log.debug("Registering a new currency..."); + } + + String currencyJson = gson.toJson(currency); + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + String signature = cryptoService.sign(currencyJson, wallet.getSecKey()); + + registerNewCurrency( + wallet.getPubKeyHash(), + currencyJson, + signature); + + // get currency + //HttpGet httpGet = new HttpGet(getAppendedPath("/currency/simple/_search?_source=currencyName")); + //String jsonString = executeRequest(httpGet, String.class); + + } + + @Override + public void registerNewCurrency(String pubkey, String jsonCurrency, String signature) { + if (log.isDebugEnabled()) { + log.debug("Registering a new currency..."); + } + + URIBuilder builder = getURIBuilder(URL_ADD_CURRENCY); + builder.addParameter("pubkey", pubkey); + builder.addParameter("currency", jsonCurrency); + builder.addParameter("sig", signature); + + HttpGet httpGet; + try { + httpGet = new HttpGet(builder.build()); + } + catch(URISyntaxException e) { + throw new TechnicalException(e); + } + + String result = executeRequest(httpGet, String.class); + + if (log.isDebugEnabled()) { + log.debug("Server response, after currency registration: " + result); + } + } + + /* -- protected methods -- */ + + protected URIBuilder getURIBuilder(String... path) { + String pathToAppend = Joiner.on('/').skipNulls().join(path); + + int customQueryStartIndex = pathToAppend.indexOf('?'); + String customQuery = null; + if (customQueryStartIndex != -1) { + customQuery = pathToAppend.substring(customQueryStartIndex+1); + pathToAppend = pathToAppend.substring(0, customQueryStartIndex); + } + + try { + URI baseUri = config.getNodeElasticSearchUrl().toURI(); + URIBuilder builder = new URIBuilder(baseUri); + + builder.setPath(baseUri.getPath() + pathToAppend); + if (StringUtils.isNotBlank(customQuery)) { + builder.setCustomQuery(customQuery); + } + return builder; + } + catch(URISyntaxException e) { + throw new TechnicalException(e); + } + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java new file mode 100644 index 0000000000000000000000000000000000000000..201b6ef48a55f0d7a6aa984dcd36de7eeefb070e --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/HttpBadRequestException.java @@ -0,0 +1,27 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.TechnicalException; + +/** + * Created by eis on 11/02/15. + */ +public class HttpBadRequestException extends TechnicalException{ + + private static final long serialVersionUID = -5260280401104018980L; + + public HttpBadRequestException() { + super(); + } + + public HttpBadRequestException(String message, Throwable cause) { + super(message, cause); + } + + public HttpBadRequestException(String message) { + super(message); + } + + public HttpBadRequestException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResult.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/InsufficientCreditException.java similarity index 58% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResult.java rename to ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/InsufficientCreditException.java index a924f440d23b7ffb699b408ecf1638f747bcce2b..2c8faf6339a338d4575bea8d4a1a71e6d1641642 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResult.java +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/InsufficientCreditException.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.client.service.exception; /* * #%L @@ -22,31 +22,27 @@ package io.ucoin.client.core.model; * #L% */ - -import java.io.Serializable; -import java.util.List; - -public class WotLookupResult implements Serializable{ - - private static final long serialVersionUID = -39452685440482106L; - - private String pubkey; - - private List<WotLookupUId> uids; - - public String getPubkey() { - return pubkey; - } - - public void setPubkey(String pubkey) { - this.pubkey = pubkey; - } - - public List<WotLookupUId> getUids() { - return uids; - } - - public void setUids(List<WotLookupUId> uids) { - this.uids = uids; - } -} + +import io.ucoin.ucoinj.core.exception.BusinessException; + +public class InsufficientCreditException extends BusinessException { + + private static final long serialVersionUID = -5260280401104018980L; + + public InsufficientCreditException() { + super(); + } + + public InsufficientCreditException(String message, Throwable cause) { + super(message, cause); + } + + public InsufficientCreditException(String message) { + super(message); + } + + public InsufficientCreditException(Throwable cause) { + super(cause); + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/JsonSyntaxException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/JsonSyntaxException.java new file mode 100644 index 0000000000000000000000000000000000000000..8543b5c21d7b352c97470c6246289b57a4b27db2 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/JsonSyntaxException.java @@ -0,0 +1,25 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.TechnicalException; + +/** + * Created by blavenie on 05/01/16. + */ +public class JsonSyntaxException extends TechnicalException { + + public JsonSyntaxException() { + super(); + } + + public JsonSyntaxException(String message, Throwable cause) { + super(message, cause); + } + + public JsonSyntaxException(String message) { + super(message); + } + + public JsonSyntaxException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PeerConnectionException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PeerConnectionException.java new file mode 100644 index 0000000000000000000000000000000000000000..9390776d8dfd92643d3d30b39273c4902e143ed5 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PeerConnectionException.java @@ -0,0 +1,25 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by eis on 05/02/15. + */ +public class PeerConnectionException extends BusinessException{ + + public PeerConnectionException() { + super(); + } + + public PeerConnectionException(String message, Throwable cause) { + super(message, cause); + } + + public PeerConnectionException(String message) { + super(message); + } + + public PeerConnectionException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PubkeyAlreadyUsedException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PubkeyAlreadyUsedException.java new file mode 100644 index 0000000000000000000000000000000000000000..9f7236b493dc90469a5d1c9965a9f8b9c78f1c50 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/PubkeyAlreadyUsedException.java @@ -0,0 +1,27 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by eis on 11/02/15. + */ +public class PubkeyAlreadyUsedException extends BusinessException{ + + private static final long serialVersionUID = -5260280401104018980L; + + public PubkeyAlreadyUsedException() { + super(); + } + + public PubkeyAlreadyUsedException(String message, Throwable cause) { + super(message, cause); + } + + public PubkeyAlreadyUsedException(String message) { + super(message); + } + + public PubkeyAlreadyUsedException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAlreadyUsedException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAlreadyUsedException.java new file mode 100644 index 0000000000000000000000000000000000000000..6a0280a0463ca9b092ac8b5631a0943e36723b82 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAlreadyUsedException.java @@ -0,0 +1,27 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by eis on 11/02/15. + */ +public class UidAlreadyUsedException extends BusinessException{ + + private static final long serialVersionUID = -5260280401104018980L; + + public UidAlreadyUsedException() { + super(); + } + + public UidAlreadyUsedException(String message, Throwable cause) { + super(message, cause); + } + + public UidAlreadyUsedException(String message) { + super(message); + } + + public UidAlreadyUsedException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAndPubkeyNotFoundException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAndPubkeyNotFoundException.java new file mode 100644 index 0000000000000000000000000000000000000000..1115512f0634661ebc58017cca038580407328ee --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidAndPubkeyNotFoundException.java @@ -0,0 +1,27 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by eis on 11/02/15. + */ +public class UidAndPubkeyNotFoundException extends BusinessException{ + + private static final long serialVersionUID = -5260280401104018980L; + + public UidAndPubkeyNotFoundException() { + super(); + } + + public UidAndPubkeyNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public UidAndPubkeyNotFoundException(String message) { + super(message); + } + + public UidAndPubkeyNotFoundException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidMatchAnotherPubkeyException.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidMatchAnotherPubkeyException.java new file mode 100644 index 0000000000000000000000000000000000000000..b8352226290bba2336cf7d59df634f8041351ad6 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/exception/UidMatchAnotherPubkeyException.java @@ -0,0 +1,27 @@ +package io.ucoin.ucoinj.core.client.service.exception; + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by eis on 11/02/15. + */ +public class UidMatchAnotherPubkeyException extends BusinessException { + + private static final long serialVersionUID = -5260280401104018980L; + + public UidMatchAnotherPubkeyException() { + super(); + } + + public UidMatchAnotherPubkeyException(String message, Throwable cause) { + super(message, cause); + } + + public UidMatchAnotherPubkeyException(String message) { + super(message); + } + + public UidMatchAnotherPubkeyException(Throwable cause) { + super(cause); + } +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyService.java new file mode 100644 index 0000000000000000000000000000000000000000..147c2dd05336e22dacead1e1bf2c77ed22203f18 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyService.java @@ -0,0 +1,71 @@ +package io.ucoin.ucoinj.core.client.service.local; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.local.Currency; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created by eis on 07/02/15. + */ +public interface CurrencyService extends Service { + + Currency save(final Currency currency); + + List<Currency> getCurrencies(long accountId); + + Currency getCurrencyById(long currencyId); + + /** + * Return a (cached) currency name, by id + * @param currencyId + * @return + */ + String getCurrencyNameById(long currencyId); + + /** + * Return a currency id, by name + * @param currencyName + * @return + */ + Long getCurrencyIdByName(String currencyName); + + /** + * Return a (cached) list of currency ids + * @return + */ + Set<Long> getCurrencyIds(); + + /** + * Return a (cached) number of registered currencies + * @return + */ + int getCurrencyCount(); + + /** + * Fill all cache need for currencies + * @param context + */ + void loadCache(long accountId); + + /** + * Return the value of the last universal dividend + * @param currencyId + * @return + */ + long getLastUD(long currencyId); + + /** + * Return a map of UD (key=blockNumber, value=amount) + * @return + */ + Map<Integer, Long> refreshAndGetUD(long currencyId, long lastSyncBlockNumber); + + /** + * Return a map of UD (key=blockNumber, value=amount) + * @return + */ + Map<Integer, Long> getAllUD(long currencyId); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..539c2e00226dbe426b2bfb6dd1036678e2099619 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/CurrencyServiceImpl.java @@ -0,0 +1,226 @@ +package io.ucoin.ucoinj.core.client.service.local; + +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.client.dao.CurrencyDao; +import io.ucoin.ucoinj.core.client.model.local.Currency; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.core.util.cache.Cache; +import io.ucoin.ucoinj.core.util.cache.SimpleCache; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * Created by eis on 07/02/15. + */ +public class CurrencyServiceImpl implements CurrencyService, InitializingBean { + + + private static final long UD_CACHE_TIME_MILLIS = 5 * 60 * 1000; // = 5 min + + private Cache<Long, Currency> mCurrencyCache; + private Cache<Long, Long> mUDCache; + + private BlockchainRemoteService blockchainRemoteService; + private CurrencyDao currencyDao; + + public CurrencyServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() throws Exception { + blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + currencyDao = ServiceLocator.instance().getBean(CurrencyDao.class); + + // Load cache from account + long accountId = ServiceLocator.instance().getDataContext().getAccountId(); + if (accountId != -1) { + loadCache(accountId); + } + } + + @Override + public void close() throws IOException { + currencyDao = null; + blockchainRemoteService = null; + } + + public Currency save(final Currency currency) { + ObjectUtils.checkNotNull(currency); + ObjectUtils.checkArgument(StringUtils.isNotBlank(currency.getCurrencyName())); + ObjectUtils.checkArgument(StringUtils.isNotBlank(currency.getFirstBlockSignature())); + ObjectUtils.checkNotNull(currency.getMembersCount()); + ObjectUtils.checkArgument(currency.getMembersCount().intValue() >= 0); + ObjectUtils.checkNotNull(currency.getLastUD()); + ObjectUtils.checkArgument(currency.getLastUD().longValue() > 0); + + ObjectUtils.checkArgument((currency.getAccount() != null && currency.getAccount().getId() != null) + || currency.getAccountId() != null, "One of 'currency.account.id' or 'currency.accountId' is mandatory."); + + Currency result; + + // Create + if (currency.getId() == null) { + result = currencyDao.create(currency); + + // Update the cache (if already initialized) + if (mCurrencyCache != null) { + mCurrencyCache.put(currency.getId(), currency); + } + } + + // or update + else { + currencyDao.update(currency); + + result = currency; + } + + return result; + } + + public List<Currency> getCurrencies(long accountId) { + return currencyDao.getCurrencies(accountId); + } + + + public Currency getCurrencyById(long currencyId) { + return mCurrencyCache.get(currencyId); + } + + /** + * Return a (cached) currency name, by id + * @param currencyId + * @return + */ + public String getCurrencyNameById(long currencyId) { + Currency currency = mCurrencyCache.getIfPresent(currencyId); + if (currency == null) { + return null; + } + return currency.getCurrencyName(); + } + + /** + * Return a currency id, by name + * @param currencyName + * @return + */ + public Long getCurrencyIdByName(String currencyName) { + ObjectUtils.checkArgument(StringUtils.isNotBlank(currencyName)); + + // Search from currencies + for (Map.Entry<Long, Currency> entry : mCurrencyCache.entrySet()) { + Currency currency = entry.getValue(); + if (ObjectUtils.equals(currencyName, currency.getCurrencyName())) { + return entry.getKey(); + } + } + return null; + } + + /** + * Return a (cached) list of currency ids + * @return + */ + public Set<Long> getCurrencyIds() { + return mCurrencyCache.keySet(); + } + + /** + * Return a (cached) number of registered currencies + * @return + */ + public int getCurrencyCount() { + return mCurrencyCache.entrySet().size(); + } + + + /** + * Fill all cache need for currencies + * @param accountId + */ + public void loadCache(long accountId) { + if (mCurrencyCache == null || mUDCache == null) { + // Create and fill the currency cache + List<Currency> currencies = getCurrencies(accountId); + if (mCurrencyCache == null) { + + mCurrencyCache = new SimpleCache<Long, Currency>() { + @Override + public Currency load(Long currencyId) { + return currencyDao.getById(currencyId); + } + }; + + // Fill the cache + for (Currency currency : currencies) { + mCurrencyCache.put(currency.getId(), currency); + } + } + + // Create the UD cache + if (mUDCache == null) { + + mUDCache = new SimpleCache<Long, Long>(UD_CACHE_TIME_MILLIS) { + @Override + public Long load(final Long currencyId) { + // Retrieve the last UD from the blockchain + final long lastUD = blockchainRemoteService.getLastUD(currencyId); + + // Update currency + Currency currency = getCurrencyById(currencyId); + if (!ObjectUtils.equals(currency.getLastUD(), lastUD)) { + currency.setLastUD(lastUD); + currencyDao.update(currency); + } + + return lastUD; + } + }; + } + } + } + + /** + * Return the value of the last universal dividend + * @param currencyId + * @return + */ + public long getLastUD(long currencyId) { + return mUDCache.get(currencyId); + } + + /** + * Return a map of UD (key=blockNumber, value=amount) + * @return + */ + public Map<Integer, Long> refreshAndGetUD(long currencyId, long lastSyncBlockNumber) { + + // Retrieve new UDs from blockchain + Map<Integer, Long> newUDs = blockchainRemoteService.getUDs(currencyId, lastSyncBlockNumber + 1); + + // If any, insert new into DB + if (newUDs != null && newUDs.size() > 0) { + currencyDao.insertUDs(currencyId, newUDs); + } + + return getAllUD(currencyId); + } + + /** + * Return a map of UD (key=blockNumber, value=amount) + * @return + */ + public Map<Integer, Long> getAllUD(long currencyId) { + return currencyDao.getAllUD(currencyId); + } + +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerService.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerService.java new file mode 100644 index 0000000000000000000000000000000000000000..2711f18d18b3334ae35e90df93be28b07e522ec2 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerService.java @@ -0,0 +1,37 @@ +package io.ucoin.ucoinj.core.client.service.local; + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.util.List; + +/** + * Created by eis on 07/02/15. + */ +public interface PeerService extends Service { + + Peer save(final Peer peer); + + Peer getPeerById(long peerId); + + /** + * Return a (cached) active peer, by currency id + * @param currencyId + * @return + */ + Peer getActivePeerByCurrencyId(long currencyId); + + /** + * Return a (cached) peer list, by currency id + * @param currencyId + * @return + */ + List<Peer> getPeersByCurrencyId(long currencyId); + + /** + * Fill all cache need for currencies + * @param context + * @param accountId + */ + void loadCache(long accountId); +} diff --git a/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerServiceImpl.java b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..9cc583859ef9cec92fbcd52b576122ae0bdd16d0 --- /dev/null +++ b/ucoinj-core-client/src/main/java/io/ucoin/ucoinj/core/client/service/local/PeerServiceImpl.java @@ -0,0 +1,158 @@ +package io.ucoin.ucoinj.core.client.service.local; + +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.client.dao.PeerDao; +import io.ucoin.ucoinj.core.client.model.local.Currency; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.core.util.cache.Cache; +import io.ucoin.ucoinj.core.util.cache.SimpleCache; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by eis on 07/02/15. + */ +public class PeerServiceImpl implements PeerService, InitializingBean { + + private Cache<Long, List<Peer>> peersByCurrencyIdCache; + private Cache<Long, Peer> activePeerByCurrencyIdCache; + + private CurrencyService currencyService; + private PeerDao peerDao; + + public PeerServiceImpl() { + super(); + } + + @Override + public void afterPropertiesSet() throws Exception { + currencyService = ServiceLocator.instance().getCurrencyService(); + peerDao = ServiceLocator.instance().getBean(PeerDao.class); + } + + @Override + public void close() throws IOException { + currencyService = null; + peerDao = null; + peersByCurrencyIdCache = null; + activePeerByCurrencyIdCache = null; + } + + public Peer save(final Peer peer) { + ObjectUtils.checkNotNull(peer); + ObjectUtils.checkNotNull(peer.getCurrencyId()); + ObjectUtils.checkArgument(StringUtils.isNotBlank(peer.getHost())); + ObjectUtils.checkArgument(peer.getPort() >= 0); + + Peer result; + // Create + if (peer.getId() == null) { + result = peerDao.create(peer); + } + + // or update + else { + peerDao.update(peer); + result = peer; + } + + // update cache (if already loaded) + if (peersByCurrencyIdCache != null) { + List<Peer> peers = peersByCurrencyIdCache.get(peer.getCurrencyId()); + if (peers == null) { + peers = new ArrayList<Peer>(); + peersByCurrencyIdCache.put(peer.getCurrencyId(), peers); + peers.add(peer); + } + else if (!peers.contains(peer)) { + peers.add(peer); + } + } + + return result; + } + + + public Peer getPeerById(long peerId) { + return peerDao.getById(peerId); + } + + /** + * Return a (cached) active peer, by currency id + * @param currencyId + * @return + */ + public Peer getActivePeerByCurrencyId(long currencyId) { + // Check if cache as been loaded + if (activePeerByCurrencyIdCache == null) { + + activePeerByCurrencyIdCache = new SimpleCache<Long, Peer>() { + @Override + public Peer load(Long currencyId) { + List<Peer> peers = peerDao.getPeersByCurrencyId(currencyId); + if (CollectionUtils.isEmpty(peers)) { + String currencyName = currencyService.getCurrencyNameById(currencyId); + throw new TechnicalException(String.format( + "No peers configure for currency [%s]", + currencyName != null ? currencyName : currencyId)); + } + + return peers.get(0); + } + }; + } + + return activePeerByCurrencyIdCache.get(currencyId); + } + + /** + * Return a (cached) peer list, by currency id + * @param currencyId + * @return + */ + public List<Peer> getPeersByCurrencyId(long currencyId) { + // Check if cache as been loaded + if (peersByCurrencyIdCache == null) { + throw new TechnicalException("Cache not initialize. Please call loadCache() before getPeersByCurrencyId()."); + } + // Get it from cache + return peersByCurrencyIdCache.get(currencyId); + } + + /** + * Fill all cache need for currencies + * @param accountId + */ + public void loadCache(long accountId) { + if (peersByCurrencyIdCache != null) { + return; + } + + peersByCurrencyIdCache = new SimpleCache<Long, List<Peer>>() { + @Override + public List<Peer> load(Long currencyId) { + return peerDao.getPeersByCurrencyId(currencyId); + } + }; + + List<Currency> currencies = ServiceLocator.instance().getCurrencyService().getCurrencies(accountId); + + for (Currency currency: currencies) { + // Get peers from DB + List<Peer> peers = getPeersByCurrencyId(currency.getId()); + + // Then fill the cache + if (CollectionUtils.isNotEmpty(peers)) { + peersByCurrencyIdCache.put(currency.getId(), peers); + } + } + } + +} diff --git a/ucoinj-core-client/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider b/ucoinj-core-client/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider new file mode 100644 index 0000000000000000000000000000000000000000..51bc7a282dfae6f9ccaa742477b67d543eb6805d --- /dev/null +++ b/ucoinj-core-client/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider @@ -0,0 +1 @@ +io.ucoin.ucoinj.core.client.config.ConfigurationProvider diff --git a/ucoinj-core/src/main/resources/i18n/ucoinj-core_en_GB.properties b/ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_en_GB.properties similarity index 62% rename from ucoinj-core/src/main/resources/i18n/ucoinj-core_en_GB.properties rename to ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_en_GB.properties index 098dabb82378ee2e9eb7190eec4e2a0f91d21541..3bb9992b919e3cf6be4d88181e31ab52c5b65699 100644 --- a/ucoinj-core/src/main/resources/i18n/ucoinj-core_en_GB.properties +++ b/ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_en_GB.properties @@ -5,9 +5,18 @@ ucoinj.config.option.data.directory.description= ucoinj.config.option.i18n.directory.description= ucoinj.config.option.i18n.locale.description= ucoinj.config.option.inceptionYear.description= +ucoinj.config.option.network.timeout.description= ucoinj.config.option.node.currency.description= ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.elasticsearch.url.description= ucoinj.config.option.node.host.description= ucoinj.config.option.node.port.description= ucoinj.config.option.node.protocol.description= diff --git a/ucoinj-core/src/main/resources/i18n/ucoinj-core_fr_FR.properties b/ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_fr_FR.properties similarity index 64% rename from ucoinj-core/src/main/resources/i18n/ucoinj-core_fr_FR.properties rename to ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_fr_FR.properties index 2b73c56818d634ce23dbc3d103c629a25ef63779..1cae31705e6daf8317c07c9ec442a72e8a6c3d55 100644 --- a/ucoinj-core/src/main/resources/i18n/ucoinj-core_fr_FR.properties +++ b/ucoinj-core-client/src/main/resources/i18n/ucoinj-core-client_fr_FR.properties @@ -6,9 +6,18 @@ ucoinj.config.option.data.directory.description= ucoinj.config.option.i18n.directory.description= ucoinj.config.option.i18n.locale.description= ucoinj.config.option.inceptionYear.description= +ucoinj.config.option.network.timeout.description= ucoinj.config.option.node.currency.description= ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.elasticsearch.url.description= ucoinj.config.option.node.host.description= ucoinj.config.option.node.port.description= ucoinj.config.option.node.protocol.description= diff --git a/ucoinj-core/src/main/resources/log4j.properties b/ucoinj-core-client/src/main/resources/log4j.properties similarity index 100% rename from ucoinj-core/src/main/resources/log4j.properties rename to ucoinj-core-client/src/main/resources/log4j.properties diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestFixtures.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestFixtures.java new file mode 100644 index 0000000000000000000000000000000000000000..f4305657d3daf67795a21e0407c54ac6bd5de070 --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestFixtures.java @@ -0,0 +1,10 @@ +package io.ucoin.ucoinj.core.client; + + +public class TestFixtures extends io.ucoin.ucoinj.core.test.TestFixtures{ + + + public long getDefaultCurrencyId() { + return -1; + } +} diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestResource.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestResource.java new file mode 100644 index 0000000000000000000000000000000000000000..2eadccc47b1222c38267d45a5dd3506fb7a804ec --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/TestResource.java @@ -0,0 +1,164 @@ +package io.ucoin.ucoinj.core.client; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.collect.Lists; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.config.ConfigurationOption; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import org.apache.commons.io.FileUtils; +import org.junit.runner.Description; +import org.nuiton.i18n.I18n; +import org.nuiton.i18n.init.DefaultI18nInitializer; +import org.nuiton.i18n.init.UserI18nInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +public class TestResource extends io.ucoin.ucoinj.core.test.TestResource { + + private static final Logger log = LoggerFactory.getLogger(TestResource.class); + + public static TestResource create() { + return new TestResource(null); + } + + public static TestResource create(String configName) { + return new TestResource(configName); + } + + private io.ucoin.ucoinj.core.client.TestFixtures fixtures = new io.ucoin.ucoinj.core.client.TestFixtures(); + + protected TestResource(String configName) { + super(configName); + } + + public io.ucoin.ucoinj.core.client.TestFixtures getFixtures() { + return fixtures; + } + + protected void before(Description description) throws Throwable { + super.before(description); + + // Initialize configuration + initConfiguration(getConfigFileName()); + + // Init i18n + initI18n(); + + // Initialize service locator + ServiceLocator.instance().init(); + + initMockData(); + } + + @Override + protected void after(Description description) throws Throwable { + super.after(description); + + ServiceLocator.instance().close(); + } + + /** + * Return configuration files prefix (i.e. 'allegro-test') + * Could be override by external project + * + * @return the prefix to use to retrieve configuration files + */ + protected String getConfigFilesPrefix() { + return "ucoinj-core-client-test"; + } + + protected String getI18nBundleName() { + return "ucoinj-core-client-i18n"; + } + + /* -- -- */ + + /** + * Convenience methods that could be override to initialize other configuration + * + * @param configFilename + * @param configArgs + */ + protected void initConfiguration(String configFilename) { + String[] configArgs = getConfigArgs(); + Configuration config = new Configuration(configFilename, configArgs); + Configuration.setInstance(config); + } + + protected void initI18n() throws IOException { + Configuration config = Configuration.instance(); + + // --------------------------------------------------------------------// + // init i18n + // --------------------------------------------------------------------// + File i18nDirectory = new File(config.getDataDirectory(), "i18n"); + if (i18nDirectory.exists()) { + // clean i18n cache + FileUtils.cleanDirectory(i18nDirectory); + } + + FileUtils.forceMkdir(i18nDirectory); + + if (log.isDebugEnabled()) { + log.debug("I18N directory: " + i18nDirectory); + } + + Locale i18nLocale = config.getI18nLocale(); + + if (log.isInfoEnabled()) { + log.info(String.format("Starts i18n with locale [%s] at [%s]", + i18nLocale, i18nDirectory)); + } + I18n.init(new UserI18nInitializer( + i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())), + i18nLocale); + } + + protected String[] getConfigArgs() { + List<String> configArgs = Lists.newArrayList(); + configArgs.addAll(Lists.newArrayList( + "--option", ConfigurationOption.BASEDIR.getKey(), getResourceDirectory().getAbsolutePath())); + return configArgs.toArray(new String[configArgs.size()]); + } + + protected void initMockData() { + Configuration config = Configuration.instance(); + + // Set a default account id, then load cache + ServiceLocator.instance().getDataContext().setAccountId(0); + + Peer peer = new Peer(config.getNodeHost(), config.getNodePort()); + peer.setCurrencyId(fixtures.getDefaultCurrencyId()); + + ServiceLocator.instance().getPeerService().save(peer); + + } +} diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParserTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..88cba8c04462b8951ea24d454b159e744f1d0b56 --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/model/bma/gson/JsonArrayParserTest.java @@ -0,0 +1,26 @@ +package io.ucoin.ucoinj.core.client.model.bma.gson; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by blavenie on 05/01/16. + */ +public class JsonArrayParserTest { + + @Test + public void getValues() { + String obj = "{'id':'joe','ts':'2014-12-02T13:58:23.801+0100','foo':{'bar':{'v1':50019820,'v2':0, 'v3':0.001, 'v4':-100, 'v5':0.000001, 'v6':0.0, 'b':true}}}".replace("'", "\""); + String string = String.format("[%s,%s,%s,%s]", obj , obj , obj , obj ); + + JsonArrayParser parser = new JsonArrayParser(); + String[] result = parser.getValuesAsArray(string); + + Assert.assertNotNull(result); + Assert.assertEquals(4, result.length); + Assert.assertEquals(obj, result[0]); + + result = parser.getValuesAsArray("[]"); + Assert.assertNull(result); + } +} diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1c7ed5b46e026250c9b67b21555c4ca57adf778b --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/BlockchainRemoteServiceTest.java @@ -0,0 +1,114 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import io.ucoin.ucoinj.core.client.TestResource; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.BasicIdentity; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.Member; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import org.junit.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BlockchainRemoteServiceTest { + + private static final Logger log = LoggerFactory.getLogger(BlockchainRemoteServiceTest.class); + + @ClassRule + public static final TestResource resource = TestResource.create(); + + private BlockchainRemoteService service; + + @Before + public void setUp() { + service = ServiceLocator.instance().getBlockchainRemoteService(); + } + + @Test + public void getParameters() throws Exception { + + BlockchainParameters result = service.getParameters(createTestPeer()); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getCurrency()); + } + + @Test + public void getBlock() throws Exception { + + BlockchainBlock result = service.getBlock(createTestPeer(), 0); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getCurrency()); + + for (BlockchainBlock.Identity id: result.getIdentities()) { + Assert.assertNotNull(id.getUid()); + } + + for (BlockchainBlock.Joiner id: result.getJoiners()) { + Assert.assertNotNull(id.getUid()); + } + } + + @Test + public void getBlocksAsJson() throws Exception { + + String[] result= service.getBlocksAsJson(createTestPeer(), 10, 0); + + Assert.assertNotNull(result); + Assert.assertEquals(10, result.length); + + // Make sure all json are valid blocks + Gson gson = GsonUtils.newBuilder().create(); + int number = 0; + for (String jsonBlock: result) { + try { + gson.fromJson(jsonBlock, BlockchainBlock.class); + } + catch(JsonSyntaxException e) { + e.printStackTrace(); + Assert.fail(String.format("Invalid block format #%s. See previous error", number)); + } + number++; + } + + } + + /* -- Internal methods -- */ + + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); + + return peer; + } +} diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bc8909a602c85b2a8bb765a5da0f0523d817eecc --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/NetworkRemoteServiceTest.java @@ -0,0 +1,96 @@ +package io.ucoin.ucoinj.core.client.service.bma; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.TestResource; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.EndpointProtocol; +import io.ucoin.ucoinj.core.client.model.bma.NetworkPeering; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class NetworkRemoteServiceTest { + + private static final Logger log = LoggerFactory.getLogger(NetworkRemoteServiceTest.class); + + @ClassRule + public static final TestResource resource = TestResource.create(); + + private NetworkRemoteService service; + private Peer peer; + + @Before + public void setUp() { + service = ServiceLocator.instance().getNetworkRemoteService(); + peer = createTestPeer(); + } + + @Test + public void getPeering() throws Exception { + + NetworkPeering result = service.getPeering(peer); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getPubkey()); + Assert.assertNotNull(result.getSignature()); + Assert.assertNotNull(result.getCurrency()); + } + + + @Test + public void findPeers() throws Exception { + + List<Peer> result = service.findPeers(peer, null, EndpointProtocol.BASIC_MERKLED_API, null, null); + + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + } + + @Test + public void getPeers() throws Exception { + + List<Peer> result = service.getPeers(peer); + + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + } + + /* -- internal methods */ + + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); + + return peer; + } +} diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/TransactionServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java similarity index 64% rename from ucoinj-core/src/test/java/io/ucoin/client/core/service/TransactionServiceTest.java rename to ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java index 4b4e0c8a836195b39e456ad12365ba500eb40c28..7c93d5196fd95f529a03f23979fb5c41310799d0 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/TransactionServiceTest.java +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/TransactionRemoteServiceTest.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.service; +package io.ucoin.ucoinj.core.client.service.bma; /* * #%L @@ -23,10 +23,13 @@ package io.ucoin.client.core.service; */ -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.model.TxSourceResults; -import io.ucoin.client.core.model.Wallet; -import io.ucoin.client.core.technical.crypto.CryptoUtils; +import io.ucoin.ucoinj.core.client.TestResource; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.TxSource; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; @@ -34,17 +37,18 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TransactionServiceTest { +public class TransactionRemoteServiceTest { + + private static final Logger log = LoggerFactory.getLogger(TransactionRemoteServiceTest.class); - private static final Logger log = LoggerFactory.getLogger(TransactionServiceTest.class); @ClassRule public static final TestResource resource = TestResource.create(); - private TransactionService service; + private TransactionRemoteService service; @Before public void setUp() { - service = ServiceLocator.instance().getTransactionService(); + service = ServiceLocator.instance().getTransactionRemoteService(); } @Test @@ -56,28 +60,24 @@ public class TransactionServiceTest { resource.getFixtures().getOtherUserPublicKey(), 1, "my comments" + System.currentTimeMillis()); - - // close - service.close(); } @Test public void getSources() throws Exception { String pubKey = resource.getFixtures().getUserPublicKey(); + Peer peer = createTestPeer(); - TransactionService service = new TransactionService(); - TxSourceResults sourceResults = service.getSources(pubKey); + TxSource sourceResults = service.getSources(peer, pubKey); Assert.assertNotNull(sourceResults); Assert.assertNotNull(sourceResults.getSources()); Assert.assertEquals(resource.getFixtures().getCurrency(), sourceResults.getCurrency()); Assert.assertEquals(pubKey, sourceResults.getPubkey()); - Assert.assertTrue(sourceResults.getBalance() > 0d); - // close - service.close(); - } + long credit = service.computeCredit(sourceResults.getSources()); + Assert.assertTrue(credit > 0d); + } /* -- internal methods */ @@ -87,7 +87,17 @@ public class TransactionServiceTest { resource.getFixtures().getUid(), CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); - + + wallet.setCurrencyId(resource.getFixtures().getDefaultCurrencyId()); + return wallet; } + + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); + + return peer; + } } diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/WotServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java similarity index 51% rename from ucoinj-core/src/test/java/io/ucoin/client/core/service/WotServiceTest.java rename to ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java index 82e8491fcdfb550bda09f5b76b4902acb98932fe..09f8eea33addb2ecca909549f8a9a57604c4fc36 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/WotServiceTest.java +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/bma/WotRemoteServiceTest.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.service; +package io.ucoin.ucoinj.core.client.service.bma; /* * #%L @@ -23,112 +23,128 @@ package io.ucoin.client.core.service; */ -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.model.*; -import io.ucoin.client.core.technical.crypto.SecretBox; -import org.apache.commons.collections4.CollectionUtils; +import io.ucoin.ucoinj.core.client.TestResource; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.BasicIdentity; +import io.ucoin.ucoinj.core.client.model.bma.WotCertification; +import io.ucoin.ucoinj.core.client.model.bma.WotLookup; +import io.ucoin.ucoinj.core.client.model.local.Identity; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import io.ucoin.ucoinj.core.util.crypto.SecretBox; import org.junit.Assert; +import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class WotServiceTest { +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class WotRemoteServiceTest { + + private static final Logger log = LoggerFactory.getLogger(WotRemoteServiceTest.class); - private static final Logger log = LoggerFactory.getLogger(WotServiceTest.class); @ClassRule public static final TestResource resource = TestResource.create(); - @Test - public void find() throws Exception { + private WotRemoteService service; - WotService service = new WotService(); - WotLookupResults results = service - .find(resource.getFixtures().getUid()); - Assert.assertNotNull(results); + @Before + public void setUp() { + service = ServiceLocator.instance().getWotRemoteService(); + } - // close - service.close(); + @Test + public void getIdentity() throws Exception { + Set<Long> currencyIds = new HashSet<>(); + currencyIds.add(resource.getFixtures().getDefaultCurrencyId()); + List<Identity> result = service + .findIdentities(currencyIds, resource.getFixtures().getUid()); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); } @Test public void findByUid() throws Exception { - - WotService service = new WotService(); - WotLookupUId result = service - .findByUid(resource.getFixtures().getUid()); + WotLookup.Uid result = service + .findByUid(resource.getFixtures().getDefaultCurrencyId(), + resource.getFixtures().getUid()); Assert.assertNotNull(result); - - // close - service.close(); } @Test public void getCertifiedBy() throws Exception { + WotRemoteService service = ServiceLocator.instance().getWotRemoteService(); + WotCertification result = service.getCertifiedBy( + resource.getFixtures().getDefaultCurrencyId(), + resource.getFixtures().getUid()); - WotService service = new WotService(); - WotIdentityCertifications result = service.getCertifiedBy(resource - .getFixtures().getUid()); - assertBasicIdentity(result, false); + Assert.assertNotNull(result); + Assert.assertNotNull(result.getUid()); + Assert.assertNotNull(result.getPubkey()); Assert.assertTrue( String.format( "Test user (uid=%s) should have some certifications return by %s", resource.getFixtures().getUid(), - ProtocolUrls.WOT_CERTIFIED_BY), CollectionUtils + "certified-by"), CollectionUtils .isNotEmpty(result.getCertifications())); - for (WotCertification cert : result.getCertifications()) { + for (WotCertification.Certification cert : result.getCertifications()) { Assert.assertNotNull(cert.getUid()); - WotCertificationTime certTime = cert.getCert_time(); + WotCertification.CertTime certTime = cert.getCert_time(); Assert.assertNotNull(certTime); Assert.assertTrue(certTime.getBlock() >= 0); Assert.assertNotNull(certTime.getMedianTime() >= 0); } - - // close - service.close(); } @Test public void getCertifiersOf() throws Exception { + WotCertification result = service.getCertifiersOf( + resource.getFixtures().getDefaultCurrencyId(), + resource.getFixtures().getUid()); - WotService service = new WotService(); - WotIdentityCertifications result = service.getCertifiersOf(resource - .getFixtures().getUid()); - assertBasicIdentity(result, false); + Assert.assertNotNull(result); + Assert.assertNotNull(result.getUid()); + Assert.assertNotNull(result.getPubkey()); Assert.assertTrue( String.format( "Test user (uid=%s) should have some certifications return by %s", resource.getFixtures().getUid(), - ProtocolUrls.WOT_CERTIFIERS_OF), CollectionUtils - .isNotEmpty(result.getCertifications())); + "certifiers-of"), + CollectionUtils.isNotEmpty(result.getCertifications())); - for (WotCertification cert : result.getCertifications()) { + for (WotCertification.Certification cert : result.getCertifications()) { Assert.assertNotNull(cert.getUid()); - WotCertificationTime certTime = cert.getCert_time(); + WotCertification.CertTime certTime = cert.getCert_time(); Assert.assertNotNull(certTime); Assert.assertTrue(certTime.getBlock() >= 0); Assert.assertNotNull(certTime.getMedianTime() >= 0); } - - // close - service.close(); } @Test - public void getSelfCertification() throws Exception { + public void sendSelf() throws Exception { - WotService service = new WotService(); - SecretBox secretBox = createSercretBox(); + SecretBox secretBox = createSecretBox(); String uid = resource.getFixtures().getUid(); long timestamp = resource.getFixtures().getSelfTimestamp(); + Wallet wallet = createTestWallet(); - String selfCertification = service.getSelfCertification(secretBox, uid, + String selfCertification = service.getSelfCertification( + wallet.getSecKey(), + wallet.getUid(), timestamp); String expectedCertification = String.format( @@ -136,16 +152,13 @@ public class WotServiceTest { .getFixtures().getSelfSignature()); Assert.assertEquals(expectedCertification, selfCertification); - - // close - service.close(); } @Test public void getCertification() throws Exception { - WotService service = new WotService(); - SecretBox secretBox = createSercretBox(); + SecretBox secretBox = createSecretBox(); + Wallet wallet = createTestWallet(); String userUid = "kimamila"; long userTimestamp = 1418377981; @@ -153,7 +166,8 @@ public class WotServiceTest { int blockNumber = 3328; String blockHash = "0837171AD6CE72B7DAD0409A230D43A9CCFFE0DC"; - String selfCertification = service.getCertification(secretBox, userUid, + String selfCertification = service.getCertification(wallet.getPubKey(), + wallet.getSecKey(), userUid, userTimestamp, userSelf, blockNumber, blockHash); String expectedCertification = String @@ -166,9 +180,6 @@ public class WotServiceTest { "wOAbhxPzlnwmKgMXirPjxNno5tsHN95KMSUrVrZSLPcXn69cFg6ZbiWpSKVSFcHVVuZ4rhRvi46RFvVT/yFuDA=="); Assert.assertEquals(expectedCertification, selfCertification); - - // close - service.close(); } /* -- internal methods */ @@ -187,6 +198,7 @@ public class WotServiceTest { } + protected void assertIdentity(Identity identity) { assertBasicIdentity(identity, true); @@ -194,11 +206,30 @@ public class WotServiceTest { } - protected SecretBox createSercretBox() { + protected Wallet createTestWallet() { + Wallet wallet = new Wallet( + resource.getFixtures().getCurrency(), + resource.getFixtures().getUid(), + CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), + CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); + + return wallet; + } + + protected SecretBox createSecretBox() { String salt = resource.getFixtures().getUserSalt(); String password = resource.getFixtures().getUserPassword(); SecretBox secretBox = new SecretBox(salt, password); return secretBox; } + + + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); + + return peer; + } } diff --git a/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..530a51e70f56779e4d489eda3564eb0198eb5d6c --- /dev/null +++ b/ucoinj-core-client/src/test/java/io/ucoin/ucoinj/core/client/service/elasticsearch/CurrencyRegistryRemoteServiceTest.java @@ -0,0 +1,124 @@ +package io.ucoin.ucoinj.core.client.service.elasticsearch; + +/* + * #%L + * UCoin Java Client :: ElasticSearch Indexer + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.client.TestResource; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.Currency; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import org.junit.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Created by Benoit on 06/05/2015. + */ +public class CurrencyRegistryRemoteServiceTest { + private static final Logger log = LoggerFactory.getLogger(CurrencyRegistryRemoteServiceTest.class); + + @ClassRule + public static final TestResource resource = TestResource.create(); + + private CurrencyRegistryRemoteService service; + private Configuration config; + + @Before + public void setUp() { + service = ServiceLocator.instance().getCurrencyRegistryRemoteService(); + config = Configuration.instance(); + + // Make sure ES node is alive + if (!service.isNodeAlive()) { + log.warn(String.format("Unable to connect to elasticsearch node [%s:%s]. Skipping test.", + config.getNodeElasticSearchHost(), + config.getNodeElasticSearchPort())); + Assume.assumeTrue(false); + } + } + + @Test + public void isNodeAlive() { + boolean isNodeAlive = service.isNodeAlive(); + Assert.assertTrue(isNodeAlive); + } + + @Test + public void getAllCurrencyNames() { + List<String> currencyNames = service.getAllCurrencyNames(); + for (String currencyName: currencyNames) { + log.info(" - " + currencyName); + } + } + + @Test + public void registerCurrency() { + Currency currency = new Currency(); + currency.setCurrencyName("register-test-" + System.currentTimeMillis()); + + String currencyJson = GsonUtils.newBuilder().create().toJson(currency); + + String pubKey = resource.getFixtures().getUserPublicKey(); + String secretKey = resource.getFixtures().getUserSecretKey(); + + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + String signature = cryptoService.sign(currencyJson, secretKey); + + service.registerNewCurrency(pubKey, currencyJson, signature); + } + + /* -- internal methods -- */ + + protected Wallet createTestWallet() { + Wallet wallet = new Wallet( + resource.getFixtures().getCurrency(), + resource.getFixtures().getUid(), + CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), + CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); + + return wallet; + } + + protected void assertResults(String queryText, List<Currency> result) { + log.info(String.format("Results for a search on [%s]", queryText)); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + for (Currency currency: result) { + log.info(" - " + currency.getCurrencyName()); + } + } + + protected void assertSuggestions(String queryText, List<String> result) { + log.info(String.format("Suggestions for [%s]", queryText)); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + for (String suggestion: result) { + log.info(" - " + suggestion); + } + } +} diff --git a/ucoinj-core-client/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-core-client/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean new file mode 100644 index 0000000000000000000000000000000000000000..ea1d12da2ffe7ead9557024a3ea85b25942efc20 --- /dev/null +++ b/ucoinj-core-client/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean @@ -0,0 +1,12 @@ +io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.WotRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.TransactionRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.elasticsearch.CurrencyRegistryRemoteServiceImpl +io.ucoin.ucoinj.core.service.Ed25519CryptoServiceImpl +io.ucoin.ucoinj.core.client.service.HttpServiceImpl +io.ucoin.ucoinj.core.client.service.DataContext +io.ucoin.ucoinj.core.client.service.local.PeerServiceImpl +io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl \ No newline at end of file diff --git a/ucoinj-core/src/test/resources/log4j.properties b/ucoinj-core-client/src/test/resources/log4j.properties similarity index 78% rename from ucoinj-core/src/test/resources/log4j.properties rename to ucoinj-core-client/src/test/resources/log4j.properties index c3e49a9511ad13aaf4a1c992440c8590e12bba3e..b828a73a8a4971029a286063bc17c9d38973bc4a 100644 --- a/ucoinj-core/src/test/resources/log4j.properties +++ b/ucoinj-core-client/src/test/resources/log4j.properties @@ -8,9 +8,9 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - %m%n # ucoin levels -log4j.logger.io.ucoin=DEBUG -#log4j.logger.io.ucoin.client.core.service.AbstractNetworkService=WARN -log4j.logger.io.ucoin.client.core.service.AbstractNetworkService=TRACE +log4j.logger.io.ucoin.ucoinj=INFO +#log4j.logger.io.ucoin.ucoinj.core.client.service=DEBUG +log4j.appender.io.ucoin.ucoinj.core.beans=WARN log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.file=ucoin-client.log diff --git a/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties b/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties new file mode 100644 index 0000000000000000000000000000000000000000..ed9ab39ef7d714d2a7b2c2230519744ad6f8e4fc --- /dev/null +++ b/ucoinj-core-client/src/test/resources/ucoinj-core-client-test.properties @@ -0,0 +1,9 @@ +#ucoinj.node.host=metab.ucoin.io +ucoinj.node.host=metab.ucoin.fr +ucoinj.node.port=9201 + +ucoinj.node.elasticsearch.host=localhost +ucoinj.node.elasticsearch.port=8080 + +#ucoinj.node.elasticsearch.rest.host=www.data.ucoin.fr +#ucoinj.node.elasticsearch.rest.port=80 diff --git a/ucoinj-core-shared/LICENSE b/ucoinj-core-shared/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/ucoinj-core-shared/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ucoinj-core/lib/sodium.dll b/ucoinj-core-shared/lib/sodium.dll similarity index 100% rename from ucoinj-core/lib/sodium.dll rename to ucoinj-core-shared/lib/sodium.dll diff --git a/ucoinj-core/pom.xml b/ucoinj-core-shared/pom.xml similarity index 87% rename from ucoinj-core/pom.xml rename to ucoinj-core-shared/pom.xml index 10035a1911ee00da5c331a7118855c3782c8e193..784d46ecee093664fe58f88b0abef979c3a2fd3e 100644 --- a/ucoinj-core/pom.xml +++ b/ucoinj-core-shared/pom.xml @@ -8,10 +8,9 @@ </parent> <groupId>io.ucoin</groupId> - <artifactId>ucoinj-core</artifactId> + <artifactId>ucoinj-core-shared</artifactId> <packaging>jar</packaging> - <name>UCoin Java Client :: Core API</name> - + <name>UCoin Java :: Core Shared</name> <properties> <i18n.bundleOutputName>ucoinj-core-i18n</i18n.bundleOutputName> @@ -32,14 +31,6 @@ <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - </dependency> <!-- NaCL lib --> <dependency> <groupId>org.abstractj.kalium</groupId> @@ -54,7 +45,7 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> - <dependency> + <!--dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> @@ -73,11 +64,7 @@ <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> - </dependency> - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - </dependency> + </dependency--> <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-config</artifactId> @@ -87,20 +74,21 @@ <artifactId>nuiton-i18n</artifactId> </dependency> - <!-- Elastic Search --> + <!-- Unit test --> <dependency> - <groupId>org.elasticsearch</groupId> - <artifactId>elasticsearch</artifactId> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>compile</scope> + <optional>true</optional> </dependency> <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <scope>test</scope> </dependency> - - <!-- Unit test --> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> <scope>test</scope> </dependency> </dependencies> diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Bean.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Bean.java new file mode 100644 index 0000000000000000000000000000000000000000..344bc38d3c31687308695db8ca6cb7dd5cf8081b --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Bean.java @@ -0,0 +1,31 @@ +package io.ucoin.ucoinj.core.beans; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +/** + * Created by eis on 10/01/15. + */ +public interface Bean { + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/BeanFactory.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/BeanFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..d8f25bd3b31ac41a9c8d602cca97088892c685fc --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/BeanFactory.java @@ -0,0 +1,84 @@ +package io.ucoin.ucoinj.core.beans; + +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * Created by blavenie on 18/12/15. + */ +public class BeanFactory implements Closeable{ + + + private static final Logger log = LoggerFactory.getLogger(BeanFactory.class); + + private final Map<Class<?>, Object> beansCache; + private final ServiceLoader<Bean> beansLoader; + + public BeanFactory() { + beansCache = new HashMap<>(); + beansLoader = ServiceLoader.load(Bean.class); + } + + public <S extends Bean> S getBean(Class<S> clazz) { + if (beansCache.containsKey(clazz)) { + return (S)beansCache.get(clazz); + } + S bean = newBean(clazz); + beansCache.put(clazz, bean); + + // Call initialization + if (bean instanceof InitializingBean){ + if (log.isDebugEnabled()) { + log.debug(String.format("Initializing bean of type [%s]", clazz.getName())); + } + try { + ((InitializingBean) bean).afterPropertiesSet(); + } + catch(Exception e) { + throw new TechnicalException(String.format("Unable to initialize bean of type [%s]", clazz.getName()), e); + } + } + + return bean; + } + + + public <S extends Bean> S newBean(Class<S> clazz) { + + for (Bean bean: beansLoader) { + + if (clazz.isInstance(bean)) { + if (log.isDebugEnabled()) { + log.debug(String.format("Creating new bean of type [%s]", clazz.getName())); + } + return (S)bean; + } + } + + throw new TechnicalException(String.format("Unable to create bean with type [%s]: not configured for the service loader [%s]", clazz.getName(), Bean.class.getCanonicalName())); + } + + @Override + public void close() throws IOException { + for(Object bean: beansCache.values()) { + if (bean instanceof Closeable) { + if (log.isDebugEnabled()) { + log.debug(String.format("Closing bean of type [%s]...", bean.getClass().getName())); + } + try { + ((Closeable) bean).close(); + } + catch (Exception e) { + // continue + } + } + } + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/service/BaseService.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/InitializingBean.java similarity index 86% rename from ucoinj-core/src/main/java/io/ucoin/client/core/service/BaseService.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/InitializingBean.java index 0393ccedbc95fc431d54dc730a6b58ff21a1fae6..d121d1e6e94aa283cecf93fb7ba7438d9e15c856 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/service/BaseService.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/InitializingBean.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.service; +package io.ucoin.ucoinj.core.beans; /* * #%L @@ -26,13 +26,10 @@ package io.ucoin.client.core.service; /** * Created by eis on 10/01/15. */ -public abstract class BaseService { - - public BaseService() { - } +public interface InitializingBean { /** * Init bean (e.g. link to another services...) */ - public void initialize() {} + void afterPropertiesSet() throws Exception; } diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/Identity.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Service.java similarity index 63% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/Identity.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Service.java index bd76a8dae8decc96bc0ef4ce406bb846d12cda25..152daf1fdc99b47a57ee4823fb85dc3c874418c4 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/Identity.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/beans/Service.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.beans; /* * #%L @@ -22,23 +22,12 @@ package io.ucoin.client.core.model; * #L% */ - -public class Identity extends BasicIdentity { - - private static final long serialVersionUID = -7451079677730158794L; - - private int timestamp = -1; - - /** - * The timestamp value of the signature date - * @return - */ - public int getTimestamp() { - return timestamp; - } - - public void setTimestamp(int timestamp) { - this.timestamp = timestamp; - } - -} + +import java.io.Closeable; + +/** + * Created by eis on 10/01/15. + */ +public interface Service extends Bean, Closeable { + +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotIdentityCertifications.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/BusinessException.java similarity index 61% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotIdentityCertifications.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/BusinessException.java index 4059313e2902150ac94779a5d4c28a95089504d0..ede4ac46bdd103ead16807ee4280fa70db8d147d 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotIdentityCertifications.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/BusinessException.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.core.exception; /* * #%L @@ -22,28 +22,31 @@ package io.ucoin.client.core.model; * #L% */ - -import java.util.List; - -/** - * A list of certifications done to user, or by user - * @author Benoit Lavenier <benoit.lavenier@e-is.pro> - * @since 1.0 - * - */ -public class WotIdentityCertifications extends BasicIdentity { - - private static final long serialVersionUID = 8568496827055074607L; - - private List<WotCertification> certifications; - - public List<WotCertification> getCertifications() { - return certifications; - } - - public void setCertifications(List<WotCertification> certifications) { - this.certifications = certifications; - } - - -} + +/** + * A uCoin business exception + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + * + */ +public class BusinessException extends RuntimeException{ + + private static final long serialVersionUID = -6715624222174163366L; + + public BusinessException() { + super(); + } + + public BusinessException(String message, Throwable cause) { + super(message, cause); + } + + public BusinessException(String message) { + super(message); + } + + public BusinessException(Throwable cause) { + super(cause); + } + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java new file mode 100644 index 0000000000000000000000000000000000000000..ef8d644ea8caf7472d2b2f8a0165810176182e95 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/exception/TechnicalException.java @@ -0,0 +1,56 @@ +package io.ucoin.ucoinj.core.exception; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +/** + * A uCoin technical exception + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since + * + */ +public class TechnicalException extends RuntimeException{ + + private static final long serialVersionUID = -6715624222174163366L; + + public TechnicalException() { + super(); + } + + public TechnicalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public TechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public TechnicalException(String message) { + super(message); + } + + public TechnicalException(Throwable cause) { + super(cause); + } + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModel.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModel.java new file mode 100644 index 0000000000000000000000000000000000000000..1345b5f9a70823cc9dba02e1931185d0cc12507f --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModel.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.core.model; + +import java.beans.PropertyChangeListener; +import java.io.Serializable; + +/** + * Used to follow a task progression + * + * Created by eis on 09/02/15. + */ +public interface ProgressionModel extends Serializable { + enum Status { + NOT_STARTED, + WAITING_EXECUTION, + RUNNING, + FAILED, + SUCCESS, + STOPPED + } + + String PROPERTY_CURRENT = "current"; + + String PROPERTY_MESSAGE = "message"; + + String PROPERTY_TASK = "task"; + + String PROPERTY_CANCEL = "cancel"; + + String PROPERTY_STATUS = "status"; + + String PROPERTY_TOTAL = "total"; + + void setTask(String task); + String getTask(); + + String getMessage(); + void setMessage(String message); + + int getCurrent(); + void setCurrent(int progression); + + void setTotal(int total); + int getTotal(); + + void increment(); + void increment(int nb); + void increment(String message); + + boolean isCancel(); + void cancel(); + + Status getStatus(); + void setStatus(Status status); + + // For property change listener + void addPropertyChangeListener(PropertyChangeListener listener); + void addPropertyChangeListener(String propertyName, PropertyChangeListener listener); + void removePropertyChangeListener(PropertyChangeListener listener); + + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModelImpl.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModelImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..0d7891733ce704a6c2febf693043698f067b0cd6 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/model/ProgressionModelImpl.java @@ -0,0 +1,165 @@ +package io.ucoin.ucoinj.core.model; + +/* + * #%L + * SIH-Adagio :: Synchro Server WebApp + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.Serializable; + +public class ProgressionModelImpl implements ProgressionModel, Serializable { + + private static final long serialVersionUID = 1L; + + protected String task; + protected String message; + protected int current; + protected boolean cancel; + protected int total; + protected Status status; + + /* set as transient to avoid serialization of all listener */ + protected transient final PropertyChangeSupport propertyChangeSupport; + + public ProgressionModelImpl() { + super(); + this.propertyChangeSupport = new PropertyChangeSupport(this); + this.task = ""; + this.message = ""; + this.current = 0; + this.cancel = false; + this.total = 100; + this.status = Status.NOT_STARTED; + } + + @Override + public synchronized void addPropertyChangeListener(PropertyChangeListener listener) { + this.propertyChangeSupport.addPropertyChangeListener(listener); + } + + @Override + public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + this.propertyChangeSupport.addPropertyChangeListener(propertyName, listener); + } + + @Override + public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { + this.propertyChangeSupport.removePropertyChangeListener(listener); + } + + @Override + public synchronized String getMessage() { + return message; + } + + @Override + public synchronized void setTask(String task) { + String oldValue = this.task; + this.task = task; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_TASK, oldValue, this.task); + setMessage(task); + } + + @Override + public synchronized String getTask() { + return this.task; + } + + @Override + public synchronized void setMessage(String progressionMessage) { + String oldValue = this.message; + this.message = progressionMessage; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_MESSAGE, oldValue, this.message); + } + + @Override + public synchronized void setTotal(int total) { + int oldValue = this.total; + this.total = total; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_TOTAL, oldValue, this.total); + } + + @Override + public int getTotal() { + return this.total; + } + + @Override + public synchronized void setCurrent(int current) { + int oldValue = this.current; + this.current = current; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_CURRENT, oldValue, this.current); + } + + @Override + public synchronized int getCurrent() { + return current; + } + + @Override + public synchronized void increment() { + setCurrent(current + 1); + } + + @Override + public synchronized void increment(int increment) { + setCurrent(current + increment); + } + + @Override + public synchronized void increment(String message) { + increment(); + setMessage(message); + } + + public boolean isCancel() { + return cancel; + } + + @Override + public void cancel() { + if (!cancel) { + boolean oldValue = this.cancel; + this.cancel = true; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_CANCEL, oldValue, this.cancel); + } + } + + @Override + public synchronized ProgressionModel.Status getStatus() { + if (status == null) { + status = Status.NOT_STARTED; + } + return status; + } + + @Override + public synchronized void setStatus(Status progressionStatus) { + Status oldValue = this.status; + this.status = progressionStatus; + propertyChangeSupport.firePropertyChange(ProgressionModel.PROPERTY_STATUS, oldValue, this.status); + } + + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java new file mode 100644 index 0000000000000000000000000000000000000000..1041f32dee8ddca237eeb86149e4b5a0bcd47cd8 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/CryptoService.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.core.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.util.crypto.KeyPair; + + +/** + * Crypto services (sign...) + * Created by eis on 10/01/15. + */ +public interface CryptoService extends Bean { + byte[] getSeed(String salt, String password); + + /** + * Returns a new signing key pair generated from salt and password. + * The salt and password must contain enough entropy to be secure. + * + * @param salt + * @param password + * @return + */ + KeyPair getKeyPair(String salt, String password); + + /** + * Returns a new signing key pair generated from salt and password. + * The salt and password must contain enough entropy to be secure. + * + * @param seed + * @return + */ + KeyPair getKeyPairFromSeed(byte[] seed); + + String sign(String message, byte[] secretKey); + + String sign(String message, String secretKey); + + boolean verify(String message, String signature, String publicKey); +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/service/CryptoService.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java similarity index 85% rename from ucoinj-core/src/main/java/io/ucoin/client/core/service/CryptoService.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java index e29f9248e225a8b0b339ca11ca84aed9f25bc355..17a5a36495ff02b121421fe84462678b18678b64 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/service/CryptoService.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceImpl.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.service; +package io.ucoin.ucoinj.core.service; /* * #%L @@ -24,22 +24,23 @@ package io.ucoin.client.core.service; import com.lambdaworks.crypto.SCrypt; -import io.ucoin.client.core.technical.UCoinTechnicalException; -import io.ucoin.client.core.technical.crypto.KeyPair; +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.crypto.KeyPair; import jnr.ffi.byref.LongLongByReference; import org.abstractj.kalium.NaCl; import org.abstractj.kalium.NaCl.Sodium; import java.security.GeneralSecurityException; -import static io.ucoin.client.core.technical.crypto.CryptoUtils.*; +import static io.ucoin.ucoinj.core.util.crypto.CryptoUtils.*; /** * Crypto services (sign...) * Created by eis on 10/01/15. */ -public class CryptoService extends BaseService { +public class Ed25519CryptoServiceImpl implements CryptoService { // Length of the seed key (generated deterministically, use to generate the 64 key pair). private static int SEED_BYTES = 32; @@ -57,11 +58,11 @@ public class CryptoService extends BaseService { private final Sodium naCl; - public CryptoService() { + public Ed25519CryptoServiceImpl() { naCl = NaCl.sodium(); } - + @Override public byte[] getSeed(String salt, String password) { try { byte[] seed = SCrypt.scrypt( @@ -71,31 +72,18 @@ public class CryptoService extends BaseService { SCRYPT_PARAMS_p, SEED_BYTES); return seed; } catch (GeneralSecurityException e) { - throw new UCoinTechnicalException( + throw new TechnicalException( "Unable to salt password, using Scrypt library", e); } } - /** - * Returns a new signing key pair generated from salt and password. - * The salt and password must contain enough entropy to be secure. - * - * @param salt - * @param password - * @return - */ + @Override public KeyPair getKeyPair(String salt, String password) { return getKeyPairFromSeed(getSeed(salt, password)); } - /** - * Returns a new signing key pair generated from salt and password. - * The salt and password must contain enough entropy to be secure. - * - * @param seed - * @return - */ + @Override public KeyPair getKeyPairFromSeed(byte[] seed) { byte[] secretKey = zeros(SECRETKEY_BYTES); byte[] publicKey = zeros(PUBLICKEY_BYTES); @@ -105,6 +93,7 @@ public class CryptoService extends BaseService { return new KeyPair(publicKey, secretKey); } + @Override public String sign(String message, byte[] secretKey) { byte[] messageBinary = decodeUTF8(message); return encodeBase64( @@ -112,6 +101,7 @@ public class CryptoService extends BaseService { ); } + @Override public String sign(String message, String secretKey) { byte[] messageBinary = decodeUTF8(message); byte[] secretKeyBinary = decodeBase58(secretKey); @@ -120,6 +110,7 @@ public class CryptoService extends BaseService { ); } + @Override public boolean verify(String message, String signature, String publicKey) { byte[] messageBinary = decodeUTF8(message); byte[] signatureBinary = decodeBase64(signature); diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/TestFixtures.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java similarity index 98% rename from ucoinj-core/src/test/java/io/ucoin/client/core/TestFixtures.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java index ed0cc6ce06c3706a8acc58dee1556f8261f7acbb..7649583e4fb2be6b8ef6f1833326560de7a095d8 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/TestFixtures.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestFixtures.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core; +package io.ucoin.ucoinj.core.test; /* * #%L diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/TestResource.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestResource.java similarity index 61% rename from ucoinj-core/src/test/java/io/ucoin/client/core/TestResource.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestResource.java index 44fdd89b2c997ec78386af55ec28e8aa135989a9..e7b06bdc4f0c9a49ebef433f2fcb4ca23d19487d 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/TestResource.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/test/TestResource.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core; +package io.ucoin.ucoinj.core.test; /* * #%L @@ -24,27 +24,18 @@ package io.ucoin.client.core; import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.config.ConfigurationOption; -import io.ucoin.client.core.service.ServiceLocator; +import io.ucoin.ucoinj.core.util.FileUtils; +import io.ucoin.ucoinj.core.util.StringUtils; import org.abstractj.kalium.NaCl; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; -import org.nuiton.i18n.I18n; -import org.nuiton.i18n.init.DefaultI18nInitializer; -import org.nuiton.i18n.init.UserI18nInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.List; -import java.util.Locale; public class TestResource implements TestRule { @@ -62,6 +53,7 @@ public class TestResource implements TestRule { private TestFixtures fixtures = new TestFixtures(); private File resourceDirectory; private String configName; + private String configFileName; private boolean witherror = false; protected Class<?> testClass; @@ -108,72 +100,28 @@ public class TestResource implements TestRule { resourceDirectory = getTestSpecificDirectory(testClass, ""); // check that config file is in classpath (avoid to find out why it does not works...) - String configFilename = getConfigFilesPrefix(); + this.configFileName = getConfigFilesPrefix(); if (!defaultDbName) { - configFilename += "-" + configName; + this.configFileName += "-" + configName; } - configFilename += ".properties"; + this.configFileName += ".properties"; - InputStream resourceAsStream = getClass().getResourceAsStream("/" + configFilename); - Preconditions.checkNotNull(resourceAsStream, "Could not find " + configFilename + " in test class-path"); - - // Initialize configuration - initConfiguration(configFilename); - - // Init i18n - initI18n(); - - // Initialize service locator - ServiceLocator.instance().init(); + InputStream resourceAsStream = getClass().getResourceAsStream("/" + this.configFileName); + Preconditions.checkNotNull(resourceAsStream, "Could not find " + this.configFileName + " in test class-path"); + resourceAsStream.close(); } protected void after(Description description) throws Throwable { } - - /** - * Convenience methods that could be override to initialize other configuration - * - * @param configFilename - * @param configArgs - */ - protected void initConfiguration(String configFilename) { - String[] configArgs = getConfigArgs(); - Configuration config = new Configuration(configFilename, configArgs); - Configuration.setInstance(config); + protected String getConfigFileName() { + return this.configFileName; } - protected void initI18n() throws IOException { - Configuration config = Configuration.instance(); - - // --------------------------------------------------------------------// - // init i18n - // --------------------------------------------------------------------// - File i18nDirectory = new File(config.getDataDirectory(), "i18n"); - if (i18nDirectory.exists()) { - // clean i18n cache - FileUtils.cleanDirectory(i18nDirectory); - } - - FileUtils.forceMkdir(i18nDirectory); - - if (log.isDebugEnabled()) { - log.debug("I18N directory: " + i18nDirectory); - } - - Locale i18nLocale = config.getI18nLocale(); - - if (log.isInfoEnabled()) { - log.info(String.format("Starts i18n with locale [%s] at [%s]", - i18nLocale, i18nDirectory)); - } - I18n.init(new UserI18nInitializer( - i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())), - i18nLocale); + protected File getResourceDirectory() { + return this.resourceDirectory; } - - /** * Return configuration files prefix (i.e. 'allegro-test') * Could be override by external project @@ -183,19 +131,7 @@ public class TestResource implements TestRule { protected String getConfigFilesPrefix() { return "ucoinj-test"; } - - protected String getI18nBundleName() { - return "ucoinj-core-i18n"; - } - - protected String[] getConfigArgs() { - List<String> configArgs = Lists.newArrayList(); - configArgs.addAll(Lists.newArrayList( - "--option", ConfigurationOption.BASEDIR.getKey(), resourceDirectory.getAbsolutePath())); - return configArgs.toArray(new String[configArgs.size()]); - } - - protected File getTestSpecificDirectory(Class<?> testClass, + protected File getTestSpecificDirectory(Class<?> testClass, String name) throws IOException { // Trying to look for the temporary folder to store data for the test String tempDirPath = System.getProperty("java.io.tmpdir"); diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CollectionUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CollectionUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..7b1e8218c0157c9dcbdb06010af88b4652e51ea5 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CollectionUtils.java @@ -0,0 +1,72 @@ +package io.ucoin.ucoinj.core.util; + +import java.util.Collection; +import java.util.Iterator; + +/** + * Created by eis on 23/12/14. + */ +public class CollectionUtils { + + public static boolean isNotEmpty(Collection<?> coll) { + return coll != null && coll.size() > 0; + } + + public static boolean isEmpty(Collection<?> coll) { + return coll == null || coll.size() == 0; + } + + public static boolean isNotEmpty(Object[] coll) { + return coll != null && coll.length > 0; + } + public static boolean isEmpty(Object[] coll) { + return coll == null || coll.length == 0; + } + + public static String join(final Object[] array) { + return join(array, ", "); + } + + public static String join(final Object[] array, final String separator) { + if (array == null || array.length == 0) { + return null; + } + StringBuilder sb = new StringBuilder(array.length * 7); + sb.append(array[0]); + for (int i = 1; i < array.length; i++) { + sb.append(separator); + sb.append(array[i]); + } + return sb.toString(); + } + + public static String join(final Collection<?> collection) { + return join(collection, ", "); + } + + public static String join(final Collection<?> collection, final String separator) { + if (collection == null || collection.size() == 0) { + return null; + } + StringBuilder sb = new StringBuilder(collection.size() * 7); + Iterator<?> iterator = collection.iterator(); + sb.append(iterator.next()); + while (iterator.hasNext()) { + sb.append(separator); + sb.append(iterator.next()); + } + return sb.toString(); + } + + public static int size(final Collection<?> collection) { + return collection == null ? 0 : collection.size(); + } + + public static <E> E extractSingleton(Collection<E> collection) { + if(collection != null && collection.size() == 1) { + return collection.iterator().next(); + } else { + throw new IllegalArgumentException("Can extract singleton only when collection size == 1"); + } + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CommandLinesUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CommandLinesUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..faee6f2792f26b8531d10598172bc171e9662e40 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/CommandLinesUtils.java @@ -0,0 +1,67 @@ +package io.ucoin.ucoinj.core.util; + +/* + * #%L + * SIH-Adagio :: Core for Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import java.util.Scanner; + +public class CommandLinesUtils { + + protected CommandLinesUtils() { + + } + + public static String readNotBlankInput(String message) { + String value = readInput(message, null, true); + return value; + } + + public static String readInput(String message, String defaultValue, boolean mandatory) { + + Scanner scanIn = new Scanner(System.in); + String inputValue = null; + while (inputValue == null) { + System.out.print(message.trim()); + if (StringUtils.isNotEmpty(defaultValue)) { + System.out.print(String.format(" [%s]", defaultValue)); + } + System.out.print(": "); + inputValue = scanIn.nextLine(); + if (StringUtils.isBlank(inputValue)) { + // A default exists: use it + if (StringUtils.isNotEmpty(defaultValue)) { + inputValue = defaultValue; + } + // No default value, but mandatory: prepare for a new iteration + else if (mandatory) { + inputValue = null; + } + } + } + // scanIn.close(); + + return inputValue; + } + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/FileUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/FileUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..eadcefa30ef2335c94d1c595bb97b40536906fc0 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/FileUtils.java @@ -0,0 +1,24 @@ +package io.ucoin.ucoinj.core.util; + +import java.io.File; +import java.io.IOException; + +/** + * Created by blavenie on 05/01/16. + */ +public class FileUtils { + + public static void forceMkdir(File directory) throws IOException { + String message; + if(directory.exists()) { + if(!directory.isDirectory()) { + message = "File " + directory + " exists and is " + "not a directory. Unable to create directory."; + throw new IOException(message); + } + } else if(!directory.mkdirs() && !directory.isDirectory()) { + message = "Unable to create directory " + directory; + throw new IOException(message); + } + + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/ObjectUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/ObjectUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..7a99f0033fb17d34cc04bb03762df167ad5b91bf --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/ObjectUtils.java @@ -0,0 +1,65 @@ +package io.ucoin.ucoinj.core.util; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +/** + * Created by eis on 22/12/14. + */ +public class ObjectUtils { + + public static void checkNotNull(Object value) { + if (value == null) { + throw new NullPointerException(); + } + } + + public static void checkNotNull(Object value, String message) { + if (value == null) { + throw new NullPointerException(message); + } + } + + + public static void checkArgument(boolean value, String message) { + if (!value) { + throw new IllegalArgumentException(message); + } + } + + public static void checkArgument(boolean value) { + if (!value) { + throw new IllegalArgumentException(); + } + } + + public static boolean equals(Object o1, Object o2) { + if (o1 == null && o2 == null) { + return true; + } + if ((o1 != null && o2 == null) ||(o1 == null && o2 != null)) { + return false; + } + return o1.equals(o2); + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/StringUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/StringUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..320e26b7458b69ed3e4c6206b243092b27b68da0 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/StringUtils.java @@ -0,0 +1,45 @@ +package io.ucoin.ucoinj.core.util; + +/** + * Created by eis on 21/12/14. + */ +public class StringUtils { + + public static boolean isNotBlank(String value) { + return value != null && value.trim().length() > 0; + } + + public static boolean isBlank(String value) { + return value == null || value.trim().length() == 0; + } + + public static boolean isNotEmpty(String value) { + return value != null && value.length() > 0; + } + + public static boolean isEmpty(String value) { + return value == null || value.length() == 0; + } + + public static String truncate(String value, int maxLength) { + if (value != null && value.length() > maxLength && maxLength >= 1) { + return value.substring(0, maxLength - 1); + } + else { + return value; + } + } + + public static String truncateWithIndicator(String value, int maxLength) { + if (value != null && value.length() > maxLength && maxLength >= 4) { + return value.substring(0, maxLength - 3) + "..."; + } + else { + return value; + } + } + + public static boolean equals(String cs1, String cs2) { + return cs1 == null?cs2 == null:cs1.equals(cs2); + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/Cache.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/Cache.java new file mode 100644 index 0000000000000000000000000000000000000000..c9651a2f8aecaa39269cf2eb517c8938c2ef51c4 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/Cache.java @@ -0,0 +1,50 @@ +package io.ucoin.ucoinj.core.util.cache; + +import java.util.Map; +import java.util.Set; + +/** + * Created by eis on 30/03/15. + */ +public interface Cache<K, V> { + + /** + * Get a cached instance, only if present. + * @param key + * @return the cached object if present, or null + */ + V getIfPresent(K key); + + /** + * Get the cached value. If not already loaded, <code>load()</code> + * will be called. + * @param key + * @return + */ + V get(K key); + + /** + * Set a value into the cache + * @param key + * @param value + */ + void put(K key, V value); + + /** + * @see Map#keySet() + */ + Set<K> keySet(); + + /** + * @see Map#entrySet() + */ + Set<Map.Entry<K,V>> entrySet(); + + /** + * Clear cached values + */ + void clear(); + + V load(K key); + +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/SimpleCache.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/SimpleCache.java new file mode 100644 index 0000000000000000000000000000000000000000..e2d0b8bb4e02d40b61a16a5d2246d832e673b7b8 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/cache/SimpleCache.java @@ -0,0 +1,197 @@ +package io.ucoin.ucoinj.core.util.cache; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by eis on 30/03/15. + */ +public abstract class SimpleCache<K, V> implements Cache<K, V> { + + private static final long ETERNAL_TIME = -1l; + private static final long ILLIMITED_ITEMS_COUNT = -1l; + private static final long ITEMS_COUNT_FOR_DEFAULT_CLEANING = 1000; + + private final Map<K, V> mCachedValues; + private final Map<K, Long> mCachedTimes; + private final long mCacheTimeInMillis; + private final long mCacheMaxItemCount; + + final Object mutex; + + public SimpleCache() { + this(ETERNAL_TIME, ILLIMITED_ITEMS_COUNT); + } + + public SimpleCache(long cacheTimeInMillis) { + this(cacheTimeInMillis, ILLIMITED_ITEMS_COUNT); + } + + public SimpleCache(long cacheTimeInMillis, long cacheMaxItemsCount) { + this.mCachedValues = Collections.synchronizedMap(new ConcurrentHashMap<K, V>()); + this.mCachedTimes = new ConcurrentHashMap<K, Long>(); + this.mCacheTimeInMillis = cacheTimeInMillis; + this.mCacheMaxItemCount = cacheMaxItemsCount; + this.mutex = mCachedValues; + } + + public V getIfPresent(K key) { + synchronized (mutex) { + V cachedValue = mCachedValues.get(key); + long timeInMillis = System.currentTimeMillis(); + if (cachedValue != null) { + Long cachedTime = mCachedTimes.get(key); + if (mCacheTimeInMillis == ETERNAL_TIME + || cachedTime.longValue() - timeInMillis < mCacheTimeInMillis) { + return cachedValue; + } + } + return null; + } + } + + /** + * Get the cached value. If not already loaded, <code>load()</code> + * will be called. + * @param key + * @return + */ + public V get(K key) { + synchronized (mutex) { + V cachedValue = mCachedValues.get(key); + long timeInMillis = System.currentTimeMillis(); + if (cachedValue != null) { + Long cachedTime = mCachedTimes.get(key); + if (timeInMillis - cachedTime.longValue() < mCacheTimeInMillis) { + return cachedValue; + } + } + + // Load a new value + cachedValue = load(key); + + // Fill caches + mCachedValues.put(key, cachedValue); + mCachedTimes.put(key, timeInMillis); + + return cachedValue; + } + } + + /** + * Set a value into the cache + * @param key + * @param value + */ + public synchronized void put(K key, V value) { + synchronized (mutex) { + // Fill caches + mCachedValues.put(key, value); + mCachedTimes.put(key, System.currentTimeMillis()); + + clean(); + } + } + + /** + * @see Map#keySet() + */ + public Set<K> keySet() { + return mCachedValues.keySet(); + } + + /** + * @see Map#entrySet() + */ + public Set<Map.Entry<K,V>> entrySet() { + return mCachedValues.entrySet(); + } + + /** + * Clear cached values + */ + public void clear() { + synchronized (mutex) { + mCachedValues.clear(); + mCachedTimes.clear(); + } + } + + public abstract V load(K key); + + /** -- protected methods -- */ + + protected void clean() { + synchronized (mutex) { + // Clean older items, to fit the max size + if (mCacheMaxItemCount != ILLIMITED_ITEMS_COUNT + && mCachedValues.size() > mCacheMaxItemCount) { + + // Clean too old items + if (mCacheTimeInMillis != ETERNAL_TIME) { + removeOldItems(); + } + + // Size still exceed max: clean older items also + if (mCachedValues.size() > mCacheMaxItemCount) { + reduceSizeToExpectedMaxItemCount(); + } + } else if (mCacheMaxItemCount == ILLIMITED_ITEMS_COUNT + && mCachedValues.size() > ITEMS_COUNT_FOR_DEFAULT_CLEANING) { + removeOldItems(); + } + } + } + + /** -- private methods -- */ + + /** + * Remove items older than <code>cacheTimeInMillis</code> + */ + private void removeOldItems() { + long now = System.currentTimeMillis(); + + List<K> keysToRemove = new ArrayList<>(); + for (Map.Entry<K, Long> entry : mCachedTimes.entrySet()) { + if (now - entry.getValue() > mCacheTimeInMillis) { + keysToRemove.add(entry.getKey()); + } + } + + for (K key : keysToRemove) { + mCachedValues.remove(key); + mCachedTimes.remove(key); + } + } + + /** + * Reduce size of items: will first remove older items + */ + private void reduceSizeToExpectedMaxItemCount() { + + K keyToRemove = null; + Long olderTime = null; + + while (mCachedValues.size() > mCacheMaxItemCount) { + + K olderKey = getOlderKey(); + mCachedValues.remove(olderKey); + mCachedTimes.remove(olderKey); + } + } + + private K getOlderKey() { + + K olderKey = null; + long olderTime = -1; + + for (Map.Entry<K, Long> entry : mCachedTimes.entrySet()) { + if (olderTime == -1 || entry.getValue() < olderTime) { + olderTime = entry.getValue(); + olderKey = entry.getKey(); + } + } + + return olderKey; + } +} diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/AddressFormatException.java similarity index 71% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.java rename to ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/AddressFormatException.java index 4c4d2f076dc3da1b0a6e2c12dbcabead99b36f31..7c535bc16bc7c1453003cba6fc4cee8225817bae 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.java +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/AddressFormatException.java @@ -1,8 +1,8 @@ -package io.ucoin.client.ui.pages.login; +package io.ucoin.ucoinj.core.util.crypto; /* * #%L - * UCoin Java Client :: Web + * UCoin Java Client :: Core API * %% * Copyright (C) 2014 - 2015 EIS * %% @@ -23,11 +23,13 @@ package io.ucoin.client.ui.pages.login; */ -import io.ucoin.client.ui.pages.BasePage; -import org.apache.wicket.request.mapper.parameter.PageParameters; +@SuppressWarnings("serial") +public class AddressFormatException extends Exception { + public AddressFormatException() { + super(); + } -public class LoginPage extends BasePage { - public LoginPage(final PageParameters parameters) { - super(parameters); + public AddressFormatException(String message) { + super(message); } -} \ No newline at end of file +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/Base58.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/Base58.java new file mode 100644 index 0000000000000000000000000000000000000000..9a71909f0e3cfe7cea8f351f720c88a3d9e2239f --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/Base58.java @@ -0,0 +1,193 @@ +package io.ucoin.ucoinj.core.util.crypto; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * <p>Base58 is a way to encode Bitcoin addresses as numbers and letters. Note that this is not the same base58 as used by + * Flickr, which you may see reference to around the internet.</p> + * + * <p>You may instead wish to work with {@link VersionedChecksummedBytes}, which adds support for testing the prefix + * and suffix bytes commonly found in addresses.</p> + * + * <p>Satoshi says: why base-58 instead of standard base-64 encoding?<p> + * + * <ul> + * <li>Don't want 0OIl characters that look the same in some fonts and + * could be used to create visually identical looking account numbers.</li> + * <li>A string with non-alphanumeric characters is not as easily accepted as an account number.</li> + * <li>E-mail usually won't line-break if there's no punctuation to break at.</li> + * <li>Doubleclicking selects the whole number as one word if it's all alphanumeric.</li> + * </ul> + */ +public class Base58 { + public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); + private static final MessageDigest digest; + static { + try { + digest = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); // Can't happen. + } + } + private static final int[] INDEXES = new int[128]; + static { + for (int i = 0; i < INDEXES.length; i++) { + INDEXES[i] = -1; + } + for (int i = 0; i < ALPHABET.length; i++) { + INDEXES[ALPHABET[i]] = i; + } + } + + /** Encodes the given bytes in base58. No checksum is appended. */ + public static String encode(byte[] input) { + if (input.length == 0) { + return ""; + } + input = copyOfRange(input, 0, input.length); + // Count leading zeroes. + int zeroCount = 0; + while (zeroCount < input.length && input[zeroCount] == 0) { + ++zeroCount; + } + // The actual encoding. + byte[] temp = new byte[input.length * 2]; + int j = temp.length; + + int startAt = zeroCount; + while (startAt < input.length) { + byte mod = divmod58(input, startAt); + if (input[startAt] == 0) { + ++startAt; + } + temp[--j] = (byte) ALPHABET[mod]; + } + + // Strip extra '1' if there are some after decoding. + while (j < temp.length && temp[j] == ALPHABET[0]) { + ++j; + } + // Add as many leading '1' as there were leading zeros. + while (--zeroCount >= 0) { + temp[--j] = (byte) ALPHABET[0]; + } + + byte[] output = copyOfRange(temp, j, temp.length); + try { + return new String(output, "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // Cannot happen. + } + } + + public static byte[] decode(String input) throws AddressFormatException { + if (input.length() == 0) { + return new byte[0]; + } + byte[] input58 = new byte[input.length()]; + // Transform the String to a base58 byte sequence + for (int i = 0; i < input.length(); ++i) { + char c = input.charAt(i); + + int digit58 = -1; + if (c >= 0 && c < 128) { + digit58 = INDEXES[c]; + } + if (digit58 < 0) { + throw new AddressFormatException("Illegal character " + c + " at " + i); + } + + input58[i] = (byte) digit58; + } + // Count leading zeroes + int zeroCount = 0; + while (zeroCount < input58.length && input58[zeroCount] == 0) { + ++zeroCount; + } + // The encoding + byte[] temp = new byte[input.length()]; + int j = temp.length; + + int startAt = zeroCount; + while (startAt < input58.length) { + byte mod = divmod256(input58, startAt); + if (input58[startAt] == 0) { + ++startAt; + } + + temp[--j] = mod; + } + // Do no add extra leading zeroes, move j to first non null byte. + while (j < temp.length && temp[j] == 0) { + ++j; + } + + return copyOfRange(temp, j - zeroCount, temp.length); + } + + // + // number -> number / 58, returns number % 58 + // + private static byte divmod58(byte[] number, int startAt) { + int remainder = 0; + for (int i = startAt; i < number.length; i++) { + int digit256 = (int) number[i] & 0xFF; + int temp = remainder * 256 + digit256; + + number[i] = (byte) (temp / 58); + + remainder = temp % 58; + } + + return (byte) remainder; + } + + // + // number -> number / 256, returns number % 256 + // + private static byte divmod256(byte[] number58, int startAt) { + int remainder = 0; + for (int i = startAt; i < number58.length; i++) { + int digit58 = (int) number58[i] & 0xFF; + int temp = remainder * 58 + digit58; + + number58[i] = (byte) (temp / 256); + + remainder = temp % 256; + } + + return (byte) remainder; + } + + private static byte[] copyOfRange(byte[] source, int from, int to) { + byte[] range = new byte[to - from]; + System.arraycopy(source, from, range, 0, range.length); + + return range; + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/CryptoUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/CryptoUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..63affb21d1441e274234ecd1b4fc858137465121 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/CryptoUtils.java @@ -0,0 +1,88 @@ +package io.ucoin.ucoinj.core.util.crypto; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.lambdaworks.codec.Base64; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.abstractj.kalium.crypto.Util; + +import java.nio.charset.Charset; + +public class CryptoUtils extends Util { + + public static final Charset CHARSET_UTF8 = Charset.forName("UTF-8"); + public static final Charset CHARSET_ASCII = Charset.forName("US-ASCII"); + + public static byte[] zeros(int n) { + return new byte[n]; + } + + public static byte[] copyEnsureLength(byte[] source, int length) { + byte[] result = zeros(length); + if (source.length > length) { + System.arraycopy(source, 0, result, 0, length); + } + else { + System.arraycopy(source, 0, result, 0, source.length); + } + return result; + } + + protected static Charset initCharset(String charsetName) { + Charset result = Charset.forName(charsetName); + if (result == null) { + throw new TechnicalException("Could not load charset: " + charsetName); + } + return result; + } + + public static byte[] decodeUTF8(String string) { + return string.getBytes(CHARSET_UTF8); + } + + public static byte[] decodeAscii(String string) { + return string.getBytes(CHARSET_ASCII); + } + + + public static byte[] decodeBase64(String data) { + return Base64.decode(data.toCharArray()); + } + + public static String encodeBase64(byte[] data) { + return new String(Base64.encode(data)); + } + + public static byte[] decodeBase58(String data) { + try { + return Base58.decode(data); + } catch (AddressFormatException e) { + throw new TechnicalException("Could decode from base 58: " + e.getMessage()); + } + } + + public static String encodeBase58(byte[] data) { + return Base58.encode(data); + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/DigestUtils.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/DigestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..4597633f18c8f6219d7c88e20c48a3337250412a --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/DigestUtils.java @@ -0,0 +1,65 @@ +package io.ucoin.ucoinj.core.util.crypto; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Neither org.apache.commons.codec.digest.DigestUtils nor org.apache.commons.codec.binary.Hex + * take the ENCODING into account, they both use the system's default encoding which is wrong + * in a web environment. + * <p/> + * @see: https://github.com/MyMalcom/malcom-lib-android/blob/master/src/main/java/com/malcom/library/android/utils/DigestUtils.java + * @author Malcom Ventures, S.L. + * @since 2012 + */ +public class DigestUtils { + private static final char[] HEXITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + private static final String SHA1_ALGORITHM = "SHA1"; + private static final String UTF_8 = "UTF-8"; + + /** + * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order. + * The returned array will be double the length of the passed array, as it takes two characters to represent any + * given byte. + * + * @param data a byte[] to convert to Hex characters + * @return A char[] containing hexidecimal characters + * @see: http://stackoverflow.com/questions/332079/in-java-how-do-i-convert-a-byte-array-to-a-string-of-hex-digits-while-keeping-le + */ + public static String encodeHex(byte[] data) { + char[] out = new char[data.length << 1]; // == new char[data.length * 2]; + for (int i = 0, j = 0; i < data.length; i++) { + out[j++] = HEXITS[(0xF0 & data[i]) >>> 4]; // HEXITS[(data[i] & 0xFF) / 16]; + out[j++] = HEXITS[0x0F & data[i]]; // HEXITS[(data[i] & 0xFF) % 16]; + } + return new String(out); + } + + /** + * Genera a SHA1 fingerprint from the given message + * + * @param message a message to encodeinto SHA-1 + * @return a SHA1 fingerprint + */ + public static String sha1Hex(String message) { + return sha1Hex(message, UTF_8); + } + + public static String sha1Hex(String message, String encoding) { + try { + MessageDigest md = getSHA1Instance(); + return encodeHex(md.digest(message.getBytes(encoding))); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static MessageDigest getSHA1Instance() { + try { + return MessageDigest.getInstance(SHA1_ALGORITHM); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/KeyPair.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/KeyPair.java new file mode 100644 index 0000000000000000000000000000000000000000..d7b84f1c52275a44dbe54e95ab03fb1c0e00d716 --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/KeyPair.java @@ -0,0 +1,54 @@ +package io.ucoin.ucoinj.core.util.crypto; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +/** + * Created by eis on 28/01/15. + */ +public class KeyPair { + + public byte[] publicKey; + public byte[] secretKey; + + public KeyPair(byte[] publicKey, byte[] secretKey) { + this.publicKey = publicKey; + this.secretKey = secretKey; + } + + public byte[] getSecKey() { + return secretKey; + } + + public void setSecKey(byte[] secKey) { + this.secretKey = secKey; + } + + public byte[] getPubKey() { + return publicKey; + } + + public void setPubKey(byte[] pubKey) { + this.publicKey = pubKey; + } +} diff --git a/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/SecretBox.java b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/SecretBox.java new file mode 100644 index 0000000000000000000000000000000000000000..9bd943098e558cc0a1cb5b29a8458431a008b9eb --- /dev/null +++ b/ucoinj-core-shared/src/main/java/io/ucoin/ucoinj/core/util/crypto/SecretBox.java @@ -0,0 +1,139 @@ +package io.ucoin.ucoinj.core.util.crypto; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.lambdaworks.crypto.SCrypt; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import jnr.ffi.byref.LongLongByReference; +import org.abstractj.kalium.crypto.Util; + +import java.security.GeneralSecurityException; + +import static io.ucoin.ucoinj.core.util.crypto.CryptoUtils.*; +import static io.ucoin.ucoinj.core.util.crypto.CryptoUtils.slice; +import static io.ucoin.ucoinj.core.util.crypto.CryptoUtils.zeros; +import static org.abstractj.kalium.NaCl.Sodium.*; +import static org.abstractj.kalium.NaCl.sodium; +import static org.abstractj.kalium.crypto.Util.checkLength; +import static org.abstractj.kalium.crypto.Util.isValid; +import static org.abstractj.kalium.crypto.Util.removeZeros; + + +public class SecretBox { + + // Length of the key + private static int SEED_LENGTH = 32; + private static int SIGNATURE_BYTES = 64; + private static int SCRYPT_PARAMS_N = 4096; + private static int SCRYPT_PARAMS_r = 16; + private static int SCRYPT_PARAMS_p = 1; + + private final String pubKey; + private final byte[] secretKey; + private final byte[] seed; + + public SecretBox(String salt, String password) { + this(computeSeedFromSaltAndPassword(salt, password)); + } + + public SecretBox(byte[] seed) { + checkLength(seed, SEED_LENGTH); + this.seed = seed; + this.secretKey = zeros(SECRETKEY_BYTES * 2); + byte[] publicKey = zeros(PUBLICKEY_BYTES); + isValid(sodium().crypto_sign_ed25519_seed_keypair(publicKey, secretKey, seed), + "Failed to generate a key pair"); + this.pubKey = Base58.encode(publicKey); + } + + /** + * Retrun the public key, encode in Base58 + * @return + */ + public String getPublicKey() { + return pubKey; + } + + /** + * Return the secret key, encode in Base58 + * @return + */ + public String getSecretKey() { + return Base58.encode(secretKey); + } + + public String sign(String message) { + byte[] messageBinary = decodeUTF8(message); + return encodeBase64( + sign(messageBinary) + ); + } + + public byte[] sign(byte[] message) { + byte[] signature = Util.prependZeros(SIGNATURE_BYTES, message); + LongLongByReference bufferLen = new LongLongByReference(0); + sodium().crypto_sign_ed25519(signature, bufferLen, message, message.length, secretKey); + signature = slice(signature, 0, SIGNATURE_BYTES); + + checkLength(signature, SIGNATURE_BYTES); + return signature; + } + + + public byte[] encrypt(byte[] nonce, byte[] message) { + checkLength(nonce, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES); + byte[] msg = Util.prependZeros(ZERO_BYTES, message); + byte[] ct = Util.zeros(msg.length); + isValid(sodium().crypto_secretbox_xsalsa20poly1305(ct, msg, msg.length, + nonce, seed), "Encryption failed"); + return removeZeros(BOXZERO_BYTES, ct); + } + + public byte[] decrypt(byte[] nonce, byte[] ciphertext) { + checkLength(nonce, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES); + byte[] ct = Util.prependZeros(BOXZERO_BYTES, ciphertext); + byte[] message = Util.zeros(ct.length); + isValid(sodium().crypto_secretbox_xsalsa20poly1305_open(message, ct, + ct.length, nonce, seed), "Decryption failed. Ciphertext failed verification"); + return removeZeros(ZERO_BYTES, message); + } + + /* -- Internal methods -- */ + + public static byte[] computeSeedFromSaltAndPassword(String salt, String password) { + try { + byte[] seed = SCrypt.scrypt( + decodeAscii(password), + decodeAscii(salt), + SCRYPT_PARAMS_N, SCRYPT_PARAMS_r, + SCRYPT_PARAMS_p, SEED_LENGTH); + return seed; + } catch (GeneralSecurityException e) { + throw new TechnicalException( + "Unable to salt password, using Scrypt library", e); + } + } + + +} diff --git a/ucoinj-core-shared/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-core-shared/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean new file mode 100644 index 0000000000000000000000000000000000000000..5b3708cff6d13b03f0bf09fa072162e489e33f98 --- /dev/null +++ b/ucoinj-core-shared/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean @@ -0,0 +1 @@ +io.ucoin.ucoinj.core.service.Ed25519CryptoServiceImpl \ No newline at end of file diff --git a/ucoinj-web/src/main/webapp/WEB-INF/classes/TOTO.txt b/ucoinj-core-shared/src/main/resources/i18n/ucoinj-core-shared_en_GB.properties similarity index 100% rename from ucoinj-web/src/main/webapp/WEB-INF/classes/TOTO.txt rename to ucoinj-core-shared/src/main/resources/i18n/ucoinj-core-shared_en_GB.properties diff --git a/ucoinj-core-shared/src/main/resources/i18n/ucoinj-core-shared_fr_FR.properties b/ucoinj-core-shared/src/main/resources/i18n/ucoinj-core-shared_fr_FR.properties new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/CryptoServiceTest.java b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java similarity index 55% rename from ucoinj-core/src/test/java/io/ucoin/client/core/service/CryptoServiceTest.java rename to ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java index d24b8954d10038e09d6a28e16aaf4afd04bc9bcf..7be64c870e2d9ae89ccc0150cebfce29b17245d6 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/CryptoServiceTest.java +++ b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/service/Ed25519CryptoServiceTest.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.service; +package io.ucoin.ucoinj.core.service; /* * #%L @@ -23,41 +23,35 @@ package io.ucoin.client.core.service; */ -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.technical.crypto.Base58; -import io.ucoin.client.core.technical.crypto.CryptoUtils; -import io.ucoin.client.core.technical.crypto.SecretBox; +import io.ucoin.ucoinj.core.test.TestFixtures; +import io.ucoin.ucoinj.core.util.crypto.Base58; +import io.ucoin.ucoinj.core.util.crypto.SecretBox; import org.junit.Assert; import org.junit.Before; -import org.junit.ClassRule; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.UnsupportedEncodingException; -public class CryptoServiceTest { +public class Ed25519CryptoServiceTest { - private static final Logger log = LoggerFactory.getLogger(CryptoServiceTest.class); - @ClassRule - public static final TestResource resource = TestResource.create(); - - private byte[] message; + private String message; + private byte[] messageAsBytes; + private CryptoService service; @Before public void setUp() throws UnsupportedEncodingException { - message = "my message to encrypt !".getBytes("UTF-8"); - + message = "my message to encrypt !"; + messageAsBytes = message.getBytes("UTF-8"); + service = new Ed25519CryptoServiceImpl(); } @Test public void sign() throws Exception { - - CryptoService service = new CryptoService(); SecretBox secretBox = createSecretBox(); - byte[] signatureBinary = service.sign(message, Base58.decode(secretBox.getSecretKey())); - String signature = CryptoUtils.encodeBase64(signatureBinary); + String signature = service.sign(message, Base58.decode(secretBox.getSecretKey())); Assert.assertEquals("aAxVThibiZGbpJWrFo8MzZe8RDIoJ1gMC1UIr0utDBQilG44PjA/7o+pOoPAOXgDE3sosGeLHTw1Q/RhFBa4CA==", signature); } @@ -65,14 +59,11 @@ public class CryptoServiceTest { @Test public void verify() throws Exception { - CryptoService service = new CryptoService(); SecretBox secretBox = createSecretBox(); - byte[] signatureBinary = service.sign(message, Base58.decode(secretBox.getSecretKey())); - String signature = CryptoUtils.encodeBase64(signatureBinary); + String signature = service.sign(message, Base58.decode(secretBox.getSecretKey())); - String messageString = new String(message, "UTF-8"); - boolean validSignature = service.verify(messageString, signature, secretBox.getPublicKey()); + boolean validSignature = service.verify(message, signature, secretBox.getPublicKey()); Assert.assertTrue(validSignature); } @@ -80,8 +71,9 @@ public class CryptoServiceTest { /* -- internal methods */ protected SecretBox createSecretBox() { - String salt = resource.getFixtures().getUserSalt(); - String password = resource.getFixtures().getUserPassword(); + TestFixtures fixtures = new TestFixtures(); + String salt = fixtures.getUserSalt(); + String password = fixtures.getUserPassword(); SecretBox secretBox = new SecretBox(salt, password); return secretBox; diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/technical/crypto/SecretBoxTest.java b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/util/crypto/SecretBoxTest.java similarity index 83% rename from ucoinj-core/src/test/java/io/ucoin/client/core/technical/crypto/SecretBoxTest.java rename to ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/util/crypto/SecretBoxTest.java index 97dc62101894d2b0a3f81ced8d6cb4872c64634e..c466725ebe5eef43d915f2442d98dcc89506019d 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/technical/crypto/SecretBoxTest.java +++ b/ucoinj-core-shared/src/test/java/io/ucoin/ucoinj/core/util/crypto/SecretBoxTest.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.technical.crypto; +package io.ucoin.ucoinj.core.util.crypto; /* * #%L @@ -23,12 +23,11 @@ package io.ucoin.client.core.technical.crypto; */ -import io.ucoin.client.core.TestResource; +import io.ucoin.ucoinj.core.test.TestFixtures; import org.abstractj.kalium.keys.SigningKey; import org.abstractj.kalium.keys.VerifyKey; import org.junit.Assert; import org.junit.Before; -import org.junit.ClassRule; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,27 +40,23 @@ import static org.abstractj.kalium.NaCl.Sodium.XSALSA20_POLY1305_SECRETBOX_NONCE public class SecretBoxTest { private static final Logger log = LoggerFactory.getLogger(SecretBoxTest.class); - + + private TestFixtures fixtures = new TestFixtures(); private byte[] message; private byte[] nonce = new byte[XSALSA20_POLY1305_SECRETBOX_NONCEBYTES]; - - @ClassRule - public static final TestResource resource = TestResource.create(); - @Before public void setUp() throws UnsupportedEncodingException { message = "my message to encrypt !".getBytes("UTF-8"); - } @Test public void computeSeedFromSaltAndPassword() throws UnsupportedEncodingException { - String salt = resource.getFixtures().getUserSalt(); - String password = resource.getFixtures().getUserPassword(); - String expectedBase64Hash = resource.getFixtures().getUserSeedHash(); + String salt = fixtures.getUserSalt(); + String password = fixtures.getUserPassword(); + String expectedBase64Hash = fixtures.getUserSeedHash(); byte[] seed = SecretBox.computeSeedFromSaltAndPassword(salt, password); String hash = CryptoUtils.encodeBase64(seed); @@ -74,7 +69,7 @@ public class SecretBoxTest { SecretBox secretBox = createSecretBox(); - Assert.assertEquals(resource.getFixtures().getUserPublicKey(), + Assert.assertEquals(fixtures.getUserPublicKey(), secretBox.getPublicKey()); } @@ -83,7 +78,7 @@ public class SecretBoxTest { SecretBox secretBox = createSecretBox(); - Assert.assertEquals(resource.getFixtures().getUserSecretKey(), + Assert.assertEquals(fixtures.getUserSecretKey(), secretBox.getSecretKey()); } @@ -110,7 +105,7 @@ public class SecretBoxTest { SecretBox secretBox = createSecretBox(); String utf8Message = String.format("UID:%s\nMETA:TS:%s\n", - resource.getFixtures().getUid(), + fixtures.getUid(), "1420881879"); byte[] message = CryptoUtils.decodeUTF8(utf8Message); String expectedSignatureBase64 = "TMgQysT7JwY8XwemskwWb8LBDJybLUsnxqaaUvSteIYpOxRiB92gkFQQcGpBwq4hAwhEiqBAiFkiXIozppDDDg=="; @@ -153,16 +148,16 @@ public class SecretBoxTest { } protected SecretBox createSecretBox() { - String salt = resource.getFixtures().getUserSalt(); - String password = resource.getFixtures().getUserPassword(); + String salt = fixtures.getUserSalt(); + String password = fixtures.getUserPassword(); SecretBox secretBox = new SecretBox(salt, password); return secretBox; } protected SigningKey createSigningKey() { - String salt = resource.getFixtures().getUserSalt(); - String password = resource.getFixtures().getUserPassword(); + String salt = fixtures.getUserSalt(); + String password = fixtures.getUserPassword(); byte[] seed = SecretBox.computeSeedFromSaltAndPassword(salt, password); return new SigningKey(seed); diff --git a/ucoinj-core-shared/src/test/resources/log4j.properties b/ucoinj-core-shared/src/test/resources/log4j.properties new file mode 100644 index 0000000000000000000000000000000000000000..83496cefd60e1884b601e0b9ac66a68ee7166271 --- /dev/null +++ b/ucoinj-core-shared/src/test/resources/log4j.properties @@ -0,0 +1,23 @@ +### +# Global logging configuration +log4j.rootLogger=ERROR, stdout, file + +# Console output +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - %m%n + +# ucoin levels +log4j.logger.io.ucoin.ucoinj=INFO +#log4j.logger.io.ucoin.ucoinj.core.client.service=DEBUG +#log4j.appender.io.ucoin.ucoinj.core.beans=DEBUG + +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.file=ucoin-core-shared.log +log4j.appender.file.MaxFileSize=10MB +log4j.appender.file.MaxBackupIndex=4 + +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p %c - %m%n + + diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/UCoinClientCore.java b/ucoinj-core/src/main/java/io/ucoin/client/core/UCoinClientCore.java deleted file mode 100644 index b5a187c599864526207c775a2f3cd2d452daaa49..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/UCoinClientCore.java +++ /dev/null @@ -1,119 +0,0 @@ -package io.ucoin.client.core; - -/* - * #%L - * UCoin Java Client :: Core API - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.technical.UCoinTechnicalException; -import org.apache.commons.io.FileUtils; -import org.nuiton.config.ApplicationConfig; -import org.nuiton.i18n.I18n; -import org.nuiton.i18n.init.DefaultI18nInitializer; -import org.nuiton.i18n.init.UserI18nInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Locale; - -public class UCoinClientCore { - - private static final Logger log = LoggerFactory.getLogger(UCoinClientCore.class); - - - public static void main(String[] args) { - if (log.isInfoEnabled()) { - log.info("Starting UCOin Java Client :: Core with arguments: " + Arrays.toString(args)); - } - - // By default, display help - if (args == null || args.length == 0) { - args = new String[] { "--help" }; - } - - // Could override config file name (useful for dev) - String configFile = "ucoinj.config"; - if (System.getProperty(configFile) != null) { - configFile = System.getProperty(configFile); - configFile = configFile.replaceAll("\\\\", "/"); - } - - // Create configuration - Configuration config = new Configuration(configFile, args) { - protected void addAlias(ApplicationConfig applicationConfig) { - super.addAlias(applicationConfig); - // Add custom alias - }; - }; - Configuration.setInstance(config); - - // Init i18n - try { - initI18n(config); - } catch (IOException e) { - throw new UCoinTechnicalException("i18n initialization failed", e); - } - - try { - config.getApplicationConfig().doAllAction(); - } catch (Exception e) { - e.printStackTrace(); - } - - //IOUtils.closeQuietly(ServiceLocator.instance()); - } - - protected static void initI18n(Configuration config) throws IOException { - - // --------------------------------------------------------------------// - // init i18n - // --------------------------------------------------------------------// - File i18nDirectory = new File(config.getDataDirectory(), "i18n"); - if (i18nDirectory.exists()) { - // clean i18n cache - FileUtils.cleanDirectory(i18nDirectory); - } - - FileUtils.forceMkdir(i18nDirectory); - - if (log.isDebugEnabled()) { - log.debug("I18N directory: " + i18nDirectory); - } - - Locale i18nLocale = config.getI18nLocale(); - - if (log.isInfoEnabled()) { - log.info(String.format("Starts i18n with locale [%s] at [%s]", - i18nLocale, i18nDirectory)); - } - I18n.init(new UserI18nInitializer( - i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())), - i18nLocale); - } - - protected static String getI18nBundleName() { - return "ucoinj-core-i18n"; - } -} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainBlock.java b/ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainBlock.java deleted file mode 100644 index e0428b0f1169fe06d15b94d4b019c6902907d6af..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/BlockchainBlock.java +++ /dev/null @@ -1,181 +0,0 @@ -package io.ucoin.client.core.model; - -/* - * #%L - * UCoin Java Client :: Core API - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import java.io.Serializable; -import java.util.List; - -/** - * A block from the blockchain. - * - * @author Benoit Lavenier <benoit.lavenier@e-is.pro> - * @since 1.0 - */ -public class BlockchainBlock implements Serializable { - - private static final long serialVersionUID = -5598140972293452669L; - - private String version; - private Integer nonce; - private Integer powMin; - private Integer number; - private Integer time; - private Integer medianTime; - private Integer membersCount; - private Long monetaryMass; - private String currency; - private String issuer; - private String signature; - private String hash; - private String parameters; - private String previousHash; - private String previousIssuer; - private Integer dividend; - //private int memberChanges; - private List<Identity> identities; - private List<Member> joiners; -// private int actives": [], -// private int leavers": [], -// private int excluded": [], -// private int certifications": [], -// private int transactions": [], - -// private int raw": "Version: 1\nType: Block\nCurrency: zeta_brouzouf\nNonce: 8233\nNumber: 1\nDate: 1416589860\nConfirmedDate: 1416589860\nIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nPreviousHash: 00006CD96A01378465318E48310118AC6B2F3625\nPreviousIssuer: HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk\nMembersCount: 4\nIdentities:\nJoiners:\nActives:\nLeavers:\nExcluded:\nCertifications:\nTransactions:\n" - //private String raw; - - public String getVersion() { - return version; - } - public void setVersion(String version) { - this.version = version; - } - public Integer getNonce() { - return nonce; - } - public void setNonce(Integer nonce) { - this.nonce = nonce; - } - - public Integer getPowMin() { - return powMin; - } - - public void setPowMin(Integer powMin) { - this.powMin = powMin; - } - - public Integer getNumber() { - return number; - } - public void setNumber(Integer number) { - this.number = number; - } - public Integer getTime() { - return time; - } - public void setTime(Integer time) { - this.time = time; - } - public Integer getMedianTime() { - return medianTime; - } - public void setMedianTime(Integer medianTime) { - this.medianTime = medianTime; - } - public Integer getMembersCount() { - return membersCount; - } - public void setMembersCount(Integer membersCount) { - this.membersCount = membersCount; - } - - public Long getMonetaryMass() { - return monetaryMass; - } - - public void setMonetaryMass(Long monetaryMass) { - this.monetaryMass = monetaryMass; - } - - public String getCurrency() { - return currency; - } - public void setCurrency(String currency) { - this.currency = currency; - } - public String getIssuer() { - return issuer; - } - public void setIssuer(String issuer) { - this.issuer = issuer; - } - public String getSignature() { - return signature; - } - public void setSignature(String signature) { - this.signature = signature; - } - public String getHash() { - return hash; - } - public void setHash(String hash) { - this.hash = hash; - } - public String getParameters() { - return parameters; - } - public void setParameters(String parameters) { - this.parameters = parameters; - } - public String getPreviousHash() { - return previousHash; - } - public void setPreviousHash(String previousHash) { - this.previousHash = previousHash; - } - public String getPreviousIssuer() { - return previousIssuer; - } - public void setPreviousIssuer(String previousIssuer) { - this.previousIssuer = previousIssuer; - } - public Integer getDividend() { - return dividend; - } - public void setDividend(Integer dividend) { - this.dividend = dividend; - } - public List<Identity> getIdentities() { - return identities; - } - public void setIdentities(List<Identity> identities) { - this.identities = identities; - } - public List<Member> getJoiners() { - return joiners; - } - public void setJoiners(List<Member> joiners) { - this.joiners = joiners; - } -} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupUId.java b/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupUId.java deleted file mode 100644 index 819c4eb02cf0c689a814e5378815600a3b02e3d9..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupUId.java +++ /dev/null @@ -1,70 +0,0 @@ -package io.ucoin.client.core.model; - -/* - * #%L - * UCoin Java Client :: Core API - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import java.util.List; -import java.util.Map; - -public class WotLookupUId { - - private String uid; - - private Map<String, String> meta; - - private String self; - - private List<WotLookupSignature> others; - - public String getUid() { - return uid; - } - - public void setUid(String uid) { - this.uid = uid; - } - - public Map<String, String> getMeta() { - return meta; - } - - public void setMeta(Map<String, String> meta) { - this.meta = meta; - } - - public String getSelf() { - return self; - } - - public void setSelf(String self) { - this.self = self; - } - - public List<WotLookupSignature> getOthers() { - return others; - } - - public void setOthers(List<WotLookupSignature> others) { - this.others = others; - } -} diff --git a/ucoinj-core/src/main/resources/META-INF/services/io.ucoin.client.core.service.BlockchainService b/ucoinj-core/src/main/resources/META-INF/services/io.ucoin.client.core.service.BlockchainService deleted file mode 100644 index 4d6a71f477d1e06f3e76167e5f355cb581ed269f..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/main/resources/META-INF/services/io.ucoin.client.core.service.BlockchainService +++ /dev/null @@ -1 +0,0 @@ -io.ucoin.client.core.service.BlockchainService \ No newline at end of file diff --git a/ucoinj-core/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider b/ucoinj-core/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider deleted file mode 100644 index 4bc90bc4b8ec5988e264b26c5ebd5ec41831003f..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider +++ /dev/null @@ -1 +0,0 @@ -io.ucoin.client.core.config.ConfigurationProvider \ No newline at end of file diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/BlockchainServiceTest.java b/ucoinj-core/src/test/java/io/ucoin/client/core/service/BlockchainServiceTest.java deleted file mode 100644 index 7c2b4e9aad68091d87e8e1e6bf9d590d85a4b63e..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/BlockchainServiceTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package io.ucoin.client.core.service; - -/* - * #%L - * UCoin Java Client :: Core API - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.model.BasicIdentity; -import io.ucoin.client.core.model.BlockchainBlock; -import io.ucoin.client.core.model.BlockchainParameter; -import io.ucoin.client.core.model.Member; -import org.junit.Assert; -import org.junit.ClassRule; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class BlockchainServiceTest { - - private static final Logger log = LoggerFactory.getLogger(BlockchainServiceTest.class); - - @ClassRule - public static final TestResource resource = TestResource.create(); - - - @Test - public void getParameters() throws Exception { - - BlockchainService blockchainService = new BlockchainService(); - BlockchainParameter result = blockchainService.getParameters(); - - // close - blockchainService.close(); - - Assert.assertNotNull(result); - Assert.assertNotNull(result.getCurrency()); - } - - @Test - public void getBlock() throws Exception { - - BlockchainService blockchainService = new BlockchainService(); - BlockchainBlock result = blockchainService.getBlock(0); - // close - blockchainService.close(); - - Assert.assertNotNull(result); - Assert.assertNotNull(result.getCurrency()); - - for (BasicIdentity id: result.getIdentities()) { - Assert.assertNotNull(id.getUid()); - } - - for (Member id: result.getJoiners()) { - Assert.assertNotNull(id.getUid()); - } - } -} diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/BlockIndexerServiceTest.java b/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/BlockIndexerServiceTest.java deleted file mode 100644 index b659cdfd3a133c073ffd7b91a44c62c13dffe9d1..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/BlockIndexerServiceTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package io.ucoin.client.core.service.indexer; - -/* - * #%L - * UCoin Java Client :: Core API - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.model.BlockchainBlock; -import io.ucoin.client.core.service.BlockchainService; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.service.search.BlockIndexerService; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -public class BlockIndexerServiceTest { - - private static final Logger log = LoggerFactory.getLogger(BlockIndexerServiceTest.class); - @ClassRule - public static final TestResource resource = TestResource.create(); - - private BlockIndexerService service; - private BlockchainService blockchainService; - private Configuration config; - - @Before - public void setUp() { - service = ServiceLocator.instance().getBlockIndexerService(); - blockchainService = ServiceLocator.instance().getBlockchainService(); - config = Configuration.instance(); - } - - @Test - public void createIndex() throws Exception { - - // drop and recreate index - service.deleteIndex(config.getNodeCurrency()); - - service.createIndex(config.getNodeCurrency()); - } - - @Test - public void allInOne() throws Exception { - - createIndex(); - indexBlock(); - searchBlocks(); - } - - @Test - public void indexBlock() throws Exception { - // Read a block - BlockchainBlock currentBlock = blockchainService.getCurrentBlock(); - - // Create a new non-existing block - service.indexBlock(currentBlock); - - // Update a existing block - { - currentBlock.setMembersCount(1000000); - - service.indexBlock(currentBlock); - } - } - - @Test - public void searchBlocks() throws Exception { - - // Create a block with a fake hash - BlockchainBlock aBlock = blockchainService.getCurrentBlock(); - aBlock.setHash("myUnitTestHash"); - service.saveBlock(aBlock, true); - - // match multi words - String queryText = aBlock.getHash(); - List<BlockchainBlock> blocks = service.findBlocksByHash(config.getNodeCurrency(), queryText); - assertResults(queryText, blocks); - } - - /* -- internal methods */ - - protected void assertResults(String queryText, List<BlockchainBlock> result) { - log.info(String.format("Results for a search on [%s]", queryText)); - Assert.assertNotNull(result); - Assert.assertTrue(result.size() > 0); - for (BlockchainBlock block: result) { - log.info(" - " + block.getNumber()); - } - } - -} diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/client/CurrencyIndexerRestClientServiceTest.java b/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/client/CurrencyIndexerRestClientServiceTest.java deleted file mode 100644 index 7765efd3ef8be610933a75ce884360290249b5b9..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/client/CurrencyIndexerRestClientServiceTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package io.ucoin.client.core.service.indexer.client; - -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.model.Currency; -import io.ucoin.client.core.model.Wallet; -import io.ucoin.client.core.service.CryptoService; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.service.search.client.CurrencyIndexerRestClientService; -import io.ucoin.client.core.technical.crypto.CryptoUtils; -import io.ucoin.client.core.technical.gson.GsonUtils; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -/** - * Created by Benoit on 06/05/2015. - */ -public class CurrencyIndexerRestClientServiceTest { - private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerRestClientServiceTest.class); - - @ClassRule - public static final TestResource resource = TestResource.create(); - - private CurrencyIndexerRestClientService service; - private Configuration config; - - @Before - public void setUp() { - service = ServiceLocator.instance().getCurrencyIndexerRestClientService(); - config = Configuration.instance(); - } - - @Test - public void isNodeAlive() { - boolean isNodeAlive = service.isNodeAlive(); - Assert.assertTrue(isNodeAlive); - } - - @Test - public void getAllCurrencyNames() { - List<String> currencyNames = service.getAllCurrencyNames(); - for (String currencyName: currencyNames) { - log.info(" - " + currencyName); - } - } - - @Test - public void registerCurrency() { - Currency currency = new Currency(); - currency.setCurrencyName("register-test-" + System.currentTimeMillis()); - - String currencyJson = GsonUtils.newBuilder().create().toJson(currency); - - String pubKey = resource.getFixtures().getUserPublicKey(); - String secretKey = resource.getFixtures().getUserSecretKey(); - - CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); - String signature = cryptoService.sign(currencyJson, secretKey); - - service.registerNewCurrency(pubKey, currencyJson, signature); - } - - /* -- -- */ - - protected Wallet createTestWallet() { - Wallet wallet = new Wallet( - resource.getFixtures().getCurrency(), - resource.getFixtures().getUid(), - CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), - CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); - - return wallet; - } -} diff --git a/ucoinj-core/src/test/resources/ucoinj-test.properties b/ucoinj-core/src/test/resources/ucoinj-test.properties deleted file mode 100644 index dfda70024410f3c2de9d979ad64f38c7066888af..0000000000000000000000000000000000000000 --- a/ucoinj-core/src/test/resources/ucoinj-test.properties +++ /dev/null @@ -1,17 +0,0 @@ -#ucoinj.node.host=server.e-is.pro -#ucoinj.node.port=9101 - -ucoinj.node.host=metab.ucoin.io -ucoinj.node.port=9201 -#ucoinj.node.elasticsearch.local=true -#ucoinj.node.elasticsearch.local.clusterName=ucoinj-unit-test -ucoinj.node.elasticsearch.local.clusterName=data.ucoin.fr - -ucoinj.node.elasticsearch.host=192.168.0.5 -ucoinj.node.elasticsearch.port=9300 - -#ucoinj.node.elasticsearch.rest.host=www.data.ucoin.fr -#ucoinj.node.elasticsearch.rest.port=80 - -ucoinj.node.elasticsearch.rest.host=localhost -ucoinj.node.elasticsearch.rest.port=8080 \ No newline at end of file diff --git a/ucoinj-elasticsearch/LICENSE b/ucoinj-elasticsearch/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/ucoinj-elasticsearch/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ucoinj-elasticsearch/LICENSE.txt b/ucoinj-elasticsearch/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/ucoinj-elasticsearch/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ucoinj-elasticsearch/pom.xml b/ucoinj-elasticsearch/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f42a342a93595954a9cd8a4ec4ef37838c7a918 --- /dev/null +++ b/ucoinj-elasticsearch/pom.xml @@ -0,0 +1,275 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj</artifactId> + <version>1.0-SNAPSHOT</version> + </parent> + + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-elasticsearch</artifactId> + <packaging>jar</packaging> + <name>UCoin Java Client :: ElasticSearch Indexer</name> + + <properties> + <!-- bundle configuration --> + <bundlePrefix>ucoinj-elasticsearch-${project.version}</bundlePrefix> + + <!-- i18n configuration --> + <i18n.bundleOutputName>ucoinj-elasticsearch-i18n</i18n.bundleOutputName> + <i18n.generateCsvFile>true</i18n.generateCsvFile> + <i18n.bundleCsvFile> + ${maven.gen.dir}/resources/META-INF/${i18n.bundleOutputName}.csv + </i18n.bundleCsvFile> + <config.i18nBundleName>${i18n.bundleOutputName}</config.i18nBundleName> + + <maven.jar.main.class> + io.ucoin.ucoinj.elasticsearch.Main + </maven.jar.main.class> + + </properties> + + <dependencies> + <dependency> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-core-client</artifactId> + <version>${project.version}</version> + </dependency> + <!-- LOGGING DEPENDENCIES - SLF4J --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <!-- Elastic Search --> + <dependency> + <groupId>org.elasticsearch</groupId> + <artifactId>elasticsearch</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + + <!-- JNA (need for OS shutdown hook) --> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna</artifactId> + </dependency> + <dependency> + <groupId>net.java.dev.jna</groupId> + <artifactId>jna-platform</artifactId> + </dependency> + + <!-- Unit test --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/filtered-resources</directory> + <filtering>true</filtering> + <includes> + <include>*.config</include> + <include>*.properties</include> + </includes> + </resource> + <resource> + <directory>src/main/resources</directory> + <filtering>false</filtering> + </resource> + </resources> + + <plugins> + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifest> + <useUniqueVersions>false</useUniqueVersions> + <addClasspath>true</addClasspath> + <classpathPrefix>./lib/</classpathPrefix> + </manifest> + </archive> + </configuration> + </plugin> + + <plugin> + <groupId>org.nuiton.i18n</groupId> + <artifactId>i18n-maven-plugin</artifactId> + + <executions> + <execution> + <id>scan-sources</id> + <configuration> + <entries> + <entry> + <specificGoal>parserValidation</specificGoal> + <basedir>${maven.src.dir}/main/java/</basedir> + <includes> + <param>**/**-validation.xml</param> + </includes> + </entry> + </entries> + </configuration> + <goals> + <goal>parserJava</goal> + <goal>parserValidation</goal> + <goal>gen</goal> + </goals> + </execution> + <execution> + <id>make-bundle</id> + <goals> + <goal>bundle</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>default-bundle</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + <build> + <defaultGoal>package</defaultGoal> + <plugins> + <plugin> + <artifactId>maven-dependency-plugin</artifactId> + <executions> + <execution> + <id>copy-dependencies</id> + <goals> + <goal>copy-dependencies</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <overWriteReleases>false</overWriteReleases> + <overWriteSnapshots>true</overWriteSnapshots> + <overWriteIfNewer>true</overWriteIfNewer> + <outputDirectory>${project.build.directory}/lib</outputDirectory> + <silent>true</silent> + <includeScope>runtime</includeScope> + <excludeScope>test</excludeScope> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <executions> + <execution> + <id>assembly-standalone</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + <configuration> + <attach>true</attach> + <finalName>${bundlePrefix}</finalName> + <descriptors> + <descriptor> + src/main/assembly/standalone.xml + </descriptor> + <descriptor> + src/main/assembly/i18n.xml + </descriptor> + <descriptor> + src/main/assembly/help.xml + </descriptor> + </descriptors> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + <!-- use this profile to run the main class --> + <profile> + <id>run</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <build> + <defaultGoal>package</defaultGoal> + <plugins> + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <executions> + <execution> + <id>check-run</id> + <goals> + <goal>enforce</goal> + </goals> + <phase>initialize</phase> + <configuration> + <rules> + <requireProperty> + <property>maven.jar.main.class</property> + <message>Could not find the "maven.jar.main.class" + required property, use + -Dmaven.jar.main.class=your.main.class.fqn + </message> + </requireProperty> + </rules> + <ignoreCache>true</ignoreCache> + <failFast>true</failFast> + <fail>true</fail> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <id>run</id> + <goals> + <goal>java</goal> + </goals> + <phase>compile</phase> + <configuration> + <mainClass>${exec.mainClass}</mainClass> + <classpathScope>${exec.classpathScope}</classpathScope> + <commandlineArgs>start</commandlineArgs> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <properties> + <exec.mainClass>${maven.jar.main.class}</exec.mainClass> + <exec.classpathScope>runtime</exec.classpathScope> + <ucoinj.log.file>${project.build.directory}/exec.log</ucoinj.log.file> + </properties> + </profile> + </profiles> +</project> diff --git a/ucoinj-elasticsearch/src/license/THIRD-PARTY.properties b/ucoinj-elasticsearch/src/license/THIRD-PARTY.properties new file mode 100644 index 0000000000000000000000000000000000000000..8610ec5bda0d6673a7c224b7fd16226cc1bcd664 --- /dev/null +++ b/ucoinj-elasticsearch/src/license/THIRD-PARTY.properties @@ -0,0 +1,26 @@ +# Generated by org.codehaus.mojo.license.AddThirdPartyMojo +#------------------------------------------------------------------------------- +# Already used licenses in project : +# - ASL, version 2 +# - Apache License 2.0 +# - Apache License Version 2.0 +# - BSD License +# - CC0 1.0 Universal +# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 +# - Eclipse Public License 1.0 +# - General Public License (GPL) v3 +# - Indiana University Extreme! Lab Software License, vesion 1.1.1 +# - LGPL, version 2.1 +# - Lesser General Public License (LGPL) v 3.0 +# - Lesser General Public License (LPGL) +# - Lesser General Public License (LPGL) v 2.1 +# - MIT License +# - New BSD License +# - Public Domain, per Creative Commons CC0 +# - The Apache Software License, Version 2.0 +#------------------------------------------------------------------------------- +# Please fill the missing licenses for dependencies : +# +# +#Tue Jan 05 15:24:57 CET 2016 +commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 diff --git a/ucoinj-elasticsearch/src/main/assembly/help.xml b/ucoinj-elasticsearch/src/main/assembly/help.xml new file mode 100644 index 0000000000000000000000000000000000000000..d9fbefa35e3e529105288284add5bfde598a81ca --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/help.xml @@ -0,0 +1,52 @@ +<!-- + #%L + Reef DB :: Quadrige2 Server Core + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 - 2015 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>help</id> + <formats> + <format>zip</format> + </formats> + + <fileSets> + + <fileSet> + <directory>src/main/help</directory> + <outputDirectory/> + <includes> + <include>**/*</include> + </includes> + </fileSet> + + <fileSet> + <directory>src/main/assembly/min</directory> + <outputDirectory/> + <filtered>true</filtered> + <includes> + <include>version.appup</include> + </includes> + </fileSet> + + </fileSets> +</assembly> diff --git a/ucoinj-elasticsearch/src/main/assembly/i18n.xml b/ucoinj-elasticsearch/src/main/assembly/i18n.xml new file mode 100644 index 0000000000000000000000000000000000000000..008c050913e10f0ead8f39057908b94873a5610a --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/i18n.xml @@ -0,0 +1,53 @@ +<!-- + #%L + Reef DB :: Quadrige2 Server Core + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 - 2015 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>i18n</id> + <formats> + <format>zip</format> + </formats> + + <fileSets> + + <fileSet> + <directory>target/classes/META-INF</directory> + <outputDirectory/> + <includes> + <include>ucoinj-elasticsearch-i18n*.properties</include> + <include>ucoinj-elasticsearch-i18n*.csv</include> + </includes> + </fileSet> + + <fileSet> + <directory>src/main/assembly/min</directory> + <outputDirectory/> + <filtered>true</filtered> + <includes> + <include>version.appup</include> + </includes> + </fileSet> + + </fileSets> +</assembly> diff --git a/ucoinj-elasticsearch/src/main/assembly/min/README.txt b/ucoinj-elasticsearch/src/main/assembly/min/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..fedac4d3495b61106419802e911322141e052305 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/min/README.txt @@ -0,0 +1,12 @@ + + README + + ${project.name} Help + + ------------------------------------ + +Start a ElastoicSearch node : + > ucoinj-elasticsearch.<bat|sh> --start + +To show help (list all options) : + > ucoinj-elasticsearch.<bat|sh> --help diff --git a/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.bat b/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.bat new file mode 100644 index 0000000000000000000000000000000000000000..c7ba1ea71e448aef181ba779fcc9d70b276b5642 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.bat @@ -0,0 +1,46 @@ +@echo off + +REM Comment out this line to specify your JAVA path: +REM SET JAVA_HOME=<path_to_java> + + +set OLDDIR=%CD% +cd /d %~dp0% + +set APP_BASEDIR=%CD% +set JAVA_COMMAND=%JAVA_HOME%\bin\java +set APP_LOG_FILE=%APP_BASEDIR%\data\${project.artifactId}-${project.version}.log +set JAVA_OPTS=-Xmx1G + +if not exist "%JAVA_HOME%" goto no_java + +echo =============================================================================== +echo . +echo ${project.name} +echo . +echo JAVA: %JAVA_COMMAND% +echo . +echo JAVA_OPTS: %JAVA_OPTS% +echo . +echo log file: %APP_LOG_FILE% +echo . +echo =============================================================================== +echo . + + +set OLDDIR=%CD% +cd /d %~dp0% + +call "%JAVA_COMMAND%" %JAVA_OPTS% "-Ducoinj.log.file=%APP_LOG_FILE%" -jar ${project.build.finalName}.${project.packaging} %1 %2 %3 %4 %5 %6 %7 %8 %9 +set exitcode=%ERRORLEVEL% +echo Stop with exitcode: %exitcode% +cd %OLDDIR% +exit /b %exitcode% +goto end + +no_java: +echo "Java not detected ! Please set environment variable JAVA_HOME before launching," +echo "or edit the file 'launch.bat' and insert this line :" +echo " SET JAVA_HOME=<path_to_java>" + +:end diff --git a/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.sh b/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.sh new file mode 100644 index 0000000000000000000000000000000000000000..b62ea245faee83097dd25eb390e90692acad35ed --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/min/ucoinj-elasticsearch.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +#Comment out this line to specify your JAVA path: +#export JAVA_HOME=/etc/jre... + +export APP_BASEDIR=$(pwd) +export JAVA_COMMAND=$JAVA_HOME/bin/java +export APP_LOG_FILE=$APP_BASEDIR/data/${project.artifactId}-${project.version}.log + +cd $APP_BASEDIR + +if [ -d $JAVA_HOME ]; then + echo "${project.name}" + echo " basedir: $APP_BASEDIR" + echo " jre home: $JAVA_HOME" + echo " log file: $APP_LOG_FILE" + + MEMORY="-Xmx1G" + #APP_JVM_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000" + + REP=$(dirname $0) + + cd $REP + + echo "launch java" + echo "java command: $JAVA_COMMAND" + + $JAVA_COMMAND $MEMORY $APP_JVM_OPTS -Ducoinj.log.file=$APP_LOG_FILE -jar ${project.build.finalName}.${project.packaging} $* + exitcode=$? + echo "Stop ${project.name} with exitcode: $exitcode" + exit $exitcode + +else + echo "Java not detected ! Please set environment variable JAVA_HOME before launching," + echo "or edit the file 'launch.sh' and insert this line :" + echo " export JAVA_HOME=<path_to_java>" +fi + diff --git a/ucoinj-elasticsearch/src/main/assembly/min/version.appup b/ucoinj-elasticsearch/src/main/assembly/min/version.appup new file mode 100644 index 0000000000000000000000000000000000000000..f2ab45c3b0ef08a7742373cd3434573d500b3b22 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/min/version.appup @@ -0,0 +1 @@ +${project.version} \ No newline at end of file diff --git a/ucoinj-elasticsearch/src/main/assembly/standalone.xml b/ucoinj-elasticsearch/src/main/assembly/standalone.xml new file mode 100644 index 0000000000000000000000000000000000000000..7ab6a0df0b5e5912156c58ba4776984e7d5e64fb --- /dev/null +++ b/ucoinj-elasticsearch/src/main/assembly/standalone.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + allegro-obsdeb :: UI :: Swing + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2009 - 2013 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<assembly + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>standalone</id> + <formats> + <format>zip</format> + </formats> + + <fileSets> + + <fileSet> + <directory>target</directory> + <outputDirectory/> + <includes> + <include>${project.build.finalName}.${project.packaging}</include> + </includes> + </fileSet> + + <fileSet> + <directory>target/lib</directory> + <outputDirectory>lib</outputDirectory> + <includes> + <include>*.jar</include> + </includes> + <excludes> + <exclude>junit-*.jar</exclude> + </excludes> + </fileSet> + + <fileSet> + <directory>src/main/assembly/min</directory> + <outputDirectory/> + <filtered>true</filtered> + <fileMode>0755</fileMode> + <includes> + <include>ucoinj-elasticsearch.sh</include> + <include>ucoinj-elasticsearch.bat</include> + <include>version.appup</include> + <include>README*</include> + </includes> + </fileSet> + + <!-- configuration file --> + <fileSet> + <directory>target/classes</directory> + <outputDirectory/> + <includes> + <include>ucoinj.config</include> + </includes> + </fileSet> + + <!-- diff --> + <fileSet> + <directory>target/classes/fr/ifremer/quadrige2/core/db/changelog</directory> + <outputDirectory>changelog</outputDirectory> + <includes> + <include>**/*.*</include> + </includes> + </fileSet> + + <!-- I18N component --> + <fileSet> + <directory>target/classes/META-INF</directory> + <outputDirectory>i18n</outputDirectory> + <includes> + <include>ucoinj-elasticsearch-i18n*.properties</include> + <include>ucoinj-elasticsearch-i18n*.csv</include> + </includes> + </fileSet> + <fileSet> + <directory>src/main/assembly/min</directory> + <outputDirectory>i18n</outputDirectory> + <filtered>true</filtered> + <includes> + <include>version.appup</include> + </includes> + </fileSet> + + <fileSet> + <includes> + <include>LICENSE*</include> + </includes> + </fileSet> + + </fileSets> +</assembly> diff --git a/ucoinj-elasticsearch/src/main/filtered-resources/log4j.properties b/ucoinj-elasticsearch/src/main/filtered-resources/log4j.properties new file mode 100644 index 0000000000000000000000000000000000000000..377ad53caf3f07bd89e9faf6fca928a3e0410ef3 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/filtered-resources/log4j.properties @@ -0,0 +1,30 @@ + +# Global logging configuration +#log4j.rootLogger=ERROR, stdout, file +log4j.rootLogger=ERROR, stdout + +# Console output +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p %m%n + +# uCoinj levels +log4j.logger.io.ucoin.ucoinj=INFO +#log4j.logger.io.ucoin.ucoinj.core.client=DEBUG +#log4j.logger.io.ucoin.ucoinj.core.client.service=DEBUG +#log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG + +# Other frameworks levels +log4j.logger.org.nuiton.util=WARN +log4j.logger.org.nuiton.config=WARN +log4j.logger.org.elasticsearch=WARN +#log4j.logger.org.elasticsearch=INFO + +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.file=${ucoinj.log.file} +log4j.appender.file.MaxFileSize=10MB +log4j.appender.file.MaxBackupIndex=4 + +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n + diff --git a/ucoinj-elasticsearch/src/main/filtered-resources/ucoinj.config b/ucoinj-elasticsearch/src/main/filtered-resources/ucoinj.config new file mode 100644 index 0000000000000000000000000000000000000000..267e81bf077ecb4fbf41c0039d4e03fe6d0a19fe --- /dev/null +++ b/ucoinj-elasticsearch/src/main/filtered-resources/ucoinj.config @@ -0,0 +1,4 @@ +ucoinj.version=${project.version} +ucoinj.site.url=${project.url} +ucoinj.inceptionYear=${project.inceptionYear} +ucoinj.organizationName=${license.organizationName} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/Main.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..029b956ba668cfdccd09836bccb3366f323d7518 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/Main.java @@ -0,0 +1,214 @@ +package io.ucoin.ucoinj.elasticsearch; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.collect.Lists; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.CommandLinesUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.config.ConfigurationAction; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.elasticsearch.util.Desktop; +import io.ucoin.ucoinj.elasticsearch.util.DesktopPower; +import org.apache.commons.io.FileUtils; +import org.nuiton.config.ApplicationConfig; +import org.nuiton.i18n.I18n; +import org.nuiton.i18n.init.DefaultI18nInitializer; +import org.nuiton.i18n.init.UserI18nInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.Scanner; + +public class Main { + + private static final Logger log = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) { + Main main = new Main(); + main.run(args); + } + + public void run(String[] args) { + if (log.isInfoEnabled()) { + log.info("Starting uCoinj :: ElasticSearch Indexer with arguments " + Arrays.toString(args)); + } + + // By default, display help + if (args == null || args.length == 0) { + args = new String[] { "--help" }; + } + + List<String> arguments = Lists.newArrayList(Arrays.asList(args)); + arguments.removeAll(Arrays.asList(ConfigurationAction.HELP.aliases)); + + // Could override config file name (useful for dev) + String configFile = "ucoinj.config"; + if (System.getProperty(configFile) != null) { + configFile = System.getProperty(configFile); + configFile = configFile.replaceAll("\\\\", "/"); + } + + // Create configuration + Configuration config = new Configuration(configFile, args) { + protected void addAlias(ApplicationConfig applicationConfig) { + super.addAlias(applicationConfig); + // Add custom alias + }; + }; + Configuration.setInstance(config); + + // Init i18n + try { + initI18n(config); + } catch (IOException e) { + throw new TechnicalException("i18n initialization failed", e); + } + + // Add hook on system + addShutdownHook(); + + // Run all actions + try { + config.getApplicationConfig().doAllAction(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + if (arguments.size() > 0) { + + // Check if auto-quit if need + boolean quit = true; + for (String startAlias: ConfigurationAction.START.aliases) { + if (arguments.contains(startAlias)) { + quit = false; + break; + } + } + + // If scheduling is running, wait quit instruction + if (!quit) { + while (!quit) { + String userInput = CommandLinesUtils.readInput("Press [Q] or enter to quit", "Q", true); + quit = StringUtils.isNotBlank(userInput) && "Q".equalsIgnoreCase(userInput); + } + } + } + + // shutdown + shutdown(); + + log.info("uCoinj :: ElasticSearch Indexer successfully stopped"); + //System.exit(-1); + } + + /* -- protected methods -- */ + + /** + * Shutdown all services + */ + protected static void shutdown() { + if (ServiceLocator.instance() != null) { + try { + ServiceLocator.instance().close(); + } + catch(IOException e) { + // Silent is gold + } + } + } + + protected void initI18n(Configuration config) throws IOException { + + // --------------------------------------------------------------------// + // init i18n + // --------------------------------------------------------------------// + File i18nDirectory = new File(config.getDataDirectory(), "i18n"); + if (i18nDirectory.exists()) { + // clean i18n cache + FileUtils.cleanDirectory(i18nDirectory); + } + + FileUtils.forceMkdir(i18nDirectory); + + if (log.isDebugEnabled()) { + log.debug("I18N directory: " + i18nDirectory); + } + + Locale i18nLocale = config.getI18nLocale(); + + if (log.isInfoEnabled()) { + log.info(String.format("Starts i18n with locale [%s] at [%s]", + i18nLocale, i18nDirectory)); + } + I18n.init(new UserI18nInitializer( + i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())), + i18nLocale); + } + + protected String getI18nBundleName() { + return "ucoinj-elasticsearch-i18n"; + } + + /** + * Add an OS shutdown hook, to close application on shutdown + */ + private void addShutdownHook() { + + // Use shutdownHook to close context on System.exit + Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { + @Override + public void run() { + shutdown(); + } + })); + + // Add DesktopPower to hook computer shutdown + DesktopPower desktopPower = Desktop.getDesktopPower(); + if (desktopPower != null) { + + desktopPower.addListener(new DesktopPower.Listener() { + @Override + public void quit() { + if (ServiceLocator.instance() != null) { + try { + ServiceLocator.instance().close(); + } + catch(IOException e) { + // Silent is gold + } + } + } + }); + } + + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/HelpAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/HelpAction.java new file mode 100644 index 0000000000000000000000000000000000000000..5728513a389ae573413db5f7cc564b19f3c89e00 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/HelpAction.java @@ -0,0 +1,49 @@ +package io.ucoin.ucoinj.elasticsearch.action; + +/* + * #%L + * SIH-Adagio :: Shared + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +public class HelpAction { + + public void show() { + StringBuilder sb = new StringBuilder(); + + sb.append("Usage: ucoinj-elaticsearch.<sh|bat> <commands> [options]\n\n") + .append("Commands:\n\n") + .append(" start Start elastic search node\n") + .append(" index Index blocks from BMA Node\n") + .append(" reset-data Reset indexed data for the uCoin node's currency\n") + .append("\n") + .append("\n") + .append("Options:\n\n") + .append(" --help Output usage information\n") + .append(" -h --host <user> uCoin node host (with Basic Merkled API)\n") + .append(" -p --port <pwd> uCoin node port (with Basic Merkled API)\n") + .append("\n") + .append(" -esh --es-host <user> ElasticSearch node host\n") + .append(" -esp --es-port <pwd> ElasticSearch node port\n"); + + System.out.println(sb.toString()); + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java new file mode 100644 index 0000000000000000000000000000000000000000..8338048b42fd968744a4f268bb04f62c3bda6e03 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/IndexerAction.java @@ -0,0 +1,109 @@ +package io.ucoin.ucoinj.elasticsearch.action; + +/* + * #%L + * SIH-Adagio :: Shared + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class IndexerAction { + /* Logger */ + private static final Logger log = LoggerFactory.getLogger(IndexerAction.class); + + public void indexLastBlocks() { + + Runnable runnable = new Runnable() { + @Override + public void run() { + Configuration config = Configuration.instance(); + Peer peer = checkConfigAndGetPeer(config); + BlockIndexerService blockIndexerService = ServiceLocator.instance().getBlockIndexerService(); + + blockIndexerService.indexLastBlocks(peer); + } + }; + + ServiceLocator.instance().getExecutorService().execute(runnable); + } + + public void resetAllBlocks() { + BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService(); + BlockIndexerService indexerService = ServiceLocator.instance().getBlockIndexerService(); + Configuration config = Configuration.instance(); + Peer peer = checkConfigAndGetPeer(config); + + try { + // Get the currency name from node + BlockchainParameters parameter = blockchainService.getParameters(peer); + if (parameter == null) { + log.error(String.format("Could not connect to node [%s:%s]", + config.getNodeBmaHost(), config.getNodeBmaPort())); + return; + } + String currencyName = parameter.getCurrency(); + + log.info(String.format("Reset data for index [%s]", currencyName)); + + // Check if index exists + boolean indexExists = indexerService.existsIndex(currencyName); + if (indexExists) { + log.debug(String.format("Deleting index [%s]", currencyName)); + indexerService.deleteIndex(currencyName); + + log.debug(String.format("Creating index [%s]", currencyName)); + indexerService.createIndex(currencyName); + } + + log.info(String.format("Successfully reset data for index [%s]", currencyName)); + } catch(Exception e) { + log.error("Error during reset data: " + e.getMessage(), e); + } + } + + /* -- -- */ + + protected Peer checkConfigAndGetPeer(Configuration config) { + if (StringUtils.isBlank(config.getNodeBmaHost())) { + log.error("ERROR: node host is required"); + System.exit(-1); + return null; + } + if (config.getNodeBmaPort() <= 0) { + log.error("ERROR: node port is required"); + System.exit(-1); + return null; + } + + Peer peer = new Peer(config.getNodeBmaHost(), config.getNodeBmaPort()); + return peer; + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java new file mode 100644 index 0000000000000000000000000000000000000000..07d0c7735a4c91d23cb1c93977ab65a76169e966 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/action/NodeAction.java @@ -0,0 +1,89 @@ +package io.ucoin.ucoinj.elasticsearch.action; + +/* + * #%L + * SIH-Adagio :: Shared + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.util.CommandLinesUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService; +import io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class NodeAction { + /* Logger */ + private static final Logger log = LoggerFactory.getLogger(NodeAction.class); + + public void start() { + + Configuration config = Configuration.instance(); + //config.setNodeElasticSearchLocal(false); + + // Starting ES node + ElasticSearchService esService = ServiceLocator.instance().getElasticSearchService(); + esService.startNode(); + + // Wait 5s, to avoid error on existsIndex() + try { + Thread t = new Thread() { + @Override + public void run() { + super.run(); + try { + sleep(5000); + } + catch(InterruptedException e) { + // continue + } + catch(IllegalMonitorStateException e) { + e.printStackTrace(); + } + } + }; + t.start(); + t.join(); + } + catch(InterruptedException e) { + // continue + } + + + // Create indexed if need + CurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService(); + currencyIndexerService.createIndexIfNotExists(); + } + + /*public void stop() { + // Starting ES node + ElasticSearchService esService = ServiceLocator.instance().getElasticSearchService(); + esService.stopNode(); + }*/ + + /* -- protected methods -- */ + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java new file mode 100644 index 0000000000000000000000000000000000000000..8434a9eb3340b6bf044de67bd96f0bb8e01bee91 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/Configuration.java @@ -0,0 +1,284 @@ +package io.ucoin.ucoinj.elasticsearch.config; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.base.Charsets; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.nuiton.config.ApplicationConfig; +import org.nuiton.config.ApplicationConfigHelper; +import org.nuiton.config.ApplicationConfigProvider; +import org.nuiton.config.ArgumentsParserException; +import org.nuiton.util.version.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URL; +import java.util.Locale; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * Access to configuration options + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public class Configuration { + /** Logger. */ + private static final Logger log = LoggerFactory.getLogger(Configuration.class); + + /** + * Delegate application config. + */ + protected final ApplicationConfig applicationConfig; + + private static Configuration instance; + + public static Configuration instance() { + return instance; + } + + public static void setInstance(Configuration instance) { + Configuration.instance = instance; + + // Cascade the application config to the client module + io.ucoin.ucoinj.core.client.config.Configuration clientConfig = new io.ucoin.ucoinj.core.client.config.Configuration(instance.getApplicationConfig()); + io.ucoin.ucoinj.core.client.config.Configuration.setInstance(clientConfig); + } + + protected final String[] optionKeyToNotSave; + + protected File configFile; + + public Configuration(ApplicationConfig applicationConfig) { + super(); + this.applicationConfig = applicationConfig; + this.optionKeyToNotSave = null; + + // Override application version + initVersion(applicationConfig); + } + + public Configuration(String file, String... args) { + super(); + this.applicationConfig = new ApplicationConfig(); + this.applicationConfig.setEncoding(Charsets.UTF_8.name()); + this.applicationConfig.setConfigFileName(file); + + // get all config providers + Set<ApplicationConfigProvider> providers = + ApplicationConfigHelper.getProviders(null, + null, + null, + true); + + // load all default options + ApplicationConfigHelper.loadAllDefaultOption(applicationConfig, + providers); + + // Load actions + for (ApplicationConfigProvider provider : providers) { + applicationConfig.loadActions(provider.getActions()); + } + + // Define Alias + addAlias(applicationConfig); + + // Override application version + initVersion(applicationConfig); + + // get all transient and final option keys + Set<String> optionToSkip = + ApplicationConfigHelper.getTransientOptionKeys(providers); + + if (log.isDebugEnabled()) { + log.debug("Option that won't be saved: " + optionToSkip); + } + optionKeyToNotSave = optionToSkip.toArray(new String[optionToSkip.size()]); + + try { + applicationConfig.parse(args); + + } catch (ArgumentsParserException e) { + throw new TechnicalException(t("ucoinj.config.parse.error"), e); + } + + // TODO Review this, this is very dirty to do this... + File appBasedir = applicationConfig.getOptionAsFile( + ConfigurationOption.BASEDIR.getKey()); + + if (appBasedir == null) { + appBasedir = new File(""); + } + if (!appBasedir.isAbsolute()) { + appBasedir = new File(appBasedir.getAbsolutePath()); + } + if (appBasedir.getName().equals("..")) { + appBasedir = appBasedir.getParentFile().getParentFile(); + } + if (appBasedir.getName().equals(".")) { + appBasedir = appBasedir.getParentFile(); + } + if (log.isInfoEnabled()) { + log.info("Application basedir: " + appBasedir); + } + applicationConfig.setOption( + ConfigurationOption.BASEDIR.getKey(), + appBasedir.getAbsolutePath()); + + // Init other configuration + io.ucoin.ucoinj.core.client.config.Configuration coreConfig = new io.ucoin.ucoinj.core.client.config.Configuration(applicationConfig); + io.ucoin.ucoinj.core.client.config.Configuration.setInstance(coreConfig); + } + + /** + * Override the version default option, from the MANIFEST implementation version (if any) + * @param applicationConfig + */ + protected void initVersion(ApplicationConfig applicationConfig) { + // Override application version + String implementationVersion = this.getClass().getPackage().getSpecificationVersion(); + if (implementationVersion != null) { + applicationConfig.setDefaultOption( + ConfigurationOption.VERSION.getKey(), + implementationVersion); + } + } + + /** + * Add alias to the given ApplicationConfig. <p/> + * This method could be override to add specific alias + * + * @param applicationConfig + */ + protected void addAlias(ApplicationConfig applicationConfig) { + applicationConfig.addAlias("-h", "--option", ConfigurationOption.NODE_BMA_HOST.getKey()); + applicationConfig.addAlias("--host", "--option", ConfigurationOption.NODE_BMA_HOST.getKey()); + applicationConfig.addAlias("-p", "--option", ConfigurationOption.NODE_BMA_PORT.getKey()); + applicationConfig.addAlias("--port", "--option", ConfigurationOption.NODE_BMA_PORT.getKey()); + + applicationConfig.addAlias("-esh", "--option", ConfigurationOption.HOST.getKey()); + applicationConfig.addAlias("--es-host", "--option", ConfigurationOption.HOST.getKey()); + applicationConfig.addAlias("-esp", "--option", ConfigurationOption.PORT.getKey()); + applicationConfig.addAlias("--es-port", "--option", ConfigurationOption.PORT.getKey()); + } + + public File getConfigFile() { + if (configFile == null) { + File dir = getBasedir(); + if (dir == null || !dir.exists()) { + dir = new File(applicationConfig.getUserConfigDirectory()); + } + configFile = new File(dir, applicationConfig.getConfigFileName()); + } + return configFile; + } + + /** @return {@link ConfigurationOption#BASEDIR} value */ + public File getBasedir() { + File result = applicationConfig.getOptionAsFile(ConfigurationOption.BASEDIR.getKey()); + return result; + } + + /** @return {@link ConfigurationOption#DATA_DIRECTORY} value */ + public File getDataDirectory() { + File result = applicationConfig.getOptionAsFile(ConfigurationOption.DATA_DIRECTORY.getKey()); + return result; + } + + public ApplicationConfig getApplicationConfig() { + return applicationConfig; + } + + public Version getVersion() { + return applicationConfig.getOptionAsVersion(ConfigurationOption.VERSION.getKey()); + } + + public File getI18nDirectory() { + return applicationConfig.getOptionAsFile( + ConfigurationOption.I18N_DIRECTORY.getKey()); + } + + public Locale getI18nLocale() { + return applicationConfig.getOptionAsLocale( + ConfigurationOption.I18N_LOCALE.getKey()); + } + + public void setI18nLocale(Locale locale) { + applicationConfig.setOption(ConfigurationOption.I18N_LOCALE.getKey(), locale.toString()); + } + + public String getNodeBmaHost() { + return applicationConfig.getOption(ConfigurationOption.NODE_BMA_HOST.getKey()); + } + + public int getNodeBmaPort() { + return applicationConfig.getOptionAsInt(ConfigurationOption.NODE_BMA_PORT.getKey()); + } + + public String getHost() { + return applicationConfig.getOption(ConfigurationOption.HOST.getKey()); + } + + public int getPort() { + return applicationConfig.getOptionAsInt(ConfigurationOption.PORT.getKey()); + } + + public boolean isEmbedded() { + return applicationConfig.getOptionAsBoolean(ConfigurationOption.EMBEDDED_ENABLE.getKey()); + } + + public void setEmbedded(boolean embeddedNode) { + applicationConfig.setOption(ConfigurationOption.EMBEDDED_ENABLE.getKey(), Boolean.toString(embeddedNode)); + } + + public boolean isLocal() { + return applicationConfig.getOptionAsBoolean(ConfigurationOption.LOCAL_ENABLE.getKey()); + } + + public boolean isHttpEnable() { + return applicationConfig.getOptionAsBoolean(ConfigurationOption.HTTP_ENABLE.getKey()); + } + + public String getClusterName() { + return applicationConfig.getOption(ConfigurationOption.CLUSTER_NAME.getKey()); + } + + public int getTaskExecutorQueueCapacity() { + return applicationConfig.getOptionAsInt(ConfigurationOption.TASK_EXECUTOR_QUEUE_CAPACITY.getKey()); + } + + public int getTaskExecutorTimeToIdle() { + return applicationConfig.getOptionAsInt(ConfigurationOption.TASK_EXECUTOR_TIME_TO_IDLE.getKey()); + } + + public boolean isIndexBulkEnable() { + return applicationConfig.getOptionAsBoolean(ConfigurationOption.INDEX_BULK_ENABLE.getKey()); + } + + public int getIndexBulkSize() { + return applicationConfig.getOptionAsInt(ConfigurationOption.INDEX_BULK_SIZE.getKey()); + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationAction.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationAction.java new file mode 100644 index 0000000000000000000000000000000000000000..13572ec11812976ecd7bbb8213dfbd7ecbbb326e --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationAction.java @@ -0,0 +1,59 @@ +package io.ucoin.ucoinj.elasticsearch.config; + +/* + * #%L + * SIH-Adagio :: Shared + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.elasticsearch.action.HelpAction; +import io.ucoin.ucoinj.elasticsearch.action.IndexerAction; +import io.ucoin.ucoinj.elasticsearch.action.NodeAction; +import org.nuiton.config.ConfigActionDef; + +public enum ConfigurationAction implements ConfigActionDef { + + HELP(HelpAction.class.getName() + "#show", "--help"), + + START(NodeAction.class.getName() + "#start", "start"), + + INDEX_BLOCKS(IndexerAction.class.getName() + "#indexLastBlocks", "index"), + + RESET_BLOCKS(IndexerAction.class.getName() + "#resetAllBlocks", "reset-data"); + + public String action; + public String[] aliases; + + private ConfigurationAction(String action, String... aliases) { + this.action = action; + this.aliases = aliases; + } + + @Override + public String getAction() { + return action; + } + + @Override + public String[] getAliases() { + return aliases; + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java new file mode 100644 index 0000000000000000000000000000000000000000..f502fecb716f6134b89b35bd8921a81263fa8e3b --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationOption.java @@ -0,0 +1,259 @@ +package io.ucoin.ucoinj.elasticsearch.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationOption.java 1441 2013-12-09 20:13:47Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ConfigOptionDef; +import org.nuiton.util.Version; + +import java.io.File; +import java.net.URL; +import java.util.Locale; + +import static org.nuiton.i18n.I18n.n; + +/** + * All application configuration options. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public enum ConfigurationOption implements ConfigOptionDef { + + + // ------------------------------------------------------------------------// + // -- READ-ONLY OPTIONS ---------------------------------------------------// + // ------------------------------------------------------------------------// + + + BASEDIR( + "ucoinj.basedir", + n("ucoinj.config.option.basedir.description"), + "${user.home}/.ucoinj-elasticsearch", + File.class), + + DATA_DIRECTORY( + "ucoinj.data.directory", + n("ucoinj.config.option.data.directory.description"), + "${ucoinj.basedir}/data", + File.class), + + I18N_DIRECTORY( + "ucoinj.i18n.directory", + n("ucoinj.config.option.i18n.directory.description"), + "${ucoinj.basedir}/i18n", + File.class), + + VERSION( + "ucoinj.version", + n("ucoinj.config.option.version.description"), + "1.0", + Version.class), + + // ------------------------------------------------------------------------// + // -- READ-WRITE OPTIONS ---------------------------------------------------// + // ------------------------------------------------------------------------// + + I18N_LOCALE( + "ucoinj.i18n.locale", + n("ucoinj.config.option.i18n.locale.description"), + Locale.FRANCE.getCountry(), + Locale.class, + false), + + NODE_BMA_HOST( + "ucoinj.node.host", + n("ucoinj.config.option.node.host.description"), + "metab.ucoin.io", + String.class, + false), + + NODE_BMA_PORT( + "ucoinj.node.port", + n("ucoinj.config.option.node.port.description"), + "9201", + Integer.class, + false), + + NODE_BMA_URL( + "ucoinj.node.url", + n("ucoinj.config.option.node.port.description"), + "${ucoinj.node.protocol}://${ucoinj.node.host}:${ucoinj.node.port}", + URL.class, + false), + + HOST( + "ucoinj.elasticsearch.host", + n("ucoinj.config.option.elasticsearch.host.description"), + "localhost", + String.class, + false), + + PORT( + "ucoinj.elasticsearch.port", + n("ucoinj.config.option.node.elasticsearch.port.description"), + "9300", + Integer.class, + false), + + EMBEDDED_ENABLE( + "ucoinj.elasticsearch.embedded.enable", + n("ucoinj.config.option.elasticsearch.embedded.enable.description"), + "false", + Boolean.class, + false), + + LOCAL_ENABLE( + "ucoinj.elasticsearch.local", + n("ucoinj.config.option.elasticsearch.local.description"), + "false", + Boolean.class, + false), + + HTTP_ENABLE( + "ucoinj.elasticsearch.http.enable", + n("ucoinj.config.option.node.elasticsearch.http.enable.description"), + "true", + Boolean.class, + false), + + CLUSTER_NAME( + "ucoinj.elasticsearch.cluster.name", + n("ucoinj.config.option.elasticsearch.cluster.name.description"), + "ucoinj-elasticsearch", + String.class, + false), + + INDEX_BULK_ENABLE( + "ucoinj.elasticsearch.bulk.enable", + n("ucoinj.config.option.elasticsearch.bulk.enable.description"), + "true", + Boolean.class, + false), + + INDEX_BULK_SIZE( + "ucoinj.elasticsearch.bulk.size", + n("ucoinj.config.option.elasticsearch.bulk.size.description"), + "1000", + Integer.class, + false), + + TASK_EXECUTOR_QUEUE_CAPACITY( + "ucoinj.elasticsearch.tasks.queueCapacity", + n("ucoinj.config.option.tasks.queueCapacity.description"), + "50", + Integer.class, + false), + + TASK_EXECUTOR_TIME_TO_IDLE( + "ucoinj.elasticsearch.tasks.timeToIdle", + "ucoinj.elasticsearch.tasks.timeToIdle.description", + "180", // 180s = 3min + Integer.class, + false) + ; + + /** Configuration key. */ + private final String key; + + /** I18n key of option description */ + private final String description; + + /** Type of option */ + private final Class<?> type; + + /** Default value of option. */ + private String defaultValue; + + /** Flag to not keep option value on disk */ + private boolean isTransient; + + /** Flag to not allow option value modification */ + private boolean isFinal; + + ConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type, + boolean isTransient) { + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + this.type = type; + this.isTransient = isTransient; + this.isFinal = isTransient; + } + + ConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type) { + this(key, description, defaultValue, type, true); + } + + @Override + public String getKey() { + return key; + } + + @Override + public Class<?> getType() { + return type; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } + + @Override + public boolean isTransient() { + return isTransient; + } + + @Override + public boolean isFinal() { + return isFinal; + } + + @Override + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public void setTransient(boolean newValue) { + // not used + } + + @Override + public void setFinal(boolean newValue) { + // not used + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationProvider.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..85e01d4fdf057577c7566cc275b098a9fe2fa10b --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/config/ConfigurationProvider.java @@ -0,0 +1,61 @@ +package io.ucoin.ucoinj.elasticsearch.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationProvider.java 1418 2013-12-01 21:18:22Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationProvider.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ApplicationConfigProvider; +import org.nuiton.config.ConfigActionDef; +import org.nuiton.config.ConfigOptionDef; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l; + +/** + * Config provider (for site generation). + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + */ +public class ConfigurationProvider implements ApplicationConfigProvider { + + @Override + public String getName() { + return "ucoinj"; + } + + @Override + public String getDescription(Locale locale) { + return l(locale, "ucoinj-elasticsearch.config"); + } + + @Override + public ConfigOptionDef[] getOptions() { + return ConfigurationOption.values(); + } + + @Override + public ConfigActionDef[] getActions() { + return ConfigurationAction.values(); + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/Currency.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/Currency.java new file mode 100644 index 0000000000000000000000000000000000000000..e89d2b24a22a5df31cdae2b83254ca0b2810deab --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/Currency.java @@ -0,0 +1,109 @@ +package io.ucoin.ucoinj.elasticsearch.model; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.io.Serializable; + +/** + * Created by eis on 05/02/15. + */ +public class Currency implements Serializable { + + private String currencyName; + private Integer membersCount; + private String firstBlockSignature; + private Long lastUD; + private BlockchainParameters parameters; + private Peer peers[]; + + private String[] tags; + private String senderPubkey; + + public String getCurrencyName() { + return currencyName; + } + + public void setCurrencyName(String currencyName) { + this.currencyName = currencyName; + } + + public Integer getMembersCount() { + return membersCount; + } + + public void setMembersCount(Integer membersCount) { + this.membersCount = membersCount; + } + + public String getFirstBlockSignature() { + return firstBlockSignature; + } + + public void setFirstBlockSignature(String firstBlockSignature) { + this.firstBlockSignature = firstBlockSignature; + } + + public Long getLastUD() { + return lastUD; + } + + public void setLastUD(Long lastUD) { + this.lastUD = lastUD; + } + + public BlockchainParameters getParameters() { + return parameters; + } + + public void setParameters(BlockchainParameters parameters) { + this.parameters = parameters; + } + + public Peer[] getPeers() { + return peers; + } + + public void setPeers(Peer[] peers) { + this.peers = peers; + } + + public String[] getTags() { + return tags; + } + + public void setTags(String[] tags) { + this.tags = tags; + } + + public String getSenderPubkey() { + return senderPubkey; + } + + public void setSenderPubkey(String senderPubkey) { + this.senderPubkey = senderPubkey; + } +} \ No newline at end of file diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/SearchResult.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/SearchResult.java new file mode 100644 index 0000000000000000000000000000000000000000..e7013ad2145c3ef9bd0d4a37fb50304eaef44361 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/model/SearchResult.java @@ -0,0 +1,63 @@ +package io.ucoin.ucoinj.elasticsearch.model; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Peer; + +import java.io.Serializable; + +/** + * Created by eis on 05/02/15. + */ +public class SearchResult implements Serializable { + + private String id; + private String value; + private String type; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} \ No newline at end of file diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BaseIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BaseIndexerService.java new file mode 100644 index 0000000000000000000000000000000000000000..9c44d15c696c1b5c08872ce6363d7bb8d8a218dc --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BaseIndexerService.java @@ -0,0 +1,110 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; + +/** + * Created by Benoit on 08/04/2015. + */ +public abstract class BaseIndexerService implements Bean, InitializingBean, Closeable { + + private static final Logger log = LoggerFactory.getLogger(BaseIndexerService.class); + private ElasticSearchService elasticSearchService; + + public BaseIndexerService() { + } + + @Override + public void afterPropertiesSet() throws Exception { + this.elasticSearchService = ServiceLocator.instance().getElasticSearchService(); + } + + @Override + public void close() throws IOException { + this.elasticSearchService = null; + } + + /* -- protected methods -- */ + + protected Client getClient() { + return elasticSearchService.getClient(); + } + + protected ObjectMapper getObjectMapper() { + return elasticSearchService.getObjectMapper(); + } + + protected boolean existsIndex(String indexes) { + IndicesExistsRequestBuilder requestBuilder = getClient().admin().indices().prepareExists(indexes); + IndicesExistsResponse response = requestBuilder.execute().actionGet(); + + return response.isExists(); + } + + protected void deleteIndexIfExists(String indexName){ + if (!existsIndex(indexName)) { + return; + } + log.info(String.format("Deleting index [%s]", indexName)); + + DeleteIndexRequestBuilder deleteIndexRequestBuilder = getClient().admin().indices().prepareDelete(indexName); + deleteIndexRequestBuilder.execute().actionGet(); + } + + protected XContentBuilder createDefaultAnalyzer() { + try { + XContentBuilder analyzer = XContentFactory.jsonBuilder().startObject().startObject("analyzer") + .startObject("custom_french_analyzer") + .field("tokenizer", "letter") + .field("filter", "asciifolding", "lowercase", "french_stem", "elision", "stop") + .endObject() + .startObject("tag_analyzer") + .field("tokenizer", "keyword") + .field("filter", "asciifolding", "lowercase") + .endObject() + .endObject().endObject(); + + return analyzer; + } catch(IOException e) { + throw new TechnicalException("Error while preparing default index analyzer: " + e.getMessage(), e); + } + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java new file mode 100644 index 0000000000000000000000000000000000000000..963376a15233e93ddfd40ccc279d9bedeb0d0401 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerService.java @@ -0,0 +1,868 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.bma.EndpointProtocol; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.bma.gson.JsonAttributeParser; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteService; +import io.ucoin.ucoinj.core.client.service.exception.HttpBadRequestException; +import io.ucoin.ucoinj.core.client.service.exception.JsonSyntaxException; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import io.ucoin.ucoinj.core.model.ProgressionModelImpl; +import io.ucoin.ucoinj.core.util.CollectionUtils; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.service.exception.DuplicateIndexIdException; +import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequestBuilder; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.client.Client; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHitField; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.metrics.max.Max; +import org.elasticsearch.search.highlight.HighlightField; +import org.elasticsearch.search.sort.SortOrder; +import org.nuiton.i18n.I18n; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.*; + +/** + * Created by Benoit on 30/03/2015. + */ +public class BlockIndexerService extends BaseIndexerService { + + private static final Logger log = LoggerFactory.getLogger(BlockIndexerService.class); + + public static final String INDEX_TYPE_BLOCK = "block"; + + private static final int SYNC_MISSING_BLOCK_MAX_RETRY = 5; + + private CurrencyIndexerService currencyIndexerService; + + private BlockchainRemoteService blockchainService; + + private Gson gson; + + private Configuration config; + + public BlockIndexerService() { + gson = GsonUtils.newBuilder().create(); + } + + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService(); + blockchainService = ServiceLocator.instance().getBlockchainRemoteService(); + config = Configuration.instance(); + } + + @Override + public void close() throws IOException { + super.close(); + currencyIndexerService = null; + blockchainService = null; + config = null; + gson = null; + } + + public void indexLastBlocks(Peer peer) { + indexLastBlocks(peer, new ProgressionModelImpl()); + } + + public void indexLastBlocks(Peer peer, ProgressionModel progressionModel) { + boolean bulkIndex = config.isIndexBulkEnable(); + + progressionModel.setStatus(ProgressionModel.Status.RUNNING); + progressionModel.setTotal(100); + long timeStart = System.currentTimeMillis(); + + try { + // Get the currency name from node + BlockchainParameters parameter = blockchainService.getParameters(peer); + if (parameter == null) { + progressionModel.setStatus(ProgressionModel.Status.FAILED); + log.error(String.format("Could not connect to node [%s:%s]", + config.getNodeBmaHost(), config.getNodeBmaPort())); + return; + } + String currencyName = parameter.getCurrency(); + + progressionModel.setTask(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.task", currencyName, peer.getHost(), peer.getPort())); + log.info(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.task", + currencyName, config.getNodeBmaHost(), config.getNodeBmaPort())); + + // Create index currency if need + currencyIndexerService.createIndexIfNotExists(); + + Currency currency = currencyIndexerService.getCurrencyById(currencyName); + if (currency == null) { + currencyIndexerService.indexCurrencyFromPeer(peer); + } + + // Check if index exists + createIndexIfNotExists(currencyName); + + // Then index all blocks + BlockchainBlock currentBlock = blockchainService.getCurrentBlock(peer); + + if (currentBlock != null) { + int maxBlockNumber = currentBlock.getNumber(); + + // Get the last indexed block number + int startNumber = 0; + + int currentBlockNumber = -1; + BlockchainBlock indexedCurrentBlock = getCurrentBlock(currencyName); + if (indexedCurrentBlock != null && indexedCurrentBlock.getNumber() != null) { + currentBlockNumber = indexedCurrentBlock.getNumber(); + + // Previous block could have been not indexed : so start at the max(number) + indexedCurrentBlock = getBlockById(currencyName, currentBlockNumber); + // If exists on blockchain, so can use it + if (indexedCurrentBlock != null) { + startNumber = currentBlockNumber + 1; + } + } + + // Before to start at '0' (first block), try to use the max(number) + if (startNumber <= 1 ){ + startNumber = getMaxBlockNumber(currencyName) + 1; + } + + if (startNumber <= maxBlockNumber) { + Collection<String> missingBlocks = bulkIndex + ? indexBlocksUsingBulk(peer, currencyName, startNumber, maxBlockNumber, progressionModel) + : indexBlocksNoBulk(peer, currencyName, startNumber, maxBlockNumber, progressionModel); + + + // If some blocks are missing, try to get it using other peers + if (CollectionUtils.isNotEmpty(missingBlocks)) { + progressionModel.setTask(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.otherPeers.task", currencyName)); + missingBlocks = indexMissingBlocksFromOtherPeers(peer, currentBlock, missingBlocks, 1); + } + + if (CollectionUtils.isEmpty(missingBlocks)) { + log.info(String.format("All blocks indexed [%s ms]", (System.currentTimeMillis() - timeStart))); + progressionModel.setStatus(ProgressionModel.Status.SUCCESS); + } + else { + log.warn(String.format("Could not indexed all blocks. Missing %s blocks.", missingBlocks.size())); + progressionModel.setStatus(ProgressionModel.Status.FAILED); + } + } + else { + if (log.isDebugEnabled()) { + log.debug(String.format("Current block from peer [%s:%s] is #%s. Index is up to date.", peer.getHost(), peer.getPort(), maxBlockNumber)); + } + progressionModel.setStatus(ProgressionModel.Status.SUCCESS); + } + } + } catch(Exception e) { + log.error("Error during indexation: " + e.getMessage(), e); + progressionModel.setStatus(ProgressionModel.Status.FAILED); + } + } + + public void deleteIndex(String currencyName) { + deleteIndexIfExists(currencyName); + } + + public boolean existsIndex(String currencyName) { + return super.existsIndex(currencyName); + } + + public void createIndexIfNotExists(String currencyName) { + if (!existsIndex(currencyName)) { + createIndex(currencyName); + } + } + + public void createIndex(String currencyName) { + log.info(String.format("Creating index [%s]", currencyName)); + + CreateIndexRequestBuilder createIndexRequestBuilder = getClient().admin().indices().prepareCreate(currencyName); + Settings indexSettings = Settings.settingsBuilder() + .put("number_of_shards", 1) + .put("number_of_replicas", 1) + .put("analyzer", createDefaultAnalyzer()) + .build(); + createIndexRequestBuilder.setSettings(indexSettings); + createIndexRequestBuilder.addMapping(INDEX_TYPE_BLOCK, createIndexMapping()); + CreateIndexResponse response = createIndexRequestBuilder.execute().actionGet(); + } + + public void createBlock(BlockchainBlock block) throws DuplicateIndexIdException { + ObjectUtils.checkNotNull(block, "block could not be null") ; + ObjectUtils.checkNotNull(block.getCurrency(), "block attribute 'currency' could not be null"); + ObjectUtils.checkNotNull(block.getNumber(), "block attribute 'number' could not be null"); + + BlockchainBlock existingBlock = getBlockById(block.getCurrency(), block.getNumber()); + if (existingBlock != null) { + throw new DuplicateIndexIdException(String.format("Block with number [%s] already exists.", block.getNumber())); + } + + indexBlock(block, false); + } + + /** + * Create or update a block, depending on its existence and hash + * @param block + * @param updateWhenSameHash if true, always update an existing block. If false, update only if hash has changed. + * @param wait wait indexation end + * @throws DuplicateIndexIdException + */ + public void saveBlock(BlockchainBlock block, boolean updateWhenSameHash, boolean wait) throws DuplicateIndexIdException { + ObjectUtils.checkNotNull(block, "block could not be null") ; + ObjectUtils.checkNotNull(block.getCurrency(), "block attribute 'currency' could not be null"); + ObjectUtils.checkNotNull(block.getNumber(), "block attribute 'number' could not be null"); + ObjectUtils.checkNotNull(block.getHash(), "block attribute 'hash' could not be null"); + + BlockchainBlock existingBlock = getBlockById(block.getCurrency(), block.getNumber()); + + // Currency not exists, or has changed, so create it + if (existingBlock == null) { + if (log.isTraceEnabled()) { + log.trace(String.format("Insert new block [%s]", block.getNumber())); + } + + // Create new block + indexBlock(block, wait); + } + + // Exists, so check the owner signature + else { + boolean doUpdate = false; + if (updateWhenSameHash) { + doUpdate = true; + if (log.isTraceEnabled() && doUpdate) { + log.trace(String.format("Update block [%s]", block.getNumber())); + } + } + else { + doUpdate = !StringUtils.equals(existingBlock.getHash(), block.getHash()); + if (log.isTraceEnabled()) { + if (doUpdate) { + log.trace(String.format("Update block [%s]: hash has been changed, old=[%s] new=[%s]", block.getNumber(), existingBlock.getHash(), block.getHash())); + } + else { + log.trace(String.format("Skipping update block [%s]: hash is up to date.", block.getNumber())); + } + } + } + + // Update existing block + if (doUpdate) { + indexBlock(block, wait); + } + } + } + + public void indexBlock(BlockchainBlock block, boolean wait) { + ObjectUtils.checkNotNull(block); + ObjectUtils.checkArgument(StringUtils.isNotBlank(block.getCurrency())); + ObjectUtils.checkNotNull(block.getHash()); + ObjectUtils.checkNotNull(block.getNumber()); + + // Serialize into JSON + // WARN: must use GSON, to have same JSON result (e.g identities and joiners field must be converted into String) + String json = gson.toJson(block); + + // Preparing indexation + IndexRequestBuilder indexRequest = getClient().prepareIndex(block.getCurrency(), INDEX_TYPE_BLOCK) + .setId(block.getNumber().toString()) + .setSource(json); + + // Execute indexation + ActionFuture<IndexResponse> futureResponse = indexRequest + .setRefresh(true) + .execute(); + + if (wait) { + futureResponse.actionGet(); + } + } + + /** + * + * @param currencyName + * @param number the block number + * @param json block as JSON + */ + public void indexBlockAsJson(String currencyName, int number, byte[] json, boolean refresh, boolean wait) { + ObjectUtils.checkNotNull(json); + ObjectUtils.checkArgument(json.length > 0); + + // Preparing indexation + IndexRequestBuilder indexRequest = getClient().prepareIndex(currencyName, INDEX_TYPE_BLOCK) + .setId(String.valueOf(number)) + .setSource(json); + + // Execute indexation + if (!wait) { + indexRequest + .setRefresh(refresh) + .execute(); + } + else { + indexRequest + .setRefresh(refresh) + .execute().actionGet(); + } + } + + /** + * + * @param currentBlock + */ + public void indexCurrentBlock(BlockchainBlock currentBlock, boolean wait) { + ObjectUtils.checkNotNull(currentBlock); + ObjectUtils.checkArgument(StringUtils.isNotBlank(currentBlock.getCurrency())); + ObjectUtils.checkNotNull(currentBlock.getHash()); + ObjectUtils.checkNotNull(currentBlock.getNumber()); + + // Serialize into JSON + // WARN: must use GSON, to have same JSON result (e.g identities and joiners field must be converted into String) + String json = gson.toJson(currentBlock); + + indexCurrentBlockAsJson(currentBlock.getCurrency(), json.getBytes(), true, wait); + } + + /** + * + * @param currencyName + * @param currentBlockJson block as JSON + */ + public void indexCurrentBlockAsJson(String currencyName, byte[] currentBlockJson, boolean refresh, boolean wait) { + ObjectUtils.checkNotNull(currentBlockJson); + ObjectUtils.checkArgument(currentBlockJson.length > 0); + + // Preparing indexation + IndexRequestBuilder indexRequest = getClient().prepareIndex(currencyName, INDEX_TYPE_BLOCK) + .setId("current") + .setSource(currentBlockJson); + + // Execute indexation + if (!wait) { + boolean acceptedInPool = false; + while(!acceptedInPool) + try { + indexRequest + .setRefresh(refresh) + .execute(); + acceptedInPool = true; + } + catch(EsRejectedExecutionException e) { + // not accepted, so wait + try { + Thread.sleep(1000); // 1s + } + catch(InterruptedException e2) { + // silent + } + } + + } else { + indexRequest + .setRefresh(refresh) + .execute().actionGet(); + } + } + + public List<BlockchainBlock> findBlocksByHash(String currencyName, String query) { + String[] queryParts = query.split("[\\t ]+"); + + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(currencyName) + .setTypes(INDEX_TYPE_BLOCK) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // If only one term, search as prefix + if (queryParts.length == 1) { + searchRequest.setQuery(QueryBuilders.prefixQuery("hash", query)); + } + + // If more than a word, search on terms match + else { + searchRequest.setQuery(QueryBuilders.matchQuery("hash", query)); + } + + // Sort as score/memberCount + searchRequest.addSort("_score", SortOrder.DESC) + .addSort("number", SortOrder.DESC); + + // Highlight matched words + searchRequest.setHighlighterTagsSchema("styled") + .addHighlightedField("hash") + .addFields("hash") + .addFields("*", "_source"); + + // Execute query + SearchResponse searchResponse = searchRequest.execute().actionGet(); + + // Read query result + return toBlocks(searchResponse, true); + } + + public int getMaxBlockNumber(String currencyName) { + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(currencyName) + .setTypes(INDEX_TYPE_BLOCK) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // Get max(number) + searchRequest.addAggregation(AggregationBuilders.max("max_number").field("number")); + + // Execute query + SearchResponse searchResponse = searchRequest.execute().actionGet(); + + // Read query result + Max result = searchResponse.getAggregations().get("max_number"); + if (result == null) { + return -1; + } + + return (result.getValue() == Double.NEGATIVE_INFINITY) + ? -1 + : (int)result.getValue(); + } + + public BlockchainBlock getBlockById(String currencyName, int number) { + return getBlockByIdStr(currencyName, String.valueOf(number)); + } + + public BlockchainBlock getCurrentBlock(String currencyName) { + return getBlockByIdStr(currencyName, "current"); + } + + /* -- Internal methods -- */ + + + public XContentBuilder createIndexMapping() { + try { + XContentBuilder mapping = XContentFactory.jsonBuilder() + .startObject() + .startObject(INDEX_TYPE_BLOCK) + .startObject("properties") + + // block number + .startObject("number") + .field("type", "integer") + .endObject() + + // hash + .startObject("hash") + .field("type", "string") + .endObject() + + // membercount + .startObject("memberCount") + .field("type", "integer") + .endObject() + + // membersChanges + .startObject("membersChanges") + .field("type", "string") + .endObject() + + // identities: + //.startObject("identities") + //.endObject() + + .endObject() + .endObject().endObject(); + + return mapping; + } + catch(IOException ioe) { + throw new TechnicalException("Error while getting mapping for block index: " + ioe.getMessage(), ioe); + } + } + + public BlockchainBlock getBlockByIdStr(String currencyName, String blockId) { + + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(currencyName) + .setTypes(INDEX_TYPE_BLOCK) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // If more than a word, search on terms match + searchRequest.setQuery(QueryBuilders.matchQuery("_id", blockId)); + + // Execute query + try { + SearchResponse searchResponse = searchRequest.execute().actionGet(); + List<BlockchainBlock> currencies = toBlocks(searchResponse, false); + if (CollectionUtils.isEmpty(currencies)) { + return null; + } + + // Return the unique result + return CollectionUtils.extractSingleton(currencies); + } + catch(JsonSyntaxException e) { + throw new TechnicalException(String.format("Error while getting indexed block #%s for currency [%s]", blockId, currencyName), e); + } + + } + + protected List<BlockchainBlock> toBlocks(SearchResponse response, boolean withHighlight) { + // Read query result + SearchHit[] searchHits = response.getHits().getHits(); + List<BlockchainBlock> result = Lists.newArrayListWithCapacity(searchHits.length); + for (SearchHit searchHit : searchHits) { + BlockchainBlock block; + if (searchHit.source() != null) { + String jsonString = new String(searchHit.source()); + try { + block = GsonUtils.newBuilder().create().fromJson(jsonString, BlockchainBlock.class); + } catch(Exception e) { + if (log.isDebugEnabled()) { + log.debug("Error while parsing block from JSON:\n" + jsonString); + } + throw new JsonSyntaxException("Error while read block from JSON: " + e.getMessage(), e); + } + } + else { + block = new BlockchainBlock(); + SearchHitField field = searchHit.getFields().get("hash"); + block.setHash((String) field.getValue()); + } + result.add(block); + + // If possible, use highlights + if (withHighlight) { + Map<String, HighlightField> fields = searchHit.getHighlightFields(); + for (HighlightField field : fields.values()) { + String blockNameHighLight = field.getFragments()[0].string(); + block.setHash(blockNameHighLight); + } + } + } + + return result; + } + + + public Collection<String> indexBlocksNoBulk(Peer peer, String currencyName, int firstNumber, int lastNumber, ProgressionModel progressionModel) { + Set<String> missingBlockNumbers = new LinkedHashSet<>(); + + for (int curNumber = firstNumber; curNumber <= lastNumber; curNumber++) { + if (curNumber != 0 && curNumber % 1000 == 0) { + + // Check is stopped + if (progressionModel.isCancel()) { + progressionModel.setStatus(ProgressionModel.Status.STOPPED); + if (log.isInfoEnabled()) { + log.info(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.stopped")); + } + return missingBlockNumbers; + } + + // Report progress + reportIndexBlocksProgress(progressionModel, firstNumber, lastNumber, curNumber); + } + + try { + String blockAsJson = blockchainService.getBlockAsJson(peer, curNumber); + indexBlockAsJson(currencyName, curNumber, blockAsJson.getBytes(), false, true /*wait*/); + + // If last block + if (curNumber == lastNumber - 1) { + // update the current block + indexCurrentBlockAsJson(currencyName, blockAsJson.getBytes(), true, true /*wait*/); + } + } + catch(Throwable t) { + log.debug(String.format("Error while getting block #%s: %s. Skipping this block.", curNumber, t.getMessage())); + missingBlockNumbers.add(String.valueOf(curNumber)); + } + } + + return missingBlockNumbers; + } + + public Collection<String> indexBlocksUsingBulk(Peer peer, String currencyName, int firstNumber, int lastNumber, ProgressionModel progressionModel) { + Set<String> missingBlockNumbers = new LinkedHashSet<>(); + + Client client = getClient(); + boolean debug = log.isDebugEnabled(); + + int batchSize = config.getIndexBulkSize(); + JsonAttributeParser blockNumberParser = new JsonAttributeParser("number"); + + for (int batchFirstNumber = firstNumber; batchFirstNumber < lastNumber; ) { + // Check if stop (e.g. ask by user) + if (progressionModel.isCancel()) { + progressionModel.setStatus(ProgressionModel.Status.STOPPED); + if (log.isInfoEnabled()) { + log.info(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.stopped")); + } + return missingBlockNumbers; + } + + String[] blocksAsJson = null; + try { + blocksAsJson = blockchainService.getBlocksAsJson(peer, batchSize, batchFirstNumber); + } catch(HttpBadRequestException e) { + if (log.isDebugEnabled()) { + log.debug(String.format("Error while getting blocks from #%s (count=%s): %s. Skipping blocks.", batchFirstNumber, batchSize, e.getMessage())); + } + } + + // Peer send no blocks + if (CollectionUtils.isEmpty(blocksAsJson)) { + + // Add range to missing blocks + missingBlockNumbers.add(batchFirstNumber + "-" + (batchFirstNumber+batchSize)); + + // Update counter + batchFirstNumber += batchSize; + } + + // Process received blocks + else { + BulkRequestBuilder bulkRequest = client.prepareBulk(); + for (String blockAsJson : blocksAsJson) { + int itemNumber = blockNumberParser.getValueAsInt(blockAsJson); + + // update curNumber with max number; + if (itemNumber > batchFirstNumber) { + batchFirstNumber = itemNumber; + } + + // Add to bulk + bulkRequest.add(client.prepareIndex(currencyName, INDEX_TYPE_BLOCK, String.valueOf(itemNumber)) + .setRefresh(false) + .setSource(blockAsJson) + ); + + // If last block : also update the current block + if (itemNumber == lastNumber) { + bulkRequest.add(client.prepareIndex(currencyName, INDEX_TYPE_BLOCK, "current") + .setRefresh(true) + .setSource(blockAsJson) + ); + } + } + + if (bulkRequest.numberOfActions() > 0) { + + // Flush the bulk if not empty + BulkResponse bulkResponse = bulkRequest.get(); + + // If failures, continue but save missing blocks + if (bulkResponse.hasFailures()) { + // process failures by iterating through each bulk response item + for (BulkItemResponse itemResponse : bulkResponse) { + boolean skip = !itemResponse.isFailed() + || Objects.equal("current", itemResponse.getId()) + || missingBlockNumbers.contains(Integer.parseInt(itemResponse.getId())); + if (!skip) { + int itemNumber = Integer.parseInt(itemResponse.getId()); + if (debug) { + log.debug(String.format("Error while getting block #%s: %s. Skipping this block.", itemNumber, itemResponse.getFailureMessage())); + } + missingBlockNumbers.add(itemResponse.getId()); + } + } + } + } + } + + // Report progress + reportIndexBlocksProgress(progressionModel, firstNumber, lastNumber, batchFirstNumber); + + } + + return missingBlockNumbers; + } + + /** + * Get blocks from other peers. + * WARNING: given list must be ordered (with ascending order) + * @param peer + * @param currentBlock + * @param sortedMissingBlocks + * @param tryCounter + */ + protected Collection<String> indexMissingBlocksFromOtherPeers(Peer peer, BlockchainBlock currentBlock, Collection<String> sortedMissingBlocks, int tryCounter) { + ObjectUtils.checkNotNull(peer); + ObjectUtils.checkNotNull(currentBlock); + ObjectUtils.checkNotNull(currentBlock.getHash()); + ObjectUtils.checkNotNull(currentBlock.getNumber()); + ObjectUtils.checkArgument(CollectionUtils.isNotEmpty(sortedMissingBlocks)); + ObjectUtils.checkArgument(tryCounter >= 1); + + NetworkRemoteService networkRemoteService = ServiceLocator.instance().getNetworkRemoteService(); + BlockchainRemoteService blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + String currencyName = currentBlock.getCurrency(); + boolean debug = log.isDebugEnabled(); + + Set<String> newMissingBlocks = new LinkedHashSet<>(); + newMissingBlocks.addAll(sortedMissingBlocks); + + if (debug) { + log.debug(String.format("Missing blocks are: %s", newMissingBlocks.toString())); + } + + // Select other peers, in filtering on the same blockchain version + + // TODO : a activer quand les peers seront bien mis à jour (UP/DOWN, block, hash...) + //List<Peer> otherPeers = networkRemoteService.findPeers(peer, "UP", EndpointProtocol.BASIC_MERKLED_API, + // currentBlock.getNumber(), currentBlock.getHash()); + List<Peer> otherPeers = networkRemoteService.findPeers(peer, null, EndpointProtocol.BASIC_MERKLED_API, + null, null); + + for(Peer childPeer: otherPeers) { + if (log.isInfoEnabled()) { + log.info(String.format("Trying to get missing blocks from other peer [%s:%s]...", childPeer.getHost(), childPeer.getPort())); + } + try { + for(String blockNumberStr: ImmutableSet.copyOf(sortedMissingBlocks)) { + + boolean isBlockRange = blockNumberStr.indexOf('-') != -1; + + // Get using bulk + if (isBlockRange) { + String[] rangeParts = blockNumberStr.split("-"); + int firstNumber = Integer.parseInt(rangeParts[0]); + int lastNumber = Integer.parseInt(rangeParts[1]); + + // Remove current blocks range + newMissingBlocks.remove(blockNumberStr); + + Collection<String> bulkMissingBlocks = indexBlocksUsingBulk(childPeer, currencyName, firstNumber, lastNumber, new ProgressionModelImpl()); + + // Re add if new missing blocks + if (CollectionUtils.isNotEmpty(bulkMissingBlocks)) { + newMissingBlocks.addAll(bulkMissingBlocks); + } + } + + // Get blocks one by one + else { + int blockNumber = Integer.parseInt(blockNumberStr); + String blockAsJson = blockchainRemoteService.getBlockAsJson(childPeer, blockNumber); + if (StringUtils.isNotBlank(blockAsJson)) { + if (debug) { + log.trace("Found missing block #%s on peer [%s:%s].", blockNumber, childPeer.getHost(), childPeer.getPort()); + } + + // Index the missing block + indexBlockAsJson(currencyName, blockNumber, blockAsJson.getBytes(), false, true/*wait*/); + + // Remove this block number from the final missing list + newMissingBlocks.remove(blockNumber); + } + } + } + + if (CollectionUtils.isEmpty(newMissingBlocks)) { + break; + } + + // Update the list, for the next iteration + sortedMissingBlocks = newMissingBlocks; + } + catch(TechnicalException e) { + if (debug) { + log.debug("Error while getting blocks from peer [%s:%s]: %s. Skipping this peer.", childPeer.getHost(), childPeer.getPort(), e.getMessage()); + } + + continue; // skip this peer + } + } + + + if (CollectionUtils.isEmpty(newMissingBlocks)) { + return null; + } + + tryCounter++; + if (tryCounter >= SYNC_MISSING_BLOCK_MAX_RETRY) { + // Max retry : stop here + log.error("Some blocks are still missing, after %s try: %s", SYNC_MISSING_BLOCK_MAX_RETRY, newMissingBlocks.toArray(new String[0])); + return newMissingBlocks; + } + + if (debug) { + log.debug("Some blocks are still missing: %s. Will retry later (%s/%s)...", newMissingBlocks.toArray(new String[0]), tryCounter, SYNC_MISSING_BLOCK_MAX_RETRY); + } + try { + Thread.sleep(60 *1000); // wait 1 min + + } + catch (InterruptedException e) { + return null; // stop here + } + + // retrying, with the new new blockchain + BlockchainBlock newCurrentBlock = blockchainRemoteService.getCurrentBlock(peer); + return indexMissingBlocksFromOtherPeers(peer, newCurrentBlock, newMissingBlocks, tryCounter); + } + + protected void reportIndexBlocksProgress(ProgressionModel progressionModel, int firstNumber, int lastNumber, int curNumber) { + int pct = (curNumber - firstNumber) * 100 / (lastNumber - firstNumber); + progressionModel.setCurrent(pct); + + progressionModel.setMessage(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.progress", curNumber, lastNumber, pct)); + if (log.isInfoEnabled()) { + log.info(I18n.t("ucoinj.blockIndexerService.indexLastBlocks.progress", curNumber, lastNumber, pct)); + } + + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java new file mode 100644 index 0000000000000000000000000000000000000000..4fb885e599d25cb783b025c43a47a733c753a02b --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerService.java @@ -0,0 +1,587 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.elasticsearch.model.SearchResult; +import io.ucoin.ucoinj.elasticsearch.service.exception.AccessDeniedException; +import io.ucoin.ucoinj.elasticsearch.service.exception.DuplicateIndexIdException; +import io.ucoin.ucoinj.elasticsearch.service.exception.InvalidSignatureException; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; +import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.search.SearchPhaseExecutionException; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchType; +import org.elasticsearch.action.suggest.SuggestRequestBuilder; +import org.elasticsearch.action.suggest.SuggestResponse; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHitField; +import org.elasticsearch.search.highlight.HighlightField; +import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.search.suggest.Suggest; +import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Created by Benoit on 30/03/2015. + */ +public class CurrencyIndexerService extends BaseIndexerService { + + private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class); + + public static final String INDEX_NAME = "currency"; + + public static final String INDEX_TYPE_SIMPLE = "simple"; + + public static final String REGEX_WORD_SEPARATOR = "[-\\t@# ]+"; + public static final String REGEX_SPACE = "[\\t\\n\\r ]+"; + + private CryptoService cryptoService; + private BlockIndexerService blockIndexerService; + private Gson gson; + + public CurrencyIndexerService() { + super(); + this.gson = GsonUtils.newBuilder().create(); + } + + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + + this.cryptoService = ServiceLocator.instance().getCryptoService(); + this.blockIndexerService = ServiceLocator.instance().getBlockIndexerService(); + } + + @Override + public void close() throws IOException { + super.close(); + this.cryptoService = null; + this.blockIndexerService = null; + this.gson = null; + } + + /** + * Delete currency index, and all data + * @throws JsonProcessingException + */ + public void deleteIndex() throws JsonProcessingException { + deleteIndexIfExists(INDEX_NAME); + } + + /** + * Create index need for currency registry, if need + */ + public void createIndexIfNotExists() { + try { + if (!existsIndex(INDEX_NAME)) { + createIndex(); + } + } + catch(JsonProcessingException e) { + throw new TechnicalException(String.format("Error while creating index [%s]", INDEX_NAME)); + } + } + + /** + * Create index need for currency registry + * @throws JsonProcessingException + */ + public void createIndex() throws JsonProcessingException { + log.info(String.format("Creating index [%s]", INDEX_NAME)); + + CreateIndexRequestBuilder createIndexRequestBuilder = getClient().admin().indices().prepareCreate(INDEX_NAME); + try { + + Settings indexSettings = Settings.settingsBuilder() + .put("number_of_shards", 1) + .put("number_of_replicas", 1) + .put("analyzer", createDefaultAnalyzer()) + .build(); + createIndexRequestBuilder.setSettings(indexSettings); + + XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject(INDEX_TYPE_SIMPLE) + .startObject("properties") + .startObject("currencyName") + .field("type", "string") + .endObject() + .startObject("memberCount") + .field("type", "integer") + .endObject() + .startObject("tags") + .field("type", "completion") + .field("search_analyzer", "simple") + .field("analyzer", "simple") + .field("preserve_separators", "false") + .endObject() + .endObject() + .endObject().endObject(); + + createIndexRequestBuilder.addMapping(INDEX_TYPE_SIMPLE, mapping); + + } + catch(IOException ioe) { + throw new TechnicalException("Error while preparing index: " + ioe.getMessage(), ioe); + } + CreateIndexResponse response = createIndexRequestBuilder.execute().actionGet(); + } + + /** + * Retrieve the currency data, from peer + * + * @param peer + * @return the created currency + */ + public Currency indexCurrencyFromPeer(Peer peer) { + BlockchainRemoteService blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + BlockchainParameters parameters = blockchainRemoteService.getParameters(peer); + BlockchainBlock firstBlock = blockchainRemoteService.getBlock(peer, 0); + BlockchainBlock currentBlock = blockchainRemoteService.getCurrentBlock(peer); + long lastUD = blockchainRemoteService.getLastUD(peer); + + Currency result = new Currency(); + result.setCurrencyName(parameters.getCurrency()); + result.setFirstBlockSignature(firstBlock.getSignature()); + result.setMembersCount(currentBlock.getMembersCount()); + result.setLastUD(lastUD); + result.setParameters(parameters); + result.setPeers(new Peer[]{peer}); + + indexCurrency(result); + + // Index the first block + blockIndexerService.createIndexIfNotExists(parameters.getCurrency()); + blockIndexerService.indexBlock(firstBlock, false); + blockIndexerService.indexCurrentBlock(firstBlock, true); + + return result; + } + + /** + * Index a currency + * @param currency + */ + public void indexCurrency(Currency currency) { + try { + ObjectUtils.checkNotNull(currency.getCurrencyName()); + + // Fill tags + if (ArrayUtils.isEmpty(currency.getTags())) { + String currencyName = currency.getCurrencyName(); + String[] tags = currencyName.split(REGEX_WORD_SEPARATOR); + List<String> tagsList = Lists.newArrayList(tags); + + // Convert as a sentence (replace seprator with a space) + String sentence = currencyName.replaceAll(REGEX_WORD_SEPARATOR, " "); + if (!tagsList.contains(sentence)) { + tagsList.add(sentence); + } + + currency.setTags(tagsList.toArray(new String[tagsList.size()])); + } + + // Serialize into JSON + byte[] json = getObjectMapper().writeValueAsBytes(currency); + + // Preparing indexation + IndexRequestBuilder indexRequest = getClient().prepareIndex(INDEX_NAME, INDEX_TYPE_SIMPLE) + .setId(currency.getCurrencyName()) + .setSource(json); + + // Execute indexation + indexRequest + .setRefresh(true) + .execute().actionGet(); + + } catch(JsonProcessingException e) { + throw new TechnicalException(e); + } + } + + /** + * Get suggestions from a string query. Useful for web autocomplete field (e.g. text full search) + * @param query + * @return + */ + public List<String> getSuggestions(String query) { + CompletionSuggestionBuilder suggestionBuilder = new CompletionSuggestionBuilder(INDEX_TYPE_SIMPLE) + .text(query) + .size(10) // limit to 10 results + .field("tags"); + + // Prepare request + SuggestRequestBuilder suggestRequest = getClient() + .prepareSuggest(INDEX_NAME) + .addSuggestion(suggestionBuilder); + + // Execute query + SuggestResponse response = suggestRequest.execute().actionGet(); + + // Read query result + return toSuggestions(response, INDEX_TYPE_SIMPLE, query); + } + + /** + * Find currency that match the givent string query (Full text search) + * @param query + * @return + */ + public List<Currency> searchCurrencies(String query) { + String[] queryParts = query.split(REGEX_SPACE); + + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(INDEX_NAME) + .setTypes(INDEX_TYPE_SIMPLE) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // If only one term, search as prefix + if (queryParts.length == 1) { + searchRequest.setQuery(QueryBuilders.prefixQuery("currencyName", query)); + } + + // If more than a word, search on terms match + else { + searchRequest.setQuery(QueryBuilders.matchQuery("currencyName", query)); + } + + // Sort as score/memberCount + searchRequest.addSort("_score", SortOrder.DESC) + .addSort("memberCount", SortOrder.DESC); + + // Highlight matched words + searchRequest.setHighlighterTagsSchema("styled") + .addHighlightedField("currencyName") + .addFields("currencyName") + .addFields("currencyName", "_source"); + + // Execute query + SearchResponse searchResponse = searchRequest.execute().actionGet(); + + // Read query result + return toCurrencies(searchResponse, true); + } + + /** + * find currency that match string query (full text search), and return a generic VO for search result. + * @param query + * @return a list of generic search result + */ + public List<SearchResult> searchCurrenciesAsVO(String query) { + String[] queryParts = query.split(REGEX_SPACE); + + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(INDEX_NAME) + .setTypes(INDEX_TYPE_SIMPLE) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // If only one term, search as prefix + if (queryParts.length == 1) { + searchRequest.setQuery(QueryBuilders.prefixQuery("currencyName", query)); + } + + // If more than a word, search on terms match + else { + searchRequest.setQuery(QueryBuilders.matchQuery("currencyName", query)); + } + + // Sort as score/memberCount + searchRequest.addSort("_score", SortOrder.DESC) + .addSort("memberCount", SortOrder.DESC); + + // Highlight matched words + searchRequest.setHighlighterTagsSchema("styled") + .addHighlightedField("currencyName") + .addFields("currencyName") + .addFields("memberCount"); + + // Execute query + SearchResponse searchResponse = searchRequest.execute().actionGet(); + + // Read query result + return toSearchResults(searchResponse, true); + } + + /** + * Retrieve a currency from its name + * @param currencyId + * @return + */ + public Currency getCurrencyById(String currencyId) { + + if (!existsIndex(currencyId)) { + return null; + } + + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(INDEX_NAME) + .setTypes(INDEX_TYPE_SIMPLE) + .setSearchType(SearchType.DFS_QUERY_THEN_FETCH); + + // If more than a word, search on terms match + searchRequest.setQuery(QueryBuilders.matchQuery("_id", currencyId)); + + // Execute query + List<Currency> currencies = null; + try { + SearchResponse searchResponse = searchRequest.execute().actionGet(); + currencies = toCurrencies(searchResponse, false); + } + catch(SearchPhaseExecutionException e) { + // Failed or no item on index + } + + // No result : return null + if (CollectionUtils.isEmpty(currencies)) { + return null; + } + + // Return the unique result + return CollectionUtils.extractSingleton(currencies); + } + + /** + * Save a currency (update or create) into the currency index. + * @param currency + * @param senderPubkey + * @throws DuplicateIndexIdException + * @throws AccessDeniedException if exists and user if not the original currency sender + */ + public void saveCurrency(Currency currency, String senderPubkey) throws DuplicateIndexIdException { + ObjectUtils.checkNotNull(currency, "currency could not be null") ; + ObjectUtils.checkNotNull(currency.getCurrencyName(), "currency attribute 'currencyName' could not be null"); + + Currency existingCurrency = getCurrencyById(currency.getCurrencyName()); + + // Currency not exists, so create it + if (existingCurrency == null || currency.getSenderPubkey() == null) { + // make sure to fill the sender + currency.setSenderPubkey(senderPubkey); + + // Save it + indexCurrency(currency); + } + + // Exists, so check the owner signature + else { + if (!Objects.equals(currency.getSenderPubkey(), senderPubkey)) { + throw new AccessDeniedException("Could not change currency, because it has been registered by another public key."); + } + + // Make sure the sender is not changed + currency.setSenderPubkey(senderPubkey); + + // Save changes + indexCurrency(currency); + } + } + + /** + * Get the full list of currencies names, from currency index + * @return + */ + public List<String> getAllCurrencyNames() { + // Prepare request + SearchRequestBuilder searchRequest = getClient() + .prepareSearch(INDEX_NAME) + .setTypes(INDEX_TYPE_SIMPLE); + + // Sort as score/memberCount + searchRequest.addSort("currencyName", SortOrder.ASC) + .addField("_id"); + + // Execute query + SearchResponse searchResponse = searchRequest.execute().actionGet(); + + // Read query result + return toCurrencyNames(searchResponse, true); + } + + /** + * Registrer a new currency. + * @param pubkey the sender pubkey + * @param jsonCurrency the currency, as JSON + * @param signature the signature of sender. + * @throws InvalidSignatureException if signature not correspond to sender pubkey + */ + public void registerCurrency(String pubkey, String jsonCurrency, String signature) { + Preconditions.checkNotNull(pubkey); + Preconditions.checkNotNull(jsonCurrency); + Preconditions.checkNotNull(signature); + + if (!cryptoService.verify(jsonCurrency, signature, pubkey)) { + String currencyName = GsonUtils.getValueFromJSONAsString(jsonCurrency, "currencyName"); + log.warn(String.format("Currency not added, because bad signature. currency [%s]", currencyName)); + throw new InvalidSignatureException("Bad signature"); + } + + Currency currency = null; + try { + currency = gson.fromJson(jsonCurrency, Currency.class); + Preconditions.checkNotNull(currency); + Preconditions.checkNotNull(currency.getCurrencyName()); + } catch(Throwable t) { + log.error("Error while reading currency JSON: " + jsonCurrency); + throw new TechnicalException("Error while reading currency JSON: " + jsonCurrency, t); + } + + saveCurrency(currency, pubkey); + } + + /* -- Internal methods -- */ + + protected void createCurrency(Currency currency) throws DuplicateIndexIdException, JsonProcessingException { + ObjectUtils.checkNotNull(currency, "currency could not be null") ; + ObjectUtils.checkNotNull(currency.getCurrencyName(), "currency attribute 'currencyName' could not be null"); + + Currency existingCurrency = getCurrencyById(currency.getCurrencyName()); + if (existingCurrency != null) { + throw new DuplicateIndexIdException(String.format("Currency with name [%s] already exists.", currency.getCurrencyName())); + } + + // register to currency + indexCurrency(currency); + + // Create sub indexes + ServiceLocator.instance().getBlockIndexerService().createIndex(currency.getCurrencyName()); + } + + protected List<Currency> toCurrencies(SearchResponse response, boolean withHighlight) { + try { + // Read query result + SearchHit[] searchHits = response.getHits().getHits(); + List<Currency> result = Lists.newArrayListWithCapacity(searchHits.length); + for (SearchHit searchHit : searchHits) { + Currency currency = null; + if (searchHit.source() != null) { + currency = getObjectMapper().readValue(searchHit.source(), Currency.class); + } + else { + currency = new Currency(); + SearchHitField field = searchHit.getFields().get("currencyName"); + currency.setCurrencyName((String)field.getValue()); + } + result.add(currency); + + // If possible, use highlights + if (withHighlight) { + Map<String, HighlightField> fields = searchHit.getHighlightFields(); + for (HighlightField field : fields.values()) { + String currencyNameHighLight = field.getFragments()[0].string(); + currency.setCurrencyName(currencyNameHighLight); + } + } + } + + return result; + } catch(IOException e) { + throw new TechnicalException("Error while reading currency search result: " + e.getMessage(), e); + } + } + + protected List<SearchResult> toSearchResults(SearchResponse response, boolean withHighlight) { + // Read query result + SearchHit[] searchHits = response.getHits().getHits(); + List<SearchResult> result = Lists.newArrayListWithCapacity(searchHits.length); + for (SearchHit searchHit : searchHits) { + SearchResult value = new SearchResult(); + value.setId(searchHit.getId()); + value.setType(searchHit.getType()); + value.setValue(searchHit.getId()); + + result.add(value); + + // If possible, use highlights + if (withHighlight) { + Map<String, HighlightField> fields = searchHit.getHighlightFields(); + for (HighlightField field : fields.values()) { + String currencyNameHighLight = field.getFragments()[0].string(); + value.setValue(currencyNameHighLight); + } + } + } + + return result; + } + + protected List<String> toSuggestions(SuggestResponse response, String suggestionName, String query) { + if (response.getSuggest() == null + || response.getSuggest().getSuggestion(suggestionName) == null) { + return null; + } + + // Read query result + Iterator<? extends Suggest.Suggestion.Entry.Option> iterator = + response.getSuggest().getSuggestion(suggestionName).iterator().next().getOptions().iterator(); + + List<String> result = Lists.newArrayList(); + while (iterator.hasNext()) { + Suggest.Suggestion.Entry.Option next = iterator.next(); + String suggestion = next.getText().string(); + result.add(suggestion); + } + + return result; + } + + protected List<String> toCurrencyNames(SearchResponse response, boolean withHighlight) { + // Read query result + SearchHit[] searchHits = response.getHits().getHits(); + List<String> result = Lists.newArrayListWithCapacity(searchHits.length); + for (SearchHit searchHit : searchHits) { + result.add(searchHit.getId()); + } + + return result; + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java new file mode 100644 index 0000000000000000000000000000000000000000..11997301bcdb3aba6b8cdc49ae7893a5fe9bee7f --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ElasticSearchService.java @@ -0,0 +1,242 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.fasterxml.jackson.databind.ObjectMapper; +import io.ucoin.ucoinj.core.beans.Bean; +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import org.elasticsearch.client.Client; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.logging.ESLoggerFactory; +import org.elasticsearch.common.logging.slf4j.Slf4jESLoggerFactory; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.InetSocketTransportAddress; +import org.elasticsearch.node.Node; +import org.elasticsearch.node.NodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Created by Benoit on 08/04/2015. + */ +public class ElasticSearchService implements Bean,InitializingBean, Closeable { + + private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class); + private Client client; + private Node node; + private boolean localNode = false; + private ObjectMapper objectMapper; + + public ElasticSearchService() { + node = null; + } + + @Override + public void afterPropertiesSet() { + + Configuration config = Configuration.instance(); + + // Define Slf4j as ES logging framework + ESLoggerFactory.setDefaultFactory(new Slf4jESLoggerFactory()); + + // Create the object mapper + objectMapper = new ObjectMapper(); + + // Create the local node, if need (useful in dev mode) + if (config.isEmbedded()) { + startNode(); + } + + // Create the client + client = createClient(); + } + + public void startNode() { + Configuration config = Configuration.instance(); + startNode( + config.isHttpEnable(), + config.isLocal()); + } + + public void startNode(boolean enableHttp, boolean local) { + + if (node != null && !localNode) { + //already running + return; + } + + // Close client and node + try { + close(); + } + catch(IOException e) { + // continue + } + client = null; + + node = createNode(enableHttp, local); + client = createClient(); + } + + public void stopNode() { + // Close client and node + try { + close(); + } + catch(IOException e) { + // continue + } + + // Only recreate the client + client = createClient(); + } + + @Override + public void close() throws IOException { + + // Closing the client (if exists) + if (client != null) { + if (log.isDebugEnabled()) { + log.debug("Closing ElasticSearch client"); + } + client.close(); + client = null; + } + + // Closing the node (if exists) + if (node != null) { + log.info("Closing ElasticSearch node"); + + node.close(); + node = null; + } + } + + public Client getClient() { + return client; + } + + public Node getNode() { + return node; + } + + public ObjectMapper getObjectMapper() { + return objectMapper; + } + + /* -- internal methods -- */ + + protected Node createNode(boolean enableHttp, boolean local) { + + Configuration config = Configuration.instance(); + String clusterName = config.getClusterName(); + this.localNode = local; + + // Log starting + if (local) { + if (StringUtils.isNotBlank(clusterName)) { + log.warn(String.format("Starts ElasticSearch as [local] node with cluster name [%s] at [%s]. Local node are not recommended for production deployment.", clusterName, config.getDataDirectory())); + } else { + log.warn(String.format("Starts ElasticSearch as [local] node at [%s]. Local node are not recommended for production deployment.", config.getDataDirectory())); + } + } + else { + if (StringUtils.isNotBlank(clusterName)) { + log.info(String.format("Starts ElasticSearch node with cluster name [%s] at [%s].", clusterName, config.getDataDirectory())); + } else { + log.warn(String.format("Starts ElasticSearch node at [%s] without cluster name. Having no cluster name is not recommended for production deployment.", config.getDataDirectory())); + } + } + + Settings settings = Settings.settingsBuilder() + .put("http.enabled", enableHttp) + .put("http.host", config.getHost()) + .put("path.home", config.getBasedir()) + .put("path.data", config.getDataDirectory()) + .build(); + + // Create a node builder + NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder() + .clusterName(clusterName) + .settings(settings) + .local(local); + + if (StringUtils.isNotBlank(clusterName)) { + nodeBuilder.clusterName(clusterName); + } + + // Start the node from builder + Node node = nodeBuilder.node().start(); + + return node; + } + + protected Client createClient() { + if (node != null) { + return node.client(); + } + + Configuration config = Configuration.instance(); + String host = config.getHost(); + int port = config.getPort(); + String clusterName = config.getClusterName(); + File dataDirectory = new File(config.getDataDirectory(), "client"); + + if (log.isDebugEnabled()) { + log.debug(String.format("Starts ElasticSearch client for node [%s:%s] at [%s]", host, port, dataDirectory)); + } + + + Settings.Builder settings = Settings.settingsBuilder() + .put("path.home", config.getBasedir()) + .put("path.data", dataDirectory); + + if (io.ucoin.ucoinj.core.util.StringUtils.isNotBlank(clusterName)) { + settings.put("cluster.name", clusterName); + } + else { + settings.put("client.transport.ignore_cluster_name", true); + log.warn("Ignoring cluster name verification (no cluster name found in configuration). This is not recommended for production deployment."); + } + + // Create the transport Client + try { + return TransportClient.builder() + .settings(settings.build()) + .build() + .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host), port)); + } catch (UnknownHostException e) { + throw new TechnicalException(e); + } + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorService.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorService.java new file mode 100644 index 0000000000000000000000000000000000000000..c0076f338494002b5c9d8be797cc177cb8cf3062 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorService.java @@ -0,0 +1,45 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: ElasticSearch Indexer + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.beans.Service; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import io.ucoin.ucoinj.elasticsearch.service.task.Job; +import io.ucoin.ucoinj.elasticsearch.service.task.JobVO; + +import java.util.List; +import java.util.Locale; + +public interface ExecutorService extends Service{ + + void stop(String jobId); + + Job execute(Runnable runnable, String jobId, String issuer, Locale locale, ProgressionModel progression); + + void execute(Runnable runnable); + + ProgressionModel getProgressionByJobId(String jobId); + + List<JobVO> getAllJobs(); +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorServiceImpl.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..db08101c74fc89d43569af0fb2ff5be9a80ebd43 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ExecutorServiceImpl.java @@ -0,0 +1,278 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * SIH-Adagio :: Synchro Server WebApp + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.util.concurrent.*; +import io.ucoin.ucoinj.core.beans.InitializingBean; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import io.ucoin.ucoinj.core.model.ProgressionModelImpl; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.service.task.Job; +import io.ucoin.ucoinj.elasticsearch.service.task.JobFuture; +import io.ucoin.ucoinj.elasticsearch.service.task.JobVO; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.i18n.I18n; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.nuiton.i18n.I18n.l; + +public class ExecutorServiceImpl implements ExecutorService, InitializingBean { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ExecutorServiceImpl.class); + + + private Configuration config; + private ListeningExecutorService delegate; + private final Map<String, JobFuture> jobsById; + private final LoadingCache<String, ProgressionModel> progressionByJobIdCache; + + public ExecutorServiceImpl() { + this.jobsById = Maps.newHashMap(); + this.config = Configuration.instance(); + this.progressionByJobIdCache = initJobByIdCache( + config.getTaskExecutorQueueCapacity() * 2, + config.getTaskExecutorTimeToIdle()); + delegate = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(config.getTaskExecutorQueueCapacity())); + } + + @Override + public void afterPropertiesSet() throws Exception { + + } + + @Override + public void close() throws IOException { + + log.debug("Closing executor service"); + + synchronized (jobsById) { + + for (ListenableFuture<Job> task : jobsById.values()) { + task.cancel(true); + } + jobsById.clear(); + + for (ProgressionModel progressionModel : progressionByJobIdCache.asMap().values()) { + progressionModel.cancel(); + } + progressionByJobIdCache.cleanUp(); + } + + if (!delegate.isShutdown()) { + delegate.shutdownNow(); + } + } + + @Override + public ProgressionModel getProgressionByJobId(String jobId) { + if (StringUtils.isBlank(jobId)) { + return null; + } + synchronized (jobsById) { + ListenableFuture<Job> job = jobsById.get(jobId); + if (job != null) { + try { + return job.get().getProgressionModel(); + } + catch(InterruptedException | ExecutionException e) { + // continue + } + } + } + + // Call the cache, but return null if the key is not present + return progressionByJobIdCache.getIfPresent(jobId); + } + + @Override + public void execute(Runnable runnable) { + execute(runnable, "ucoinj|job|" + System.currentTimeMillis(), null, Locale.getDefault(), new ProgressionModelImpl()); + } + + @Override + public Job execute(Runnable runnable, String jobId, String issuer, Locale locale, ProgressionModel progression) { + + // Make sure no import already launched + ProgressionModel existingProgression = getProgressionByJobId(jobId); + if (existingProgression != null && existingProgression.getStatus() == ProgressionModel.Status.RUNNING) { + throw new TechnicalException("Could not start a new synchronization: already running."); + } + + // Run the synchro thread + final Job job = new Job( + runnable, + jobId, + issuer, + locale, + progression); + + // Execute the job + shedule(jobId, + job, + l(locale, "ucoinj.task.starting"), + locale); + + return job; + } + + @Override + public void stop(String jobId) { + JobFuture job = jobsById.get(jobId); + if (job != null) { + job.cancel(false); + } + } + + @Override + public List<JobVO> getAllJobs() { + synchronized (jobsById) { + List<JobVO> result = Lists.newArrayListWithExpectedSize(jobsById.size()); + for (Map.Entry<String, JobFuture> entry : jobsById.entrySet()) { + String jobId = entry.getKey(); + Job job = entry.getValue().getJob(); + + // System job + String issuer = job.getIssuer(); + if (StringUtils.isBlank(issuer)) { + issuer = I18n.t("ucoinj.task.issuer.system"); + } + + JobVO jobVO = new JobVO( + jobId, + issuer + ); + + result.add(jobVO); + } + return result; + } + } + + public Job getJobById(String jobId) { + synchronized (jobsById) { + JobFuture jobFuture = jobsById.get(jobId); + if (jobFuture != null) { + return jobFuture.getJob(); + } + return null; + } + } + + /* -- Internal methods -- */ + + protected final LoadingCache<String, ProgressionModel> initJobByIdCache( + final int maximumSize, + final int expireDurationInSecond) { + return CacheBuilder.newBuilder() + .maximumSize(maximumSize) + .expireAfterWrite(expireDurationInSecond, TimeUnit.SECONDS) + .build( + new CacheLoader<String, ProgressionModel>() { + @Override + public ProgressionModel load(String jobId) throws SQLException { + Job job = getJobById(jobId); + if (job == null) { + throw new TechnicalException("Unknown task id"); + } + return job.getProgressionModel(); + } + }); + } + + protected void shedule(final String jobId, + final Job job, + String taskMessage, + final Locale locale) { + + // Set progression as as 'waiting execution' + final ProgressionModel progressionModel = job.getProgressionModel(); + progressionModel.setTask(taskMessage); + progressionModel.setMessage(l(locale, "ucoinj.executor.task.waitingExecution")); + progressionModel.setStatus(ProgressionModel.Status.WAITING_EXECUTION); + + + ListenableFuture<Job> future = delegate.submit(new Callable<Job>(){ + @Override + public Job call() throws Exception { + job.run(); + return job; + } + }); + + JobFuture jobFuture = new JobFuture(job, future); + Futures.addCallback(jobFuture, new FutureCallback<Job>() { + @Override + public void onSuccess(Job result) { + onJobFinish(jobId, progressionModel); + } + + @Override + public void onFailure(Throwable t) { + // TODO EIS : remove this (and log into the progress message instead ?) + log.error(t); + onJobFinish(jobId, progressionModel); + } + }); + + // start job + onJobScheduled(jobId, job, jobFuture); + } + + protected void onJobScheduled(final String jobId, final Job job, final JobFuture jobFuture) { + synchronized (jobsById) { + jobsById.put(jobId, jobFuture); + } + } + + protected void onJobFinish(final String jobId, final ProgressionModel progressionModel) { + synchronized (jobsById) { + // Before to remove from jobsById map, put the progressionModel again into the cache + // To avoid a getStatus() does not get retrieve it (mantis #23391) + progressionByJobIdCache.put(jobId, progressionModel); + + // ok, progressionModel is in the cache, so remove from map + jobsById.remove(jobId); + } + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java new file mode 100644 index 0000000000000000000000000000000000000000..5e9918821ece7bd01fc453acc561dc7f7da27d30 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/ServiceLocator.java @@ -0,0 +1,65 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServiceLocator extends io.ucoin.ucoinj.core.client.service.ServiceLocator { + + + /* Logger */ + private static final Logger log = LoggerFactory.getLogger(ServiceLocator.class); + + /** + * The shared instance of this ServiceLocator. + */ + private static ServiceLocator instance = new ServiceLocator(); + + static { + io.ucoin.ucoinj.core.client.service.ServiceLocator.setInstance(instance); + } + + public static ServiceLocator instance() { + return instance; + } + + /* -- ElasticSearch Service-- */ + + public CurrencyIndexerService getCurrencyIndexerService() { + return getBean(CurrencyIndexerService.class); + } + + public ElasticSearchService getElasticSearchService() { + return getBean(ElasticSearchService.class); + } + + public BlockIndexerService getBlockIndexerService() { + return getBean(BlockIndexerService.class); + } + + public ExecutorService getExecutorService() { + return getBean(ExecutorService.class); + } +} diff --git a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResults.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/AccessDeniedException.java similarity index 60% rename from ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResults.java rename to ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/AccessDeniedException.java index 55af45bd13d50ec7073c85275229cf558e9df6b0..8c984799063ca868e066f0e5e6da98bccf8654c2 100644 --- a/ucoinj-core/src/main/java/io/ucoin/client/core/model/WotLookupResults.java +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/AccessDeniedException.java @@ -1,4 +1,4 @@ -package io.ucoin.client.core.model; +package io.ucoin.ucoinj.elasticsearch.service.exception; /* * #%L @@ -22,28 +22,28 @@ package io.ucoin.client.core.model; * #L% */ - -import java.util.List; - -public class WotLookupResults { - - private boolean partial; - - private List<WotLookupResult> results; - - public boolean isPartial() { - return partial; - } - - public void setPartial(boolean partial) { - this.partial = partial; - } - - public List<WotLookupResult> getResults() { - return results; - } - - public void setResults(List<WotLookupResult> results) { - this.results = results; - } -} + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by Benoit on 03/04/2015. + */ +public class AccessDeniedException extends BusinessException{ + + public AccessDeniedException() { + super(); + } + + public AccessDeniedException(String message, Throwable cause) { + super(message, cause); + } + + public AccessDeniedException(String message) { + super(message); + } + + public AccessDeniedException(Throwable cause) { + super(cause); + } + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/DuplicateIndexIdException.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/DuplicateIndexIdException.java new file mode 100644 index 0000000000000000000000000000000000000000..eb535b140d792708e6f8cda819602345d5a0f089 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/DuplicateIndexIdException.java @@ -0,0 +1,49 @@ +package io.ucoin.ucoinj.elasticsearch.service.exception; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by Benoit on 03/04/2015. + */ +public class DuplicateIndexIdException extends BusinessException{ + + public DuplicateIndexIdException() { + super(); + } + + public DuplicateIndexIdException(String message, Throwable cause) { + super(message, cause); + } + + public DuplicateIndexIdException(String message) { + super(message); + } + + public DuplicateIndexIdException(Throwable cause) { + super(cause); + } + +} diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinSession.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/InvalidSignatureException.java similarity index 57% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinSession.java rename to ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/InvalidSignatureException.java index de0753180a3850282345f2b9ba225e453c2ec649..fa977061bee567b844941adb1c3e85dbb6bb1b22 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinSession.java +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/exception/InvalidSignatureException.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.application; +package io.ucoin.ucoinj.elasticsearch.service.exception; /* * #%L @@ -23,25 +23,27 @@ package io.ucoin.client.ui.application; */ -import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; -import org.apache.wicket.authroles.authorization.strategies.role.Roles; -import org.apache.wicket.request.Request; +import io.ucoin.ucoinj.core.exception.BusinessException; + +/** + * Created by Benoit on 03/04/2015. + */ +public class InvalidSignatureException extends BusinessException { -public class UcoinSession extends AuthenticatedWebSession { - private static final long serialVersionUID = 1L; + public InvalidSignatureException() { + super(); + } - public UcoinSession(Request request) { - super(request); + public InvalidSignatureException(String message, Throwable cause) { + super(message, cause); } - @Override - public boolean authenticate(String username, String password) { - return false; + public InvalidSignatureException(String message) { + super(message); } - - @Override - public Roles getRoles() { - return null; + + public InvalidSignatureException(Throwable cause) { + super(cause); } -} \ No newline at end of file +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/Job.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/Job.java new file mode 100644 index 0000000000000000000000000000000000000000..a1d7be77b9a40be5ebf73c8ff7644ad5077d6903 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/Job.java @@ -0,0 +1,171 @@ +package io.ucoin.ucoinj.elasticsearch.service.task; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Locale; + +import static org.nuiton.i18n.I18n.t; + +/** + * Encapsulate a RunnableWithProgress into a Job, with meta data + * + * + */ +public class Job implements java.lang.Runnable { + + private static final Logger log = LoggerFactory.getLogger(Job.class); + + + protected final ProgressionModel progressionModel; + protected final Configuration config; + protected final String jobId; + protected final String issuer; + protected final Locale locale; + protected boolean interrupted; + protected final Runnable delegate; + + public Job(Runnable delegate, String jobId, String issuer, Locale locale, ProgressionModel progressionModel) { + ObjectUtils.checkNotNull(delegate); + ObjectUtils.checkNotNull(jobId); + ObjectUtils.checkNotNull(locale); + ObjectUtils.checkNotNull(progressionModel); + + this.delegate = delegate; + this.jobId = jobId; + this.issuer = issuer; + this.locale = locale; + this.progressionModel = progressionModel; + this.config = Configuration.instance(); + } + + public ProgressionModel getProgressionModel() { + return this.progressionModel; + } + + public String getIssuer() { + return issuer; + } + + public Locale getLocale() { + return locale; + } + + public void stop() { + this.interrupted = true; + } + + @Override + public void run() { + delegate.run(); + } + + /** + * Remap progression model to a new progression model, to be able to encapsulate many tasks + * + * @param progressionModel + * @param progressionModelOffset + * @param progressionCount + */ + protected void addProgressionListeners(final ProgressionModel progressionModel, + final int progressionModelOffset, + final int progressionCount) { + // Listen 'current' attribute changes + progressionModel.addPropertyChangeListener(ProgressionModel.PROPERTY_CURRENT, + new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Integer current = (Integer) evt.getNewValue(); + + onProgressionCurrentChanged(current, progressionModel.getTotal(), progressionModelOffset, progressionCount); + } + }); + + // Listen message changes + progressionModel.addPropertyChangeListener(ProgressionModel.PROPERTY_MESSAGE, + new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + String message = (String) evt.getNewValue(); + onProgressionMessageChanged(message); + } + }); + } + + protected void onProgressionCurrentChanged(Integer current, Integer total, int progressionOffset, int progressionCount) { + if (current == null || total == null) { + progressionModel.setCurrent(progressionOffset); + return; + } + int progression = progressionOffset + + Math.round(progressionCount * current / total); + if (progression >= progressionOffset + progressionCount) { + progression = progressionOffset + progressionCount - 2; // max - 2, to avoid ProgressionPanel to run + // onComplet() + } + progressionModel.setCurrent(progression); + + checkJobInterruption(); + } + + protected void onProgressionMessageChanged(String message) { + progressionModel.setMessage(message); + } + + protected void onError(String errorMessage) { + progressionModel.setCurrent(0); + progressionModel.setTask(""); + progressionModel.setMessage(errorMessage); + progressionModel.setStatus(ProgressionModel.Status.FAILED); + } + + protected void onSuccess() { + progressionModel.setCurrent(100); + progressionModel.setTask(""); + progressionModel.setMessage(t("ucoinj.job.success")); + progressionModel.setStatus(ProgressionModel.Status.SUCCESS); + } + + /** + * Will stop the synchronization if job cancellation has been asked + */ + protected void checkJobInterruption() { + if (this.interrupted) { + if (log.isInfoEnabled()) { + log.info(t("ucoinj.job.stopping")); + } + throw new TechnicalException(t("ucoinj.job.stopped"), new InterruptedException()); + } + } + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobFuture.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobFuture.java new file mode 100644 index 0000000000000000000000000000000000000000..09c0cd39290ac2737cd742ab095051b68ed98510 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobFuture.java @@ -0,0 +1,92 @@ +package io.ucoin.ucoinj.elasticsearch.service.task; + +/* + * #%L + * SIH-Adagio :: Synchro Server WebApp + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * + * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro> + */ +public class JobFuture implements ListenableFuture<Job> { + + private final Job job; + private final ListenableFuture<Job> delegate; + + public JobFuture(Job job, ListenableFuture<Job> delegate) { + this.job = job; + this.delegate = delegate; + } + + public Job getJob() { + return job; + } + + public void addCallback(FutureCallback<? super Job> callback) { + Futures.addCallback(delegate,callback); + } + + @Override + public void addListener(Runnable runnable, Executor executor) { + delegate.addListener(runnable, executor); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + this.job.stop(); + return delegate.cancel(mayInterruptIfRunning); + } + + @Override + public boolean isCancelled() { + return delegate.isCancelled(); + } + + @Override + public boolean isDone() { + return delegate.isDone(); + } + + @Override + public Job get() throws InterruptedException, ExecutionException { + return delegate.get(); + } + + @Override + public Job get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + return delegate.get(timeout, unit); + } + + + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobVO.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobVO.java new file mode 100644 index 0000000000000000000000000000000000000000..b240eb9872edcfdd15e6dcfb8537f9696c351800 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/service/task/JobVO.java @@ -0,0 +1,47 @@ +package io.ucoin.ucoinj.elasticsearch.service.task; + +/* + * #%L + * SIH-Adagio :: Synchro Server WebApp + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import java.io.Serializable; + +public class JobVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String id; + + private final String issuer; + + public JobVO(String id, String issuer) { + this.id = id; + this.issuer = issuer; + } + + public String getId() { + return id; + } + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/Desktop.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/Desktop.java new file mode 100644 index 0000000000000000000000000000000000000000..6c981a2055b51ebb2d0f5cfefc9f8311e20c82ea --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/Desktop.java @@ -0,0 +1,63 @@ +package io.ucoin.ucoinj.elasticsearch.util; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.elasticsearch.util.os.win.WindowsPower; +import org.apache.commons.lang3.SystemUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class Desktop { + + private static final Logger LOG = LoggerFactory.getLogger(Desktop.class); + + static DesktopPower desktopPower = null; + + public static DesktopPower getDesktopPower() { + if (desktopPower == null) { + + + if (SystemUtils.IS_OS_WINDOWS) { + // All Windows version are handled with WindowsPower class + try { + desktopPower = new WindowsPower(); + } catch (Exception e) { + LOG.error(e.getLocalizedMessage(), e); + } + + + } else if (SystemUtils.IS_OS_LINUX) { + + // TODO create a Linux/UnixPower because (for example) Kubuntu sends KILL signal when it shutdown, it should sent TERM !! + } + + + } + + return desktopPower; + } + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/DesktopPower.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/DesktopPower.java new file mode 100644 index 0000000000000000000000000000000000000000..5228126ac640506b10543348b8a7fac11b66478f --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/DesktopPower.java @@ -0,0 +1,55 @@ +package io.ucoin.ucoinj.elasticsearch.util; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import java.util.HashSet; +import java.util.Set; + +public abstract class DesktopPower { + + public interface Listener { + /** + * os asks to App to quit. + * + * Windows machines - on reboot / logout. Mac - on reboot / logout + + * Command + Q Linux - reboot / logout + */ + void quit(); + + } + + protected Set<Listener> listeners = new HashSet<Listener>(); + + public void addListener(Listener l) { + listeners.add(l); + } + + public void removeListener(Listener l) { + listeners.remove(l); + } + + abstract public void close(); + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/WindowsPower.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/WindowsPower.java new file mode 100644 index 0000000000000000000000000000000000000000..8e03e46d78e16df58af1f985eca54d97e67aed16 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/WindowsPower.java @@ -0,0 +1,232 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.User32; +import com.sun.jna.platform.win32.WinDef.*; +import com.sun.jna.platform.win32.WinUser.HHOOK; +import com.sun.jna.platform.win32.WinUser.HOOKPROC; +import com.sun.jna.platform.win32.WinUser.MSG; +import io.ucoin.ucoinj.elasticsearch.util.DesktopPower; +import io.ucoin.ucoinj.elasticsearch.util.os.win.handle.CWPSSTRUCT; +import io.ucoin.ucoinj.elasticsearch.util.os.win.handle.HANDLER_ROUTINE; +import io.ucoin.ucoinj.elasticsearch.util.os.win.handle.WNDPROC; +import io.ucoin.ucoinj.elasticsearch.util.os.win.libs.Kernel32Ex; +import io.ucoin.ucoinj.elasticsearch.util.os.win.wrap.GetLastErrorException; +import io.ucoin.ucoinj.elasticsearch.util.os.win.wrap.WNDCLASSEXWrap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.swing.*; + +public class WindowsPower extends DesktopPower { + + private static final Logger LOG = LoggerFactory.getLogger(WindowsPower.class); + + public static final int WM_QUERYENDSESSION = 17; + public static final int WM_ENDSESSION = 22; + public static final int WH_CALLWNDPROC = 4; + + public class MessagePump implements Runnable { + Thread t; + + WNDCLASSEXWrap wc; + WNDPROC WndProc; + HWND hWnd; + HINSTANCE hInstance; + + final Object lock = new Object(); + + public MessagePump() { + t = new Thread(this, WindowsPower.class.getSimpleName()); + } + + public void start() { + synchronized (lock) { + t.start(); + try { + lock.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + + void create() { + WndProc = new WNDPROC() { + public LRESULT callback(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_ENDSESSION: + return new LRESULT(0); + case WM_QUERYENDSESSION: + JOptionPane.showMessageDialog(null, "exit"); + callListeners("WM_QUERYENDSESSION callback"); + return new LRESULT(0); + case User32.WM_QUIT: + User32.INSTANCE.PostMessage(hWnd, User32.WM_QUIT, null, null); + break; + } + + return User32.INSTANCE.DefWindowProc(hWnd, msg, wParam, lParam); + } + }; + hWnd = createWindow(); + } + + // http://osdir.com/ml/java.jna.user/2008-07/msg00049.html + + HWND createWindow() { + hInstance = Kernel32.INSTANCE.GetModuleHandle(null); + + wc = new WNDCLASSEXWrap(hInstance, WndProc, WindowsPower.class.getSimpleName()); + + HWND hwnd = User32.INSTANCE.CreateWindowEx(0, wc.getClassName(), wc.getName(), User32.WS_OVERLAPPED, 0, 0, + 0, 0, null, null, hInstance, null); + + if (hwnd == null) + throw new GetLastErrorException(); + + return hwnd; + } + + @Override + public void run() { + create(); + + synchronized (lock) { + lock.notifyAll(); + } + + MSG msg = new MSG(); + + while (User32.INSTANCE.GetMessage(msg, null, 0, 0) > 0) { + User32.INSTANCE.DispatchMessage(msg); + } + + destory(); + } + + void destory() { + if (hWnd != null) { + if (!User32.INSTANCE.DestroyWindow(hWnd)) + throw new GetLastErrorException(); + hWnd = null; + } + + if (wc != null) { + wc.close(); + wc = null; + } + } + + void close() { + User32.INSTANCE.PostQuitMessage(0); + + try { + if (!Thread.currentThread().equals(t)) + t.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + + MessagePump mp = new MessagePump(); + + HANDLER_ROUTINE hr = new HANDLER_ROUTINE() { + @Override + public long callback(long dwCtrlType) { + if ((dwCtrlType & HANDLER_ROUTINE.CTRL_CLOSE_EVENT) == HANDLER_ROUTINE.CTRL_CLOSE_EVENT) { + callListeners("HANDLER_ROUTINE.CTRL_CLOSE_EVENT"); + } + if ((dwCtrlType & HANDLER_ROUTINE.CTRL_LOGOFF_EVENT) == HANDLER_ROUTINE.CTRL_LOGOFF_EVENT) { + callListeners("HANDLER_ROUTINE.CTRL_LOGOFF_EVENT"); + } + if ((dwCtrlType & HANDLER_ROUTINE.CTRL_SHUTDOWN_EVENT) == HANDLER_ROUTINE.CTRL_SHUTDOWN_EVENT) { + callListeners("HANDLER_ROUTINE.CTRL_SHUTDOWN_EVENT"); + } + return 1; + } + }; + + HOOKPROC hp = new HOOKPROC() { + @SuppressWarnings("unused") + public LRESULT callback(int nCode, WPARAM wParam, CWPSSTRUCT hookProcStruct) { + switch (hookProcStruct.message) { + case WM_QUERYENDSESSION: + callListeners("WM_QUERYENDSESSION hook"); + break; + } + return new LRESULT(); + } + }; + HHOOK hHook; + JFrame f = new JFrame(); + + public WindowsPower() { + if (!Kernel32Ex.INSTANCE.SetProcessShutdownParameters(0x03FF, 0)) + throw new GetLastErrorException(); + + mp.start(); + + if (!Kernel32Ex.INSTANCE.SetConsoleCtrlHandler(hr, true)) + throw new GetLastErrorException(); + + final HWND hwnd = new HWND(); + f.pack(); + hwnd.setPointer(Native.getComponentPointer(f)); + + int wID = User32.INSTANCE.GetWindowThreadProcessId(hwnd, null); + hHook = User32.INSTANCE.SetWindowsHookEx(WH_CALLWNDPROC, hp, null, wID); + if (hHook == null) + throw new GetLastErrorException(); + } + + @Override + public void close() { + if (!User32.INSTANCE.UnhookWindowsHookEx(hHook)) + throw new GetLastErrorException(); + + f.dispose(); + f = null; + + mp.close(); + + if (!Kernel32Ex.INSTANCE.SetConsoleCtrlHandler(hr, false)) + throw new GetLastErrorException(); + } + + protected void callListeners(String source) { + + if (LOG.isDebugEnabled()) LOG.debug("call listeners from " + source); + + for (Listener l : listeners) { + l.quit(); + } + + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/CWPSSTRUCT.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/CWPSSTRUCT.java new file mode 100644 index 0000000000000000000000000000000000000000..96ecbcc3a9a6df1f63819c4152c102a2238892ed --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/CWPSSTRUCT.java @@ -0,0 +1,45 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.handle; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.WPARAM; + +import java.util.Arrays; +import java.util.List; + +public class CWPSSTRUCT extends Structure { + public LPARAM lParam; + public WPARAM wParam; + public int message; + public HWND hwnd; + + @Override + protected List<?> getFieldOrder() { + return Arrays.asList("lParam", "wParam", "message", "hwnd"); + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java new file mode 100644 index 0000000000000000000000000000000000000000..65a71c00e40b4a8c8f673e5e54d05aeba9348883 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/HANDLER_ROUTINE.java @@ -0,0 +1,35 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.handle; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; + +public interface HANDLER_ROUTINE extends StdCallCallback { + int CTRL_CLOSE_EVENT = 2; + int CTRL_LOGOFF_EVENT = 5; + int CTRL_SHUTDOWN_EVENT = 6; + + long callback(long dwCtrlType); +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/WNDPROC.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/WNDPROC.java new file mode 100644 index 0000000000000000000000000000000000000000..92175f6e78954146e3ddaf9368a067326a01203c --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/handle/WNDPROC.java @@ -0,0 +1,35 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.handle; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.platform.win32.WinDef.HWND; +import com.sun.jna.platform.win32.WinDef.LPARAM; +import com.sun.jna.platform.win32.WinDef.LRESULT; +import com.sun.jna.platform.win32.WinDef.WPARAM; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; + +public interface WNDPROC extends StdCallCallback { + LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam); +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/libs/Kernel32Ex.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/libs/Kernel32Ex.java new file mode 100644 index 0000000000000000000000000000000000000000..c5f3a3f134caa0630bed16ddfa35c0d2d953d7b3 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/libs/Kernel32Ex.java @@ -0,0 +1,52 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.libs; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.win32.W32APIOptions; +import io.ucoin.ucoinj.elasticsearch.util.os.win.handle.HANDLER_ROUTINE; + +public interface Kernel32Ex extends Library { + + Kernel32Ex INSTANCE = (Kernel32Ex) Native.loadLibrary("kernel32", Kernel32Ex.class, W32APIOptions.DEFAULT_OPTIONS); + + /** + * BOOL WINAPI SetProcessShutdownParameters( _In_ DWORD dwLevel, _In_ DWORD + * dwFlags ); + * <p/> + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms686227(v=vs.85).aspx + */ + boolean SetProcessShutdownParameters(long dwLevel, long dwFlags); + + /** + * BOOL WINAPI SetConsoleCtrlHandler( _In_opt_ PHANDLER_ROUTINE + * HandlerRoutine, _In_ BOOL Add ); + * <p/> + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v=vs.85).aspx + */ + boolean SetConsoleCtrlHandler(HANDLER_ROUTINE HandlerRoutine, boolean Add); + +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/GetLastErrorException.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/GetLastErrorException.java new file mode 100644 index 0000000000000000000000000000000000000000..0ad62eb85e1fc4e8acd687749316ba34c349167b --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/GetLastErrorException.java @@ -0,0 +1,41 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.wrap; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.LastErrorException; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.Kernel32Util; + +public class GetLastErrorException extends LastErrorException { + + public GetLastErrorException() { + super(Kernel32.INSTANCE.GetLastError()); + } + + @Override + public String getLocalizedMessage() { + return super.getMessage() + " : " + Kernel32Util.formatMessage(getErrorCode()); + } +} diff --git a/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java new file mode 100644 index 0000000000000000000000000000000000000000..c1c7c6996f9f8dbff217662f12caed86b749e6bf --- /dev/null +++ b/ucoinj-elasticsearch/src/main/java/io/ucoin/ucoinj/elasticsearch/util/os/win/wrap/WNDCLASSEXWrap.java @@ -0,0 +1,83 @@ +package io.ucoin.ucoinj.elasticsearch.util.os.win.wrap; + +/* + * #%L + * Reef DB :: UI + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.sun.jna.WString; +import com.sun.jna.platform.win32.User32; +import com.sun.jna.platform.win32.WinDef.ATOM; +import com.sun.jna.platform.win32.WinDef.HINSTANCE; +import com.sun.jna.platform.win32.WinUser; +import io.ucoin.ucoinj.elasticsearch.util.os.win.handle.WNDPROC; + +public class WNDCLASSEXWrap { + + WString klass; + ATOM wcatom; + HINSTANCE hInstance; + + public WNDCLASSEXWrap(HINSTANCE hInstance, WNDPROC WndProc, String klass) { + this.klass = new WString(klass); + this.hInstance = hInstance; + + WinUser.WNDCLASSEX wc = new WinUser.WNDCLASSEX(); + wc.cbSize = wc.size(); + wc.style = 0; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = null; + wc.hbrBackground = null; + wc.lpszMenuName = null; + wc.lpszClassName = new WString(klass); + + wcatom = User32.INSTANCE.RegisterClassEx(wc); + if (wcatom == null) + throw new GetLastErrorException(); + } + + public void close() { + if (wcatom != null) { + if (!User32.INSTANCE.UnregisterClass(klass, hInstance)) + throw new GetLastErrorException(); + wcatom = null; + } + } + + public WString getClassName() { + return klass; + } + + public String getName() { + return klass.toString(); + } + + protected void finalize() throws Throwable { + close(); + + super.finalize(); + } + +} diff --git a/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean new file mode 100644 index 0000000000000000000000000000000000000000..7335329fc0f4622db856b48d1e2db1633930be16 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean @@ -0,0 +1,17 @@ +io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.WotRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.TransactionRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.elasticsearch.CurrencyRegistryRemoteServiceImpl +io.ucoin.ucoinj.core.service.Ed25519CryptoServiceImpl +io.ucoin.ucoinj.core.client.service.HttpServiceImpl +io.ucoin.ucoinj.core.client.service.DataContext +io.ucoin.ucoinj.core.client.service.local.PeerServiceImpl +io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl +io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService +io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService +io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService +io.ucoin.ucoinj.elasticsearch.service.ExecutorServiceImpl +io.ucoin.ucoinj.elasticsearch.client.CurrencyIndexerClientService diff --git a/ucoinj-elasticsearch/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider b/ucoinj-elasticsearch/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider new file mode 100644 index 0000000000000000000000000000000000000000..8bd14945d41a3db3c001078b923362c2405443d3 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider @@ -0,0 +1 @@ +io.ucoin.ucoinj.elasticsearch.config.ConfigurationProvider diff --git a/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_en_GB.properties b/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_en_GB.properties new file mode 100644 index 0000000000000000000000000000000000000000..a3777902aa14800607f06081ce3bd4cba7949170 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_en_GB.properties @@ -0,0 +1,49 @@ +ucoinj-elasticsearch.config= +ucoinj.blockIndexerService.indexLastBlocks.otherPeers.task= +ucoinj.blockIndexerService.indexLastBlocks.progress= +ucoinj.blockIndexerService.indexLastBlocks.stopped= +ucoinj.blockIndexerService.indexLastBlocks.task= +ucoinj.config.option.basedir.description= +ucoinj.config.option.cache.directory.description= +ucoinj.config.option.data.directory.description= +ucoinj.config.option.elasticsearch.bulk.enable.description= +ucoinj.config.option.elasticsearch.bulk.size.description= +ucoinj.config.option.elasticsearch.cluster.name.description= +ucoinj.config.option.elasticsearch.embedded.enable.description= +ucoinj.config.option.elasticsearch.host.description= +ucoinj.config.option.elasticsearch.local.description= +ucoinj.config.option.i18n.directory.description= +ucoinj.config.option.i18n.locale.description= +ucoinj.config.option.index.parallel_processing.description= +ucoinj.config.option.node.elasticsearch.cluster.name.description= +ucoinj.config.option.node.elasticsearch.clusterName.description= +ucoinj.config.option.node.elasticsearch.embeddeb.description= +ucoinj.config.option.node.elasticsearch.embeddeb.http.description= +ucoinj.config.option.node.elasticsearch.embeddeb.local.description= +ucoinj.config.option.node.elasticsearch.embedded.enable.description= +ucoinj.config.option.node.elasticsearch.embedded.http.enable.description= +ucoinj.config.option.node.elasticsearch.embedded.local.description= +ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.http.enable.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= +ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.host.description= +ucoinj.config.option.node.port.description= +ucoinj.config.option.node.protocol.description= +ucoinj.config.option.taskExecutor.queueCapacity.description= +ucoinj.config.option.tasks.queueCapacity.description= +ucoinj.config.option.tmp.directory.description= +ucoinj.config.option.version.description= +ucoinj.config.parse.error= +ucoinj.executor.task.waitingExecution= +ucoinj.job.stopped= +ucoinj.job.stopping= +ucoinj.job.success= +ucoinj.task.issuer.system=System +ucoinj.task.starting=Starting task... diff --git a/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_fr_FR.properties b/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_fr_FR.properties new file mode 100644 index 0000000000000000000000000000000000000000..181d65ac6132de305adecbb8685f58cc1f1f8190 --- /dev/null +++ b/ucoinj-elasticsearch/src/main/resources/i18n/ucoinj-elasticsearch_fr_FR.properties @@ -0,0 +1,49 @@ +ucoinj-elasticsearch.config= +ucoinj.blockIndexerService.indexLastBlocks.otherPeers.task=Indexing missing blocks of [%s] from other peers +ucoinj.blockIndexerService.indexLastBlocks.progress=Indexing block \#%s / %s (%s%%)... +ucoinj.blockIndexerService.indexLastBlocks.stopped=Indexing last block - stopped +ucoinj.blockIndexerService.indexLastBlocks.task=Indexing last blocks of [%s] from peer [%s\:%s] +ucoinj.config.option.basedir.description= +ucoinj.config.option.cache.directory.description= +ucoinj.config.option.data.directory.description= +ucoinj.config.option.elasticsearch.bulk.enable.description= +ucoinj.config.option.elasticsearch.bulk.size.description= +ucoinj.config.option.elasticsearch.cluster.name.description= +ucoinj.config.option.elasticsearch.embedded.enable.description= +ucoinj.config.option.elasticsearch.host.description= +ucoinj.config.option.elasticsearch.local.description= +ucoinj.config.option.i18n.directory.description= +ucoinj.config.option.i18n.locale.description= +ucoinj.config.option.index.parallel_processing.description= +ucoinj.config.option.node.elasticsearch.cluster.name.description= +ucoinj.config.option.node.elasticsearch.clusterName.description= +ucoinj.config.option.node.elasticsearch.embeddeb.description= +ucoinj.config.option.node.elasticsearch.embeddeb.http.description= +ucoinj.config.option.node.elasticsearch.embeddeb.local.description= +ucoinj.config.option.node.elasticsearch.embedded.enable.description= +ucoinj.config.option.node.elasticsearch.embedded.http.enable.description= +ucoinj.config.option.node.elasticsearch.embedded.local.description= +ucoinj.config.option.node.elasticsearch.host.description= +ucoinj.config.option.node.elasticsearch.http.enable.description= +ucoinj.config.option.node.elasticsearch.local.clusterName.description= +ucoinj.config.option.node.elasticsearch.local.description= +ucoinj.config.option.node.elasticsearch.port.description= +ucoinj.config.option.node.elasticsearch.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.host.description= +ucoinj.config.option.node.elasticsearch.rest.port.description= +ucoinj.config.option.node.elasticsearch.rest.protocol.description= +ucoinj.config.option.node.elasticsearch.rest.url.description= +ucoinj.config.option.node.host.description= +ucoinj.config.option.node.port.description= +ucoinj.config.option.node.protocol.description= +ucoinj.config.option.taskExecutor.queueCapacity.description= +ucoinj.config.option.tasks.queueCapacity.description= +ucoinj.config.option.tmp.directory.description= +ucoinj.config.option.version.description= +ucoinj.config.parse.error= +ucoinj.executor.task.waitingExecution= +ucoinj.job.stopped= +ucoinj.job.stopping= +ucoinj.job.success= +ucoinj.task.issuer.system=Système +ucoinj.task.starting=Démarrage du traitement... diff --git a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestFixtures.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestFixtures.java new file mode 100644 index 0000000000000000000000000000000000000000..eeb1c1e15db8b6ec470414c08efaa9cb70a0ce0f --- /dev/null +++ b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestFixtures.java @@ -0,0 +1,28 @@ +package io.ucoin.ucoinj.elasticsearch; + +/* + * #%L + * UCoin Java Client :: ElasticSearch Indexer + * %% + * Copyright (C) 2014 - 2016 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +public class TestFixtures extends io.ucoin.ucoinj.core.test.TestFixtures{ + +} diff --git a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestResource.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestResource.java new file mode 100644 index 0000000000000000000000000000000000000000..8ff2d538f957fe0bfc6f3875073927c8bd2a6f6e --- /dev/null +++ b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/TestResource.java @@ -0,0 +1,142 @@ +package io.ucoin.ucoinj.elasticsearch; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import com.google.common.collect.Lists; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.elasticsearch.config.ConfigurationOption; +import org.apache.commons.io.FileUtils; +import org.junit.runner.Description; +import org.nuiton.i18n.I18n; +import org.nuiton.i18n.init.DefaultI18nInitializer; +import org.nuiton.i18n.init.UserI18nInitializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +public class TestResource extends io.ucoin.ucoinj.core.test.TestResource { + + private static final Logger log = LoggerFactory.getLogger(TestResource.class); + + public static TestResource create() { + return new TestResource(null); + } + + public static TestResource create(String configName) { + return new TestResource(configName); + } + + private TestFixtures fixtures = new TestFixtures(); + + protected TestResource(String configName) { + super(configName); + } + + public TestFixtures getFixtures() { + return fixtures; + } + + protected void before(Description description) throws Throwable { + super.before(description); + + // Initialize configuration + initConfiguration(getConfigFileName()); + + // Init i18n + initI18n(); + + // Initialize service locator + ServiceLocator.instance().init(); + } + + /** + * Return configuration files prefix (i.e. 'allegro-test') + * Could be override by external project + * + * @return the prefix to use to retrieve configuration files + */ + protected String getConfigFilesPrefix() { + return "ucoinj-elasticsearch-test"; + } + + protected String getI18nBundleName() { + return "ucoinj-elasticsearch-i18n"; + } + + /* -- -- */ + + /** + * Convenience methods that could be override to initialize other configuration + * + * @param configFilename + * @param configArgs + */ + protected void initConfiguration(String configFilename) { + String[] configArgs = getConfigArgs(); + Configuration config = new Configuration(configFilename, configArgs); + Configuration.setInstance(config); + } + + protected void initI18n() throws IOException { + Configuration config = Configuration.instance(); + + // --------------------------------------------------------------------// + // init i18n + // --------------------------------------------------------------------// + File i18nDirectory = new File(config.getDataDirectory(), "i18n"); + if (i18nDirectory.exists()) { + // clean i18n cache + FileUtils.cleanDirectory(i18nDirectory); + } + + FileUtils.forceMkdir(i18nDirectory); + + if (log.isDebugEnabled()) { + log.debug("I18N directory: " + i18nDirectory); + } + + Locale i18nLocale = config.getI18nLocale(); + + if (log.isInfoEnabled()) { + log.info(String.format("Starts i18n with locale [%s] at [%s]", + i18nLocale, i18nDirectory)); + } + I18n.init(new UserI18nInitializer( + i18nDirectory, new DefaultI18nInitializer(getI18nBundleName())), + i18nLocale); + } + + protected String[] getConfigArgs() { + List<String> configArgs = Lists.newArrayList(); + configArgs.addAll(Lists.newArrayList( + "--option", ConfigurationOption.BASEDIR.getKey(), getResourceDirectory().getAbsolutePath())); + return configArgs.toArray(new String[configArgs.size()]); + } + +} diff --git a/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..dcc7eb8f917f9cb84e4e5d3807878dfd04f96c5c --- /dev/null +++ b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/BlockIndexerServiceTest.java @@ -0,0 +1,171 @@ +package io.ucoin.ucoinj.elasticsearch.service; + +/* + * #%L + * UCoin Java Client :: Core API + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainBlock; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.elasticsearch.TestResource; +import org.junit.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class BlockIndexerServiceTest { + + private static final Logger log = LoggerFactory.getLogger(BlockIndexerServiceTest.class); + + @ClassRule + public static final TestResource resource = TestResource.create(); + + private BlockIndexerService service; + private BlockchainRemoteService blockchainRemoteService; + private Configuration config; + private Peer peer; + + @Before + public void setUp() throws Exception { + service = ServiceLocator.instance().getBlockIndexerService(); + blockchainRemoteService = ServiceLocator.instance().getBlockchainRemoteService(); + config = Configuration.instance(); + peer = createTestPeer(); + + initLocalNode(); + } + + @Test + public void createIndex() throws Exception { + String currencyName = resource.getFixtures().getCurrency(); + + // drop and recreate index + service.deleteIndex(currencyName); + + service.createIndex(currencyName); + } + + + @Test + public void indexBlock() throws Exception { + // Read a block + BlockchainBlock currentBlock = blockchainRemoteService.getCurrentBlock(peer); + + // Create a new non-existing block + service.indexBlock(currentBlock, true); + + // Update a existing block + { + currentBlock.setMembersCount(1000000); + + service.indexBlock(currentBlock, true); + } + } + + @Test + public void indexCurrentBlock() throws Exception { + // Create a block with a fake hash + BlockchainBlock aBlock = blockchainRemoteService.getBlock(peer, 8450); + service.indexCurrentBlock(aBlock, true); + } + + @Test + // FIXME make this works + @Ignore + public void searchBlocks() throws Exception { + String currencyName = resource.getFixtures().getCurrency(); + + // Create a block with a fake hash + BlockchainBlock aBlock = blockchainRemoteService.getCurrentBlock(peer); + aBlock.setHash("myUnitTestHash"); + service.saveBlock(aBlock, true, true); + + Thread.sleep(5 * 1000); // wait 5s that ES process the block + + // match multi words + String queryText = aBlock.getHash(); + List<BlockchainBlock> blocks = service.findBlocksByHash(currencyName, queryText); + //assertResults(queryText, blocks); + + Thread.sleep(5 * 1000); // wait 5s that ES process the block + + BlockchainBlock loadBlock = service.getBlockById(currencyName, aBlock.getNumber()); + Assert.assertNotNull(loadBlock); + Assert.assertEquals(aBlock.getHash(), loadBlock.getHash()); + } + + @Test + public void getMaxBlockNumber() throws Exception { + String currencyName = resource.getFixtures().getCurrency(); + + // match multi words + Integer maxBlockNumber = service.getMaxBlockNumber(currencyName); + Assert.assertNotNull(maxBlockNumber); + } + + + @Test + @Ignore + public void allInOne() throws Exception { + + createIndex(); + indexBlock(); + searchBlocks(); + } + + /* -- internal methods */ + + protected void initLocalNode() throws Exception { + String currencyName = resource.getFixtures().getCurrency(); + + // Make sure the index exists + service.deleteIndex(currencyName); + service.createIndex(currencyName); + + // Get the first block from peer + BlockchainBlock firstBlock = blockchainRemoteService.getBlock(peer, 0); + + // Make sure the block has been indexed + service.indexBlock(firstBlock, true); + + } + + protected void assertResults(String queryText, List<BlockchainBlock> result) { + log.info(String.format("Results for a search on [%s]", queryText)); + Assert.assertNotNull(result); + Assert.assertTrue(result.size() > 0); + for (BlockchainBlock block: result) { + log.info(" - " + block.getNumber()); + } + } + + protected Peer createTestPeer() { + Peer peer = new Peer( + Configuration.instance().getNodeHost(), + Configuration.instance().getNodePort()); + + return peer; + } + +} diff --git a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/CurrencyIndexerServiceTest.java b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java similarity index 57% rename from ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/CurrencyIndexerServiceTest.java rename to ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java index 7fb5515187a432a2b9a5f6d77adec57c03d7e982..84ac72e9ad1f0c8ee3154aca15d4d9e57c35bf5c 100644 --- a/ucoinj-core/src/test/java/io/ucoin/client/core/service/indexer/CurrencyIndexerServiceTest.java +++ b/ucoinj-elasticsearch/src/test/java/io/ucoin/ucoinj/elasticsearch/service/CurrencyIndexerServiceTest.java @@ -1,10 +1,10 @@ -package io.ucoin.client.core.service.indexer; +package io.ucoin.ucoinj.elasticsearch.service; /* * #%L - * UCoin Java Client :: Core API + * UCoin Java Client :: ElasticSearch Indexer * %% - * Copyright (C) 2014 - 2015 EIS + * Copyright (C) 2014 - 2016 EIS * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as @@ -22,15 +22,16 @@ package io.ucoin.client.core.service.indexer; * #L% */ - -import io.ucoin.client.core.TestResource; -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.model.BlockchainParameter; -import io.ucoin.client.core.model.Currency; -import io.ucoin.client.core.model.Peer; -import io.ucoin.client.core.service.BlockchainService; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.service.search.CurrencyIndexerService; +import io.ucoin.ucoinj.core.client.model.local.Wallet; +import io.ucoin.ucoinj.core.client.model.bma.BlockchainParameters; +import io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteService; +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import io.ucoin.ucoinj.elasticsearch.TestResource; +import io.ucoin.ucoinj.elasticsearch.config.Configuration; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; @@ -40,21 +41,47 @@ import org.slf4j.LoggerFactory; import java.util.List; +/** + * Created by Benoit on 06/05/2015. + */ public class CurrencyIndexerServiceTest { + private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerService.class); - private static final Logger log = LoggerFactory.getLogger(CurrencyIndexerServiceTest.class); - @ClassRule - public static final TestResource resource = TestResource.create(); + @ClassRule + public static final TestResource resource = TestResource.create(); private CurrencyIndexerService service; private Configuration config; + private Peer peer; @Before - public void setUp() { + public void setUp() throws Exception { service = ServiceLocator.instance().getCurrencyIndexerService(); config = Configuration.instance(); + peer = createTestPeer(); + + if (config.isLocal()) { + initLocalNode(); + } } + @Test + public void registerCurrency() { + Currency currency = new Currency(); + currency.setCurrencyName("register-test-" + System.currentTimeMillis()); + + String currencyJson = GsonUtils.newBuilder().create().toJson(currency); + + String pubKey = resource.getFixtures().getUserPublicKey(); + String secretKey = resource.getFixtures().getUserSecretKey(); + + CryptoService cryptoService = ServiceLocator.instance().getCryptoService(); + String signature = cryptoService.sign(currencyJson, secretKey); + + service.registerCurrency(pubKey, currencyJson, signature); + } + + @Test public void createIndex() throws Exception { @@ -64,6 +91,14 @@ public class CurrencyIndexerServiceTest { service.createIndex(); } + @Test + public void getAllCurrencyNames() { + List<String> currencyNames = service.getAllCurrencyNames(); + for (String currencyName: currencyNames) { + log.info(" - " + currencyName); + } + } + @Test public void allInOne() throws Exception { @@ -74,7 +109,7 @@ public class CurrencyIndexerServiceTest { } @Test - public void indexCurrency() throws Exception { + public void indexCurrency() throws Exception { // Create a new non-existing currency Currency currency = new Currency(); @@ -83,20 +118,19 @@ public class CurrencyIndexerServiceTest { // Update a existing currency, with peer { - Peer peer = new Peer(config.getNodeHost(), config.getNodePort()); - BlockchainService blockchainService = ServiceLocator.instance().getBlockchainService(); + Peer peer = createTestPeer(); + BlockchainRemoteService blockchainService = ServiceLocator.instance().getBlockchainRemoteService(); - // TODO : use the peer to connect (see android app) - BlockchainParameter parameter = blockchainService.getParameters(); + BlockchainParameters parameter = blockchainService.getParameters(peer); currency = new Currency(); currency.setCurrencyName(parameter.getCurrency()); currency.setMembersCount(10); - currency.addPeer(peer); + currency.setPeers(new Peer[]{peer}); service.indexCurrency(currency); } - } + } @Test public void getSuggestions() throws Exception { @@ -127,16 +161,24 @@ public class CurrencyIndexerServiceTest { //assertResults(queryText, currencies); } - @Test - public void getAllCurrencyNames() { - List<String> currencyNames = service.getAllCurrencyNames(); - for (String currencyName: currencyNames) { - log.info(" - " + currencyName); - } + /* -- internal methods -- */ + + protected void initLocalNode() throws Exception { + service.deleteIndex(); + service.createIndex(); + indexCurrency(); } - /* -- internal methods */ + protected Wallet createTestWallet() { + Wallet wallet = new Wallet( + resource.getFixtures().getCurrency(), + resource.getFixtures().getUid(), + CryptoUtils.decodeBase58(resource.getFixtures().getUserPublicKey()), + CryptoUtils.decodeBase58(resource.getFixtures().getUserSecretKey())); + + return wallet; + } protected void assertResults(String queryText, List<Currency> result) { log.info(String.format("Results for a search on [%s]", queryText)); @@ -155,4 +197,14 @@ public class CurrencyIndexerServiceTest { log.info(" - " + suggestion); } } + + protected Peer createTestPeer() { + Configuration config = Configuration.instance(); + + Peer peer = new Peer( + config.getNodeBmaHost(), + config.getNodeBmaPort()); + + return peer; + } } diff --git a/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean new file mode 100644 index 0000000000000000000000000000000000000000..fc3c26a12cdc0b222ddfcbdafb5e256a471f8a4c --- /dev/null +++ b/ucoinj-elasticsearch/src/test/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean @@ -0,0 +1,13 @@ +io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.WotRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.TransactionRemoteServiceImpl +io.ucoin.ucoinj.core.service.Ed25519CryptoServiceImpl +io.ucoin.ucoinj.core.client.service.HttpServiceImpl +io.ucoin.ucoinj.core.client.service.DataContext +io.ucoin.ucoinj.core.client.service.local.PeerServiceImpl +io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl +io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService +io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService \ No newline at end of file diff --git a/ucoinj-elasticsearch/src/test/resources/log4j.properties b/ucoinj-elasticsearch/src/test/resources/log4j.properties new file mode 100644 index 0000000000000000000000000000000000000000..ab3b55380dd939a15cb92f6173dd8f1ff84b5835 --- /dev/null +++ b/ucoinj-elasticsearch/src/test/resources/log4j.properties @@ -0,0 +1,18 @@ +### +# Global logging configuration +log4j.rootLogger=ERROR, stdout + +# Console output +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n + +# uCoinj levels +log4j.logger.io.ucoin=INFO +#log4j.logger.io.ucoin.ucoinj=DEBUG +#log4j.logger.io.ucoin.ucoinj.core=WARN +#log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG + +# Other frameworks levels +log4j.logger.org.elasticsearch=INFO + diff --git a/ucoinj-elasticsearch/src/test/resources/ucoinj-elasticsearch-test.properties b/ucoinj-elasticsearch/src/test/resources/ucoinj-elasticsearch-test.properties new file mode 100644 index 0000000000000000000000000000000000000000..5e30d7dc793d2b07b59bafe0e970fe4d23d708de --- /dev/null +++ b/ucoinj-elasticsearch/src/test/resources/ucoinj-elasticsearch-test.properties @@ -0,0 +1,12 @@ +ucoinj.node.host=metab.ucoin.fr +ucoinj.node.port=9201 + +ucoinj.elasticsearch.embedded.enable=true +ucoinj.elasticsearch.local=true +ucoinj.elasticsearch.http.enable=false +ucoinj.elasticsearch.cluster.name=ucoinj-elacticsearch-test + +#ucoinj.elasticsearch.cluster.name=ucoinj-elacticsearch + +#ucoinj.elasticsearch.host=192.168.0.5 +#ucoinj.elasticsearch.port=9300 diff --git a/ucoinj-ui-wicket/LICENSE b/ucoinj-ui-wicket/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..94a9ed024d3859793618152ea559a168bbcbb5e2 --- /dev/null +++ b/ucoinj-ui-wicket/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/ucoinj-web/lib/sodium.dll b/ucoinj-ui-wicket/lib/sodium.dll similarity index 100% rename from ucoinj-web/lib/sodium.dll rename to ucoinj-ui-wicket/lib/sodium.dll diff --git a/ucoinj-web/pom.xml b/ucoinj-ui-wicket/pom.xml similarity index 85% rename from ucoinj-web/pom.xml rename to ucoinj-ui-wicket/pom.xml index a313a440bc88018dd67226038c26eb214b10e62a..0f06552310d437d07b8bd5461255fbbc845bdeb7 100644 --- a/ucoinj-web/pom.xml +++ b/ucoinj-ui-wicket/pom.xml @@ -8,9 +8,9 @@ </parent> <groupId>io.ucoin</groupId> - <artifactId>ucoinj-web</artifactId> + <artifactId>ucoinj-ui-wicket</artifactId> <packaging>war</packaging> - <name>UCoin Java Client :: Web</name> + <name>uCoinj :: UI Wicket</name> <properties> <performRelease>false</performRelease> @@ -23,19 +23,25 @@ <!-- Unit test --> <ucoin.log.file>${project.build.directory}/${bundlePrefix}.log</ucoin.log.file> <wicket.configuration>development</wicket.configuration> + <synchro-web.config>${project.basedir}/src/test/resources/ucoinj-ui-wicket-test.properties</synchro-web.config> + <ucoinj.log.file>${project.build.directory}/${bundlePrefix}.log</ucoinj.log.file> </properties> <dependencies> <dependency> <groupId>io.ucoin</groupId> - <artifactId>ucoinj-core</artifactId> + <artifactId>ucoinj-core-client</artifactId> <version>${project.version}</version> </dependency> - - <!-- Elastic Search --> <dependency> - <groupId>org.elasticsearch</groupId> - <artifactId>elasticsearch</artifactId> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-core-shared</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.ucoin</groupId> + <artifactId>ucoinj-elasticsearch</artifactId> + <version>${project.version}</version> </dependency> <!-- WICKET DEPENDENCIES --> @@ -60,8 +66,8 @@ <artifactId>wicket-datetime</artifactId> </dependency> <dependency> - <groupId>org.wicketstuff</groupId> - <artifactId>wicketstuff-restannotations-json</artifactId> + <groupId>org.apache.wicket</groupId> + <artifactId>wicket-spring</artifactId> </dependency> <dependency> <groupId>com.googlecode.wicket-jquery-ui</groupId> @@ -80,6 +86,41 @@ <artifactId>guava</artifactId> </dependency> + <!-- Spring, for security and rest services --> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-config</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-core</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-webmvc</artifactId> + </dependency> + <dependency> + <groupId>org.aspectj</groupId> + <artifactId>aspectjweaver</artifactId> + </dependency> + <!-- LOGGING DEPENDENCIES - SLF4J --> <dependency> <groupId>org.slf4j</groupId> @@ -196,9 +237,11 @@ <jetty.forked.jvmArgs> -XX:+HeapDumpOnOutOfMemoryError -Xrunjdwp:transport=dt_socket,address=${jetty.forked.debug.port},server=y,suspend=n </jetty.forked.jvmArgs> - + <jetty.port>8080</jetty.port> + <maven.jar.main.class>fake</maven.jar.main.class> </properties> <build> + <defaultGoal></defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -231,6 +274,16 @@ <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> + <executions> + <execution> + <id>run</id> + <phase>prepare-package</phase> + <goals> + <!--goal>run-forked</goal--> + <goal>run</goal> + </goals> + </execution> + </executions> <configuration> <war>target/${project.parent.artifactId}-${project.version}.war</war> <!-- required to run jetty:stop goal --> @@ -239,23 +292,21 @@ <systemProperties> <systemProperty> <name>ucoinj-web.config</name> - <value>${project.basedir}/src/test/resources/ucoinj-web.config</value> + <value>${project.basedir}/src/test/resources/ucoinj-ui-wicket-test.properties</value> </systemProperty> <systemProperty> <name>jetty.port</name> - <value>8080</value> + <value>${jetty.port}</value> </systemProperty> <systemProperty> <name>log4j.configuration</name> - <value>${project.basedir}/src/test/resources/log4j.properties</value> + <value>file://${project.basedir}/src/test/resources/log4j.properties</value> </systemProperty> </systemProperties> <jvmArgs>${jetty.forked.jvmArgs}</jvmArgs> <reload>${jetty.reload}</reload> <useProvidedScope>true</useProvidedScope> <webXml>${jetty.docroot}/WEB-INF/web.xml</webXml> - <!-- Add log4j.properties (from test resources) - <extraClasspath>${project.basedir}/src/test/resources/log4j.properties</extraClasspath>--> <scanTargetPatterns> <scanTargetPattern> <directory>${project.basedir}/target/classes</directory> @@ -287,16 +338,23 @@ <version>${log4j.version}</version> </dependency> </dependencies> - <executions> - <execution> - <id>run</id> - <phase>prepare-package</phase> - <goals> - <!--goal>run-forked</goal--> - <goal>run</goal> - </goals> - </execution> - </executions> + </plugin> + + <plugin> + <artifactId>maven-enforcer-plugin</artifactId> + <inherited>false</inherited> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <inherited>false</inherited> + <configuration> + <skip>true</skip> + </configuration> </plugin> </plugins> </build> diff --git a/ucoinj-web/src/main/filtered-resources/log4j.properties b/ucoinj-ui-wicket/src/main/filtered-resources/log4j.properties similarity index 66% rename from ucoinj-web/src/main/filtered-resources/log4j.properties rename to ucoinj-ui-wicket/src/main/filtered-resources/log4j.properties index 3be3d3902d4f7ede17b6a4a70ae598ee9fd95c4c..20b4634ce432bf1ca1bd13d578b308a2212f4031 100644 --- a/ucoinj-web/src/main/filtered-resources/log4j.properties +++ b/ucoinj-ui-wicket/src/main/filtered-resources/log4j.properties @@ -7,18 +7,24 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p %m%n -# ucoinj core -log4j.logger.io.ucoin=INFO -log4j.logger.io.ucoin.client.core.config=WARN - -log4j.logger.org.nuiton.util=WARN -log4j.logger.org.nuiton.config=WARN -log4j.logger.org.nuiton.converter=WARN -log4j.logger.org.apache.commons.beanutils=WARN - # file logging (compatible with Ifremer/RIC) log4j.appender.file=org.apache.log4j.DailyRollingFileAppender -log4j.appender.file.file=${ucoin.log.file} +log4j.appender.file.file=${ucoinj.log.file} log4j.appender.file.DatePattern='.'yyyy-MM-dd log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} %5p (%F:%L) %M %m%n + +# uCoinj levels +log4j.logger.io.ucoin.ucoinj=INFO +#log4j.logger.io.ucoin.ucoinj.core=WARN +#log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG + +# Other frameworks levels +log4j.logger.org.nuiton.util=WARN +log4j.logger.org.nuiton.config=WARN +log4j.logger.org.nuiton.converter=WARN +log4j.logger.org.apache.commons.beanutils=WARN +log4j.logger.org.apache.wicket=WARN +log4j.logger.org.elasticsearch=WARN +log4j.logger.org.springframework=DEBUG +log4j.logger.org.springframework.security=TRACE diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..7008d3c13e3882b640aa3d10a5b087ae7c5557ef --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.java @@ -0,0 +1,142 @@ +package io.ucoin.ucoinj.web.application; + +/* + * #%L + * UCoin Java Client :: Web + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.elasticsearch.config.ConfigurationOption; +import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService; +import io.ucoin.ucoinj.web.config.WebConfiguration; +import io.ucoin.ucoinj.web.pages.admin.JobManagerPage; +import io.ucoin.ucoinj.web.pages.admin.ToolsPage; +import io.ucoin.ucoinj.web.pages.home.HomePage; +import io.ucoin.ucoinj.web.pages.login.LoginPage; +import io.ucoin.ucoinj.web.pages.registry.CurrencyPage; +import io.ucoin.ucoinj.web.pages.registry.CurrencyRegistryPage; +import io.ucoin.ucoinj.web.pages.wallet.WalletPage; +import io.ucoin.ucoinj.web.service.ServiceLocator; +import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; +import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.util.time.Duration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletContext; + +@Component("wicketApplication") +public class Application extends AuthenticatedWebApplication { + + private static final Logger log = LoggerFactory.getLogger(Application.class); + + private WebConfiguration config; + + public Application() { + config = WebConfiguration.instance(); + } + + /** + * @see org.apache.wicket.Application#init() + */ + @Override + public void init() { + super.init(); + // add the capability to gather extended browser info stuff like screen resolution + getRequestCycleSettings().setGatherExtendedBrowserInfo(true); + // set the default page timeout + getRequestCycleSettings().setTimeout(Duration.minutes(10)); + // set the UTF-8 charset + getRequestCycleSettings().setResponseRequestEncoding("UTF-8"); + getMarkupSettings().setDefaultMarkupEncoding("UTF-8"); + + mountPage("home", getHomePage()); + mountPage("currency/${currencyName}", CurrencyPage.class); + mountPage("admin/tools", ToolsPage.class); + mountPage("admin/jobs", JobManagerPage.class); + mountPage("login", LoginPage.class); + mountPage("wallet", WalletPage.class); + mountPage("currency-form", CurrencyRegistryPage.class); + + getMarkupSettings().setStripWicketTags(true); + + // Starting services + startServices(); + } + + /** + * @see org.apache.wicket.Application#getHomePage() + */ + @Override + public Class getHomePage() { + return HomePage.class; + } + + @Override + protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() { + return WebSession.class; + } + + @Override + protected Class<? extends WebPage> getSignInPageClass() { + return LoginPage.class; + } + + public WebConfiguration getConfiguration() { + return config; + } + + + + /* -- protected methods -- */ + + protected void startServices() { + try { + // Make sure the service locator is initialized + ServiceLocator.initDefault(getServletContext()); + } + catch(TechnicalException e) { + log.error("Error during services initialization: " + e.getMessage()); + throw new TechnicalException("Error during services initialization: " + e.getMessage(), e); + } + + // local node + boolean localEsNode = config.getApplicationConfig().getOptionAsBoolean(ConfigurationOption.LOCAL_ENABLE.getKey()); + if (localEsNode) { + + // Make sure main index exists + CurrencyIndexerService currencyIndexerService = ServiceLocator.instance().getCurrencyIndexerService(); + currencyIndexerService.createIndexIfNotExists(); + + // Make sure currency from default peer exists + try { + Peer peer = new Peer(config.getNodeHost(), config.getNodePort()); + currencyIndexerService.indexCurrencyFromPeer(peer); + } + catch(Exception e) { + } + } + } +} \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.properties b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.properties new file mode 100644 index 0000000000000000000000000000000000000000..88e54dcfb6145e1a7a189b3b451c0939bae4c730 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application.properties @@ -0,0 +1,21 @@ +base.pageTitle=uCoin registry +home.headerTitle=<h1>Welcome to <b>uCoin</b> registry</h1><h2>A open registry for all your <i>uCoin</i> currencies</h2> +base.footer=UCoin client v${version} +login.salt=Login or email (your crypto salt) +login.password=Password +login.header=Login +login.button=Login +login.failed=Authentification Failed + +home.search.hint=Search a currency name +home.searchButton=Search +home.result.divider.currency=Currencies +searchText=Search + +tools.startIndexLastBlocks=Index new blocks + +jobmanager.title=Job manager +jobmanager.jobs=Number of running jobs: ${jobCount} +jobmanager.issuer=User: ${issuer} + +currency.header=Currency \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication_fr.utf8.properties b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application_fr.utf8.properties similarity index 65% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication_fr.utf8.properties rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application_fr.utf8.properties index 49a77ecbcc80fc536d80c6e6f61fdb0a69303886..d906d78c0fd0995b9029c2c11165f2b12e194f71 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication_fr.utf8.properties +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/Application_fr.utf8.properties @@ -9,4 +9,10 @@ searchText=Rechercher currency.register.pubkey=Votre clef publique (dans la monnaie) currency.register.currencyJson=Information (format JSON) de la monnaie -currency.register.signature=Signature (du champ pr�c�dent) \ No newline at end of file +currency.register.signature=Signature (du champ pr�c�dent) + +tools.startIndexLastBlocks=Indexer les nouveaux blocks + +jobmanager.title=Gestionnaire de traitements +jobmanager.jobs=Nombre d'importation en cours : ${jobCount} +jobmanager.issuer=Utilisateur : ${issuer} \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/WebSession.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/WebSession.java new file mode 100644 index 0000000000000000000000000000000000000000..3df54962abfc612c8f852af47992e3a90be396dc --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/application/WebSession.java @@ -0,0 +1,75 @@ +package io.ucoin.ucoinj.web.application; + +/* + * #%L + * UCoin Java Client :: Web + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; +import org.apache.wicket.authroles.authorization.strategies.role.Roles; +import org.apache.wicket.request.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.context.SecurityContextHolder; + +public class WebSession extends AuthenticatedWebSession { + final static Logger log = LoggerFactory.getLogger(WebSession.class); + + private static final long serialVersionUID = 1L; + + public WebSession(Request request) { + super(request); + } + + @Override + public Roles getRoles() { + return null; + } + + @Override + public boolean authenticate(String username, String password) throws AuthenticationException { + /*ServiceLocator serviceLocator = ServiceLocator.instance(); + boolean authenticated; + try { + Authentication authentication = serviceLocator.getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username, password)); + SecurityContextHolder.getContext().setAuthentication(authentication); + authenticated = authentication.isAuthenticated(); + } catch (AuthenticationException e) { + String errorMessage = String.format("Authentication failed for user '%s' with error : %s", username, e.getLocalizedMessage()); + if (log.isDebugEnabled()) { + log.warn(errorMessage, e); + } + else { + log.warn(errorMessage, e); + } + throw e; + } + return authenticated; + */ + return true; + } + + + +} \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/behavior/FocusOnLoadBehavior.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/behavior/FocusOnLoadBehavior.java new file mode 100644 index 0000000000000000000000000000000000000000..264f31ecabd6b06f36499e90ca6c3f5e125c7301 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/behavior/FocusOnLoadBehavior.java @@ -0,0 +1,52 @@ +package io.ucoin.ucoinj.web.components.behavior; + +/* + * #%L + * SIH-Adagio Extractor web UI + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.OnDomReadyHeaderItem; + +public class FocusOnLoadBehavior extends AbstractDefaultAjaxBehavior { + /** + * Focus the component after loading + */ + private static final long serialVersionUID = -4369132303242175903L; + + @Override + public void renderHead(Component component, IHeaderResponse response) { + super.renderHead(component, response); + String javascript = "setTimeout(\"$('#" + component.getMarkupId() + "').focus()\", 100);" ; + response.render(OnDomReadyHeaderItem.forScript(javascript)); + } + + @Override + protected void respond(AjaxRequestTarget target) { + } + + @Override + public boolean isTemporary(Component component) { + return true; + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.html new file mode 100644 index 0000000000000000000000000000000000000000..8e8098795d2fc26d0aec3f4ac862c1d758cd553b --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.html @@ -0,0 +1,27 @@ +<!-- + #%L + SIH-Adagio Extractor web UI + %% + Copyright (C) 2012 - 2013 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<html xmlns:wicket="https://git1-us-west.apache.org/repos/asf/wicket/repo?p=wicket.git;a=blob_plain;f=wicket-core/src/main/resources/META-INF/wicket.xsd;hb=HEAD"> + <wicket:panel> + <span wicket:id="taskLabel">[task]</span> + <div wicket:id="progress"></div> + <div wicket:id="feedback" style="width: 100%;"></div> + </wicket:panel> +</html> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.java new file mode 100644 index 0000000000000000000000000000000000000000..7da7a8bbece902e9566c24a9e3f24268219c7ec3 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/components/progressionModel/ProgressionPanel.java @@ -0,0 +1,171 @@ +package io.ucoin.ucoinj.web.components.progressionModel; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel; +import com.googlecode.wicket.jquery.ui.widget.progressbar.ProgressBar; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import org.apache.wicket.ajax.AbstractAjaxTimerBehavior; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.panel.FeedbackPanel; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.util.time.Duration; + + +public class ProgressionPanel extends Panel { + private static final long serialVersionUID = 1L; + + private final AbstractAjaxTimerBehavior timer; + private final ProgressBar progressBar; + private final FeedbackPanel feedback; + private final Label taskLabel; + + private boolean stopped = false; + + public ProgressionPanel(String id, IModel<ProgressionModel> model) { + super(id, model); + + // Timer + timer = new AbstractAjaxTimerBehavior(Duration.ONE_SECOND) { + private static final long serialVersionUID = 1L; + + @Override + protected void onTimer(AjaxRequestTarget target) { + if (stopped) { + ProgressionPanel.this.stop(target); + return; + } + ProgressionModel progressionModel = getModelObject(); + if (progressionModel != null) { + synchronized (progressionModel) { + if (progressionModel.getStatus() == ProgressionModel.Status.FAILED || + progressionModel.getStatus() == ProgressionModel.Status.STOPPED) { + error(progressionModel.getMessage()); + } else { + info(progressionModel.getMessage()); + } + } + } + progressBar.refresh(target); + target.add(feedback, progressBar, taskLabel); + } + }; + add(timer); + + // Job label + taskLabel = new Label("taskLabel", new PropertyModel<String>(model, "task")); + taskLabel.setOutputMarkupId(true); + add(taskLabel); + + // ProgressBar + this.progressBar = new ProgressBar("progress", new PropertyModel<Integer>(model, "current")) { + + private static final long serialVersionUID = 1L; + + @Override + protected void onComplete(AjaxRequestTarget target) + { + timer.stop(target); // wicket6 + getFeedbackMessages().clear(); + + ProgressionPanel.this.onComplete(target); + + } + }; + // progressBar.add(new AjaxSelfUpdatingTimerBehavior(Duration.ONE_SECOND)); + progressBar.setOutputMarkupId(true); + progressBar.setVisibilityAllowed(true); + add(progressBar); + + // FeedbackPanel + feedback = new JQueryFeedbackPanel("feedback", this); + feedback.setOutputMarkupId(true); + add(feedback); + + } + + @Override + protected void onConfigure() { + super.onConfigure(); + + ProgressionModel progressionModel = getModelObject(); + if (progressionModel != null) { + synchronized (progressionModel) { + if (progressionModel.getStatus() == ProgressionModel.Status.FAILED || + progressionModel.getStatus() == ProgressionModel.Status.STOPPED) { + error(progressionModel.getMessage()); + } + else { + info(progressionModel.getMessage()); + } + } + } + } + + public void setModelObject(ProgressionModel progressionModel) { + if (getDefaultModelObject() != progressionModel) { + setDefaultModelObject(progressionModel); + } + } + + public void setModel(IModel<ProgressionModel> model) { + setDefaultModel(model); + } + + public void restart(AjaxRequestTarget target) { + stopped = false; + if (timer.isStopped()) { + timer.restart(target); + } + } + + public void stop(AjaxRequestTarget target) { + if (!timer.isStopped()) { + timer.stop(target); + } + stopped = true; + } + + public void onComplete(AjaxRequestTarget target) { + // could be override by subclass + } + + public IModel<ProgressionModel> getModel() { + @SuppressWarnings("unchecked") + IModel<ProgressionModel> result = (IModel<ProgressionModel>) getDefaultModel(); + return result; + } + + public ProgressionModel getModelObject() { + return (ProgressionModel)getDefaultModelObject(); + } + + /* -- Internal methods -- */ + + + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfiguration.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..7dcd51c4fd2757ee5e3dc5aa0f4d3caa33817040 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfiguration.java @@ -0,0 +1,197 @@ +package io.ucoin.ucoinj.web.config; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.config.ConfigurationOption; +import io.ucoin.ucoinj.core.client.service.ServiceLocator; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.core.util.StringUtils; +import io.ucoin.ucoinj.core.util.crypto.CryptoUtils; +import org.nuiton.config.ApplicationConfig; +import org.nuiton.util.version.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; + +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.io.File; +import java.util.Locale; +import java.util.Properties; + +public class WebConfiguration extends PropertyPlaceholderConfigurer { + + private static final String CONFIG_FILE_NAME = "ucoinj-web.config"; + + private static final String CONFIG_FILE_ENV_PROPERTY = CONFIG_FILE_NAME; + + private static final String CONFIG_FILE_JNDI_NAME = "java:comp/env/" + CONFIG_FILE_NAME; + + /* Logger */ + private static final Logger log = LoggerFactory.getLogger(WebConfiguration.class); + + private static WebConfiguration instance; + + public static WebConfiguration instance() { + return instance; + } + + static { + String configFile = getWebConfigFile(); + if (log.isDebugEnabled()) { + log.debug(String.format("Loading configuration from file [%s]", configFile)); + } + if (new File(configFile).exists() == false) { + log.warn(String.format("Configuration file not found [%s]. Make sure the path is correct.", configFile)); + } + instance = new WebConfiguration(configFile); + } + + private Configuration delegate; + + public WebConfiguration(String file, String... args) { + delegate = new Configuration(file, args); + Configuration.setInstance(delegate); + + io.ucoin.ucoinj.elasticsearch.config.Configuration esConfig = new io.ucoin.ucoinj.elasticsearch.config.Configuration(getApplicationConfig()); + io.ucoin.ucoinj.elasticsearch.config.Configuration.setInstance(esConfig); + + // Init Crypto (NaCL lib...) + initCrypto(); + } + + public Version getVersion() { + return delegate.getVersion(); + } + + public Locale getI18nLocale() { + return delegate.getI18nLocale(); + } + + public ApplicationConfig getApplicationConfig() { + return delegate.getApplicationConfig(); + } + + public String getVersionAsString() { + return getVersion().toString(); + } + + public String getUserPubkey() { + String pubkey = getApplicationConfig().getOption(WebConfigurationOption.USER_PUBKEY.getKey()); + if (StringUtils.isBlank(pubkey)) { + return null; + } + + // Compute the key (from salt/password) + pubkey = computeUserPubkey(); + if (StringUtils.isBlank(pubkey)) { + return null; + } + + // Store computed pubkey back into config + getApplicationConfig().setOption(WebConfigurationOption.USER_PUBKEY.getKey(), pubkey); + return pubkey; + } + + public String getNodeHost() { + return delegate.getNodeHost(); + } + + public int getNodePort() { + return delegate.getNodePort(); + } + + /* -- Internal methods -- */ + protected static String getWebConfigFile() { + // Could override config file name (useful for dev) + String configFile = CONFIG_FILE_NAME; + if (System.getProperty(CONFIG_FILE_ENV_PROPERTY) != null) { + configFile = System.getProperty(CONFIG_FILE_ENV_PROPERTY); + configFile = configFile.replaceAll("\\\\", "/"); + } + else { + try { + InitialContext ic = new InitialContext(); + String jndiPathToConfFile = (String) ic.lookup(CONFIG_FILE_JNDI_NAME); + if (StringUtils.isNotBlank(jndiPathToConfFile)) { + configFile = jndiPathToConfFile; + } + } catch (NamingException e) { + log.warn(String.format("Error while reading JNDI initial context. Skip configuration path override, from context [%s]", CONFIG_FILE_JNDI_NAME)); + } + } + + return configFile; + } + + protected void initCrypto() { + if (log.isInfoEnabled()) { + log.info("Starts Sodium (NaCL) library"); + } + + try { + // This call will load the sodium library + ServiceLocator.instance().getCryptoService(); + } catch (Throwable e) { + throw new TechnicalException("Crypto lib (NaCL) initialization failed. Make sure sodium has been installed (or add library into a ./lib directory).", e); + } + } + + /** + * Compute the user pubkey, from salt+password in config. + * If salt or password are missed, return null + * @return + */ + protected String computeUserPubkey() { + String salt = getApplicationConfig().getOption(WebConfigurationOption.USER_SALT.getKey()); + String password = getApplicationConfig().getOption(WebConfigurationOption.USER_PASSWORD.getKey()); + if (io.ucoin.ucoinj.core.util.StringUtils.isNotBlank(salt) + && io.ucoin.ucoinj.core.util.StringUtils.isNotBlank(password)) { + byte[] pubKey = ServiceLocator.instance().getCryptoService().getKeyPair(salt, password).getPubKey(); + return CryptoUtils.encodeBase58(pubKey); + } + else { + return null; + } + } + + @Override + protected String resolvePlaceholder(String placeholder, Properties props) { + if (getApplicationConfig() == null) { + throw new TechnicalException( + "delegate.getApplicationConfig() must not be null. Please initialize Configuration instance with a not null applicationConfig BEFORE starting Spring."); + } + + // Try to resolve placeholder from application configuration + String optionValue = getApplicationConfig().getOption(placeholder); + if (optionValue != null) { + return optionValue; + } + + // If not found in configuration, delegate to the default Spring mecanism + return super.resolvePlaceholder(placeholder, props); + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationOption.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationOption.java new file mode 100644 index 0000000000000000000000000000000000000000..4ff05152bdfd1cff374a19afdc26dba0d45e27a3 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationOption.java @@ -0,0 +1,159 @@ +package io.ucoin.ucoinj.web.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationOption.java 1441 2013-12-09 20:13:47Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationOption.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ConfigOptionDef; +import org.nuiton.util.Version; + +import java.io.File; +import java.net.URL; +import java.util.Locale; + +import static org.nuiton.i18n.I18n.n; + +/** + * All application configuration options. + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public enum WebConfigurationOption implements ConfigOptionDef { + + // ------------------------------------------------------------------------// + // -- READ-WRITE OPTIONS ---------------------------------------------------// + // ------------------------------------------------------------------------// + + SECURITY_TYPE( + "ucoinj.security.type", + n("ucoinj.config.option.security.type.description"), + "pubkey", + String.class, + false), + + USER_SALT( + "ucoinj.salt", + n("ucoinj.config.option.salt.description"), + "", + String.class, + false), + + USER_PASSWORD( + "ucoinj.password", + n("ucoinj.config.option.password.description"), + "", + String.class, + false), + + USER_PUBKEY( + "ucoinj.pubkey", + n("ucoinj.config.option.pubkey.description"), + "", + String.class, + false), + ; + + /** Configuration key. */ + private final String key; + + /** I18n key of option description */ + private final String description; + + /** Type of option */ + private final Class<?> type; + + /** Default value of option. */ + private String defaultValue; + + /** Flag to not keep option value on disk */ + private boolean isTransient; + + /** Flag to not allow option value modification */ + private boolean isFinal; + + WebConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type, + boolean isTransient) { + this.key = key; + this.description = description; + this.defaultValue = defaultValue; + this.type = type; + this.isTransient = isTransient; + this.isFinal = isTransient; + } + + WebConfigurationOption(String key, + String description, + String defaultValue, + Class<?> type) { + this(key, description, defaultValue, type, true); + } + + @Override + public String getKey() { + return key; + } + + @Override + public Class<?> getType() { + return type; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getDefaultValue() { + return defaultValue; + } + + @Override + public boolean isTransient() { + return isTransient; + } + + @Override + public boolean isFinal() { + return isFinal; + } + + @Override + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + @Override + public void setTransient(boolean newValue) { + // not used + } + + @Override + public void setFinal(boolean newValue) { + // not used + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationProvider.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..b53a225eb45b44c9b3c91277ceafdf70e59ac8ec --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/config/WebConfigurationProvider.java @@ -0,0 +1,63 @@ +package io.ucoin.ucoinj.web.config; + +/* + * #%L + * Tutti :: Persistence + * $Id: TuttiConfigurationProvider.java 1418 2013-12-01 21:18:22Z tchemit $ + * $HeadURL: http://svn.forge.codelutin.com/svn/tutti/trunk/tutti-persistence/src/main/java/fr/ifremer/tutti/TuttiConfigurationProvider.java $ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import io.ucoin.ucoinj.elasticsearch.config.ConfigurationAction; +import io.ucoin.ucoinj.elasticsearch.config.ConfigurationOption; +import org.nuiton.config.ApplicationConfigProvider; +import org.nuiton.config.ConfigActionDef; +import org.nuiton.config.ConfigOptionDef; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l; + +/** + * Config provider (for site generation). + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + */ +public class WebConfigurationProvider implements ApplicationConfigProvider { + + @Override + public String getName() { + return "ucoinj-web"; + } + + @Override + public String getDescription(Locale locale) { + return l(locale, "ucoinj-web.config"); + } + + @Override + public ConfigOptionDef[] getOptions() { + return WebConfigurationOption.values(); + } + + @Override + public ConfigActionDef[] getActions() { + return new ConfigActionDef[0]; + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/model/WicketProgressionModel.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/model/WicketProgressionModel.java new file mode 100644 index 0000000000000000000000000000000000000000..5c25701afd1cbf5dbd06988bf8caf5f5a4607c76 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/model/WicketProgressionModel.java @@ -0,0 +1,23 @@ +package io.ucoin.ucoinj.web.model; + +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import org.apache.wicket.model.LoadableDetachableModel; + +public class WicketProgressionModel extends LoadableDetachableModel<io.ucoin.ucoinj.core.model.ProgressionModel> { + + private static final long serialVersionUID = 1L; + + private final String jobId; + + public WicketProgressionModel(String jobId) { + this.jobId = jobId; + } + + @Override + protected io.ucoin.ucoinj.core.model.ProgressionModel load() { + io.ucoin.ucoinj.core.model.ProgressionModel object = ServiceLocator.instance().getExecutorService().getProgressionByJobId(jobId); + return object; + } + + +} \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.html similarity index 53% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.html rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.html index 221d51f15a8c71f72a6e8dd1b4a05d197b08b741..da4ceeaabad605c7e99c1e140717f37c932304c4 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.html +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.html @@ -23,28 +23,40 @@ <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta wicket:id="contentLanguage" http-equiv="Content-Language" content=""> - <wicket:header-items/> - <title wicket:id="pageTitle">UCoin client :: UI wicket</title> + <meta name="format-detection" content="telephone=no"> + <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1"> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="msapplication-tap-highlight" content="no"> + + <title wicket:id="pageTitle">uCoinj :: Web</title> <link rel="shortcut icon" href="favicon.ico"> - <link type="text/css" rel="stylesheet" href="css/jquery-mobile-ucoin/jquery.mobile.ucoin.css"> <link type="text/css" rel="stylesheet" href="css/jquery-mobile/jquery.mobile-1.4.5.min.css"> - <link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:300,400,700"> - <link type="text/css" rel="stylesheet" href="ucoin.css"/> + <link type="text/css" rel="stylesheet" href="css/ucoinj/jquery.mobile.override.css"> + <link type="text/css" rel="stylesheet" href="css/ucoinj/ucoinj.css"/> - <script src="js/jquery-1.11.2.min.js"></script> + <script src="js/jquery-2.1.4.min.js"></script> <script src="js/jquery.mobile-1.4.5.min.js"></script> + <script src="js/scrypt-em.js"></script> + <script src="js/nacl_factory.js"></script> + <script src="js/base58.js"></script> + <script src="js/base64.js"></script> + <script src="js/ucoinj.js"></script> + <script src="js/app.js"></script> + + <wicket:header-items/> </head> <body class="ui-mobile-viewport ui-overlay-a"> - <div class="ui-page ui-page-theme-a ui-page-footer-fixed ui-page-active"> - <div class="ui-content jqm-content"> - <div wicket:id="feedback"></div> - <wicket:child /> - <div class="jqm-footer ui-footer ui-bar-inherit ui-footer-fixed slideup" > - <wicket:message key="base.footer"><span wicket:id="version">[version]</span></wicket:message> - </div> - </div> + <div data-role="page" class="type-interior" data-theme="a"> + <div wicket:id="feedback"></div> + + <wicket:child /> + + <div data-role="footer" data-position="fixed" data-theme="d"> + <wicket:message key="base.footer"><span wicket:id="version">[version]</span></wicket:message> + </div> </div> </body> </html> \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.java similarity index 80% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.java rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.java index 96f477f0ff94f2c37eeb1a54da5b82fe2781bb0f..cf097cc3672289425bdc30c21b8d3a9b3f4fa593 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/BasePage.java +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/BasePage.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.pages; +package io.ucoin.ucoinj.web.pages; /* * #%L @@ -24,9 +24,9 @@ package io.ucoin.client.ui.pages; import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel; -import io.ucoin.client.ui.application.UcoinApplication; -import io.ucoin.client.ui.application.UcoinSession; -import io.ucoin.client.ui.config.WebConfiguration; +import io.ucoin.ucoinj.web.application.Application; +import io.ucoin.ucoinj.web.application.WebSession; +import io.ucoin.ucoinj.web.config.WebConfiguration; import org.apache.wicket.AttributeModifier; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.WebPage; @@ -38,11 +38,11 @@ import org.apache.wicket.request.mapper.parameter.PageParameters; public class BasePage extends WebPage { private static final long serialVersionUID = 2589483412605551035L; - private FeedbackPanel feedback = null; + private FeedbackPanel feedback = null; public BasePage(final PageParameters parameters) { - UcoinSession session = (UcoinSession)getSession(); + WebSession session = (WebSession)getSession(); // page title add(new Label("pageTitle", new StringResourceModel("base.pageTitle", this, null))); @@ -65,20 +65,24 @@ public class BasePage extends WebPage { } - public final UcoinSession getUcoinSession() { - return (UcoinSession)getSession(); + public final WebSession getWebSession() { + return (WebSession)getSession(); } - public final UcoinApplication getUcoinApplication() { - return (UcoinApplication)getApplication(); + public final Application getWebApplication() { + return (Application)getApplication(); } public final WebConfiguration getConfiguration() { - return getUcoinApplication().getConfiguration(); + return getWebApplication().getConfiguration(); } public void setUseGlobalFeedback(boolean useGlobalFeedback) { feedback.setVisibilityAllowed(useGlobalFeedback); } + + protected FeedbackPanel getFeedbackPanel() { + return feedback; + } } diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.html new file mode 100644 index 0000000000000000000000000000000000000000..374f19da39a24a50ef4d5ea965e29e6b0f84eada --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.html @@ -0,0 +1,52 @@ +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<html + xmlns:wicket="http://git-wip-us.apache.org/repos/asf/wicket/repo?p=wicket.git;a=blob_plain;f=wicket-core/src/main/resources/META-INF/wicket-1.5.xsd;hb=master"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>Job manager</title> +</head> +<body> + <wicket:extend> + + <!-- Import --> + <div class="subtitle"> + <wicket:message key="jobmanager.jobs"> + <span wicket:id="jobCount">[jobCount]</span> + </wicket:message> + </div> + <p> + <ul> + <li class="jm-list" wicket:id="jobList"> + <div class="jm-user"> + <wicket:message key="jobmanager.issuer"> + <span wicket:id="issuer">[issuer]</span> + </wicket:message> + </div> + <div class="jm-progressbar" wicket:id="progress">[progress]</div> + </li> + </ul> + </p> + </wicket:extend> +</body> +</html> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.java new file mode 100644 index 0000000000000000000000000000000000000000..4b9c02cfbaede4dfe8d726e5bd89c0dbb58e0249 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/JobManagerPage.java @@ -0,0 +1,101 @@ +package io.ucoin.ucoinj.web.pages.admin; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import io.ucoin.ucoinj.web.components.progressionModel.ProgressionPanel; +import io.ucoin.ucoinj.web.model.WicketProgressionModel; +import io.ucoin.ucoinj.web.pages.BasePage; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.elasticsearch.service.task.JobVO; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.StringResourceModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.time.Duration; + +import java.util.List; + +public class JobManagerPage extends BasePage { + + private static final long serialVersionUID = 1L; + + public JobManagerPage(PageParameters pageParameters) { + super(pageParameters); + + // Create models (list of progressionModel) + LoadableDetachableModel<List<JobVO>> jobListModel = new LoadableDetachableModel<List<JobVO>>() { + private static final long serialVersionUID = 1L; + + @Override + protected List<JobVO> load() { + return ServiceLocator.instance().getExecutorService().getAllJobs(); + } + }; + + add(new Label("jobCount", new PropertyModel<Integer>(jobListModel, "size"))); + + // List of import jobs + ListView<JobVO> jobListView = new ListView<JobVO>("jobList", jobListModel) { + private static final long serialVersionUID = 1L; + + @Override + protected void populateItem(ListItem<JobVO> item) { + // User infos + item.add(new Label("issuer", new PropertyModel<Integer>(item.getModel(), "issuer"))); + + // Progress bar + String jobId = item.getModelObject().getId(); + ProgressionPanel progressionPanel = new ProgressionPanel("progress", new WicketProgressionModel(jobId)) { + private static final long serialVersionUID = 1L; + + @Override + public void onComplete(AjaxRequestTarget target) { + stop(target); + } + }; + progressionPanel.setOutputMarkupId(true); + progressionPanel.setOutputMarkupPlaceholderTag(true); + item.add(progressionPanel); + } + }; + jobListView.setOutputMarkupId(true); + add(jobListView); + + add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(5))); + } + + /* -- internal methods -- */ + + protected IModel<String> getPageTitleModel() { + return new StringResourceModel("jobmanager.title", this, null); + } + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.html new file mode 100644 index 0000000000000000000000000000000000000000..9b76c10dfec113d3cdbe9cc2958ff5ce3b7f53dc --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.html @@ -0,0 +1,39 @@ +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<html + xmlns:wicket="http://git-wip-us.apache.org/repos/asf/wicket/repo?p=wicket.git;a=blob_plain;f=wicket-core/src/main/resources/META-INF/wicket-1.5.xsd;hb=master"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> +<title>Tools</title> +</head> +<body> + <wicket:extend> + <div wicket:id="progress"></div> + + <form wicket:id="form"> + <a href="#" data-role="button" data-icon="refresh" data-iconpos="left" wicket:id="startIndexLastBlocksButton"><wicket:message key="tools.startIndexLastBlocks">[tools.startIndexLastBlocks]</wicket:message></a> + + </form> + </wicket:extend> +</body> +</html> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.java new file mode 100644 index 0000000000000000000000000000000000000000..e52b73736f7f96ba3722fc1ab23c0a539cfc00dc --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/admin/ToolsPage.java @@ -0,0 +1,196 @@ +package io.ucoin.ucoinj.web.pages.admin; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import io.ucoin.ucoinj.core.model.ProgressionModelImpl; +import io.ucoin.ucoinj.web.components.progressionModel.ProgressionPanel; +import io.ucoin.ucoinj.web.model.WicketProgressionModel; +import io.ucoin.ucoinj.web.pages.BasePage; +import io.ucoin.ucoinj.core.client.config.Configuration; +import io.ucoin.ucoinj.core.client.model.local.Peer; +import io.ucoin.ucoinj.core.model.ProgressionModel; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.elasticsearch.service.task.Job; +import org.apache.commons.lang3.StringUtils; +import org.apache.wicket.ajax.AbstractAjaxTimerBehavior; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.StringResourceModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.time.Duration; + +public class ToolsPage extends BasePage { + private static final long serialVersionUID = 1L; + + private final ProgressionPanel progressionPanel; + + private boolean isIndexingLastBlocksRunning; + + private AbstractAjaxTimerBehavior selfUpdatingTimer; + + private WicketProgressionModel progressionModel; + + public ToolsPage(final PageParameters parameters) { + super(parameters); + + IModel<ToolsPage> model = new CompoundPropertyModel<ToolsPage>(this); + + isIndexingLastBlocksRunning = false; + + // Progression panel + progressionModel = new WicketProgressionModel(getSession().getId()); + progressionPanel = new ProgressionPanel("progress", progressionModel) { + private static final long serialVersionUID = 1L; + @Override + protected void onConfigure() { + super.onConfigure(); + setVisibilityAllowed(isIndexingLastBlocksRunning); + } + + @Override + public void onComplete(AjaxRequestTarget target) { + ToolsPage.this.onIndexLastBlocksComplete(target); + } + }; + progressionPanel.setOutputMarkupId(true); + progressionPanel.setOutputMarkupPlaceholderTag(true); + add(progressionPanel); + + Form<ToolsPage> form = new Form<ToolsPage>("form", model); + form.setOutputMarkupId(true); + add(form); + + AjaxButton startIndexLastBlocksButton = new AjaxButton("startIndexLastBlocksButton", form) { + private static final long serialVersionUID = 1L; + + @Override + protected void onAfterSubmit(AjaxRequestTarget target, Form<?> form) { + super.onAfterSubmit(target, form); + startIndexLastBlocks(target); + } + }; + form.add(startIndexLastBlocksButton); + + // auto refresh + selfUpdatingTimer = new AbstractAjaxTimerBehavior(Duration.seconds(5)) { + @Override + protected void onTimer(AjaxRequestTarget target) { + //String message = new StringResourceModel("tools.refreshLastUpdateDate.done", ToolsPage.this, new Model<ToolsPage>(ToolsPage.this)).getString(); + stop(target); + + //info(message); + target.add(ToolsPage.this); + } + }; + selfUpdatingTimer.stop(null); + add(selfUpdatingTimer); + } + + @Override + protected void onConfigure() { + super.onConfigure(); + ProgressionModel progression = progressionModel.getObject(); + + if (progression != null) { + // Refresh fields + isIndexingLastBlocksRunning = progression != null && (progression.getStatus() == ProgressionModel.Status.WAITING_EXECUTION + || progression.getStatus() == ProgressionModel.Status.RUNNING); + if (isIndexingLastBlocksRunning) { + getFeedbackPanel().setVisibilityAllowed(false); + } + } + else { + isIndexingLastBlocksRunning = false; + } + } + + /* -- internal methods -- */ + + protected IModel<String> getPageTitleModel() { + return new StringResourceModel("tools.title", this, null); + } + + protected void startIndexLastBlocks(AjaxRequestTarget target) { + isIndexingLastBlocksRunning = true; + final ProgressionModel progressionModel = new ProgressionModelImpl(); + Runnable runnable = new Runnable() { + @Override + public void run() { + Peer peer = checkConfigAndGetPeer(Configuration.instance()); + if (peer != null) { + try { + ServiceLocator.instance().getBlockIndexerService().indexLastBlocks(peer, progressionModel); + } + catch(Exception e) { + } + finally { + isIndexingLastBlocksRunning = false; + } + } + + } + }; + + ServiceLocator.instance().getExecutorService().execute(runnable, + getWebSession().getId(), + "admin", + getWebSession().getLocale(), + progressionModel); + + //progressionPanel.setModel(new Model<>(progressionModel)); + progressionPanel.setDefaultModelObject(progressionModel); + progressionPanel.restart(target); + + // Mask feedback panel, to avoid multiple message) + getFeedbackPanel().setVisibilityAllowed(false); + + target.add(ToolsPage.this); + } + + protected Peer checkConfigAndGetPeer(Configuration config) { + if (StringUtils.isBlank(config.getNodeHost())) { + return null; + } + if (config.getNodePort() <= 0) { + return null; + } + + Peer peer = new Peer(config.getNodeHost(), config.getNodePort()); + return peer; + } + + + protected void onIndexLastBlocksComplete(AjaxRequestTarget target) { + // Restore the UI + progressionPanel.setVisibilityAllowed(false); + getFeedbackPanel().setVisibilityAllowed(true); + + target.add(this); + } +} \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.html similarity index 90% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.html rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.html index 7ab34a6df09d7633013347b73c6edfc16d054216..8f148496d3439cbe6398b1cedebe6ce9f16b4bd3 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.html +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.html @@ -24,14 +24,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Home</title> <wicket:head> - <title>Wicket - jQuery UI: auto-complete (form submit)</title> <style type="text/css"> - .ui-autocomplete { - max-height: 200px; - overflow-y: auto; - overflow-x: hidden; - padding-right: 20px; - } </style> </wicket:head> </head> @@ -66,7 +59,7 @@ <wicket:message key="home.result.divider.currency">[home.result.divider.currency]</wicket:message> </li> <li wicket:id="resultItems"> - <a href="#" class="ui-btn ui-btn-icon-right ui-icon-carat-r"><span wicket:id="currencyName"/></a> + <a href="#" class="ui-btn ui-btn-icon-right ui-icon-carat-r" wicket:id="openCurrencyLink"><span wicket:id="currencyName"/></a> </li> <!-- class="ui-btn ui-btn-icon-right ui-icon-carat-r" --> </ul> diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java similarity index 84% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.java rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java index 27f6efbc2c95eebb9e9fc2937222c37366c9511b..e7b4f9e4a73991c9b7b5d0101a8b9577e3e6c962 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/home/HomePage.java +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/home/HomePage.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.pages.home; +package io.ucoin.ucoinj.web.pages.home; /* * #%L @@ -26,10 +26,12 @@ package io.ucoin.client.ui.pages.home; //import com.googlecode.wicket.jquery.ui.form.autocomplete.AutoCompleteTextField; import com.googlecode.wicket.jquery.ui.panel.JQueryFeedbackPanel; -import io.ucoin.client.core.model.Currency; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.service.search.CurrencyIndexerService; -import io.ucoin.client.ui.pages.BasePage; +import io.ucoin.ucoinj.elasticsearch.model.Currency; +import io.ucoin.ucoinj.elasticsearch.model.SearchResult; +import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.web.pages.BasePage; +import io.ucoin.ucoinj.web.pages.registry.CurrencyPage; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.ajax.AjaxRequestTarget; @@ -41,13 +43,16 @@ import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Button; import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.FeedbackPanel; +import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.util.ListModel; import org.apache.wicket.request.Response; import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.string.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,7 +68,7 @@ public class HomePage extends BasePage { private AutoCompleteTextField<String> searchTextField; private String searchQuery = ""; private WebMarkupContainer resultParent; - private ListView<Currency> resultListView; + private ListView<SearchResult> resultListView; public HomePage(final PageParameters parameters) { super(parameters); @@ -112,7 +117,7 @@ public class HomePage extends BasePage { return doSuggestions(input).iterator(); } }; - searchTextField.add(new AjaxFormComponentUpdatingBehavior("onkeyup") + searchTextField.add(new AjaxFormComponentUpdatingBehavior("keyup") { @Override protected void onUpdate(AjaxRequestTarget target){ @@ -150,7 +155,7 @@ public class HomePage extends BasePage { form.setDefaultButton(searchButton); } - //form.add(new AjaxFormValidatingBehavior("onkeyup", Duration.ONE_SECOND)); + //form.add(new AjaxFormValidatingBehavior("keyup", Duration.ONE_SECOND)); // Search result @@ -162,15 +167,23 @@ public class HomePage extends BasePage { resultParent.setVisible(false); add(resultParent); - // Result items + // History items { - resultListView = new ListView<Currency>("resultItems", new ListModel<Currency>()) { - protected void populateItem(ListItem<Currency> item) { - Currency currency = item.getModelObject(); - Label label = new Label("currencyName", currency.getCurrencyName()); + resultListView = new ListView<SearchResult>("resultItems", new ListModel<SearchResult>()) { + protected void populateItem(ListItem<SearchResult> item) { + SearchResult result = item.getModelObject(); + + // link + PageParameters pageParameters = new PageParameters(); + pageParameters.add(CurrencyPage.CURRENCY_PARAMETER, result.getId()); + BookmarkablePageLink link = new BookmarkablePageLink("openCurrencyLink", CurrencyPage.class, pageParameters); + item.add(link); + + // Currency name + Label label = new Label("currencyName", result.getValue()); label.setEscapeModelStrings(false); label.setOutputMarkupPlaceholderTag(false); - item.add(label); + link.add(label); } }; resultListView.setReuseItems(true); @@ -192,7 +205,7 @@ public class HomePage extends BasePage { else { CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService(); - List<Currency> result = service.searchCurrencies(searchQuery); + List<SearchResult> result = service.searchCurrenciesAsVO(searchQuery); if (CollectionUtils.isNotEmpty(result)) { resultListView.removeAll(); diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.html new file mode 100644 index 0000000000000000000000000000000000000000..58e9913f9545933fd051d4127eb0bdd5b9314ed6 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.html @@ -0,0 +1,96 @@ +<!-- + #%L + UCoin Java Client :: Web + %% + Copyright (C) 2014 - 2015 EIS + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> +<html xmlns:wicket="http://git-wip-us.apache.org/repos/asf/wicket/repo?p=wicket.git;a=blob_plain;f=wicket-core/src/main/resources/META-INF/wicket-1.5.xsd;hb=master"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + <!--<wicket:head> + <script type="text/javascript"> + function submitLogin(event, app) { + var salt = $('#localSalt').val(); + var password = $('#localPassword').val(); + var challengeMessage = $('#challengeMessage').val(); + + if (salt === "" || password === "" || challengeMessage === "") { + event.preventDefault(); + return; + } + + var challengeMessage = $('#challengeMessage').val(); + app.connect(salt, password); + var sign = app.sign(challengeMessage); + + $('#username').val(app.wallet.pubkey); + $('#password').val(sign + '|' + challengeMessage); + $('#form').submit(); + } + + $( document ).ready(function() { + var app = uCoinj(document); + + $('#localPassword').keypress(function( event ) { + if (event.which == 13 ) { + submitLogin(event, app); + } + }); + + $('#loginButton').click(function(event) { + submitLogin(event); + }); + + + }); + </script> + </wicket:head>--> +</head> +<body> +<wicket:extend> + + <!-- header --> + <div data-role="header" data-position="fixed" data-add-back-btn="true" data-theme="c"> + <h1> + <wicket:message key="login.header"/> + </h1> + </div> + + <label for="localSalt"><wicket:message key="login.salt"/></label> + <input id="localSalt" name="localSalt" type="text" data-clear-btn="true" value="" /> + + <label for="localPassword"><wicket:message key="login.password"/></label> + <input id="localPassword" name="localPassword" type="password" data-clear-btn="true" value="" + onkeypress="javascript:if(event.which==13){app.login(event);}"/> + + <input type="hidden" wicket:id="challengeMessage"/> + + <form wicket:id="form" id="form" method="POST" action="/j_spring_security_check"> + + <input type="hidden" id="username" name="username"/> + <input type="hidden" id="password" name="password"/> + + <label for="submitButton" id="error">[error]</label> + <input id="submitButton" name="submitButton" + data-icon="check" type="button" data-theme="b" + wicket:message="value:login.button" + onclick="javascript:app.login(event);"/> + </form> +</wicket:extend> +</body> +</html> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.java new file mode 100644 index 0000000000000000000000000000000000000000..6913a6543b95f5221d294cebddf05d8a1737c05f --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/login/LoginPage.java @@ -0,0 +1,68 @@ +package io.ucoin.ucoinj.web.pages.login; + +/* + * #%L + * UCoin Java Client :: Web + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.web.application.Application; +import io.ucoin.ucoinj.web.application.WebSession; +import io.ucoin.ucoinj.web.pages.BasePage; +import io.ucoin.ucoinj.web.security.SecurityContextHelper; +import io.ucoin.ucoinj.web.service.ServiceLocator; +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.slf4j.LoggerFactory; + +public class LoginPage extends BasePage { + + public LoginPage(final PageParameters parameters) { + super(parameters); + + if (SecurityContextHelper.isAuthenticateNotAnonymous()) { + setResponsePage(Application.get().getHomePage()); + return; + } + WebSession sesion = getWebSession(); + LoggerFactory.getLogger(LoginPage.class).info(""+ sesion.isSignedIn()); + + // Challenge message + WebMarkupContainer challengeMessageField = new WebMarkupContainer("challengeMessage") { + @Override + protected void onComponentTag(ComponentTag tag) { + super.onComponentTag(tag); + + tag.put("value", ServiceLocator.instance().getChallengeMessageStore().createNewChallenge()); + } + }; + challengeMessageField.setMarkupId("challengeMessage"); + challengeMessageField.setOutputMarkupId(true); + add(challengeMessageField); + + Form form = new Form("form"); + form.setMarkupId("form"); + form.setOutputMarkupId(true); + add(form); + } + +} \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.html similarity index 60% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.html rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.html index 483c09f8021ee9548faa5ccb63cbdd539ffb9b9c..92ceb042145d5fb531e485398d2d482dce361bed 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/login/LoginPage.html +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.html @@ -25,10 +25,30 @@ </head> <body> <wicket:extend> - - <label for="text-3"><wicket:message key="login.username"/></label> - <input type="text" data-clear-btn="true" name="text-3" id="text-3" value=""> - + + <!-- header --> + <div data-role="header" data-position="fixed" data-add-back-btn="true" data-back-btn-text="Back" + data-theme="f" > + <h1> + <wicket:message key="currency.header"/> + </h1> + </div> + + + <!-- container --> + <div data-role="content" class="ui-content" data-theme="f"> + + <!-- currency_name --> + <div name="currency_name" id="currency_name" data-role="appery_label"> + <label wicket:id="currencyName"/> + </div> + + <!-- member_count --> + <div name="member_count" id="member_count" data-role="appery_label"> + Label + </div> + </div> + </wicket:extend> </body> </html> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java new file mode 100644 index 0000000000000000000000000000000000000000..693ce2a057eb239af1c0aadef2a9379a435f0eae --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyPage.java @@ -0,0 +1,56 @@ +package io.ucoin.ucoinj.web.pages.registry; + +/* + * #%L + * UCoin Java Client :: Web + * %% + * Copyright (C) 2014 - 2015 EIS + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.web.pages.BasePage; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.model.CompoundPropertyModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.util.string.StringValue; + +public class CurrencyPage extends BasePage { + + public final static String CURRENCY_PARAMETER = "currencyName"; + + public CurrencyPage(final PageParameters parameters) { + super(parameters); + + StringValue parameCurrencyName = parameters.get(CURRENCY_PARAMETER); + final String currencyName = parameCurrencyName.toString(); + + setDefaultModel(new CompoundPropertyModel<Currency>(new LoadableDetachableModel<Currency>() { + @Override + protected Currency load() { + return ServiceLocator.instance().getCurrencyIndexerService().getCurrencyById(currencyName); + } + })); + + add(new Label("currencyName")); + + //add(new Label("memberCount")); + } +} \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/registry/CurrencyRegistryPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyRegistryPage.html similarity index 100% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/registry/CurrencyRegistryPage.html rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyRegistryPage.html diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/registry/CurrencyRegistryPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyRegistryPage.java similarity index 91% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/registry/CurrencyRegistryPage.java rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyRegistryPage.java index a05aa1ec8e9fe070e719d4d34f230d76de51daab..96fe1c298aa7b30a71e3d81ce41c326cb5aa3bed 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/registry/CurrencyRegistryPage.java +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/registry/CurrencyRegistryPage.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.pages.registry; +package io.ucoin.ucoinj.web.pages.registry; /* * #%L @@ -23,7 +23,7 @@ package io.ucoin.client.ui.pages.registry; */ -import io.ucoin.client.ui.pages.BasePage; +import io.ucoin.ucoinj.web.pages.BasePage; import org.apache.wicket.request.mapper.parameter.PageParameters; public class CurrencyRegistryPage extends BasePage { diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/wallet/WalletPage.html b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/wallet/WalletPage.html similarity index 100% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/wallet/WalletPage.html rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/wallet/WalletPage.html diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/wallet/WalletPage.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/wallet/WalletPage.java similarity index 91% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/pages/wallet/WalletPage.java rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/wallet/WalletPage.java index f03f36d69a2034fbb43c37f05f1e7b47f197197b..0514e796938f0b1f4bbd139e88f27eec53a1250a 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/pages/wallet/WalletPage.java +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/pages/wallet/WalletPage.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.pages.wallet; +package io.ucoin.ucoinj.web.pages.wallet; /* * #%L @@ -23,7 +23,7 @@ package io.ucoin.client.ui.pages.wallet; */ -import io.ucoin.client.ui.pages.BasePage; +import io.ucoin.ucoinj.web.pages.BasePage; import org.apache.wicket.request.mapper.parameter.PageParameters; public class WalletPage extends BasePage { diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/service/rest/CurrencyRestService.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java similarity index 54% rename from ucoinj-web/src/main/java/io/ucoin/client/ui/service/rest/CurrencyRestService.java rename to ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java index 93a87ba0d0636e4d5c86372825d888f5e14f7e3f..cf05b8401b527374e797c44430fb9d97f1d5646b 100644 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/service/rest/CurrencyRestService.java +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/CurrencyRestController.java @@ -1,4 +1,4 @@ -package io.ucoin.client.ui.service.rest; +package io.ucoin.ucoinj.web.rest; /* * #%L @@ -23,57 +23,31 @@ package io.ucoin.client.ui.service.rest; */ -import com.google.gson.Gson; -import io.ucoin.client.core.model.Currency; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.service.search.CurrencyIndexerService; -import io.ucoin.client.core.service.search.InvalidSignatureException; -import io.ucoin.client.core.technical.gson.GsonUtils; -import io.ucoin.client.ui.application.UcoinSession; +import io.ucoin.ucoinj.core.client.model.elasticsearch.Currency; +import io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService; +import io.ucoin.ucoinj.elasticsearch.service.ServiceLocator; +import io.ucoin.ucoinj.elasticsearch.service.exception.InvalidSignatureException; +import io.ucoin.ucoinj.web.application.WebSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.wicketstuff.rest.annotations.MethodMapping; -import org.wicketstuff.rest.annotations.ResourcePath; -import org.wicketstuff.rest.annotations.parameters.PathParam; -import org.wicketstuff.rest.annotations.parameters.RequestParam; -import org.wicketstuff.rest.contenthandling.json.objserialdeserial.GsonObjectSerialDeserial; -import org.wicketstuff.rest.contenthandling.mimetypes.RestMimeTypes; -import org.wicketstuff.rest.contenthandling.webserialdeserial.TextualWebSerialDeserial; -import org.wicketstuff.rest.resource.AbstractRestResource; +import org.springframework.web.bind.annotation.*; -@ResourcePath("/rest/currency") -public class CurrencyRestService extends AbstractRestResource<TextualWebSerialDeserial> { +@RestController +@RequestMapping("/currency") +public class CurrencyRestController { // Logger - private static final Logger log = LoggerFactory.getLogger(CurrencyRestService.class); + private static final Logger log = LoggerFactory.getLogger(CurrencyRestController.class); - private static final long serialVersionUID = 1L; - - private boolean debug; - - private static Gson gson; - - public CurrencyRestService() { - super(new TextualWebSerialDeserial("UTF-8", RestMimeTypes.APPLICATION_JSON, - new GsonObjectSerialDeserial(initGson()))); - debug = log.isDebugEnabled(); - } - - private static Gson initGson() { - if (gson == null) { - gson = GsonUtils.newBuilder().create(); - } - return gson; - } - - @MethodMapping("/{currencyId}") - public Currency getCurrencyById(@PathParam("currencyId") String currencyId) { + @RequestMapping(value="/{currencyId}", method = RequestMethod.GET) + public @ResponseBody Currency getCurrencyById(@PathVariable(value="currencyId") String currencyId) { CurrencyIndexerService service = ServiceLocator.instance().getCurrencyIndexerService(); return service.getCurrencyById(currencyId); } - @MethodMapping(value = "/add", produces = RestMimeTypes.TEXT_PLAIN) - public String saveCurrency(@RequestParam("pubkey") String pubkey, @RequestParam("currency") String jsonCurrency, @RequestParam("sig") String signature) throws InvalidSignatureException { + @ResponseStatus(value= org.springframework.http.HttpStatus.OK, reason="Currency successfully register") + @RequestMapping(value="/add", method = RequestMethod.POST) + public String registerNewCurrency(@RequestParam("pubkey") String pubkey, @RequestParam("currency") String jsonCurrency, @RequestParam("sig") String signature) throws InvalidSignatureException { if (log.isDebugEnabled()) { log.debug(String.format("Asking to add new currency:\n - pubkey: %s\n - currency: %s\n - signature: %s", pubkey, jsonCurrency, signature)); } @@ -108,8 +82,8 @@ public class CurrencyRestService extends AbstractRestResource<TextualWebSerialDe /* -- Internal methods -- */ - protected UcoinSession getUcoinSession() { - UcoinSession session = (UcoinSession) UcoinSession.get(); + protected WebSession getWebSession() { + WebSession session = (WebSession) WebSession.get(); return session; } } diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/RestResponseEntityExceptionHandler.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/RestResponseEntityExceptionHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..3edebf028c9d8b5ff6027fb14de7f5310f0d17a7 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/rest/RestResponseEntityExceptionHandler.java @@ -0,0 +1,92 @@ +package io.ucoin.ucoinj.web.rest; + +/* + * #%L + * Reef DB :: Quadrige2 Synchro server + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import io.ucoin.ucoinj.core.exception.BusinessException; +import io.ucoin.ucoinj.core.exception.TechnicalException; +import io.ucoin.ucoinj.elasticsearch.service.exception.InvalidSignatureException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { + /* Logger */ + private static final Log log = LogFactory.getLog(RestResponseEntityExceptionHandler.class); + + public RestResponseEntityExceptionHandler() { + super(); + } + + /** + * Transform an exception on bad ... TODO doc + */ + @ExceptionHandler(value = { TechnicalException.class }) + protected ResponseEntity<Object> handleTechnicalException(RuntimeException ex, WebRequest request) { + String message = "internal technical error (TODO i18n)"; + if (log.isDebugEnabled()) { + log.debug(message); + } + return handleExceptionInternal(ex, message, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); + } + + @ExceptionHandler(value = {BusinessException.class }) + protected ResponseEntity<Object> handleBusinessException(RuntimeException ex, WebRequest request) { + String message = "internal business error (TODO i18n)"; + if (log.isDebugEnabled()) { + log.debug(message); + } + return handleExceptionInternal(ex, message, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); + } + + @ExceptionHandler(value = {InvalidSignatureException.class }) + protected ResponseEntity<Object> handleInvalidSignatureExceptionk(RuntimeException ex, WebRequest request) { + String message = "Bad signature (not correspond to given pubkey)"; + if (log.isDebugEnabled()) { + log.debug(message); + } + return handleExceptionInternal(ex, message, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR, request); + } + + + /* -- protected methods -- */ + + private Throwable getCause(Throwable e, Class... classes) { + for (Class clazz: classes) { + if (clazz.isInstance(e)) { + return e; + } + } + if (e.getCause() != null) { + return getCause(e.getCause(), classes); + } + return null; + } +} \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/SecurityContextHelper.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/SecurityContextHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..c1025698a30db5840ff61566f1a6cf69f830aa7c --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/SecurityContextHelper.java @@ -0,0 +1,79 @@ +package io.ucoin.ucoinj.web.security; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +public class SecurityContextHelper { + + public static final String USER_ANONYMOUS = "anonymousUser"; + + public static String getPrincipalPubkey() { + String pubkey = getPrincipal(); + if (pubkey == null) { + return null; + } + if (USER_ANONYMOUS.equals(pubkey)) { + return null; + } + return pubkey; + } + + public static String getPrincipal() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || authentication.getPrincipal() == null) { + return null; + } + Object principal = authentication.getPrincipal(); + if (principal instanceof String) { + return (String) principal; + } else { + return null; + } + } + + /** + * @return + */ + public static boolean isAuthenticateNotAnonymous() { + return getPrincipalPubkey() != null; + } + + /** + * @return + */ + public static boolean isAuthenticate() { + return getPrincipal() != null; + } + + + /** + * @return + */ + public static boolean isAuthenticateAnonymous() { + return getPrincipalPubkey() == null; + } + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjGrantedAuthority.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjGrantedAuthority.java new file mode 100644 index 0000000000000000000000000000000000000000..854c308aede1dfde63b5b1df0a1bdd9801edb2fc --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjGrantedAuthority.java @@ -0,0 +1,31 @@ +package io.ucoin.ucoinj.web.security; + +/* + * #%L + * Reef DB :: Quadrige2 Synchro server + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +public enum UcoinjGrantedAuthority { + + ROLE_ADMIN, + ROLE_USER +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetails.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetails.java new file mode 100644 index 0000000000000000000000000000000000000000..f3c69fbef2141f5698af37c4452d8ec6554a7f64 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetails.java @@ -0,0 +1,42 @@ +package io.ucoin.ucoinj.web.security; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import org.springframework.security.core.userdetails.UserDetails; + +/** + * + * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro> + */ +public interface UcoinjUserDetails extends UserDetails { + + /** + * return the user pubkey + * + * @return user pubkey + */ + String getPubkey(); + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetailsImpl.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetailsImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ab7a22b0e051d66df53053281d0519486a4547b7 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/UcoinjUserDetailsImpl.java @@ -0,0 +1,116 @@ +package io.ucoin.ucoinj.web.security; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * + * @author Benoit Lavenier <benoit.lavenier@e-is.pro> + * @since 1.0 + */ +public class UcoinjUserDetailsImpl implements UcoinjUserDetails { + + private static final long serialVersionUID = 1L; + + private String pubkey; + + private String password = ""; + + private Collection<? extends GrantedAuthority> authorities; + + public UcoinjUserDetailsImpl(String pubkey, boolean isAdmin) { + this.pubkey = pubkey; + this.password = ""; + this.authorities = isAdmin + ? createAllAuthorities() + : createAuthorities(Sets.newHashSet(UcoinjGrantedAuthority.ROLE_USER.name())); + } + + @Override + public String getPubkey() { + return pubkey; + } + + @Override + public Collection<? extends GrantedAuthority> getAuthorities() { + return authorities; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return pubkey; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + /* -- Internal methods -- */ + + protected Collection<? extends GrantedAuthority> createAllAuthorities() { + List<SimpleGrantedAuthority> authorities = Lists.newArrayList( + new SimpleGrantedAuthority(UcoinjGrantedAuthority.ROLE_ADMIN.name()), + new SimpleGrantedAuthority(UcoinjGrantedAuthority.ROLE_USER.name()) + ); + return authorities; + } + + protected Collection<? extends GrantedAuthority> createAuthorities(Set<String> roles) { + List<SimpleGrantedAuthority> authorities = Lists.newArrayListWithExpectedSize(roles.size()); + for (String role: roles) { + authorities.add(new SimpleGrantedAuthority(role)); + } + return authorities; + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStore.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStore.java new file mode 100644 index 0000000000000000000000000000000000000000..da6b5e74a57d8bdafa2ed374db1ca945750f6605 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStore.java @@ -0,0 +1,19 @@ +package io.ucoin.ucoinj.web.security.keypair; + +/** + * Created by blavenie on 06/01/16. + */ +public interface ChallengeMessageStore { + /** + * Validate a given challenge + * @return + */ + boolean validateChallenge(String challenge); + + /** + * Compute a new challenge message, and remember it to validate it later. + * @return + */ + String createNewChallenge(); + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStoreImpl.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStoreImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..d741434415d80a3a4b3debefa4c09b125dfd51b3 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/ChallengeMessageStoreImpl.java @@ -0,0 +1,79 @@ +package io.ucoin.ucoinj.web.security.keypair; + +import com.google.common.base.Preconditions; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.core.util.StringUtils; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.Assert; + +import java.util.concurrent.TimeUnit; + +/** + * Created by blavenie on 06/01/16. + */ +public class ChallengeMessageStoreImpl implements ChallengeMessageStore, InitializingBean{ + + + private String prefix; + private long validityDurationInSeconds; + private LoadingCache<String, String> chalengeMessageCache; + + public ChallengeMessageStoreImpl() { + } + + @Override + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.prefix, "An not null prefix must be set"); + Assert.isTrue(this.validityDurationInSeconds > 0, "An validityDurationInSeconds must be set (and not equals to zero)"); + this.chalengeMessageCache = initGeneratedMessageCache(); + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public void setValidityDurationInSeconds(long validityDurationInSeconds) { + this.validityDurationInSeconds = validityDurationInSeconds; + } + + @Override + public boolean validateChallenge(String challenge) { + Preconditions.checkArgument(StringUtils.isNotBlank(challenge)); + + String storedChallenge = chalengeMessageCache.getIfPresent(challenge); + + // if no value in cache => maybe challenge expired + return ObjectUtils.equals(storedChallenge, challenge); + } + + @Override + public String createNewChallenge() { + String challenge = newChallenge(); + chalengeMessageCache.put(challenge, challenge); + return newChallenge(); + } + + + + /* -- internal methods -- */ + + protected String newChallenge() { + return String.valueOf(prefix + System.currentTimeMillis() * System.currentTimeMillis()); + } + + + protected LoadingCache<String, String> initGeneratedMessageCache() { + return CacheBuilder.newBuilder() + .expireAfterWrite(validityDurationInSeconds, TimeUnit.SECONDS) + .build(new CacheLoader<String, String>() { + @Override + public String load(String challenge) throws Exception { + // not used. Filled manually + return null; + } + }); + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationProvider.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..10677b35e437e0a41ddc10f2ead0fc868039ff74 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationProvider.java @@ -0,0 +1,96 @@ +package io.ucoin.ucoinj.web.security.keypair; + +import io.ucoin.ucoinj.core.service.CryptoService; +import io.ucoin.ucoinj.web.service.ServiceLocator; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.authentication.AccountStatusUserDetailsChecker; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsChecker; +import org.springframework.util.Assert; + +/** + * Created by blavenie on 06/01/16. + */ +public class PubkeyAuthenticationProvider implements AuthenticationProvider, InitializingBean{ + + private AuthenticationUserDetailsService authenticationUserDetailsService; + private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker(); + private CryptoService cryptoService; + private ChallengeMessageStore challengeMessageStore; + + public PubkeyAuthenticationProvider() { + } + + public void afterPropertiesSet() throws Exception { + Assert.notNull(this.authenticationUserDetailsService, "An authenticationUserDetailsService must be set"); + cryptoService = cryptoService == null ? ServiceLocator.instance().getCryptoService() : cryptoService; + Assert.notNull(this.cryptoService, "An cryptoService must be set"); + Assert.notNull(this.challengeMessageStore, "An challengeMessageStore must be set"); + } + + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + if(!this.supports(authentication.getClass())) { + return null; + } else if(authentication instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken)authentication; + if (token.getPrincipal() == null || token.getCredentials() == null) { + throw new BadCredentialsException("Invalid authentication token. Missing principal or credentials"); + } + String pubkey = token.getPrincipal().toString(); + + checkSignature(token.getPrincipal().toString(), token.getCredentials().toString()); + PubkeyAuthenticationToken result = new PubkeyAuthenticationToken(pubkey); + + UserDetails userDetails = authenticationUserDetailsService.loadUserDetails(result); + if (userDetails != null) { + this.userDetailsChecker.check(userDetails); + result = new PubkeyAuthenticationToken(pubkey, userDetails.getAuthorities()); + result.setAuthenticated(true); + result.setDetails(userDetails); + } + return result; + } + throw new BadCredentialsException("Failed to authenticate this token. Unknown token class."); + } + + public void setAuthenticationUserDetailsService(AuthenticationUserDetailsService authenticationUserDetailsService) { + this.authenticationUserDetailsService = authenticationUserDetailsService; + } + + public void setCryptoService(CryptoService cryptoService) { + this.cryptoService = cryptoService; + } + + public void setChallengeMessageStore(ChallengeMessageStore challengeMessageStore) { + this.challengeMessageStore = challengeMessageStore; + } + + public boolean supports(Class<? extends Object> authentication) { + return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); + } + + /*-- internal method --*/ + + private boolean checkSignature(String pubkey, String sm) throws BadCredentialsException{ + + if (sm.indexOf('|') == -1) { + throw new BadCredentialsException("Invalid password. Must be <signature>|<message>"); + } + String signature = sm.substring(0, sm.indexOf('|')); + String message = sm.substring(sm.indexOf('|')+1); + + boolean valid = challengeMessageStore.validateChallenge(message) + && cryptoService.verify(message, signature, pubkey); + if (!valid) { + throw new BadCredentialsException("Invalid signature. Not signed by this pubkey or message to signed expired."); + } + + return true; + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationToken.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationToken.java new file mode 100644 index 0000000000000000000000000000000000000000..1fb24cd2509590f66a1312a2537f098ec23e0845 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyAuthenticationToken.java @@ -0,0 +1,43 @@ +package io.ucoin.ucoinj.web.security.keypair; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +import java.util.Collection; + +/** + * Created by blavenie on 06/01/16. + */ +public class PubkeyAuthenticationToken extends AbstractAuthenticationToken { + + private final String pubkey; + + public PubkeyAuthenticationToken(String pubkey) { + super(null); + this.pubkey = pubkey; + } + + public PubkeyAuthenticationToken(String pubkey, Collection<? extends GrantedAuthority> authorities) { + super(authorities); + this.pubkey = pubkey; + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getDetails() { + return pubkey; + } + + @Override + public Object getPrincipal() { + return pubkey; + } + + public String getPubkey() { + return pubkey; + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyUserDetailsServiceImpl.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyUserDetailsServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e1f95eed5fab92603220af5e9bb4e0e7204e8aa9 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/security/keypair/PubkeyUserDetailsServiceImpl.java @@ -0,0 +1,55 @@ +package io.ucoin.ucoinj.web.security.keypair; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import io.ucoin.ucoinj.core.util.ObjectUtils; +import io.ucoin.ucoinj.web.config.WebConfiguration; +import io.ucoin.ucoinj.web.security.UcoinjUserDetailsImpl; +import org.springframework.context.annotation.Lazy; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * + * @author Benoit Lavenier + */ +@Service("pubkeyAuthenticationUserDetailsService") +@Lazy +public class PubkeyUserDetailsServiceImpl implements AuthenticationUserDetailsService<PubkeyAuthenticationToken> { + + @Resource + WebConfiguration config; + + public UserDetails loadUserDetails(PubkeyAuthenticationToken pubkeyAuthentication) throws UsernameNotFoundException { + String pubkey = pubkeyAuthentication.getPubkey(); + boolean isAdmin = ObjectUtils.equals(pubkey, config.getUserPubkey()); + + return new UcoinjUserDetailsImpl(pubkey, isAdmin); + } +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/service/ServiceLocator.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/service/ServiceLocator.java new file mode 100644 index 0000000000000000000000000000000000000000..91fc7859b83f4b7dfd7a901f199a182866aa7239 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/service/ServiceLocator.java @@ -0,0 +1,86 @@ +package io.ucoin.ucoinj.web.service; + +/* + * #%L + * SIH-Adagio :: UI for Core Allegro + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2012 - 2014 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import com.google.common.base.Preconditions; +import io.ucoin.ucoinj.web.security.keypair.ChallengeMessageStore; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +import javax.servlet.ServletContext; + +public class ServiceLocator extends io.ucoin.ucoinj.elasticsearch.service.ServiceLocator { + + + private static ServiceLocator instance; + static { + initDefault(); + } + + public static void initDefault(ServletContext servletContext) { + if (instance != null) { + instance.setServletContext(servletContext); + } + else { + instance = new ServiceLocator(servletContext); + io.ucoin.ucoinj.elasticsearch.service.ServiceLocator.setInstance(instance); + } + } + + public static void initDefault() { + instance = new ServiceLocator(); + io.ucoin.ucoinj.elasticsearch.service.ServiceLocator.setInstance(instance); + } + + public static ServiceLocator instance() { + return instance; + } + + private WebApplicationContext appContext; + + public ServiceLocator() { + } + public ServiceLocator(ServletContext servletContext) { + setServletContext(servletContext); + } + + public ChallengeMessageStore getChallengeMessageStore() { + return getBean("challengeMessageStore", ChallengeMessageStore.class); + } + + /* -- internal methods -- */ + + protected <T> T getBean(String name, Class<T> type) { + Preconditions.checkNotNull(appContext, "no application context initaitliszed. Please call initDefault(ServletContext) before getting beans."); + return appContext.getBean(name, type); + } + + + protected void setServletContext(ServletContext servletContext) { + Preconditions.checkNotNull(servletContext); + appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); + } + +} diff --git a/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/util/GsonHttpMessageConverter.java b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/util/GsonHttpMessageConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..55ae916df4812394771ff0d2e77fe8262c516959 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/java/io/ucoin/ucoinj/web/util/GsonHttpMessageConverter.java @@ -0,0 +1,44 @@ +package io.ucoin.ucoinj.web.util; + +/* + * #%L + * Reef DB :: Quadrige2 Synchro server + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 - 2015 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ + + +import io.ucoin.ucoinj.core.client.model.bma.gson.GsonUtils; + +/** + * Override default converter to use specific gson configuration :<ul> + * <li>multimap support</li> + * <li>date pattern</li> + * <li>...</li> + * </ul> + * @see fr.ifremer.quadrige2.core.dao.technical.gson.GsonUtils + */ +public class GsonHttpMessageConverter extends org.springframework.http.converter.json.GsonHttpMessageConverter { + + public GsonHttpMessageConverter() { + super(); + setGson(GsonUtils.newBuilder().create()); + } + +} \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean b/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean new file mode 100644 index 0000000000000000000000000000000000000000..ef8d07e32710007d2e38a0be666fc4b6fd838d27 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/META-INF/services/io.ucoin.ucoinj.core.beans.Bean @@ -0,0 +1,14 @@ +io.ucoin.ucoinj.core.service.Ed25519CryptoServiceImpl +io.ucoin.ucoinj.core.client.service.bma.BlockchainRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.NetworkRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.WotRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.bma.TransactionRemoteServiceImpl +io.ucoin.ucoinj.core.client.service.HttpServiceImpl +io.ucoin.ucoinj.core.client.service.DataContext +io.ucoin.ucoinj.core.client.service.local.PeerServiceImpl +io.ucoin.ucoinj.core.client.service.local.CurrencyServiceImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryCurrencyDaoImpl +io.ucoin.ucoinj.core.client.dao.mem.MemoryPeerDaoImpl +io.ucoin.ucoinj.elasticsearch.service.ElasticSearchService +io.ucoin.ucoinj.elasticsearch.service.CurrencyIndexerService +io.ucoin.ucoinj.elasticsearch.service.BlockIndexerService diff --git a/ucoinj-ui-wicket/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider b/ucoinj-ui-wicket/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider new file mode 100644 index 0000000000000000000000000000000000000000..dbdf0b120656efafa96416fdd8d28e7addb95a1f --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/META-INF/services/org.nuiton.config.ApplicationConfigProvider @@ -0,0 +1 @@ +io.ucoin.ucoinj.web.config.WebConfigurationProvider diff --git a/ucoinj-ui-wicket/src/main/resources/applicationContext-conf.xml b/ucoinj-ui-wicket/src/main/resources/applicationContext-conf.xml new file mode 100644 index 0000000000000000000000000000000000000000..57a90d60b8c9170071e24c654333ba26aa6b39be --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/applicationContext-conf.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + SIH-Adagio Core for Allegro + $Id: applicationContext-conf.xml 12102 2014-05-28 21:04:57Z bl05b3e $ + $HeadURL: https://forge.ifremer.fr/svn/sih-adagio/trunk/adagio/core-allegro/src/main/resources/applicationContext-conf.xml $ + %% + Copyright (C) 2012 - 2013 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + + <!-- replace value like '${xx}' with value from configuration --> + <bean id="webConfiguration" class="io.ucoin.ucoinj.web.config.WebConfiguration" + factory-method="instance" + lazy-init="false"> + <property name="ignoreUnresolvablePlaceholders" value="true"/> + <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> + </bean> + + <bean id="esConfig" class="io.ucoin.ucoinj.elasticsearch.config.Configuration" + factory-method="instance" + lazy-init="false"> + </bean> + + <bean id="serviceLocator" class="io.ucoin.ucoinj.web.service.ServiceLocator" + factory-method="instance" + lazy-init="false"> + </bean> + +</beans> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/applicationContext-rest-servlet.xml b/ucoinj-ui-wicket/src/main/resources/applicationContext-rest-servlet.xml new file mode 100644 index 0000000000000000000000000000000000000000..6a0d173309b0d579274c1b1a4281e221f3ba835a --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/applicationContext-rest-servlet.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Reef DB :: Quadrige2 Synchro server + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 - 2015 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:mvc="http://www.springframework.org/schema/mvc" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-4.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-4.0.xsd + http://www.springframework.org/schema/mvc + http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> + + <context:component-scan base-package="io.ucoin.ucoinj.web.rest" /> + + <mvc:annotation-driven> + <mvc:message-converters> + <bean class="io.ucoin.ucoinj.web.util.GsonHttpMessageConverter"/> + </mvc:message-converters> + </mvc:annotation-driven> + + <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> + <property name="maxUploadSize" value="268435456"/> <!-- 256 megs --> + </bean> +</beans> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/applicationContext-security-pubkey.xml b/ucoinj-ui-wicket/src/main/resources/applicationContext-security-pubkey.xml new file mode 100644 index 0000000000000000000000000000000000000000..64301bbff7de761bff884f4a47aabd601c9020c4 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/applicationContext-security-pubkey.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:security="http://www.springframework.org/schema/security" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-4.0.xsd + http://www.springframework.org/schema/security + http://www.springframework.org/schema/security/spring-security-4.0.xsd"> + + <security:authentication-manager alias="authenticationManager"> + <security:authentication-provider ref="pubkeyAuthenticationProvider" /> + </security:authentication-manager> + + + <bean id="challengeMessageStore" + class="io.ucoin.ucoinj.web.security.keypair.ChallengeMessageStoreImpl"> + <property name="validityDurationInSeconds" value="60"/> <!-- challenge will expired after 60 sec --> + <property name="prefix" value="ucoinj-web-challenge-"/> + </bean> + + <bean id="pubkeyUserDetailsService" + class="io.ucoin.ucoinj.web.security.keypair.PubkeyUserDetailsServiceImpl"> + </bean> + + <bean id="pubkeyAuthenticationProvider" + class="io.ucoin.ucoinj.web.security.keypair.PubkeyAuthenticationProvider"> + <property name="authenticationUserDetailsService" ref="pubkeyUserDetailsService" /> + <property name="challengeMessageStore" ref="challengeMessageStore" /> + </bean> + +</beans> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/applicationContext-security.xml b/ucoinj-ui-wicket/src/main/resources/applicationContext-security.xml new file mode 100644 index 0000000000000000000000000000000000000000..b75e6f28f7ea8c902f9d8cc6581af714daf23aad --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/applicationContext-security.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:security="http://www.springframework.org/schema/security" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-4.0.xsd + http://www.springframework.org/schema/security + http://www.springframework.org/schema/security/spring-security-4.0.xsd"> + + <security:global-method-security + secured-annotations="enabled"> + <security:protect-pointcut access="ROLE_USER,ROLE_ADMIN" expression="execution(* io.ucoin.ucoinj.*.*(..))"/> + </security:global-method-security> + + <!-- Spring REST service --> + <security:http pattern="/service/**" create-session="always"> + <!-- Currency add: need auth --> + <security:intercept-url pattern="/service/currency/add" access="isAuthenticated()" /> + + <!-- Auth: need auth --> + <security:intercept-url pattern="/service/auth" access="isAuthenticated()" /> + + <!-- Other URL (version, etc.): no security --> + <security:intercept-url pattern="/service/**" access="permitAll" /> + + <security:http-basic /> + <security:csrf disabled="true"/> + </security:http> + + <!-- Web: Basic ressources (CSS, images) - no security --> + <security:http pattern="/images/**" security="none" /> + <security:http pattern="/css/**" security="none" /> + <security:http pattern="/js/**" security="none" /> + <security:http pattern="/wicket/**" security="none" /> + <security:http pattern="/*.css" security="none" /> + <security:http pattern="/*.ico" security="none" /> + + <!-- Web: wicket pages --> + <security:http auto-config="true"> + <security:intercept-url pattern="/" access="permitAll"/> + + <security:intercept-url pattern="/login" access="permitAll"/> + <security:intercept-url pattern="/home" access="permitAll"/> + <security:intercept-url pattern="/home2" access="permitAll"/> + <security:intercept-url pattern="/currency" access="permitAll"/> + <security:intercept-url pattern="/service" access="hasAnyRole('USER','ADMIN')"/> + <security:intercept-url pattern="/admin/**" access="hasAnyRole('ADMIN')" /> + <security:intercept-url pattern="/service/api" access="hasAnyRole('ADMIN')" /> + <security:intercept-url pattern="/**" access="hasAnyRole('USER','ADMIN')" /> + + <security:anonymous granted-authority="ROLE_ANONYMOUS" username="anonymousUser"/> + + <security:form-login login-page="/login" + default-target-url="/home" + authentication-failure-url="/login?error=true"/> + + <security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/" /> + + <security:csrf disabled="true"/> + </security:http> + +</beans> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/applicationContext-wicket.xml b/ucoinj-ui-wicket/src/main/resources/applicationContext-wicket.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f2c59bc0235c1b77b0538f14cfe76ccaa141105 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/applicationContext-wicket.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> + + <!-- mount application as bean --> + <context:component-scan base-package="io.ucoin.ucoinj.web.application"> + <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> + </context:component-scan> + + <!-- load security services --> + <context:component-scan base-package="io.ucoin.ucoinj.web.security"> + <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> + </context:component-scan> + +</beans> \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/main/resources/uiBeanRefFactory.xml b/ucoinj-ui-wicket/src/main/resources/uiBeanRefFactory.xml new file mode 100644 index 0000000000000000000000000000000000000000..9aa8dd76593d38894e48d765af7464b3f6cdc62c --- /dev/null +++ b/ucoinj-ui-wicket/src/main/resources/uiBeanRefFactory.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + SIH-Adagio :: UI for Core Allegro + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2012 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> + + <!-- Allow properties substitutions --> + <import resource="applicationContext-conf.xml" /> + + <bean id="beanRefFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext"> + <constructor-arg> + <list> + <value>classpath:applicationContext-conf.xml</value> + <value>classpath:applicationContext-wicket.xml</value> + <value>classpath:applicationContext-security.xml</value> + <value>classpath:applicationContext-security-${ucoinj.security.type}.xml</value> + </list> + </constructor-arg> + </bean> +</beans> \ No newline at end of file diff --git a/ucoinj-web/src/main/webapp/META-INF/MANIFEST.MF b/ucoinj-ui-wicket/src/main/webapp/META-INF/MANIFEST.MF similarity index 100% rename from ucoinj-web/src/main/webapp/META-INF/MANIFEST.MF rename to ucoinj-ui-wicket/src/main/webapp/META-INF/MANIFEST.MF diff --git a/ucoinj-web/src/main/webapp/META-INF/context.xml b/ucoinj-ui-wicket/src/main/webapp/META-INF/context.xml similarity index 100% rename from ucoinj-web/src/main/webapp/META-INF/context.xml rename to ucoinj-ui-wicket/src/main/webapp/META-INF/context.xml diff --git a/ucoinj-ui-wicket/src/main/webapp/WEB-INF/classes/TOTO.txt b/ucoinj-ui-wicket/src/main/webapp/WEB-INF/classes/TOTO.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ucoinj-ui-wicket/src/main/webapp/WEB-INF/urlrewrite.xml b/ucoinj-ui-wicket/src/main/webapp/WEB-INF/urlrewrite.xml new file mode 100644 index 0000000000000000000000000000000000000000..257c44cc43549083e39cf2be523d8ad18f08f121 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/WEB-INF/urlrewrite.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + #%L + Reef DB :: Quadrige2 Synchro server + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 - 2015 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> + +<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN" + "http://www.tuckey.org/res/dtds/urlrewrite4.0.dtd"> +<!-- + + Configuration file for UrlRewriteFilter + http://www.tuckey.org/urlrewrite/ + +--> +<urlrewrite> + + <rule> + <from>^/install/$</from> + <to type="redirect">%{context-path}/install</to> + </rule> + + <rule> + <from>^/download/install/$</from> + <to type="redirect">%{context-path}/install</to> + </rule> + + <rule> + <from>^/download/install$</from> + <to type="redirect">%{context-path}/install</to> + </rule> + + <rule> + <from>^/install/(.+)$</from> + <to type="redirect">%{context-path}/download/install/$1</to> + </rule> + + <rule> + <from>^/download/import/\?file=(.*)$</from> + <to type="redirect">%{context-path}/download/import/$1</to> + </rule> + + <!--rule> + <from>/download/(.*)</from> + <to type="redirect">%{context-path}/download?file=$2</to> + </rule + + <outbound-rule> + <from>/download/import[?]file=(.*)</from> + <to>/download/import/$1</to> + </outbound-rule>--> + +</urlrewrite> + diff --git a/ucoinj-ui-wicket/src/main/webapp/WEB-INF/web.xml b/ucoinj-ui-wicket/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..5d3af8348a15705a5703758f242858a86fe920b1 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,118 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" + version="2.5"> + + <display-name>uCoinj :: Web ${project.version}</display-name> + + <context-param> + <param-name>webAppRootKey</param-name> + <param-value>ucoinj-web</param-value> + </context-param> + + <!-- Configuration de la beanFactory => pour utiliser celle du fichier beanRefFactory.xml + => nécessaire pour que ServiceLocation.getContext() fonctionne correctement + cf doc : http://techo-ecco.com/blog/spring-application-context-hierarchy-and-contextsingletonbeanfactorylocator/ --> + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value></param-value> + </context-param> + <context-param> + <param-name>parentContextKey</param-name> + <param-value>beanRefFactory</param-value> + </context-param> + <context-param> + <param-name>locatorFactorySelector</param-name> + <param-value>uiBeanRefFactory.xml</param-value> + </context-param> + + <!-- This listener will load other application context file in addition to applicationContext-rest-servlet.xml --> + <listener> + <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> + </listener> + + <!-- URL rewriter filter + <filter> + <filter-name>UrlRewriteFilter</filter-name> + <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> + </filter> + <filter-mapping> + <filter-name>UrlRewriteFilter</filter-name> + <url-pattern>/install/*</url-pattern> + <dispatcher>REQUEST</dispatcher> + <dispatcher>FORWARD</dispatcher> + </filter-mapping>--> + + <!-- Spring Security --> + <filter> + <filter-name>springSecurityFilterChain</filter-name> + <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> + </filter> + <filter-mapping> + <filter-name>springSecurityFilterChain</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + + <!-- Wicket filter --> + <filter> + <filter-name>wicketFilter</filter-name> + <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> + + <init-param> + <param-name>applicationFactoryClassName</param-name> + <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value> + </init-param> + <init-param> + <param-name>applicationBean</param-name> + <param-value>wicketApplication</param-value> + </init-param> + <!-- CONFIGURATION DU RUNTIME WICKET --> + <init-param> + <param-name>configuration</param-name> + <param-value>${wicket.configuration}</param-value> + </init-param> + </filter> + <filter-mapping> + <filter-name>wicketFilter</filter-name> + <url-pattern>/*</url-pattern> + <dispatcher>REQUEST</dispatcher> + <dispatcher>ERROR</dispatcher> + </filter-mapping> + + <!-- Spring Servlet, for REST services --> + <servlet> + <servlet-name>springServlet</servlet-name> + <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> + <load-on-startup>1</load-on-startup> + <init-param> + <param-name>contextConfigLocation</param-name> + <param-value>classpath:applicationContext-rest-servlet.xml</param-value> + </init-param> + </servlet> + <servlet-mapping> + <servlet-name>springServlet</servlet-name> + <url-pattern>/service/*</url-pattern> + </servlet-mapping> + + <error-page> + <error-code>401</error-code> + <location>/loginfailed.html</location> + </error-page> + <error-page> + <error-code>403</error-code> + <location>/accessdenied.html</location> + </error-page> + <error-page> + <error-code>404</error-code> + <location>/notfound.html</location> + </error-page> + + <welcome-file-list> + <welcome-file>index.html</welcome-file> + </welcome-file-list> + + <session-config> + <session-timeout>60</session-timeout> + </session-config> + +</web-app> diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/ajax-loader.gif b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/ajax-loader.gif similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/ajax-loader.gif rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/ajax-loader.gif diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/action-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/action-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/action-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/action-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/action-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/action-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/action-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/action-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/alert-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/alert-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/alert-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/alert-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/alert-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/alert-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/alert-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/alert-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-l-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-r-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-d-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-l-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-r-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-l-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-r-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/arrow-u-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/audio-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/audio-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/audio-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/audio-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/audio-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/audio-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/audio-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/audio-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/back-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/back-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/back-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/back-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/back-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/back-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/back-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/back-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bars-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bars-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bars-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bars-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bars-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bars-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bars-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bars-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/bullets-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/calendar-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/camera-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/camera-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/camera-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/camera-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/camera-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/camera-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/camera-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/camera-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-d-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-l-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-r-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/carat-u-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/check-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/check-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/check-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/check-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/check-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/check-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/check-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/check-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/clock-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/clock-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/clock-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/clock-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/clock-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/clock-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/clock-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/clock-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/cloud-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/comment-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/comment-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/comment-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/comment-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/comment-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/comment-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/comment-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/comment-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/delete-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/delete-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/delete-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/delete-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/delete-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/delete-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/delete-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/delete-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/edit-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/edit-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/edit-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/edit-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/edit-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/edit-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/edit-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/edit-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/eye-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/eye-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/eye-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/eye-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/eye-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/eye-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/eye-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/eye-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forbidden-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forward-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forward-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forward-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forward-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forward-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forward-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/forward-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/forward-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/gear-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/gear-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/gear-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/gear-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/gear-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/gear-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/gear-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/gear-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/grid-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/grid-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/grid-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/grid-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/grid-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/grid-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/grid-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/grid-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/heart-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/heart-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/heart-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/heart-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/heart-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/heart-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/heart-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/heart-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/home-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/home-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/home-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/home-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/home-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/home-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/home-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/home-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/info-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/info-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/info-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/info-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/info-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/info-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/info-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/info-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/location-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/location-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/location-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/location-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/location-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/location-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/location-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/location-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/lock-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/lock-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/lock-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/lock-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/lock-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/lock-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/lock-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/lock-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/mail-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/mail-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/mail-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/mail-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/mail-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/mail-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/mail-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/mail-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/minus-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/minus-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/minus-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/minus-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/minus-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/minus-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/minus-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/minus-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/navigation-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/phone-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/phone-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/phone-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/phone-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/phone-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/phone-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/phone-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/phone-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/plus-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/plus-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/plus-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/plus-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/plus-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/plus-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/plus-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/plus-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/power-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/power-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/power-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/power-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/power-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/power-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/power-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/power-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/recycle-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/refresh-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/search-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/search-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/search-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/search-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/search-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/search-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/search-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/search-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/shop-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/shop-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/shop-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/shop-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/shop-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/shop-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/shop-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/shop-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/star-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/star-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/star-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/star-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/star-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/star-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/star-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/star-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/tag-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/tag-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/tag-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/tag-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/tag-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/tag-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/tag-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/tag-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/user-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/user-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/user-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/user-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/user-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/user-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/user-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/user-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/video-black.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/video-black.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/video-black.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/video-black.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/video-white.png b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/video-white.png similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-png/video-white.png rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-png/video-white.png diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/action-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/action-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/action-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/action-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/action-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/action-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/action-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/action-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/alert-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-l-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-r-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-d-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-l-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-r-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-l-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-r-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/arrow-u-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/audio-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/back-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/back-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/back-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/back-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/back-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/back-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/back-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/back-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bars-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/bullets-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/calendar-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/camera-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-d-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-l-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-r-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/carat-u-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/check-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/check-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/check-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/check-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/check-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/check-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/check-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/check-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/clock-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/cloud-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/comment-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/delete-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/edit-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/eye-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forbidden-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/forward-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/gear-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/grid-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/heart-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/home-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/home-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/home-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/home-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/home-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/home-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/home-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/home-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/info-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/info-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/info-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/info-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/info-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/info-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/info-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/info-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/location-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/location-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/location-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/location-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/location-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/location-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/location-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/location-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/lock-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/mail-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/minus-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/navigation-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/phone-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/plus-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/power-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/power-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/power-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/power-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/power-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/power-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/power-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/power-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/recycle-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/refresh-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/search-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/search-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/search-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/search-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/search-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/search-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/search-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/search-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/shop-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/star-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/star-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/star-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/star-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/star-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/star-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/star-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/star-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/tag-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/user-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/user-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/user-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/user-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/user-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/user-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/user-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/user-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/video-black.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/video-black.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/video-black.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/video-black.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/video-white.svg b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/video-white.svg similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/images/icons-svg/video-white.svg rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/images/icons-svg/video-white.svg diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.external-png-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.icons-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-png-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.inline-svg-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.structure-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.css diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.min.css b/ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.min.css similarity index 100% rename from ucoinj-web/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.min.css rename to ucoinj-ui-wicket/src/main/webapp/css/jquery-mobile/jquery.mobile.theme-1.4.5.min.css diff --git a/ucoinj-web/src/main/webapp/images/search-background-large.jpg b/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/images/search-background-large.jpg similarity index 100% rename from ucoinj-web/src/main/webapp/images/search-background-large.jpg rename to ucoinj-ui-wicket/src/main/webapp/css/ucoinj/images/search-background-large.jpg diff --git a/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/jquery.mobile.override.css b/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/jquery.mobile.override.css new file mode 100644 index 0000000000000000000000000000000000000000..f7ea526d77a9f8e6693afa388807d98bf92bd645 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/jquery.mobile.override.css @@ -0,0 +1,74 @@ + +/*.ui-overlay-a, .ui-page-theme-a, .ui-page-theme-a .ui-panel-wrapper { + background-color: #f9f9f9; + border-color: #bbb; + color: #333; + text-shadow: 0 1px 0 #f3f3f3; +}*/ + +.ui-autocomplete { + max-height: 200px; + overflow-y: auto; + overflow-x: hidden; + padding-right: 20px; +} + +/*.ui-overlay-a, .ui-page-theme-a, .ui-page-theme-a .ui-panel-wrapper { + background-color: #f9f9f9; + border-color: #bbb; + color: #333; + text-shadow: 0 1px 0 #f3f3f3; +}*/ + +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { + border: 1px solid red; + background: #fef1ec url("images/ui-bg_diagonals-thick_18_b81900_40x40.png") 50% 50% repeat-x; + color: #ffffff; +} + +div.wicket-aa-container { + color: #333; + text-shadow: 0 1px 0 #f3f3f3; + margin-top: 3px; +} + +div.wicket-aa { + font-size: 1em; + line-height: 1.3; + font-family: sans-serif; + background-color: #f6f6f6; + padding: 2px; + text-align:left; + + color: #333; + text-shadow: 0 1px 0 #f3f3f3; + + border-color: #ddd; + border-width: 1px 0 0; + border-style: solid; + margin: 0; + box-shadow: 0 1px 3px rgba(0,0,0,.15); + background-clip: padding-box; + border-radius: .3125em; +} + +div.wicket-aa ul { + list-style:none; + padding: 0; + margin: 0; +} + +div.wicket-aa li { + + display: block; + position: relative; + overflow: visible; + font-size: 16px; + cursor: pointer; + padding: .7em 1em; +} + +div.wicket-aa ul li.selected { + background-color: #ededed; + margin:0; +} \ No newline at end of file diff --git a/ucoinj-web/src/main/webapp/ucoin.css b/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/ucoinj.css similarity index 93% rename from ucoinj-web/src/main/webapp/ucoin.css rename to ucoinj-ui-wicket/src/main/webapp/css/ucoinj/ucoinj.css index ddb3f0aff7dc590570a50c41e4565907d5a4cdce..267d4179b42f675f752d4f77de379a18faa6e5ae 100644 --- a/ucoinj-web/src/main/webapp/ucoin.css +++ b/ucoinj-ui-wicket/src/main/webapp/css/ucoinj/ucoinj.css @@ -82,4 +82,11 @@ body { .inline-form .footer{ clear: left; -} \ No newline at end of file +} + +.ui-autocomplete { + max-height: 200px; + overflow-y: auto; + overflow-x: hidden; + padding-right: 20px; +} diff --git a/ucoinj-web/src/main/webapp/favicon.ico b/ucoinj-ui-wicket/src/main/webapp/favicon.ico similarity index 100% rename from ucoinj-web/src/main/webapp/favicon.ico rename to ucoinj-ui-wicket/src/main/webapp/favicon.ico diff --git a/ucoinj-web/src/main/webapp/index.html b/ucoinj-ui-wicket/src/main/webapp/index.html similarity index 100% rename from ucoinj-web/src/main/webapp/index.html rename to ucoinj-ui-wicket/src/main/webapp/index.html diff --git a/ucoinj-ui-wicket/src/main/webapp/js/app.js b/ucoinj-ui-wicket/src/main/webapp/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..8f6236ea94244022913171b3f2504677a7e8987b --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/app.js @@ -0,0 +1,35 @@ +(function() { + var app = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.app = {}); + + var + ucoinj, + + init = app.init = function() { + ucoinj = uCoinj(document); + }, + + login = app.login = function(event) { + var salt = $('#localSalt').val(); + var password = $('#localPassword').val(); + var challengeMessage = $('#challengeMessage').val(); + + if (salt === "" || password === "" || challengeMessage === "") { + event.preventDefault(); + return; + } + + var challengeMessage = $('#challengeMessage').val(); + ucoinj.connect(salt, password); + var sign = ucoinj.sign(challengeMessage); + + $('#username').val(ucoinj.wallet.pubkey); + $('#password').val(sign + '|' + challengeMessage); + $('#form').submit(); + } + ; + +}).call(this); + +$( document ).ready(function() { + app.init(); +}); diff --git a/ucoinj-ui-wicket/src/main/webapp/js/base58.js b/ucoinj-ui-wicket/src/main/webapp/js/base58.js new file mode 100644 index 0000000000000000000000000000000000000000..cc9be45841ad86685e5fe422db300be150d720dc --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/base58.js @@ -0,0 +1,94 @@ +// Generated by CoffeeScript 1.8.0 +(function() { + var Base58 = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.Base58 = {}); + + Base58.alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + Base58.alphabetMap = {} + + for(var i = 0; i < Base58.alphabet.length; i++) { + Base58.alphabetMap[Base58.alphabet.charAt(i)] = i + } + + Base58.encode = function(buffer) { + var carry, digits, j; + if (buffer.length === 0) { + return ""; + } + i = void 0; + j = void 0; + digits = [0]; + i = 0; + while (i < buffer.length) { + j = 0; + while (j < digits.length) { + digits[j] <<= 8; + j++; + } + digits[0] += buffer[i]; + carry = 0; + j = 0; + while (j < digits.length) { + digits[j] += carry; + carry = (digits[j] / 58) | 0; + digits[j] %= 58; + ++j; + } + while (carry) { + digits.push(carry % 58); + carry = (carry / 58) | 0; + } + i++; + } + i = 0; + while (buffer[i] === 0 && i < buffer.length - 1) { + digits.push(0); + i++; + } + return digits.reverse().map(function(digit) { + return Base58.alphabet[digit]; + }).join(""); + }; + + Base58.decode = function(string) { + var bytes, c, carry, j; + if (string.length === 0) { + return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(0); + } + i = void 0; + j = void 0; + bytes = [0]; + i = 0; + while (i < string.length) { + c = string[i]; + if (!(c in Base58.alphabetMap)) { + throw "Base58.decode received unacceptable input. Character '" + c + "' is not in the Base58 alphabet."; + } + j = 0; + while (j < bytes.length) { + bytes[j] *= 58; + j++; + } + bytes[0] += Base58.alphabetMap[c]; + carry = 0; + j = 0; + while (j < bytes.length) { + bytes[j] += carry; + carry = bytes[j] >> 8; + bytes[j] &= 0xff; + ++j; + } + while (carry) { + bytes.push(carry & 0xff); + carry >>= 8; + } + i++; + } + i = 0; + while (string[i] === "1" && i < string.length - 1) { + bytes.push(0); + i++; + } + return new (typeof Uint8Array !== "undefined" && Uint8Array !== null ? Uint8Array : Buffer)(bytes.reverse()); + }; + +}).call(this); diff --git a/ucoinj-ui-wicket/src/main/webapp/js/base64.js b/ucoinj-ui-wicket/src/main/webapp/js/base64.js new file mode 100644 index 0000000000000000000000000000000000000000..01d7c099881187129e80d400293663600fa86aad --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/base64.js @@ -0,0 +1,24 @@ +(function() { + var Base64 = (typeof module !== "undefined" && module !== null ? module.exports : void 0) || (window.Base64 = {}); + + Base64.encode = (function(arr) { + if (typeof btoa === 'undefined') { + return (new Buffer(arr)).toString('base64'); + } else { + var i, s = [], len = arr.length; + for (i = 0; i < len; i++) s.push(String.fromCharCode(arr[i])); + return btoa(s.join('')); + } + }); + + Base64.decode = (function(s) { + if (typeof atob === 'undefined') { + return new Uint8Array(Array.prototype.slice.call(new Buffer(s, 'base64'), 0)); + } else { + var i, d = atob(s), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; + } + }); + +}).call(this); diff --git a/ucoinj-web/src/main/webapp/js/jquery-1.11.2.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.js similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery-1.11.2.js rename to ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.js diff --git a/ucoinj-web/src/main/webapp/js/jquery-1.11.2.min.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.min.js similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery-1.11.2.min.js rename to ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.min.js diff --git a/ucoinj-web/src/main/webapp/js/jquery-1.11.2.min.map b/ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.min.map similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery-1.11.2.min.map rename to ucoinj-ui-wicket/src/main/webapp/js/jquery-1.11.2.min.map diff --git a/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.js new file mode 100644 index 0000000000000000000000000000000000000000..eed17778c688271208406367c0c1681d81feca6f --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.js @@ -0,0 +1,9210 @@ +/*! + * jQuery JavaScript Library v2.1.4 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:01Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.4", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\f]' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = "<input/>"; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // Add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // If we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // We once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android<4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android<4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", key ] ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG <use> instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: Android<4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Support: Firefox, Chrome, Safari +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE9 + option: [ 1, "<select multiple='multiple'>", "</select>" ], + + thead: [ 1, "<table>", "</table>" ], + col: [ 2, "<table><colgroup>", "</colgroup></table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + _default: [ 0, "", "" ] + }; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, type, key, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each(function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + }); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1></$2>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optimization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); + + // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse + doc = iframe[ 0 ].contentDocument; + + // Support: IE + doc.write(); + doc.close(); + + display = actualDisplay( nodeName, doc ); + iframe.detach(); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + } + + return display; +} +var rmargin = (/^margin/); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + // Support: IE<=11+, Firefox<=30+ (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + if ( elem.ownerDocument.defaultView.opener ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + } + + return window.getComputedStyle( elem, null ); + }; + + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + + // Support: IE9 + // getPropertyValue is only needed for .css('filter') (#12537) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + } + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // Support: iOS < 6 + // A tribute to the "awesome hack by Dean Edwards" + // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + // Support: IE + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return (this.get = hookFn).apply( this, arguments ); + } + }; +} + + +(function() { + var pixelPositionVal, boxSizingReliableVal, + docElem = document.documentElement, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + if ( !div.style ) { + return; + } + + // Support: IE9-11+ + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" + + "position:absolute"; + container.appendChild( div ); + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computePixelPositionAndBoxSizingReliable() { + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + + "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + + "border:1px;padding:1px;width:4px;position:absolute"; + div.innerHTML = ""; + docElem.appendChild( container ); + + var divStyle = window.getComputedStyle( div, null ); + pixelPositionVal = divStyle.top !== "1%"; + boxSizingReliableVal = divStyle.width === "4px"; + + docElem.removeChild( container ); + } + + // Support: node.js jsdom + // Don't assume that getComputedStyle is a property of the global object + if ( window.getComputedStyle ) { + jQuery.extend( support, { + pixelPosition: function() { + + // This test is executed only once but we still do memoizing + // since we can use the boxSizingReliable pre-computing. + // No need to check if the test was already performed, though. + computePixelPositionAndBoxSizingReliable(); + return pixelPositionVal; + }, + boxSizingReliable: function() { + if ( boxSizingReliableVal == null ) { + computePixelPositionAndBoxSizingReliable(); + } + return boxSizingReliableVal; + }, + reliableMarginRight: function() { + + // Support: Android 2.3 + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // This support function is only executed once so no memoizing is needed. + var ret, + marginDiv = div.appendChild( document.createElement( "div" ) ); + + // Reset CSS: box-sizing; display; margin; border; padding + marginDiv.style.cssText = div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + docElem.appendChild( container ); + + ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); + + docElem.removeChild( container ); + div.removeChild( marginDiv ); + + return ret; + } + }); + } +})(); + + +// A method for quickly swapping in/out CSS properties to get correct calculations. +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var + // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[0].toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // Both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // At this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // At this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // At this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && + ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // Use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = data_priv.get( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + } + } else { + hidden = isHidden( elem ); + + if ( display !== "none" || !hidden ) { + data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.extend({ + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + "float": "cssFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Support: IE9-11+ + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + style[ name ] = value; + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? + jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var styles = extra && getStyles( elem ); + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ) : 0 + ); + } + }; +}); + +// Support: Android 2.3 +jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, + function( elem, computed ) { + if ( computed ) { + return jQuery.swap( elem, { "display": "inline-block" }, + curCSS, [ elem, "marginRight" ] ); + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); + +jQuery.fn.extend({ + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE9 +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + } +}; + +jQuery.fx = Tween.prototype.init; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ), + target = tween.cur(), + parts = rfxnum.exec( value ), + unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && + rfxnum.exec( jQuery.css( tween.elem, prop ) ), + scale = 1, + maxIterations = 20; + + if ( start && start[ 3 ] !== unit ) { + // Trust units reported by jQuery.css + unit = unit || start[ 3 ]; + + // Make sure we update the tween properties later on + parts = parts || []; + + // Iteratively approximate from a nonzero starting point + start = +target || 1; + + do { + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur(), + // break the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + // Update tween properties + if ( parts ) { + start = tween.start = +start || +target || 0; + tween.unit = unit; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[ 1 ] ? + start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : + +parts[ 2 ]; + } + + return tween; + } ] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( (tween = collection[ index ].call( animation, prop, value )) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + /* jshint validthis: true */ + var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHidden( elem ), + dataShow = data_priv.get( elem, "fxshow" ); + + // Handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // Ensure the complete handler is called before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // Height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE9-10 do not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + display = jQuery.css( elem, "display" ); + + // Test default display if display is currently "none" + checkDisplay = display === "none" ? + data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; + + if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { + style.display = "inline-block"; + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + + // show/hide pass + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.exec( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + + // Any non-fx value stops us from restoring the original display value + } else { + display = undefined; + } + } + + if ( !jQuery.isEmptyObject( orig ) ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = data_priv.access( elem, "fxshow", {} ); + } + + // Store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + + data_priv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( prop in orig ) { + tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + + // If this is a noop like .hide().hide(), restore an overwritten display value + } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { + style.display = display; + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // Don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // Support: Android 2.3 + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || data_priv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = data_priv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = data_priv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + }); + } +}); + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + if ( timer() ) { + jQuery.fx.start(); + } else { + jQuery.timers.pop(); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.start = function() { + if ( !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); +}; + + +(function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: iOS<=5.1, Android<=4.2+ + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE<=11+ + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: Android<=2.3 + // Options inside disabled selects are incorrectly marked as disabled + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<=11+ + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +})(); + + +var nodeHook, boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend({ + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + } +}); + +jQuery.extend({ + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + elem[ propName ] = false; + } + + elem.removeAttribute( name ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + jQuery.nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle; + if ( !isXML ) { + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ name ]; + attrHandle[ name ] = ret; + ret = getter( elem, name, isXML ) != null ? + name.toLowerCase() : + null; + attrHandle[ name ] = handle; + } + return ret; + }; +}); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i; + +jQuery.fn.extend({ + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each(function() { + delete this[ jQuery.propFix[ name ] || name ]; + }); + } +}); + +jQuery.extend({ + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? + elem.tabIndex : + -1; + } + } + } +}); + +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + + + + +var rclass = /[\t\r\n\f]/g; + +jQuery.fn.extend({ + addClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + proceed = typeof value === "string" && value, + i = 0, + len = this.length; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = jQuery.trim( cur ); + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + proceed = arguments.length === 0 || typeof value === "string" && value, + i = 0, + len = this.length; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = value ? jQuery.trim( cur ) : ""; + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // Toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + data_priv.set( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + } +}); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend({ + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // Handle most common string cases + ret.replace(rreturn, "") : + // Handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + // Support: IE10-11+ + // option.text throws exceptions (#14686, #14858) + jQuery.trim( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // IE6-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) { + optionSet = true; + } + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +}); + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); + + + + +// Return jQuery for attributes-only inclusion + + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +}); + +jQuery.fn.extend({ + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + } +}); + + +var nonce = jQuery.now(); + +var rquery = (/\?/); + + + +// Support: Android 2.3 +// Workaround failure to string-cast null input +jQuery.parseJSON = function( data ) { + return JSON.parse( data + "" ); +}; + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE9 + try { + tmp = new DOMParser(); + xml = tmp.parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rhash = /#.*$/, + rts = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Document location + ajaxLocation = window.location.href, + + // Segment location into parts + ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + while ( (dataType = dataTypes[i++]) ) { + // Prepend if requested + if ( dataType[0] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); + + // Otherwise append + } else { + (structure[ dataType ] = structure[ dataType ] || []).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + }); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s[ "throws" ] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: ajaxLocation, + type: "GET", + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + // URL without anti-cache param + cacheURL, + // Response headers + responseHeadersString, + responseHeaders, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks("once memory"), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( (match = rheaders.exec( responseHeadersString )) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + var lname = name.toLowerCase(); + if ( !state ) { + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( state < 2 ) { + for ( code in map ) { + // Lazy-add the new callback in a way that preserves old ones + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } else { + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ).complete = completeDeferred.add; + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) + .replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger("ajaxStart"); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + cacheURL = s.url; + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add anti-cache in url if needed + if ( s.cache === false ) { + s.url = rts.test( cacheURL ) ? + + // If there is already a '_' parameter, set its value + cacheURL.replace( rts, "$1_=" + nonce++ ) : + + // Otherwise add one to the end + cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; + } + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout(function() { + jqXHR.abort("timeout"); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch ( e ) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader("etag"); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger("ajaxStop"); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // Shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + }; +}); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); +}; + + +jQuery.fn.extend({ + wrapAll: function( html ) { + var wrap; + + if ( jQuery.isFunction( html ) ) { + return this.each(function( i ) { + jQuery( this ).wrapAll( html.call(this, i) ); + }); + } + + if ( this[ 0 ] ) { + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function( i ) { + jQuery( this ).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); + + +jQuery.expr.filters.hidden = function( elem ) { + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; +}; +jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); +}; + + + + +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // Item is non-scalar (array or object), encode its numeric index. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function() { + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + }) + .filter(function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + }) + .map(function( i, elem ) { + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + + +jQuery.ajaxSettings.xhr = function() { + try { + return new XMLHttpRequest(); + } catch( e ) {} +}; + +var xhrId = 0, + xhrCallbacks = {}, + xhrSuccessStatus = { + // file protocol always yields status code 0, assume 200 + 0: 200, + // Support: IE9 + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +// Support: IE9 +// Open requests must be manually aborted on unload (#5280) +// See https://support.microsoft.com/kb/2856746 for more info +if ( window.attachEvent ) { + window.attachEvent( "onunload", function() { + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ](); + } + }); +} + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport(function( options ) { + var callback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(), + id = ++xhrId; + + xhr.open( options.type, options.url, options.async, options.username, options.password ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers["X-Requested-With"] ) { + headers["X-Requested-With"] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + delete xhrCallbacks[ id ]; + callback = xhr.onload = xhr.onerror = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + complete( + // file: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + // Support: IE9 + // Accessing binary-data responseText throws an exception + // (#11426) + typeof xhr.responseText === "string" ? { + text: xhr.responseText + } : undefined, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + xhr.onerror = callback("error"); + + // Create the abort callback + callback = xhrCallbacks[ id ] = callback("abort"); + + try { + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +}); + + + + +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /(?:java|ecma)script/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery("<script>").prop({ + async: true, + charset: s.scriptCharset, + src: s.url + }).on( + "load error", + callback = function( evt ) { + script.remove(); + callback = null; + if ( evt ) { + complete( evt.type === "error" ? 404 : 200, evt.type ); + } + } + ); + document.head.appendChild( script[ 0 ] ); + }, + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +}); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); + + + + +// data: string of html +// context (optional): If specified, the fragment will be created in this context, defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +// Keep a copy of the old load method +var _load = jQuery.fn.load; + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = jQuery.trim( url.slice( off ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + }).complete( callback && function( jqXHR, status ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + }); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +}); + + + + +jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; +}; + + + + +var docElem = window.document.documentElement; + +/** + * Gets a window from an element + */ +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; +} + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // Set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; + + // Need to be able to calculate position if either + // top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend({ + offset: function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, win, + elem = this[ 0 ], + box = { top: 0, left: 0 }, + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // Support: BlackBerry 5, iOS 3 (original iPhone) + // If we don't have gBCR, just use 0,0 rather than error + if ( typeof elem.getBoundingClientRect !== strundefined ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + return { + top: box.top + win.pageYOffset - docElem.clientTop, + left: box.left + win.pageXOffset - docElem.clientLeft + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + elem = this[ 0 ], + parentOffset = { top: 0, left: 0 }; + + // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + // Assume getBoundingClientRect is there when computed position is fixed + offset = elem.getBoundingClientRect(); + + } else { + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); + parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); + } + + // Subtract parent offsets and element margins + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || docElem; + + while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { + offsetParent = offsetParent.offsetParent; + } + + return offsetParent || docElem; + }); + } +}); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = "pageYOffset" === prop; + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? win[ prop ] : elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : window.pageXOffset, + top ? val : window.pageYOffset + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +// Support: Safari<7+, Chrome<37+ +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 +// getComputedStyle returns percent when specified for top/left/bottom/right; +// rather than make the css module depend on the offset module, just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + // If curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +}); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // Margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], + // whichever is greatest + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); + + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + return this.length; +}; + +jQuery.fn.andSelf = jQuery.fn.addBack; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + }); +} + + + + +var + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in AMD +// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( typeof noGlobal === strundefined ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; + +})); diff --git a/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.min.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.min.js new file mode 100644 index 0000000000000000000000000000000000000000..49990d6e14503798f142dcb0d5b23cb0c8f80244 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/jquery-2.1.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)), +void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n}); diff --git a/ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.js similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.js rename to ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.js diff --git a/ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.min.js b/ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.min.js similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.min.js rename to ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.min.js diff --git a/ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.min.map b/ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.min.map similarity index 100% rename from ucoinj-web/src/main/webapp/js/jquery.mobile-1.4.5.min.map rename to ucoinj-ui-wicket/src/main/webapp/js/jquery.mobile-1.4.5.min.map diff --git a/ucoinj-ui-wicket/src/main/webapp/js/nacl_factory.js b/ucoinj-ui-wicket/src/main/webapp/js/nacl_factory.js new file mode 100644 index 0000000000000000000000000000000000000000..4323b88f3ed2f0dd98d1171cbbb3b274ff839b8b --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/nacl_factory.js @@ -0,0 +1,26483 @@ +var nacl_factory = { + instantiate: function (requested_total_memory) { + return (function (window, document) { + var Module = {TOTAL_MEMORY: (requested_total_memory || 33554432)}; + var nacl_raw = Module; +function e(a) { + throw a; +} +var k = void 0, l = !0, m = null, n = !1; +function aa() { + return function() { + } +} +var q, r; +r || (r = eval("(function() { try { return Module || {} } catch(e) { return {} } })()")); +var ba = {}, t; +for(t in r) { + r.hasOwnProperty(t) && (ba[t] = r[t]) +} +var ca = "object" === typeof process && "function" === typeof require, da = "object" === typeof window, ea = "function" === typeof importScripts, fa = !da && !ca && !ea; +if(ca) { + r.print = function(a) { + process.stdout.write(a + "\n") + }; + r.printErr = function(a) { + process.stderr.write(a + "\n") + }; + var ga = require("fs"), ha = require("path"); + r.read = function(a, b) { + var a = ha.normalize(a), c = ga.readFileSync(a); + !c && a != ha.resolve(a) && (a = path.join(__dirname, "..", "src", a), c = ga.readFileSync(a)); + c && !b && (c = c.toString()); + return c + }; + r.readBinary = function(a) { + return r.read(a, l) + }; + r.load = function(a) { + ia(read(a)) + }; + r.arguments = process.argv.slice(2); + module.ee = r +}else { + fa ? (r.print = print, "undefined" != typeof printErr && (r.printErr = printErr), r.read = read, r.readBinary = function(a) { + return read(a, "binary") + }, "undefined" != typeof scriptArgs ? r.arguments = scriptArgs : "undefined" != typeof arguments && (r.arguments = arguments), this.Module = r) : da || ea ? (r.read = function(a) { + var b = new XMLHttpRequest; + b.open("GET", a, n); + b.send(m); + return b.responseText + }, "undefined" != typeof arguments && (r.arguments = arguments), da ? (r.print = function(a) { + console.log(a) + }, r.printErr = function(a) { + console.log(a) + }, this.Module = r) : ea && (r.print = aa(), r.load = importScripts)) : e("Unknown runtime environment. Where are we?") +} +function ia(a) { + eval.call(m, a) +} +"undefined" == !r.load && r.read && (r.load = function(a) { + ia(r.read(a)) +}); +r.print || (r.print = aa()); +r.printErr || (r.printErr = r.print); +r.arguments || (r.arguments = []); +r.print = r.print; +r.P = r.printErr; +r.preRun = []; +r.postRun = []; +for(t in ba) { + ba.hasOwnProperty(t) && (r[t] = ba[t]) +} +function ja() { + return u +} +function ka(a) { + u = a +} +function la(a) { + if(1 == ma) { + return 1 + } + var b = {"%i1":1, "%i8":1, "%i16":2, "%i32":4, "%i64":8, "%float":4, "%double":8}["%" + a]; + b || ("*" == a.charAt(a.length - 1) ? b = ma : "i" == a[0] && (a = parseInt(a.substr(1)), v(0 == a % 8), b = a / 8)); + return b +} +function na(a, b, c) { + c && c.length ? (c.splice || (c = Array.prototype.slice.call(c)), c.splice(0, 0, b), r["dynCall_" + a].apply(m, c)) : r["dynCall_" + a].call(m, b) +} +var oa; +function pa() { + var a = [], b = 0; + this.oa = function(c) { + c &= 255; + b && (a.push(c), b--); + if(0 == a.length) { + if(128 > c) { + return String.fromCharCode(c) + } + a.push(c); + b = 191 < c && 224 > c ? 1 : 2; + return"" + } + if(0 < b) { + return"" + } + var c = a[0], d = a[1], f = a[2], c = 191 < c && 224 > c ? String.fromCharCode((c & 31) << 6 | d & 63) : String.fromCharCode((c & 15) << 12 | (d & 63) << 6 | f & 63); + a.length = 0; + return c + }; + this.yb = function(a) { + for(var a = unescape(encodeURIComponent(a)), b = [], f = 0;f < a.length;f++) { + b.push(a.charCodeAt(f)) + } + return b + } +} +function qa(a) { + var b = u; + u = u + a | 0; + u = u + 7 >> 3 << 3; + return b +} +function ra(a) { + var b = sa; + sa = sa + a | 0; + sa = sa + 7 >> 3 << 3; + return b +} +function ua(a) { + var b = x; + x = x + a | 0; + x = x + 7 >> 3 << 3; + x >= va && wa("Cannot enlarge memory arrays in asm.js. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, or (2) set Module.TOTAL_MEMORY before the program runs."); + return b +} +function xa(a, b) { + return Math.ceil(a / (b ? b : 8)) * (b ? b : 8) +} +var ma = 4, ya = {}, za = n, Aa; +function v(a, b) { + a || wa("Assertion failed: " + b) +} +r.ccall = function(a, b, c, d) { + return Ba(Ca(a), b, c, d) +}; +function Ca(a) { + try { + var b = r["_" + a]; + b || (b = eval("_" + a)) + }catch(c) { + } + v(b, "Cannot call unknown function " + a + " (perhaps LLVM optimizations or closure removed it?)"); + return b +} +function Ba(a, b, c, d) { + function f(a, b) { + if("string" == b) { + if(a === m || a === k || 0 === a) { + return 0 + } + g || (g = ja()); + var c = qa(a.length + 1); + Da(a, c); + return c + } + return"array" == b ? (g || (g = ja()), c = qa(a.length), Ea(a, c), c) : a + } + var g = 0, h = 0, d = d ? d.map(function(a) { + return f(a, c[h++]) + }) : []; + a = a.apply(m, d); + "string" == b ? b = Fa(a) : (v("array" != b), b = a); + g && ka(g); + return b +} +r.cwrap = function(a, b, c) { + var d = Ca(a); + return function() { + return Ba(d, b, c, Array.prototype.slice.call(arguments)) + } +}; +function Ga(a, b, c) { + c = c || "i8"; + "*" === c.charAt(c.length - 1) && (c = "i32"); + switch(c) { + case "i1": + A[a] = b; + break; + case "i8": + A[a] = b; + break; + case "i16": + Ha[a >> 1] = b; + break; + case "i32": + B[a >> 2] = b; + break; + case "i64": + Aa = [b >>> 0, (Math.min(+Math.floor(b / 4294967296), 4294967295) | 0) >>> 0]; + B[a >> 2] = Aa[0]; + B[a + 4 >> 2] = Aa[1]; + break; + case "float": + Ia[a >> 2] = b; + break; + case "double": + Ja[a >> 3] = b; + break; + default: + wa("invalid type for setValue: " + c) + } +} +r.setValue = Ga; +r.getValue = function(a, b) { + b = b || "i8"; + "*" === b.charAt(b.length - 1) && (b = "i32"); + switch(b) { + case "i1": + return A[a]; + case "i8": + return A[a]; + case "i16": + return Ha[a >> 1]; + case "i32": + return B[a >> 2]; + case "i64": + return B[a >> 2]; + case "float": + return Ia[a >> 2]; + case "double": + return Ja[a >> 3]; + default: + wa("invalid type for setValue: " + b) + } + return m +}; +var Ka = 0, La = 1, E = 2, Na = 4; +r.ALLOC_NORMAL = Ka; +r.ALLOC_STACK = La; +r.ALLOC_STATIC = E; +r.ALLOC_DYNAMIC = 3; +r.ALLOC_NONE = Na; +function F(a, b, c, d) { + var f, g; + "number" === typeof a ? (f = l, g = a) : (f = n, g = a.length); + var h = "string" === typeof b ? b : m, c = c == Na ? d : [Oa, qa, ra, ua][c === k ? E : c](Math.max(g, h ? 1 : b.length)); + if(f) { + d = c; + v(0 == (c & 3)); + for(a = c + (g & -4);d < a;d += 4) { + B[d >> 2] = 0 + } + for(a = c + g;d < a;) { + A[d++ | 0] = 0 + } + return c + } + if("i8" === h) { + return a.subarray || a.slice ? G.set(a, c) : G.set(new Uint8Array(a), c), c + } + for(var d = 0, i, j;d < g;) { + var p = a[d]; + "function" === typeof p && (p = ya.fe(p)); + f = h || b[d]; + 0 === f ? d++ : ("i64" == f && (f = "i32"), Ga(c + d, p, f), j !== f && (i = la(f), j = f), d += i) + } + return c +} +r.allocate = F; +function Fa(a, b) { + for(var c = n, d, f = 0;;) { + d = G[a + f | 0]; + if(128 <= d) { + c = l + }else { + if(0 == d && !b) { + break + } + } + f++; + if(b && f == b) { + break + } + } + b || (b = f); + var g = ""; + if(!c) { + for(;0 < b;) { + d = String.fromCharCode.apply(String, G.subarray(a, a + Math.min(b, 1024))), g = g ? g + d : d, a += 1024, b -= 1024 + } + return g + } + c = new pa; + for(f = 0;f < b;f++) { + d = G[a + f | 0], g += c.oa(d) + } + return g +} +r.Pointer_stringify = Fa; +var A, G, Ha, Pa, B, Qa, Ia, Ja, Ra = 0, sa = 0, Sa = 0, u = 0, Ta = 0, Ua = 0, x = 0, va = r.TOTAL_MEMORY || 16777216; +v(!!Int32Array && !!Float64Array && !!(new Int32Array(1)).subarray && !!(new Int32Array(1)).set, "Cannot fallback to non-typed array case: Code is too specialized"); +var I = new ArrayBuffer(va); +A = new Int8Array(I); +Ha = new Int16Array(I); +B = new Int32Array(I); +G = new Uint8Array(I); +Pa = new Uint16Array(I); +Qa = new Uint32Array(I); +Ia = new Float32Array(I); +Ja = new Float64Array(I); +B[0] = 255; +v(255 === G[0] && 0 === G[3], "Typed arrays 2 must be run on a little-endian system"); +r.HEAP = k; +r.HEAP8 = A; +r.HEAP16 = Ha; +r.HEAP32 = B; +r.HEAPU8 = G; +r.HEAPU16 = Pa; +r.HEAPU32 = Qa; +r.HEAPF32 = Ia; +r.HEAPF64 = Ja; +function Va(a) { + for(;0 < a.length;) { + var b = a.shift(); + if("function" == typeof b) { + b() + }else { + var c = b.V; + "number" === typeof c ? b.ha === k ? na("v", c) : na("vi", c, [b.ha]) : c(b.ha === k ? m : b.ha) + } + } +} +var Wa = [], Xa = [], Ya = [], Za = [], $a = [], ab = n; +function bb(a) { + Wa.unshift(a) +} +r.addOnPreRun = r.Vd = bb; +r.addOnInit = r.Sd = function(a) { + Xa.unshift(a) +}; +r.addOnPreMain = r.Ud = function(a) { + Ya.unshift(a) +}; +r.addOnExit = r.Rd = function(a) { + Za.unshift(a) +}; +function cb(a) { + $a.unshift(a) +} +r.addOnPostRun = r.Td = cb; +function J(a, b, c) { + a = (new pa).yb(a); + c && (a.length = c); + b || a.push(0); + return a +} +r.intArrayFromString = J; +r.intArrayToString = function(a) { + for(var b = [], c = 0;c < a.length;c++) { + var d = a[c]; + 255 < d && (d &= 255); + b.push(String.fromCharCode(d)) + } + return b.join("") +}; +function Da(a, b, c) { + a = J(a, c); + for(c = 0;c < a.length;) { + A[b + c | 0] = a[c], c += 1 + } +} +r.writeStringToMemory = Da; +function Ea(a, b) { + for(var c = 0;c < a.length;c++) { + A[b + c | 0] = a[c] + } +} +r.writeArrayToMemory = Ea; +function db(a, b) { + return 0 <= a ? a : 32 >= b ? 2 * Math.abs(1 << b - 1) + a : Math.pow(2, b) + a +} +function eb(a, b) { + if(0 >= a) { + return a + } + var c = 32 >= b ? Math.abs(1 << b - 1) : Math.pow(2, b - 1); + if(a >= c && (32 >= b || a > c)) { + a = -2 * c + a + } + return a +} +Math.imul || (Math.imul = function(a, b) { + var c = a & 65535, d = b & 65535; + return c * d + ((a >>> 16) * d + c * (b >>> 16) << 16) | 0 +}); +Math.ie = Math.imul; +var K = 0, fb = {}, gb = n, hb = m; +function ib(a) { + K++; + r.monitorRunDependencies && r.monitorRunDependencies(K); + a ? (v(!fb[a]), fb[a] = 1) : r.P("warning: run dependency added without ID") +} +r.addRunDependency = ib; +function jb(a) { + K--; + r.monitorRunDependencies && r.monitorRunDependencies(K); + a ? (v(fb[a]), delete fb[a]) : r.P("warning: run dependency removed without ID"); + 0 == K && (hb !== m && (clearInterval(hb), hb = m), !gb && kb && lb()) +} +r.removeRunDependency = jb; +r.preloadedImages = {}; +r.preloadedAudios = {}; +Ra = 8; +sa = Ra + 112632; +Xa.push({V:function() { + mb() +}}); +var nb, ob, pb; +nb = nb = F([0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +ob = ob = F([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +pb = pb = F([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +F([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, +32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107, 111, 112, 116, 105, 111, 110, 32, 114, 101, 113, 117, 105, 114, 101, 115, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 115, 0, 0, 0, 0, 0, 0, 0, 111, 112, 116, 105, 111, 110, 32, 114, 101, 113, 117, 105, 114, 101, 115, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 99, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 36, 64, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 136, 195, 64, 0, 0, 0, 0, 132, 215, 151, 65, 0, 128, 224, 55, 121, 195, 65, 67, 23, 110, 5, 181, 181, 184, 147, 70, 245, 249, 63, 233, 3, 79, 56, 77, 50, 29, 48, 249, 72, 119, 130, 90, 60, 191, 115, 127, 221, 79, 21, 117, 16, 182, 1, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 111, 112, 116, 105, 111, 110, 32, 100, 111, 101, +115, 110, 39, 116, 32, 116, 97, 107, 101, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 46, 42, 115, 0, 27, 0, 0, 0, 19, 0, 0, 0, 44, 0, 0, 0, 10, 0, 0, 0, 163, 0, 0, 0, 229, 0, 0, 0, 156, 0, 0, 0, 237, 0, 0, 0, 167, 0, 0, 0, 41, 0, 0, 0, 99, 0, 0, 0, 8, 0, 0, 0, 93, 0, 0, 0, 33, 0, 0, 0, 6, 0, 0, 0, 33, 0, 0, 0, 235, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, +0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 19, 0, 0, 0, 44, 0, 0, 0, 10, 0, 0, 0, 163, 0, 0, 0, 229, 0, 0, 0, 156, 0, 0, 0, 237, 0, 0, 0, 167, 0, 0, 0, 41, 0, 0, 0, 99, 0, 0, 0, 8, 0, 0, 0, 93, 0, 0, 0, 33, 0, 0, 0, 6, 0, 0, 0, 33, 0, 0, 0, 235, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, +0, 0, 0, 255, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 211, 0, 0, 0, 245, 0, 0, 0, 92, 0, 0, 0, 26, 0, 0, 0, 99, 0, 0, 0, 18, 0, 0, 0, 88, 0, 0, 0, 214, 0, 0, 0, 156, 0, 0, 0, 247, 0, 0, 0, 162, 0, 0, 0, 222, 0, 0, 0, 249, 0, 0, 0, 222, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 237, 0, 0, 0, 211, 0, 0, 0, 245, 0, 0, 0, 92, 0, 0, 0, 26, 0, 0, 0, 99, 0, 0, 0, 18, 0, 0, 0, 88, 0, 0, 0, 214, 0, 0, 0, 156, 0, 0, 0, 247, 0, 0, 0, 162, 0, 0, 0, 222, 0, 0, 0, 249, 0, 0, 0, 222, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 106, 9, 230, 103, 243, 188, 201, +8, 187, 103, 174, 133, 132, 202, 167, 59, 60, 110, 243, 114, 254, 148, 248, 43, 165, 79, 245, 58, 95, 29, 54, 241, 81, 14, 82, 127, 173, 230, 130, 209, 155, 5, 104, 140, 43, 62, 108, 31, 31, 131, 217, 171, 251, 65, 189, 107, 91, 224, 205, 25, 19, 126, 33, 121, 106, 9, 230, 103, 187, 103, 174, 133, 60, 110, 243, 114, 165, 79, 245, 58, 81, 14, 82, 127, 155, 5, 104, 140, 31, 131, 217, 171, 91, 224, 205, 25, 106, 9, 230, 103, 243, 188, 201, 8, 187, 103, 174, 133, 132, 202, 167, 59, 60, 110, 243, 114, +254, 148, 248, 43, 165, 79, 245, 58, 95, 29, 54, 241, 81, 14, 82, 127, 173, 230, 130, 209, 155, 5, 104, 140, 43, 62, 108, 31, 31, 131, 217, 171, 251, 65, 189, 107, 91, 224, 205, 25, 19, 126, 33, 121, 106, 9, 230, 103, 187, 103, 174, 133, 60, 110, 243, 114, 165, 79, 245, 58, 81, 14, 82, 127, 155, 5, 104, 140, 31, 131, 217, 171, 91, 224, 205, 25, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +63, 117, 110, 107, 110, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 115, 0, 0, 0, 0, 117, 110, 107, 110, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 99, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 160, 0, 0, 0, 14, 0, 0, 0, 74, 0, 0, 0, 39, 0, 0, 0, 27, 0, 0, 0, 238, 0, 0, 0, 196, 0, 0, 0, 120, 0, 0, 0, 228, 0, 0, 0, 47, 0, 0, 0, 173, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 67, 0, 0, 0, 47, 0, 0, 0, 167, 0, 0, 0, 215, 0, 0, 0, 251, 0, 0, 0, +61, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 43, 0, 0, 0, 11, 0, 0, 0, 223, 0, 0, 0, 193, 0, 0, 0, 79, 0, 0, 0, 128, 0, 0, 0, 36, 0, 0, 0, 131, 0, 0, 0, 43, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 120, 0, 0, 0, 89, 0, 0, 0, 19, 0, 0, 0, 202, 0, 0, 0, 77, 0, 0, 0, 235, 0, 0, 0, 117, 0, 0, 0, 171, 0, 0, 0, 216, 0, 0, 0, +65, 0, 0, 0, 65, 0, 0, 0, 77, 0, 0, 0, 10, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 232, 0, 0, 0, 121, 0, 0, 0, 119, 0, 0, 0, 121, 0, 0, 0, 64, 0, 0, 0, 199, 0, 0, 0, 140, 0, 0, 0, 115, 0, 0, 0, 254, 0, 0, 0, 111, 0, 0, 0, 43, 0, 0, 0, 238, 0, 0, 0, 108, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0, 89, 0, 0, 0, 241, 0, 0, 0, 178, 0, 0, 0, 38, 0, 0, 0, 148, 0, 0, 0, 155, 0, 0, 0, 214, 0, 0, 0, 235, 0, 0, 0, 86, 0, 0, 0, 177, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 154, 0, 0, 0, 20, 0, 0, 0, 224, 0, 0, 0, +0, 0, 0, 0, 48, 0, 0, 0, 209, 0, 0, 0, 243, 0, 0, 0, 238, 0, 0, 0, 242, 0, 0, 0, 128, 0, 0, 0, 142, 0, 0, 0, 25, 0, 0, 0, 231, 0, 0, 0, 252, 0, 0, 0, 223, 0, 0, 0, 86, 0, 0, 0, 220, 0, 0, 0, 217, 0, 0, 0, 6, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 26, 213, 37, 143, +96, 45, 86, 201, 178, 167, 37, 149, 96, 199, 44, 105, 92, 220, 214, 253, 49, 226, 164, 192, 254, 83, 110, 205, 211, 54, 105, 33, 163, 221, 183, 165, 179, 138, 222, 109, 245, 82, 81, 119, 128, 159, 240, 32, 125, 227, 171, 100, 142, 78, 234, 102, 101, 118, 139, 215, 15, 95, 135, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 213, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, 0, 96, 0, 0, 0, 45, 0, 0, 0, 86, 0, 0, 0, 201, 0, 0, 0, 178, 0, 0, 0, 167, 0, 0, 0, 37, 0, 0, 0, 149, 0, 0, 0, 96, 0, 0, 0, 199, 0, 0, 0, 44, 0, 0, 0, 105, 0, 0, 0, 92, 0, 0, 0, 220, 0, 0, 0, 214, 0, 0, 0, 253, 0, 0, 0, 49, 0, 0, 0, 226, 0, 0, 0, 164, 0, 0, 0, 192, 0, 0, 0, 254, 0, 0, 0, 83, 0, 0, 0, 110, 0, 0, 0, 205, 0, 0, 0, 211, 0, 0, 0, 54, 0, 0, 0, 105, 0, 0, 0, 33, 0, 0, 0, 88, 0, 0, 0, 102, +0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 14, 0, 0, 0, 206, 0, 0, 0, 67, 0, 0, 0, 40, 0, 0, 0, 78, 0, 0, 0, 161, 0, +0, 0, 197, 0, 0, 0, 131, 0, 0, 0, 95, 0, 0, 0, 164, 0, 0, 0, 215, 0, 0, 0, 21, 0, 0, 0, 69, 0, 0, 0, 142, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 172, 0, 0, 0, 231, 0, 0, 0, 51, 0, 0, 0, 24, 0, 0, 0, 125, 0, 0, 0, 59, 0, 0, 0, 4, 0, 0, 0, 61, 0, 0, 0, 108, 0, 0, 0, 4, 0, 0, 0, 90, 0, 0, 0, 159, 0, 0, 0, 76, 0, 0, 0, 56, 0, 0, 0, 171, 0, 0, 0, 54, 0, 0, 0, 201, 0, 0, 0, 163, 0, 0, 0, 248, 0, 0, 0, 106, 0, 0, 0, 174, 0, 0, 0, 70, 0, 0, 0, 95, 0, 0, 0, 14, 0, 0, 0, 86, 0, 0, 0, 81, 0, 0, 0, 56, 0, 0, 0, 100, +0, 0, 0, 81, 0, 0, 0, 15, 0, 0, 0, 57, 0, 0, 0, 151, 0, 0, 0, 86, 0, 0, 0, 31, 0, 0, 0, 162, 0, 0, 0, 201, 0, 0, 0, 232, 0, 0, 0, 94, 0, 0, 0, 162, 0, 0, 0, 29, 0, 0, 0, 194, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 243, 0, 0, 0, 205, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 92, 0, 0, 0, 226, 0, 0, 0, 248, 0, 0, 0, 211, 0, 0, 0, 95, 0, 0, 0, 72, 0, 0, 0, 98, 0, 0, 0, 172, 0, 0, 0, 134, 0, 0, 0, 72, 0, 0, 0, 98, 0, 0, 0, 129, 0, 0, 0, 25, 0, 0, 0, 152, 0, 0, 0, 67, 0, 0, 0, 99, 0, 0, 0, 58, 0, 0, +0, 200, 0, 0, 0, 218, 0, 0, 0, 62, 0, 0, 0, 116, 0, 0, 0, 174, 0, 0, 0, 244, 0, 0, 0, 31, 0, 0, 0, 73, 0, 0, 0, 143, 0, 0, 0, 146, 0, 0, 0, 34, 0, 0, 0, 74, 0, 0, 0, 156, 0, 0, 0, 174, 0, 0, 0, 103, 0, 0, 0, 212, 0, 0, 0, 180, 0, 0, 0, 245, 0, 0, 0, 120, 0, 0, 0, 72, 0, 0, 0, 104, 0, 0, 0, 195, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 103, 0, 0, 0, 23, 0, 0, 0, 236, 0, 0, 0, 22, 0, 0, 0, 159, 0, 0, 0, 247, 0, 0, 0, 158, 0, 0, 0, 38, 0, 0, 0, 96, 0, 0, 0, 142, 0, 0, 0, 161, 0, 0, +0, 38, 0, 0, 0, 161, 0, 0, 0, 171, 0, 0, 0, 105, 0, 0, 0, 238, 0, 0, 0, 119, 0, 0, 0, 209, 0, 0, 0, 177, 0, 0, 0, 103, 0, 0, 0, 18, 0, 0, 0, 112, 0, 0, 0, 248, 0, 0, 0, 201, 0, 0, 0, 196, 0, 0, 0, 87, 0, 0, 0, 166, 0, 0, 0, 58, 0, 0, 0, 73, 0, 0, 0, 71, 0, 0, 0, 21, 0, 0, 0, 206, 0, 0, 0, 147, 0, 0, 0, 193, 0, 0, 0, 158, 0, 0, 0, 115, 0, 0, 0, 26, 0, 0, 0, 249, 0, 0, 0, 32, 0, 0, 0, 53, 0, 0, 0, 122, 0, 0, 0, 184, 0, 0, 0, 212, 0, 0, 0, 37, 0, 0, 0, 131, 0, 0, 0, 70, 0, 0, 0, 241, 0, 0, 0, 207, 0, +0, 0, 86, 0, 0, 0, 219, 0, 0, 0, 168, 0, 0, 0, 61, 0, 0, 0, 32, 0, 0, 0, 47, 0, 0, 0, 17, 0, 0, 0, 50, 0, 0, 0, 202, 0, 0, 0, 97, 0, 0, 0, 171, 0, 0, 0, 56, 0, 0, 0, 223, 0, 0, 0, 240, 0, 0, 0, 15, 0, 0, 0, 47, 0, 0, 0, 234, 0, 0, 0, 50, 0, 0, 0, 40, 0, 0, 0, 242, 0, 0, 0, 76, 0, 0, 0, 108, 0, 0, 0, 113, 0, 0, 0, 213, 0, 0, 0, 128, 0, 0, 0, 133, 0, 0, 0, 184, 0, 0, 0, 14, 0, 0, 0, 71, 0, 0, 0, 225, 0, 0, 0, 149, 0, 0, 0, 21, 0, 0, 0, 203, 0, 0, 0, 39, 0, 0, 0, 232, 0, 0, 0, 208, 0, 0, 0, 71, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 132, 0, 0, 0, 165, 0, 0, 0, 8, 0, 0, 0, 188, 0, 0, 0, 253, 0, 0, 0, 135, 0, 0, 0, 59, 0, 0, 0, 153, 0, 0, 0, 139, 0, 0, 0, 105, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 198, 0, 0, 0, 58, 0, 0, 0, 235, 0, 0, 0, 147, 0, 0, +0, 207, 0, 0, 0, 78, 0, 0, 0, 248, 0, 0, 0, 92, 0, 0, 0, 45, 0, 0, 0, 134, 0, 0, 0, 66, 0, 0, 0, 182, 0, 0, 0, 113, 0, 0, 0, 215, 0, 0, 0, 151, 0, 0, 0, 95, 0, 0, 0, 225, 0, 0, 0, 66, 0, 0, 0, 103, 0, 0, 0, 180, 0, 0, 0, 185, 0, 0, 0, 55, 0, 0, 0, 252, 0, 0, 0, 169, 0, 0, 0, 91, 0, 0, 0, 47, 0, 0, 0, 30, 0, 0, 0, 147, 0, 0, 0, 228, 0, 0, 0, 30, 0, 0, 0, 98, 0, 0, 0, 252, 0, 0, 0, 60, 0, 0, 0, 120, 0, 0, 0, 129, 0, 0, 0, 143, 0, 0, 0, 243, 0, 0, 0, 138, 0, 0, 0, 102, 0, 0, 0, 9, 0, 0, 0, 111, 0, 0, +0, 173, 0, 0, 0, 110, 0, 0, 0, 121, 0, 0, 0, 115, 0, 0, 0, 229, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 211, 0, 0, 0, 33, 0, 0, 0, 248, 0, 0, 0, 249, 0, 0, 0, 40, 0, 0, 0, 108, 0, 0, 0, 109, 0, 0, 0, 89, 0, 0, 0, 178, 0, 0, 0, 89, 0, 0, 0, 116, 0, 0, 0, 35, 0, 0, 0, 191, 0, 0, 0, 231, 0, 0, 0, 51, 0, 0, 0, 141, 0, 0, 0, 87, 0, 0, 0, 9, 0, 0, 0, 145, 0, 0, 0, 156, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 21, 0, 0, 0, 43, 0, 0, 0, 226, 0, 0, 0, 184, 0, 0, 0, 238, 0, 0, 0, 58, 0, 0, 0, 229, 0, 0, 0, +39, 0, 0, 0, 6, 0, 0, 0, 134, 0, 0, 0, 164, 0, 0, 0, 35, 0, 0, 0, 235, 0, 0, 0, 39, 0, 0, 0, 103, 0, 0, 0, 193, 0, 0, 0, 55, 0, 0, 0, 171, 0, 0, 0, 122, 0, 0, 0, 216, 0, 0, 0, 39, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 142, 0, 0, 0, 255, 0, 0, 0, 17, 0, 0, 0, 106, 0, 0, 0, 176, 0, 0, 0, 120, 0, 0, 0, 110, 0, 0, 0, 173, 0, 0, 0, 58, 0, 0, 0, 46, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 159, 0, 0, 0, 114, 0, 0, 0, 195, 0, 0, 0, 127, 0, 0, 0, 130, 0, 0, 0, 242, 0, 0, 0, 150, 0, 0, 0, 150, 0, 0, 0, 112, 0, 0, +0, 129, 0, 0, 0, 107, 0, 0, 0, 136, 0, 0, 0, 232, 0, 0, 0, 30, 0, 0, 0, 199, 0, 0, 0, 119, 0, 0, 0, 150, 0, 0, 0, 14, 0, 0, 0, 161, 0, 0, 0, 169, 0, 0, 0, 82, 0, 0, 0, 224, 0, 0, 0, 216, 0, 0, 0, 14, 0, 0, 0, 97, 0, 0, 0, 158, 0, 0, 0, 121, 0, 0, 0, 45, 0, 0, 0, 149, 0, 0, 0, 156, 0, 0, 0, 141, 0, 0, 0, 150, 0, 0, 0, 224, 0, 0, 0, 6, 0, 0, 0, 64, 0, 0, 0, 93, 0, 0, 0, 135, 0, 0, 0, 40, 0, 0, 0, 95, 0, 0, 0, 152, 0, 0, 0, 112, 0, 0, 0, 241, 0, 0, 0, 121, 0, 0, 0, 123, 0, 0, 0, 237, 0, 0, 0, 79, 0, +0, 0, 68, 0, 0, 0, 178, 0, 0, 0, 231, 0, 0, 0, 8, 0, 0, 0, 13, 0, 0, 0, 194, 0, 0, 0, 8, 0, 0, 0, 18, 0, 0, 0, 210, 0, 0, 0, 159, 0, 0, 0, 223, 0, 0, 0, 205, 0, 0, 0, 147, 0, 0, 0, 32, 0, 0, 0, 138, 0, 0, 0, 207, 0, 0, 0, 51, 0, 0, 0, 202, 0, 0, 0, 109, 0, 0, 0, 137, 0, 0, 0, 185, 0, 0, 0, 119, 0, 0, 0, 200, 0, 0, 0, 147, 0, 0, 0, 27, 0, 0, 0, 78, 0, 0, 0, 96, 0, 0, 0, 38, 0, 0, 0, 79, 0, 0, 0, 126, 0, 0, 0, 151, 0, 0, 0, 246, 0, 0, 0, 64, 0, 0, 0, 221, 0, 0, 0, 79, 0, 0, 0, 252, 0, 0, 0, 82, 0, +0, 0, 120, 0, 0, 0, 249, 0, 0, 0, 144, 0, 0, 0, 49, 0, 0, 0, 3, 0, 0, 0, 230, 0, 0, 0, 125, 0, 0, 0, 86, 0, 0, 0, 57, 0, 0, 0, 11, 0, 0, 0, 29, 0, 0, 0, 86, 0, 0, 0, 130, 0, 0, 0, 133, 0, 0, 0, 249, 0, 0, 0, 26, 0, 0, 0, 66, 0, 0, 0, 23, 0, 0, 0, 105, 0, 0, 0, 108, 0, 0, 0, 207, 0, 0, 0, 57, 0, 0, 0, 105, 0, 0, 0, 210, 0, 0, 0, 6, 0, 0, 0, 58, 0, 0, 0, 79, 0, 0, 0, 57, 0, 0, 0, 45, 0, 0, 0, 249, 0, 0, 0, 56, 0, 0, 0, 64, 0, 0, 0, 140, 0, 0, 0, 76, 0, 0, 0, 231, 0, 0, 0, 5, 0, 0, 0, 18, 0, 0, 0, 180, +0, 0, 0, 120, 0, 0, 0, 139, 0, 0, 0, 248, 0, 0, 0, 192, 0, 0, 0, 236, 0, 0, 0, 147, 0, 0, 0, 222, 0, 0, 0, 122, 0, 0, 0, 107, 0, 0, 0, 206, 0, 0, 0, 44, 0, 0, 0, 225, 0, 0, 0, 14, 0, 0, 0, 169, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, +0, 0, 164, 0, 0, 0, 60, 0, 0, 0, 176, 0, 0, 0, 15, 0, 0, 0, 122, 0, 0, 0, 81, 0, 0, 0, 241, 0, 0, 0, 120, 0, 0, 0, 214, 0, 0, 0, 217, 0, 0, 0, 106, 0, 0, 0, 253, 0, 0, 0, 70, 0, 0, 0, 232, 0, 0, 0, 184, 0, 0, 0, 168, 0, 0, 0, 121, 0, 0, 0, 29, 0, 0, 0, 135, 0, 0, 0, 249, 0, 0, 0, 144, 0, 0, 0, 242, 0, 0, 0, 156, 0, 0, 0, 19, 0, 0, 0, 41, 0, 0, 0, 248, 0, 0, 0, 11, 0, 0, 0, 32, 0, 0, 0, 100, 0, 0, 0, 250, 0, 0, 0, 5, 0, 0, 0, 38, 0, 0, 0, 9, 0, 0, 0, 218, 0, 0, 0, 23, 0, 0, 0, 175, 0, 0, 0, 149, 0, +0, 0, 214, 0, 0, 0, 251, 0, 0, 0, 106, 0, 0, 0, 25, 0, 0, 0, 13, 0, 0, 0, 110, 0, 0, 0, 94, 0, 0, 0, 18, 0, 0, 0, 241, 0, 0, 0, 153, 0, 0, 0, 76, 0, 0, 0, 170, 0, 0, 0, 168, 0, 0, 0, 111, 0, 0, 0, 121, 0, 0, 0, 134, 0, 0, 0, 244, 0, 0, 0, 114, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 249, 0, 0, 0, 234, 0, 0, 0, 158, 0, 0, 0, 25, 0, 0, 0, 61, 0, 0, 0, 135, 0, 0, 0, 221, 0, 0, 0, 207, 0, 0, 0, 240, 0, 0, 0, 91, 0, 0, 0, 73, 0, 0, 0, 162, 0, 0, 0, 93, 0, 0, 0, 64, 0, 0, 0, 122, 0, 0, 0, 35, 0, +0, 0, 38, 0, 0, 0, 164, 0, 0, 0, 122, 0, 0, 0, 131, 0, 0, 0, 138, 0, 0, 0, 183, 0, 0, 0, 139, 0, 0, 0, 210, 0, 0, 0, 26, 0, 0, 0, 191, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 95, 0, 0, 0, 123, 0, 0, 0, 169, 0, 0, 0, 177, 0, 0, 0, 190, 0, 0, 0, 157, 0, 0, 0, 55, 0, 0, 0, 252, 0, 0, 0, 134, 0, 0, 0, 75, 0, 0, 0, 8, 0, 0, 0, 238, 0, 0, 0, 231, 0, 0, 0, 160, 0, 0, 0, 253, 0, 0, 0, 33, 0, 0, 0, 69, 0, 0, 0, 9, 0, 0, 0, 52, 0, 0, 0, 193, 0, 0, 0, 97, 0, 0, 0, 50, 0, 0, 0, 35, 0, 0, +0, 252, 0, 0, 0, 155, 0, 0, 0, 85, 0, 0, 0, 72, 0, 0, 0, 83, 0, 0, 0, 153, 0, 0, 0, 247, 0, 0, 0, 99, 0, 0, 0, 208, 0, 0, 0, 153, 0, 0, 0, 206, 0, 0, 0, 1, 0, 0, 0, 224, 0, 0, 0, 159, 0, 0, 0, 235, 0, 0, 0, 40, 0, 0, 0, 71, 0, 0, 0, 252, 0, 0, 0, 171, 0, 0, 0, 90, 0, 0, 0, 23, 0, 0, 0, 240, 0, 0, 0, 133, 0, 0, 0, 86, 0, 0, 0, 58, 0, 0, 0, 48, 0, 0, 0, 134, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 75, 0, 0, 0, 142, 0, 0, 0, 68, 0, 0, 0, 116, 0, 0, 0, 58, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, +50, 0, 0, 0, 143, 0, 0, 0, 159, 0, 0, 0, 63, 0, 0, 0, 8, 0, 0, 0, 53, 0, 0, 0, 233, 0, 0, 0, 202, 0, 0, 0, 22, 0, 0, 0, 95, 0, 0, 0, 110, 0, 0, 0, 28, 0, 0, 0, 89, 0, 0, 0, 28, 0, 0, 0, 101, 0, 0, 0, 93, 0, 0, 0, 52, 0, 0, 0, 164, 0, 0, 0, 9, 0, 0, 0, 205, 0, 0, 0, 19, 0, 0, 0, 156, 0, 0, 0, 112, 0, 0, 0, 125, 0, 0, 0, 177, 0, 0, 0, 42, 0, 0, 0, 197, 0, 0, 0, 136, 0, 0, 0, 175, 0, 0, 0, 11, 0, 0, 0, 96, 0, 0, 0, 199, 0, 0, 0, 159, 0, 0, 0, 52, 0, 0, 0, 141, 0, 0, 0, 214, 0, 0, 0, 183, 0, 0, 0, 127, +0, 0, 0, 234, 0, 0, 0, 120, 0, 0, 0, 101, 0, 0, 0, 141, 0, 0, 0, 119, 0, 0, 0, 86, 0, 0, 0, 165, 0, 0, 0, 194, 0, 0, 0, 12, 0, 0, 0, 221, 0, 0, 0, 188, 0, 0, 0, 184, 0, 0, 0, 32, 0, 0, 0, 109, 0, 0, 0, 87, 0, 0, 0, 97, 0, 0, 0, 181, 0, 0, 0, 251, 0, 0, 0, 120, 0, 0, 0, 181, 0, 0, 0, 212, 0, 0, 0, 73, 0, 0, 0, 84, 0, 0, 0, 144, 0, 0, 0, 38, 0, 0, 0, 193, 0, 0, 0, 203, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 191, 0, 0, 0, 236, 0, 0, 0, 29, 0, 0, 0, 78, 0, 0, 0, 237, 0, 0, 0, 7, 0, 0, 0, 126, 0, 0, 0, +94, 0, 0, 0, 199, 0, 0, 0, 246, 0, 0, 0, 108, 0, 0, 0, 86, 0, 0, 0, 49, 0, 0, 0, 32, 0, 0, 0, 20, 0, 0, 0, 14, 0, 0, 0, 168, 0, 0, 0, 217, 0, 0, 0, 39, 0, 0, 0, 193, 0, 0, 0, 154, 0, 0, 0, 61, 0, 0, 0, 27, 0, 0, 0, 125, 0, 0, 0, 14, 0, 0, 0, 38, 0, 0, 0, 211, 0, 0, 0, 129, 0, 0, 0, 170, 0, 0, 0, 235, 0, 0, 0, 245, 0, 0, 0, 107, 0, 0, 0, 121, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 81, 0, 0, 0, 92, 0, 0, 0, 117, 0, 0, 0, 85, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 52, 0, 0, 0, 205, 0, 0, 0, 130, 0, 0, 0, 60, 0, 0, 0, 51, 0, 0, 0, 9, 0, 0, 0, 84, 0, 0, 0, 210, 0, 0, 0, 97, 0, 0, 0, 57, 0, 0, 0, 48, 0, 0, 0, 155, 0, 0, 0, 253, 0, 0, 0, 239, 0, 0, 0, 33, 0, 0, 0, 38, 0, 0, 0, 212, 0, 0, 0, 112, 0, 0, 0, 250, 0, 0, 0, 238, 0, 0, 0, 249, 0, 0, +0, 49, 0, 0, 0, 51, 0, 0, 0, 115, 0, 0, 0, 132, 0, 0, 0, 208, 0, 0, 0, 179, 0, 0, 0, 129, 0, 0, 0, 191, 0, 0, 0, 236, 0, 0, 0, 46, 0, 0, 0, 232, 0, 0, 0, 147, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 247, 0, 0, 0, 156, 0, 0, 0, 184, 0, 0, 0, 116, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, 0, 73, 0, 0, 0, 72, 0, 0, 0, 77, 0, 0, 0, 77, 0, 0, 0, 72, 0, 0, 0, 182, 0, 0, 0, 25, 0, 0, 0, 161, 0, 0, 0, 64, 0, 0, 0, 183, 0, 0, 0, 217, 0, 0, 0, 50, 0, 0, 0, 65, 0, 0, 0, 124, 0, 0, 0, 130, 0, 0, 0, 55, 0, 0, +0, 161, 0, 0, 0, 45, 0, 0, 0, 220, 0, 0, 0, 210, 0, 0, 0, 84, 0, 0, 0, 104, 0, 0, 0, 43, 0, 0, 0, 74, 0, 0, 0, 91, 0, 0, 0, 213, 0, 0, 0, 199, 0, 0, 0, 81, 0, 0, 0, 145, 0, 0, 0, 29, 0, 0, 0, 225, 0, 0, 0, 42, 0, 0, 0, 75, 0, 0, 0, 196, 0, 0, 0, 71, 0, 0, 0, 241, 0, 0, 0, 188, 0, 0, 0, 122, 0, 0, 0, 179, 0, 0, 0, 203, 0, 0, 0, 200, 0, 0, 0, 182, 0, 0, 0, 124, 0, 0, 0, 172, 0, 0, 0, 144, 0, 0, 0, 5, 0, 0, 0, 253, 0, 0, 0, 243, 0, 0, 0, 249, 0, 0, 0, 82, 0, 0, 0, 58, 0, 0, 0, 17, 0, 0, 0, 107, 0, 0, +0, 61, 0, 0, 0, 193, 0, 0, 0, 39, 0, 0, 0, 243, 0, 0, 0, 89, 0, 0, 0, 67, 0, 0, 0, 149, 0, 0, 0, 144, 0, 0, 0, 197, 0, 0, 0, 150, 0, 0, 0, 121, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 149, 0, 0, 0, 101, 0, 0, 0, 41, 0, 0, 0, 6, 0, 0, 0, 156, 0, 0, 0, 81, 0, 0, 0, 5, 0, 0, 0, 24, 0, 0, 0, 218, 0, 0, 0, 184, 0, 0, 0, 46, 0, 0, 0, 121, 0, 0, 0, 126, 0, 0, 0, 105, 0, 0, 0, 89, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 235, 0, 0, 0, 26, 0, 0, 0, 21, 0, 0, 0, 6, 0, 0, 0, 73, 0, 0, 0, 182, 0, 0, 0, 138, 0, 0, 0, +60, 0, 0, 0, 234, 0, 0, 0, 47, 0, 0, 0, 52, 0, 0, 0, 32, 0, 0, 0, 20, 0, 0, 0, 195, 0, 0, 0, 170, 0, 0, 0, 214, 0, 0, 0, 175, 0, 0, 0, 44, 0, 0, 0, 62, 0, 0, 0, 189, 0, 0, 0, 101, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 77, 0, 0, 0, 75, 0, 0, 0, 59, 0, 0, 0, 235, 0, 0, 0, 159, 0, 0, 0, 74, 0, 0, 0, 195, 0, 0, 0, 173, 0, 0, 0, 164, 0, 0, 0, 59, 0, 0, 0, 96, 0, 0, 0, 188, 0, 0, 0, 88, 0, 0, 0, 230, 0, 0, 0, 192, 0, 0, 0, 149, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 129, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, +243, 0, 0, 0, 210, 0, 0, 0, 6, 0, 0, 0, 190, 0, 0, 0, 72, 0, 0, 0, 188, 0, 0, 0, 12, 0, 0, 0, 197, 0, 0, 0, 70, 0, 0, 0, 224, 0, 0, 0, 106, 0, 0, 0, 212, 0, 0, 0, 172, 0, 0, 0, 15, 0, 0, 0, 217, 0, 0, 0, 204, 0, 0, 0, 130, 0, 0, 0, 52, 0, 0, 0, 44, 0, 0, 0, 175, 0, 0, 0, 219, 0, 0, 0, 31, 0, 0, 0, 247, 0, 0, 0, 23, 0, 0, 0, 19, 0, 0, 0, 189, 0, 0, 0, 251, 0, 0, 0, 188, 0, 0, 0, 210, 0, 0, 0, 236, 0, 0, 0, 69, 0, 0, 0, 179, 0, 0, 0, 21, 0, 0, 0, 49, 0, 0, 0, 233, 0, 0, 0, 175, 0, 0, 0, 130, 0, 0, +0, 132, 0, 0, 0, 61, 0, 0, 0, 40, 0, 0, 0, 198, 0, 0, 0, 252, 0, 0, 0, 17, 0, 0, 0, 245, 0, 0, 0, 65, 0, 0, 0, 181, 0, 0, 0, 139, 0, 0, 0, 211, 0, 0, 0, 18, 0, 0, 0, 118, 0, 0, 0, 82, 0, 0, 0, 231, 0, 0, 0, 26, 0, 0, 0, 60, 0, 0, 0, 78, 0, 0, 0, 54, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 162, 0, 0, 0, 21, 0, 0, 0, 32, 0, 0, 0, 81, 0, 0, 0, 196, 0, 0, 0, 42, 0, 0, 0, 195, 0, 0, 0, 98, 0, 0, 0, 139, 0, 0, 0, 94, 0, 0, 0, 127, 0, 0, 0, 166, 0, 0, 0, 15, 0, 0, 0, 249, 0, 0, 0, 69, 0, 0, 0, 133, 0, 0, 0, 108, +0, 0, 0, 17, 0, 0, 0, 134, 0, 0, 0, 183, 0, 0, 0, 126, 0, 0, 0, 229, 0, 0, 0, 215, 0, 0, 0, 249, 0, 0, 0, 195, 0, 0, 0, 145, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 214, 0, 0, 0, 222, 0, 0, 0, 41, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, +0, 185, 0, 0, 0, 2, 0, 0, 0, 89, 0, 0, 0, 203, 0, 0, 0, 38, 0, 0, 0, 196, 0, 0, 0, 186, 0, 0, 0, 153, 0, 0, 0, 177, 0, 0, 0, 151, 0, 0, 0, 47, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 38, 0, 0, 0, 79, 0, 0, 0, 82, 0, 0, 0, 235, 0, 0, 0, 71, 0, 0, 0, 27, 0, 0, 0, 137, 0, 0, 0, 139, 0, 0, 0, 36, 0, 0, 0, 192, 0, 0, 0, 19, 0, 0, 0, 125, 0, 0, 0, 213, 0, 0, 0, 32, 0, 0, 0, 91, 0, 0, 0, 128, 0, 0, 0, 166, 0, 0, 0, 128, 0, 0, 0, 32, 0, 0, 0, 149, 0, 0, 0, 195, 0, 0, 0, 233, 0, 0, 0, 159, 0, 0, +0, 142, 0, 0, 0, 135, 0, 0, 0, 158, 0, 0, 0, 30, 0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 199, 0, 0, 0, 204, 0, 0, 0, 117, 0, 0, 0, 108, 0, 0, 0, 165, 0, 0, 0, 241, 0, 0, 0, 145, 0, 0, 0, 26, 0, 0, 0, 168, 0, 0, 0, 1, 0, 0, 0, 44, 0, 0, 0, 171, 0, 0, 0, 118, 0, 0, 0, 169, 0, 0, 0, 89, 0, 0, 0, 222, 0, 0, 0, 201, 0, 0, 0, 177, 0, 0, 0, 49, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 170, 0, 0, 0, 53, 0, 0, 0, 20, 0, 0, 0, 106, 0, 0, 0, 212, 0, 0, 0, 181, 0, 0, 0, 52, 0, 0, 0, 130, 0, 0, 0, 113, 0, 0, 0, 210, 0, +0, 0, 74, 0, 0, 0, 93, 0, 0, 0, 154, 0, 0, 0, 31, 0, 0, 0, 83, 0, 0, 0, 38, 0, 0, 0, 60, 0, 0, 0, 229, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 51, 0, 0, 0, 127, 0, 0, 0, 255, 0, 0, 0, 169, 0, 0, 0, 213, 0, 0, 0, 23, 0, 0, 0, 137, 0, 0, 0, 175, 0, 0, 0, 246, 0, 0, 0, 164, 0, 0, 0, 100, 0, 0, 0, 213, 0, 0, 0, 16, 0, 0, 0, 224, 0, 0, 0, 29, 0, 0, 0, 173, 0, 0, 0, 239, 0, 0, 0, 68, 0, 0, 0, 189, 0, 0, 0, 218, 0, 0, 0, 131, 0, 0, 0, 172, 0, 0, 0, 122, 0, 0, 0, 168, 0, 0, 0, 240, 0, 0, 0, 28, 0, 0, 0, 7, +0, 0, 0, 249, 0, 0, 0, 195, 0, 0, 0, 67, 0, 0, 0, 108, 0, 0, 0, 63, 0, 0, 0, 183, 0, 0, 0, 211, 0, 0, 0, 135, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 115, 0, 0, 0, 100, 0, 0, 0, 29, 0, 0, 0, 73, 0, 0, 0, 19, 0, 0, 0, 47, 0, 0, 0, 113, 0, 0, 0, 236, 0, 0, 0, 105, 0, 0, 0, 135, 0, 0, 0, 208, 0, 0, 0, 66, 0, 0, 0, 238, 0, 0, 0, 19, 0, 0, 0, 236, 0, 0, 0, 227, 0, 0, 0, 237, 0, 0, 0, 86, 0, 0, 0, 123, 0, 0, 0, 191, 0, 0, 0, 189, 0, 0, 0, 140, 0, 0, 0, 47, 0, 0, 0, 125, 0, 0, 0, 123, 0, 0, 0, 157, 0, 0, 0, 40, +0, 0, 0, 236, 0, 0, 0, 142, 0, 0, 0, 118, 0, 0, 0, 47, 0, 0, 0, 111, 0, 0, 0, 8, 0, 0, 0, 34, 0, 0, 0, 245, 0, 0, 0, 95, 0, 0, 0, 77, 0, 0, 0, 21, 0, 0, 0, 239, 0, 0, 0, 252, 0, 0, 0, 78, 0, 0, 0, 87, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 0, 137, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 91, 0, 0, 0, 145, 0, 0, 0, 214, 0, 0, 0, 226, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, 0, 165, 0, 0, 0, 238, 0, 0, 0, 82, 0, 0, 0, 236, 0, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 143, 0, 0, 0, 51, 0, 0, 0, 144, 0, 0, 0, 90, 0, 0, 0, 148, 0, +0, 0, 114, 0, 0, 0, 138, 0, 0, 0, 75, 0, 0, 0, 231, 0, 0, 0, 56, 0, 0, 0, 188, 0, 0, 0, 218, 0, 0, 0, 194, 0, 0, 0, 176, 0, 0, 0, 133, 0, 0, 0, 225, 0, 0, 0, 74, 0, 0, 0, 254, 0, 0, 0, 45, 0, 0, 0, 68, 0, 0, 0, 132, 0, 0, 0, 203, 0, 0, 0, 32, 0, 0, 0, 107, 0, 0, 0, 45, 0, 0, 0, 191, 0, 0, 0, 17, 0, 0, 0, 156, 0, 0, 0, 215, 0, 0, 0, 190, 0, 0, 0, 211, 0, 0, 0, 62, 0, 0, 0, 95, 0, 0, 0, 191, 0, 0, 0, 104, 0, 0, 0, 188, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 137, 0, 0, 0, 40, 0, 0, 0, 34, 0, +0, 0, 106, 0, 0, 0, 120, 0, 0, 0, 170, 0, 0, 0, 41, 0, 0, 0, 3, 0, 0, 0, 200, 0, 0, 0, 116, 0, 0, 0, 149, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 0, 220, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 168, 0, 0, 0, 162, 0, 0, 0, 32, 0, 0, 0, 45, 0, 0, 0, 179, 0, 0, 0, 24, 0, 0, 0, 112, 0, 0, 0, 66, 0, 0, 0, 253, 0, 0, 0, 122, 0, 0, 0, 196, 0, 0, 0, 215, 0, 0, 0, 73, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 255, 0, 0, 0, 50, 0, 0, 0, 43, 0, 0, 0, 92, 0, 0, 0, 147, 0, 0, 0, 84, 0, 0, 0, 50, 0, 0, 0, 232, 0, 0, 0, 87, 0, 0, 0, 84, 0, 0, 0, 26, 0, 0, 0, 139, 0, 0, 0, 51, 0, 0, 0, 96, 0, 0, 0, 101, 0, 0, 0, 211, 0, 0, 0, 103, 0, 0, 0, 164, 0, 0, 0, 193, 0, 0, 0, 38, 0, 0, 0, 196, 0, 0, 0, 164, 0, 0, 0, 52, 0, 0, 0, 31, 0, 0, 0, 155, 0, 0, 0, 167, +0, 0, 0, 169, 0, 0, 0, 244, 0, 0, 0, 217, 0, 0, 0, 79, 0, 0, 0, 91, 0, 0, 0, 70, 0, 0, 0, 141, 0, 0, 0, 176, 0, 0, 0, 51, 0, 0, 0, 84, 0, 0, 0, 38, 0, 0, 0, 91, 0, 0, 0, 104, 0, 0, 0, 223, 0, 0, 0, 187, 0, 0, 0, 197, 0, 0, 0, 236, 0, 0, 0, 194, 0, 0, 0, 249, 0, 0, 0, 60, 0, 0, 0, 90, 0, 0, 0, 55, 0, 0, 0, 193, 0, 0, 0, 142, 0, 0, 0, 39, 0, 0, 0, 71, 0, 0, 0, 170, 0, 0, 0, 73, 0, 0, 0, 90, 0, 0, 0, 248, 0, 0, 0, 251, 0, 0, 0, 104, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 209, 0, 0, 0, 235, 0, 0, 0, 64, 0, +0, 0, 101, 0, 0, 0, 165, 0, 0, 0, 17, 0, 0, 0, 132, 0, 0, 0, 138, 0, 0, 0, 103, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 209, 0, 0, 0, 68, 0, 0, 0, 104, 0, 0, 0, 122, 0, 0, 0, 52, 0, 0, 0, 225, 0, 0, 0, 159, 0, 0, 0, 163, 0, 0, 0, 84, 0, 0, 0, 205, 0, 0, 0, 7, 0, 0, 0, 202, 0, 0, 0, 121, 0, 0, 0, 31, 0, 0, 0, 84, 0, 0, 0, 47, 0, 0, 0, 19, 0, 0, 0, 112, 0, 0, 0, 78, 0, 0, 0, 238, 0, 0, 0, 162, 0, 0, 0, 250, 0, 0, 0, 231, 0, 0, 0, 93, 0, 0, 0, 54, 0, 0, 0, 236, 0, 0, 0, 84, 0, 0, 0, 248, 0, 0, 0, 206, +0, 0, 0, 228, 0, 0, 0, 133, 0, 0, 0, 223, 0, 0, 0, 246, 0, 0, 0, 111, 0, 0, 0, 29, 0, 0, 0, 144, 0, 0, 0, 8, 0, 0, 0, 188, 0, 0, 0, 232, 0, 0, 0, 192, 0, 0, 0, 146, 0, 0, 0, 45, 0, 0, 0, 67, 0, 0, 0, 107, 0, 0, 0, 146, 0, 0, 0, 169, 0, 0, 0, 142, 0, 0, 0, 171, 0, 0, 0, 10, 0, 0, 0, 46, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 100, 0, 0, 0, 35, 0, 0, 0, 159, 0, 0, 0, 44, 0, 0, 0, 167, 0, 0, 0, 214, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 203, 0, 0, 0, 90, 0, 0, 0, 59, 0, 0, 0, 167, +0, 0, 0, 249, 0, 0, 0, 70, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 173, 0, 0, 0, 43, 0, 0, 0, 52, 0, 0, 0, 49, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 8, 0, 0, 0, 130, 0, 0, 0, 20, 0, 0, 0, 196, 0, 0, 0, 224, 0, 0, 0, 156, 0, 0, 0, 240, 0, 0, 0, 227, 0, 0, 0, 85, 0, 0, 0, 67, 0, 0, 0, 49, 0, 0, 0, 96, 0, 0, 0, 214, 0, 0, 0, 221, 0, 0, 0, 120, 0, 0, 0, 230, 0, 0, 0, 212, 0, 0, 0, 34, 0, 0, 0, 66, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 177, 0, 0, 0, 106, 0, 0, 0, 99, 0, 0, 0, 226, 0, 0, +0, 146, 0, 0, 0, 89, 0, 0, 0, 209, 0, 0, 0, 26, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 41, 0, 0, 0, 201, 0, 0, 0, 193, 0, 0, 0, 246, 0, 0, 0, 111, 0, 0, 0, 122, 0, 0, 0, 197, 0, 0, 0, 60, 0, 0, 0, 95, 0, 0, 0, 101, 0, 0, 0, 39, 0, 0, 0, 79, 0, 0, 0, 208, 0, 0, 0, 114, 0, 0, 0, 177, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 39, 0, 0, 0, 21, 0, 0, 0, 148, 0, 0, 0, 72, 0, 0, 0, 129, 0, 0, 0, 126, 0, 0, 0, 116, 0, 0, 0, 216, 0, 0, 0, 50, 0, 0, 0, 213, 0, 0, 0, 209, 0, 0, 0, 17, 0, 0, 0, 40, 0, 0, 0, +96, 0, 0, 0, 99, 0, 0, 0, 54, 0, 0, 0, 50, 0, 0, 0, 55, 0, 0, 0, 181, 0, 0, 0, 19, 0, 0, 0, 28, 0, 0, 0, 160, 0, 0, 0, 55, 0, 0, 0, 227, 0, 0, 0, 116, 0, 0, 0, 241, 0, 0, 0, 37, 0, 0, 0, 78, 0, 0, 0, 17, 0, 0, 0, 150, 0, 0, 0, 103, 0, 0, 0, 230, 0, 0, 0, 28, 0, 0, 0, 194, 0, 0, 0, 178, 0, 0, 0, 83, 0, 0, 0, 226, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 238, 0, 0, 0, 178, 0, 0, 0, 159, 0, 0, 0, 89, 0, 0, 0, 243, 0, 0, 0, 186, 0, 0, 0, 189, 0, 0, 0, 250, 0, 0, 0, 207, 0, 0, 0, 110, 0, 0, 0, 249, 0, 0, +0, 218, 0, 0, 0, 164, 0, 0, 0, 179, 0, 0, 0, 2, 0, 0, 0, 143, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 148, 0, 0, 0, 242, 0, 0, 0, 100, 0, 0, 0, 84, 0, 0, 0, 71, 0, 0, 0, 55, 0, 0, 0, 7, 0, 0, 0, 64, 0, 0, 0, 138, 0, 0, 0, 32, 0, +0, 0, 186, 0, 0, 0, 74, 0, 0, 0, 85, 0, 0, 0, 215, 0, 0, 0, 63, 0, 0, 0, 71, 0, 0, 0, 186, 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 176, 0, 0, 0, 44, 0, 0, 0, 232, 0, 0, 0, 85, 0, 0, 0, 168, 0, 0, 0, 166, 0, 0, 0, 239, 0, 0, 0, 81, 0, 0, 0, 189, 0, 0, 0, 111, 0, 0, 0, 106, 0, 0, 0, 113, 0, 0, 0, 214, 0, 0, 0, 22, 0, 0, 0, 118, 0, 0, 0, 178, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 121, 0, 0, 0, 245, 0, 0, 0, 196, 0, 0, 0, 195, 0, 0, 0, 82, 0, 0, 0, 126, 0, 0, 0, 97, 0, 0, 0, 209, 0, 0, 0, 225, 0, +0, 0, 173, 0, 0, 0, 112, 0, 0, 0, 120, 0, 0, 0, 29, 0, 0, 0, 22, 0, 0, 0, 17, 0, 0, 0, 248, 0, 0, 0, 124, 0, 0, 0, 43, 0, 0, 0, 252, 0, 0, 0, 85, 0, 0, 0, 159, 0, 0, 0, 82, 0, 0, 0, 248, 0, 0, 0, 245, 0, 0, 0, 22, 0, 0, 0, 52, 0, 0, 0, 150, 0, 0, 0, 154, 0, 0, 0, 246, 0, 0, 0, 197, 0, 0, 0, 224, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 14, 0, 0, 0, 76, 0, 0, 0, 173, 0, 0, 0, 158, 0, 0, 0, 154, 0, 0, 0, 112, 0, 0, 0, 35, 0, 0, 0, 150, 0, 0, 0, 178, 0, 0, 0, 241, 0, 0, 0, 46, 0, 0, 0].concat([157, +0, 0, 0, 195, 0, 0, 0, 50, 0, 0, 0, 155, 0, 0, 0, 84, 0, 0, 0, 165, 0, 0, 0, 115, 0, 0, 0, 222, 0, 0, 0, 136, 0, 0, 0, 177, 0, 0, 0, 62, 0, 0, 0, 36, 0, 0, 0, 246, 0, 0, 0, 226, 0, 0, 0, 76, 0, 0, 0, 31, 0, 0, 0, 91, 0, 0, 0, 178, 0, 0, 0, 175, 0, 0, 0, 130, 0, 0, 0, 165, 0, 0, 0, 207, 0, 0, 0, 129, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 239, 0, 0, 0, 219, 0, 0, 0, 162, 0, 0, 0, 204, 0, 0, 0, 36, 0, 0, 0, 178, 0, 0, 0, 126, 0, 0, 0, 11, 0, 0, 0, 122, 0, 0, 0, 235, 0, 0, 0, 1, 0, 0, 0, 216, 0, 0, 0, 82, +0, 0, 0, 244, 0, 0, 0, 81, 0, 0, 0, 137, 0, 0, 0, 41, 0, 0, 0, 121, 0, 0, 0, 55, 0, 0, 0, 116, 0, 0, 0, 222, 0, 0, 0, 18, 0, 0, 0, 243, 0, 0, 0, 104, 0, 0, 0, 183, 0, 0, 0, 102, 0, 0, 0, 195, 0, 0, 0, 238, 0, 0, 0, 104, 0, 0, 0, 220, 0, 0, 0, 129, 0, 0, 0, 181, 0, 0, 0, 85, 0, 0, 0, 153, 0, 0, 0, 171, 0, 0, 0, 217, 0, 0, 0, 40, 0, 0, 0, 99, 0, 0, 0, 109, 0, 0, 0, 139, 0, 0, 0, 64, 0, 0, 0, 105, 0, 0, 0, 117, 0, 0, 0, 108, 0, 0, 0, 205, 0, 0, 0, 92, 0, 0, 0, 42, 0, 0, 0, 126, 0, 0, 0, 50, 0, 0, 0, +123, 0, 0, 0, 41, 0, 0, 0, 2, 0, 0, 0, 204, 0, 0, 0, 34, 0, 0, 0, 116, 0, 0, 0, 77, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0, 192, 0, 0, 0, 218, 0, 0, 0, 181, 0, 0, 0, 118, 0, 0, 0, 81, 0, 0, 0, 42, 0, 0, 0, 170, 0, 0, 0, 166, 0, 0, 0, 10, 0, 0, 0, 95, 0, 0, 0, 38, 0, 0, 0, 212, 0, 0, 0, 188, 0, 0, 0, 175, 0, 0, 0, 72, 0, 0, 0, 136, 0, 0, 0, 127, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0, 242, 0, 0, 0, 225, 0, 0, 0, 207, 0, 0, 0, 233, 0, 0, 0, 221, 0, 0, 0, 21, 0, 0, 0, 237, 0, 0, 0, 181, 0, 0, 0, 154, 0, 0, 0, +140, 0, 0, 0, 154, 0, 0, 0, 221, 0, 0, 0, 39, 0, 0, 0, 244, 0, 0, 0, 127, 0, 0, 0, 71, 0, 0, 0, 217, 0, 0, 0, 82, 0, 0, 0, 167, 0, 0, 0, 205, 0, 0, 0, 101, 0, 0, 0, 165, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 237, 0, 0, 0, 166, 0, 0, 0, 99, 0, 0, 0, 91, 0, 0, 0, 128, 0, 0, 0, 74, 0, 0, 0, 173, 0, 0, 0, 77, 0, 0, 0, 237, 0, 0, 0, 191, 0, 0, 0, 238, 0, 0, 0, 73, 0, 0, 0, 179, 0, 0, 0, 6, 0, 0, 0, 248, 0, 0, 0, 100, 0, 0, 0, 139, 0, 0, 0, 96, 0, 0, 0, 144, 0, 0, 0, 233, 0, 0, 0, 222, 0, 0, 0, 68, 0, 0, +0, 119, 0, 0, 0, 185, 0, 0, 0, 7, 0, 0, 0, 54, 0, 0, 0, 50, 0, 0, 0, 194, 0, 0, 0, 80, 0, 0, 0, 245, 0, 0, 0, 101, 0, 0, 0, 223, 0, 0, 0, 72, 0, 0, 0, 76, 0, 0, 0, 55, 0, 0, 0, 170, 0, 0, 0, 104, 0, 0, 0, 171, 0, 0, 0, 154, 0, 0, 0, 31, 0, 0, 0, 62, 0, 0, 0, 255, 0, 0, 0, 137, 0, 0, 0, 146, 0, 0, 0, 160, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 79, 0, 0, 0, 156, 0, 0, 0, 25, 0, 0, 0, 192, 0, 0, 0, 74, 0, 0, 0, 49, 0, 0, 0, 236, 0, 0, 0, 249, 0, 0, 0, 170, 0, 0, 0, 235, 0, 0, 0, 178, 0, 0, 0, 22, 0, 0, 0, 156, 0, 0, 0, 163, 0, 0, 0, 102, 0, 0, 0, 95, 0, 0, 0, 209, 0, 0, 0, 212, 0, 0, 0, 237, 0, 0, 0, 184, 0, 0, 0, 146, 0, 0, 0, 28, 0, 0, 0, 171, 0, 0, 0, 218, 0, 0, 0, 234, 0, 0, 0, 217, 0, 0, 0, 87, 0, 0, 0, 223, 0, 0, 0, 76, 0, 0, +0, 42, 0, 0, 0, 72, 0, 0, 0, 75, 0, 0, 0, 176, 0, 0, 0, 78, 0, 0, 0, 110, 0, 0, 0, 17, 0, 0, 0, 59, 0, 0, 0, 81, 0, 0, 0, 189, 0, 0, 0, 106, 0, 0, 0, 253, 0, 0, 0, 228, 0, 0, 0, 37, 0, 0, 0, 165, 0, 0, 0, 95, 0, 0, 0, 17, 0, 0, 0, 63, 0, 0, 0, 152, 0, 0, 0, 146, 0, 0, 0, 81, 0, 0, 0, 20, 0, 0, 0, 198, 0, 0, 0, 95, 0, 0, 0, 60, 0, 0, 0, 11, 0, 0, 0, 168, 0, 0, 0, 247, 0, 0, 0, 194, 0, 0, 0, 129, 0, 0, 0, 67, 0, 0, 0, 222, 0, 0, 0, 145, 0, 0, 0, 115, 0, 0, 0, 60, 0, 0, 0, 143, 0, 0, 0, 159, 0, 0, 0, +51, 0, 0, 0, 42, 0, 0, 0, 31, 0, 0, 0, 67, 0, 0, 0, 51, 0, 0, 0, 143, 0, 0, 0, 104, 0, 0, 0, 255, 0, 0, 0, 31, 0, 0, 0, 61, 0, 0, 0, 115, 0, 0, 0, 107, 0, 0, 0, 191, 0, 0, 0, 104, 0, 0, 0, 204, 0, 0, 0, 125, 0, 0, 0, 19, 0, 0, 0, 108, 0, 0, 0, 36, 0, 0, 0, 75, 0, 0, 0, 204, 0, 0, 0, 77, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 254, 0, 0, 0, 222, 0, 0, 0, 134, 0, 0, 0, 173, 0, 0, 0, 59, 0, 0, 0, 121, 0, 0, 0, 81, 0, 0, 0, 129, 0, 0, 0, 1, 0, 0, 0, 220, 0, 0, 0, 115, 0, 0, 0, 83, 0, 0, 0, 224, 0, 0, 0, 110, +0, 0, 0, 155, 0, 0, 0, 234, 0, 0, 0, 104, 0, 0, 0, 63, 0, 0, 0, 92, 0, 0, 0, 20, 0, 0, 0, 132, 0, 0, 0, 83, 0, 0, 0, 141, 0, 0, 0, 75, 0, 0, 0, 192, 0, 0, 0, 159, 0, 0, 0, 159, 0, 0, 0, 137, 0, 0, 0, 43, 0, 0, 0, 140, 0, 0, 0, 186, 0, 0, 0, 134, 0, 0, 0, 250, 0, 0, 0, 242, 0, 0, 0, 205, 0, 0, 0, 227, 0, 0, 0, 45, 0, 0, 0, 6, 0, 0, 0, 249, 0, 0, 0, 41, 0, 0, 0, 90, 0, 0, 0, 219, 0, 0, 0, 61, 0, 0, 0, 132, 0, 0, 0, 82, 0, 0, 0, 171, 0, 0, 0, 204, 0, 0, 0, 107, 0, 0, 0, 96, 0, 0, 0, 157, 0, 0, 0, 183, +0, 0, 0, 74, 0, 0, 0, 14, 0, 0, 0, 54, 0, 0, 0, 99, 0, 0, 0, 145, 0, 0, 0, 173, 0, 0, 0, 160, 0, 0, 0, 149, 0, 0, 0, 176, 0, 0, 0, 151, 0, 0, 0, 137, 0, 0, 0, 78, 0, 0, 0, 207, 0, 0, 0, 125, 0, 0, 0, 60, 0, 0, 0, 229, 0, 0, 0, 124, 0, 0, 0, 40, 0, 0, 0, 46, 0, 0, 0, 105, 0, 0, 0, 152, 0, 0, 0, 253, 0, 0, 0, 198, 0, 0, 0, 189, 0, 0, 0, 204, 0, 0, 0, 202, 0, 0, 0, 223, 0, 0, 0, 154, 0, 0, 0, 68, 0, 0, 0, 126, 0, 0, 0, 157, 0, 0, 0, 202, 0, 0, 0, 137, 0, 0, 0, 109, 0, 0, 0, 191, 0, 0, 0, 39, 0, 0, 0, +194, 0, 0, 0, 248, 0, 0, 0, 205, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 181, 0, 0, 0, 88, 0, 0, 0, 78, 0, 0, 0, 183, 0, 0, 0, 137, 0, 0, 0, 9, 0, 0, 0, 233, 0, 0, 0, 45, 0, 0, 0, 84, 0, 0, 0, 190, 0, 0, 0, 117, 0, 0, 0, 203, 0, 0, 0, 5, 0, 0, 0, 176, 0, 0, 0, 84, 0, 0, 0, 183, 0, 0, 0, 231, 0, 0, 0, 38, 0, 0, 0, 134, 0, 0, 0, 74, 0, 0, 0, 252, 0, 0, 0, 25, 0, 0, 0, 207, 0, 0, 0, 39, 0, 0, 0, 70, 0, 0, 0, 212, 0, 0, 0, 34, 0, 0, 0, 150, 0, 0, 0, 90, 0, 0, 0, 17, 0, 0, 0, 232, 0, 0, 0, 213, +0, 0, 0, 27, 0, 0, 0, 237, 0, 0, 0, 113, 0, 0, 0, 197, 0, 0, 0, 93, 0, 0, 0, 200, 0, 0, 0, 175, 0, 0, 0, 69, 0, 0, 0, 64, 0, 0, 0, 123, 0, 0, 0, 119, 0, 0, 0, 87, 0, 0, 0, 73, 0, 0, 0, 158, 0, 0, 0, 128, 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 0, 238, 0, 0, 0, 129, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 207, 0, 0, 0, 219, 0, 0, 0, 122, 0, 0, 0, 47, 0, 0, 0, 20, 0, 0, 0, 184, 0, 0, 0, 87, 0, 0, 0, 143, 0, 0, 0, 161, 0, 0, 0, 57, 0, 0, 0, 30, 0, 0, 0, 119, 0, 0, 0, 252, 0, 0, 0, 11, 0, 0, 0, 166, 0, 0, 0, 191, +0, 0, 0, 138, 0, 0, 0, 12, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 58, 0, 0, 0, 212, 0, 0, 0, 216, 0, 0, 0, 39, 0, 0, 0, 207, 0, 0, 0, 232, 0, 0, 0, 161, 0, 0, 0, 114, 0, 0, 0, 157, 0, 0, 0, 202, 0, 0, 0, 221, 0, 0, 0, 13, 0, 0, 0, 150, 0, +0, 0, 218, 0, 0, 0, 121, 0, 0, 0, 237, 0, 0, 0, 86, 0, 0, 0, 66, 0, 0, 0, 21, 0, 0, 0, 96, 0, 0, 0, 199, 0, 0, 0, 28, 0, 0, 0, 107, 0, 0, 0, 38, 0, 0, 0, 48, 0, 0, 0, 246, 0, 0, 0, 106, 0, 0, 0, 149, 0, 0, 0, 103, 0, 0, 0, 243, 0, 0, 0, 10, 0, 0, 0, 197, 0, 0, 0, 8, 0, 0, 0, 164, 0, 0, 0, 43, 0, 0, 0, 47, 0, 0, 0, 189, 0, 0, 0, 49, 0, 0, 0, 129, 0, 0, 0, 42, 0, 0, 0, 166, 0, 0, 0, 182, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 218, 0, 0, 0, 61, 0, 0, 0, 178, 0, 0, 0, 176, 0, 0, 0, 150, 0, +0, 0, 206, 0, 0, 0, 138, 0, 0, 0, 210, 0, 0, 0, 141, 0, 0, 0, 112, 0, 0, 0, 179, 0, 0, 0, 211, 0, 0, 0, 52, 0, 0, 0, 1, 0, 0, 0, 144, 0, 0, 0, 141, 0, 0, 0, 16, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 13, 0, 0, 0, 231, 0, 0, 0, 186, 0, 0, 0, 79, 0, 0, 0, 7, 0, 0, 0, 223, 0, 0, 0, 141, 0, 0, 0, 234, 0, 0, 0, 125, 0, 0, 0, 160, 0, 0, 0, 197, 0, 0, 0, 214, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 229, 0, 0, 0, 87, 0, 0, 0, 27, 0, 0, 0, 91, 0, 0, 0, 245, 0, 0, 0, 69, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 100, 0, +0, 0, 90, 0, 0, 0, 235, 0, 0, 0, 92, 0, 0, 0, 252, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 43, 0, 0, 0, 2, 0, 0, 0, 12, 0, 0, 0, 194, 0, 0, 0, 175, 0, 0, 0, 150, 0, 0, 0, 54, 0, 0, 0, 254, 0, 0, 0, 74, 0, 0, 0, 226, 0, 0, 0, 84, 0, 0, 0, 32, 0, 0, 0, 106, 0, 0, 0, 235, 0, 0, 0, 178, 0, 0, 0, 159, 0, 0, 0, 98, 0, 0, 0, 215, 0, 0, 0, 206, 0, 0, 0, 162, 0, 0, 0, 63, 0, 0, 0, 32, 0, 0, 0, 17, 0, 0, 0, 52, 0, 0, 0, 55, 0, 0, 0, 224, 0, 0, 0, 66, 0, 0, 0, 237, 0, 0, 0, 111, 0, 0, 0, 249, 0, 0, +0, 26, 0, 0, 0, 200, 0, 0, 0, 125, 0, 0, 0, 216, 0, 0, 0, 185, 0, 0, 0, 17, 0, 0, 0, 232, 0, 0, 0, 54, 0, 0, 0, 63, 0, 0, 0, 66, 0, 0, 0, 193, 0, 0, 0, 202, 0, 0, 0, 220, 0, 0, 0, 211, 0, 0, 0, 241, 0, 0, 0, 200, 0, 0, 0, 35, 0, 0, 0, 61, 0, 0, 0, 79, 0, 0, 0, 81, 0, 0, 0, 123, 0, 0, 0, 157, 0, 0, 0, 141, 0, 0, 0, 216, 0, 0, 0, 228, 0, 0, 0, 160, 0, 0, 0, 170, 0, 0, 0, 243, 0, 0, 0, 4, 0, 0, 0, 214, 0, 0, 0, 17, 0, 0, 0, 147, 0, 0, 0, 200, 0, 0, 0, 53, 0, 0, 0, 69, 0, 0, 0, 97, 0, 0, 0, 54, 0, 0, +0, 214, 0, 0, 0, 8, 0, 0, 0, 144, 0, 0, 0, 191, 0, 0, 0, 167, 0, 0, 0, 122, 0, 0, 0, 151, 0, 0, 0, 108, 0, 0, 0, 15, 0, 0, 0, 132, 0, 0, 0, 213, 0, 0, 0, 51, 0, 0, 0, 45, 0, 0, 0, 55, 0, 0, 0, 201, 0, 0, 0, 106, 0, 0, 0, 128, 0, 0, 0, 144, 0, 0, 0, 61, 0, 0, 0, 10, 0, 0, 0, 162, 0, 0, 0, 170, 0, 0, 0, 225, 0, 0, 0, 184, 0, 0, 0, 132, 0, 0, 0, 186, 0, 0, 0, 97, 0, 0, 0, 54, 0, 0, 0, 221, 0, 0, 0, 105, 0, 0, 0, 107, 0, 0, 0, 219, 0, 0, 0, 91, 0, 0, 0, 156, 0, 0, 0, 198, 0, 0, 0, 146, 0, 0, 0, 188, +0, 0, 0, 35, 0, 0, 0, 175, 0, 0, 0, 197, 0, 0, 0, 184, 0, 0, 0, 117, 0, 0, 0, 248, 0, 0, 0, 66, 0, 0, 0, 250, 0, 0, 0, 214, 0, 0, 0, 182, 0, 0, 0, 132, 0, 0, 0, 148, 0, 0, 0, 99, 0, 0, 0, 152, 0, 0, 0, 147, 0, 0, 0, 72, 0, 0, 0, 120, 0, 0, 0, 56, 0, 0, 0, 205, 0, 0, 0, 187, 0, 0, 0, 24, 0, 0, 0, 52, 0, 0, 0, 195, 0, 0, 0, 219, 0, 0, 0, 103, 0, 0, 0, 150, 0, 0, 0, 243, 0, 0, 0, 58, 0, 0, 0, 9, 0, 0, 0, 86, 0, 0, 0, 176, 0, 0, 0, 111, 0, 0, 0, 124, 0, 0, 0, 81, 0, 0, 0, 30, 0, 0, 0, 27, 0, 0, 0, 57, +0, 0, 0, 72, 0, 0, 0, 234, 0, 0, 0, 201, 0, 0, 0, 12, 0, 0, 0, 37, 0, 0, 0, 162, 0, 0, 0, 122, 0, 0, 0, 202, 0, 0, 0, 231, 0, 0, 0, 146, 0, 0, 0, 252, 0, 0, 0, 89, 0, 0, 0, 48, 0, 0, 0, 163, 0, 0, 0, 137, 0, 0, 0, 133, 0, 0, 0, 223, 0, 0, 0, 111, 0, 0, 0, 67, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 132, 0, 0, 0, 68, 0, 0, 0, 25, 0, 0, 0, 189, 0, 0, 0, 233, 0, 0, 0, 84, 0, 0, 0, 196, 0, 0, 0, 192, 0, 0, 0, 110, 0, 0, 0, 42, 0, 0, 0, 168, 0, 0, 0, 168, 0, 0, 0, 155, 0, 0, 0, 67, 0, 0, 0, 213, 0, 0, 0, 113, 0, 0, 0, 34, 0, 0, 0, 95, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 250, 0, 0, 0, 223, 0, 0, 0, 179, 0, 0, 0, 184, 0, 0, 0, 71, 0, 0, 0, 75, 0, 0, 0, 10, 0, 0, 0, 165, 0, 0, 0, 68, 0, 0, 0, 234, 0, 0, 0, 41, 0, 0, 0, 5, 0, 0, 0, 144, 0, +0, 0, 80, 0, 0, 0, 175, 0, 0, 0, 99, 0, 0, 0, 95, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 225, 0, 0, 0, 157, 0, 0, 0, 56, 0, 0, 0, 151, 0, 0, 0, 31, 0, 0, 0, 108, 0, 0, 0, 172, 0, 0, 0, 48, 0, 0, 0, 70, 0, 0, 0, 178, 0, 0, 0, 106, 0, 0, 0, 25, 0, 0, 0, 209, 0, 0, 0, 75, 0, 0, 0, 219, 0, 0, 0, 187, 0, 0, 0, 140, 0, 0, 0, 218, 0, 0, 0, 46, 0, 0, 0, 171, 0, 0, 0, 200, 0, 0, 0, 90, 0, 0, 0, 119, 0, 0, 0, 108, 0, 0, 0, 43, 0, 0, 0, 190, 0, 0, 0, 175, 0, 0, 0, 161, 0, 0, 0, 109, 0, 0, 0, 47, 0, 0, 0, 11, +0, 0, 0, 177, 0, 0, 0, 143, 0, 0, 0, 227, 0, 0, 0, 224, 0, 0, 0, 56, 0, 0, 0, 205, 0, 0, 0, 11, 0, 0, 0, 65, 0, 0, 0, 27, 0, 0, 0, 74, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 243, 0, 0, 0, 111, 0, 0, 0, 220, 0, 0, 0, 184, 0, 0, 0, 233, 0, 0, 0, 222, 0, 0, 0, 178, 0, 0, 0, 163, 0, 0, 0, 64, 0, 0, 0, 1, 0, 0, 0, 166, 0, 0, 0, 69, 0, 0, 0, 30, 0, 0, 0, 118, 0, 0, 0, 10, 0, 0, 0, 218, 0, 0, 0, 141, 0, 0, 0, 44, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 137, 0, 0, 0, 125, 0, 0, 0, 4, 0, 0, 0, 173, 0, 0, 0, 67, 0, 0, +0, 80, 0, 0, 0, 110, 0, 0, 0, 210, 0, 0, 0, 71, 0, 0, 0, 203, 0, 0, 0, 138, 0, 0, 0, 230, 0, 0, 0, 133, 0, 0, 0, 26, 0, 0, 0, 36, 0, 0, 0, 243, 0, 0, 0, 210, 0, 0, 0, 96, 0, 0, 0, 253, 0, 0, 0, 223, 0, 0, 0, 115, 0, 0, 0, 164, 0, 0, 0, 13, 0, 0, 0, 115, 0, 0, 0, 14, 0, 0, 0, 253, 0, 0, 0, 103, 0, 0, 0, 107, 0, 0, 0, 113, 0, 0, 0, 155, 0, 0, 0, 129, 0, 0, 0, 83, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 244, 0, 0, 0, 184, 0, 0, 0, 213, 0, 0, 0, 195, 0, 0, 0, 48, 0, 0, 0, 155, 0, 0, 0, 59, 0, 0, 0, 124, 0, +0, 0, 163, 0, 0, 0, 240, 0, 0, 0, 208, 0, 0, 0, 132, 0, 0, 0, 33, 0, 0, 0, 214, 0, 0, 0, 191, 0, 0, 0, 183, 0, 0, 0, 76, 0, 0, 0, 135, 0, 0, 0, 19, 0, 0, 0, 69, 0, 0, 0, 45, 0, 0, 0, 167, 0, 0, 0, 85, 0, 0, 0, 93, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 149, 0, 0, 0, 45, 0, 0, 0, 48, 0, 0, 0, 131, 0, 0, 0, 236, 0, 0, 0, 94, 0, 0, 0, 228, 0, 0, 0, 255, 0, 0, 0, 117, 0, 0, 0, 254, 0, 0, 0, 121, 0, 0, 0, 38, 0, 0, 0, 157, 0, 0, 0, 29, 0, 0, 0, 54, 0, 0, 0, 205, 0, 0, 0, 10, 0, 0, +0, 21, 0, 0, 0, 210, 0, 0, 0, 36, 0, 0, 0, 20, 0, 0, 0, 119, 0, 0, 0, 113, 0, 0, 0, 215, 0, 0, 0, 138, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 93, 0, 0, 0, 147, 0, 0, 0, 201, 0, 0, 0, 190, 0, 0, 0, 170, 0, 0, 0, 144, 0, 0, 0, 205, 0, 0, 0, 155, 0, 0, 0, 251, 0, 0, 0, 115, 0, 0, 0, 126, 0, 0, 0, 176, 0, 0, 0, 100, 0, 0, 0, 152, 0, 0, 0, 87, 0, 0, 0, 68, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 234, 0, 0, 0, 193, 0, 0, 0, 195, 0, 0, 0, 34, 0, 0, 0, 255, 0, 0, 0, 96, 0, 0, 0, 70, 0, +0, 0, 203, 0, 0, 0, 97, 0, 0, 0, 129, 0, 0, 0, 112, 0, 0, 0, 97, 0, 0, 0, 13, 0, 0, 0, 130, 0, 0, 0, 185, 0, 0, 0, 254, 0, 0, 0, 33, 0, 0, 0, 205, 0, 0, 0, 196, 0, 0, 0, 245, 0, 0, 0, 152, 0, 0, 0, 12, 0, 0, 0, 78, 0, 0, 0, 114, 0, 0, 0, 238, 0, 0, 0, 135, 0, 0, 0, 73, 0, 0, 0, 248, 0, 0, 0, 161, 0, 0, 0, 149, 0, 0, 0, 223, 0, 0, 0, 143, 0, 0, 0, 45, 0, 0, 0, 189, 0, 0, 0, 33, 0, 0, 0, 6, 0, 0, 0, 124, 0, 0, 0, 21, 0, 0, 0, 232, 0, 0, 0, 18, 0, 0, 0, 109, 0, 0, 0, 147, 0, 0, 0, 214, 0, 0, 0, 56, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 247, 0, 0, 0, 81, 0, 0, 0, 217, 0, 0, 0, 239, 0, 0, 0, 125, 0, 0, 0, 66, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, 0, 233, 0, 0, 0, 184, 0, 0, 0, 127, 0, 0, 0, 166, 0, 0, 0, 73, 0, 0, 0, 23, 0, 0, 0, 100, 0, 0, 0, 33, 0, 0, +0, 128, 0, 0, 0, 131, 0, 0, 0, 44, 0, 0, 0, 99, 0, 0, 0, 76, 0, 0, 0, 96, 0, 0, 0, 9, 0, 0, 0, 89, 0, 0, 0, 145, 0, 0, 0, 146, 0, 0, 0, 119, 0, 0, 0, 57, 0, 0, 0, 81, 0, 0, 0, 244, 0, 0, 0, 72, 0, 0, 0, 96, 0, 0, 0, 213, 0, 0, 0, 34, 0, 0, 0, 131, 0, 0, 0, 8, 0, 0, 0, 47, 0, 0, 0, 255, 0, 0, 0, 153, 0, 0, 0, 62, 0, 0, 0, 105, 0, 0, 0, 109, 0, 0, 0, 136, 0, 0, 0, 218, 0, 0, 0, 231, 0, 0, 0, 91, 0, 0, 0, 82, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 42, 0, 0, 0, 229, 0, 0, 0, 137, 0, 0, 0, 222, 0, 0, 0, 104, +0, 0, 0, 144, 0, 0, 0, 182, 0, 0, 0, 34, 0, 0, 0, 90, 0, 0, 0, 189, 0, 0, 0, 211, 0, 0, 0, 133, 0, 0, 0, 83, 0, 0, 0, 49, 0, 0, 0, 216, 0, 0, 0, 206, 0, 0, 0, 220, 0, 0, 0, 249, 0, 0, 0, 60, 0, 0, 0, 75, 0, 0, 0, 162, 0, 0, 0, 29, 0, 0, 0, 44, 0, 0, 0, 47, 0, 0, 0, 54, 0, 0, 0, 190, 0, 0, 0, 122, 0, 0, 0, 252, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 220, 0, 0, 0, 249, 0, 0, 0, 48, 0, 0, 0, 189, 0, 0, 0, 255, 0, 0, 0, 5, 0, 0, 0, 199, 0, 0, 0, 228, 0, 0, 0, 142, 0, 0, 0, 23, 0, 0, 0, 98, 0, 0, 0, 248, +0, 0, 0, 77, 0, 0, 0, 160, 0, 0, 0, 86, 0, 0, 0, 121, 0, 0, 0, 130, 0, 0, 0, 231, 0, 0, 0, 246, 0, 0, 0, 186, 0, 0, 0, 83, 0, 0, 0, 132, 0, 0, 0, 10, 0, 0, 0, 163, 0, 0, 0, 52, 0, 0, 0, 255, 0, 0, 0, 60, 0, 0, 0, 163, 0, 0, 0, 106, 0, 0, 0, 161, 0, 0, 0, 55, 0, 0, 0, 234, 0, 0, 0, 221, 0, 0, 0, 182, 0, 0, 0, 149, 0, 0, 0, 179, 0, 0, 0, 120, 0, 0, 0, 25, 0, 0, 0, 118, 0, 0, 0, 30, 0, 0, 0, 85, 0, 0, 0, 47, 0, 0, 0, 119, 0, 0, 0, 46, 0, 0, 0, 127, 0, 0, 0, 193, 0, 0, 0, 234, 0, 0, 0, 94, 0, 0, 0, 131, +0, 0, 0, 225, 0, 0, 0, 110, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 51, 0, 0, 0, 62, 0, 0, 0, 131, 0, 0, 0, 255, 0, 0, 0, 203, 0, 0, 0, 28, 0, 0, 0, 159, 0, 0, 0, 177, 0, 0, 0, 163, 0, 0, 0, 180, 0, 0, 0, 201, 0, 0, 0, 225, 0, 0, 0, 7, 0, 0, 0, 151, 0, 0, 0, 255, 0, 0, 0, 248, 0, 0, 0, 35, 0, 0, 0, 143, 0, 0, 0, 206, 0, 0, 0, 64, 0, 0, 0, 253, 0, 0, 0, 46, 0, 0, 0, 94, 0, 0, 0, 219, 0, 0, 0, 22, 0, 0, 0, 67, 0, 0, 0, 45, 0, 0, 0, 186, 0, 0, 0, 56, 0, 0, 0, 2, 0, 0, 0, 247, 0, 0, 0, 129, 0, 0, 0, 67, 0, +0, 0, 131, 0, 0, 0, 163, 0, 0, 0, 32, 0, 0, 0, 79, 0, 0, 0, 1, 0, 0, 0, 59, 0, 0, 0, 138, 0, 0, 0, 4, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 198, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 223, 0, 0, 0, 215, 0, 0, 0, 250, 0, 0, 0, 47, 0, 0, 0, 136, 0, 0, 0, 63, 0, 0, 0, 252, 0, 0, 0, 12, 0, 0, 0, 118, 0, 0, 0, 196, 0, 0, 0, 166, 0, 0, 0, 69, 0, 0, 0, 114, 0, 0, 0, 187, 0, 0, 0, 12, 0, 0, 0, 188, 0, 0, 0, 106, 0, 0, 0, 164, 0, 0, 0, 151, 0, 0, 0, 23, 0, 0, 0, 147, 0, 0, 0, 45, 0, 0, 0, 111, 0, 0, 0, 222, 0, +0, 0, 114, 0, 0, 0, 16, 0, 0, 0, 28, 0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 50, 0, 0, 0, 104, 0, 0, 0, 39, 0, 0, 0, 212, 0, 0, 0, 171, 0, 0, 0, 221, 0, 0, 0, 197, 0, 0, 0, 88, 0, 0, 0, 97, 0, 0, 0, 19, 0, 0, 0, 109, 0, 0, 0, 17, 0, 0, 0, 30, 0, 0, 0, 77, 0, 0, 0, 26, 0, 0, 0, 185, 0, 0, 0, 201, 0, 0, 0, 16, 0, 0, 0, 251, 0, 0, 0, 30, 0, 0, 0, 78, 0, 0, 0, 244, 0, 0, 0, 132, 0, 0, 0, 75, 0, 0, 0, 138, 0, 0, 0, 94, 0, 0, 0, 123, 0, 0, 0, 75, 0, 0, 0, 232, 0, 0, 0, 67, 0, 0, 0, +140, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 181, 0, 0, 0, 84, 0, 0, 0, 19, 0, 0, 0, 197, 0, 0, 0, 92, 0, 0, 0, 182, 0, 0, 0, 53, 0, 0, 0, 78, 0, 0, 0, 157, 0, 0, 0, 228, 0, 0, 0, 91, 0, 0, 0, 65, 0, 0, 0, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 125, 0, +0, 0, 18, 0, 0, 0, 72, 0, 0, 0, 130, 0, 0, 0, 20, 0, 0, 0, 66, 0, 0, 0, 205, 0, 0, 0, 50, 0, 0, 0, 212, 0, 0, 0, 75, 0, 0, 0, 193, 0, 0, 0, 114, 0, 0, 0, 97, 0, 0, 0, 42, 0, 0, 0, 140, 0, 0, 0, 236, 0, 0, 0, 226, 0, 0, 0, 248, 0, 0, 0, 36, 0, 0, 0, 69, 0, 0, 0, 148, 0, 0, 0, 227, 0, 0, 0, 190, 0, 0, 0, 221, 0, 0, 0, 103, 0, 0, 0, 168, 0, 0, 0, 119, 0, 0, 0, 90, 0, 0, 0, 174, 0, 0, 0, 91, 0, 0, 0, 75, 0, 0, 0, 203, 0, 0, 0, 119, 0, 0, 0, 154, 0, 0, 0, 32, 0, 0, 0, 222, 0, 0, 0, 184, 0, 0, 0, 35, 0, +0, 0, 217, 0, 0, 0, 160, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 0, 123, 0, 0, 0, 165, 0, 0, 0, 203, 0, 0, 0, 174, 0, 0, 0, 182, 0, 0, 0, 236, 0, 0, 0, 66, 0, 0, 0, 103, 0, 0, 0, 14, 0, 0, 0, 88, 0, 0, 0, 164, 0, 0, 0, 117, 0, 0, 0, 152, 0, 0, 0, 33, 0, 0, 0, 113, 0, 0, 0, 132, 0, 0, 0, 179, 0, 0, 0, 224, 0, 0, 0, 118, 0, 0, 0, 148, 0, 0, 0, 115, 0, 0, 0, 223, 0, 0, 0, 252, 0, 0, 0, 105, 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 0, 63, 0, 0, 0, 91, 0, 0, 0, 248, 0, 0, 0, 59, 0, 0, 0, 36, 0, 0, 0, 55, 0, 0, 0, 243, +0, 0, 0, 29, 0, 0, 0, 213, 0, 0, 0, 34, 0, 0, 0, 107, 0, 0, 0, 208, 0, 0, 0, 152, 0, 0, 0, 168, 0, 0, 0, 108, 0, 0, 0, 207, 0, 0, 0, 255, 0, 0, 0, 6, 0, 0, 0, 225, 0, 0, 0, 19, 0, 0, 0, 223, 0, 0, 0, 185, 0, 0, 0, 193, 0, 0, 0, 12, 0, 0, 0, 169, 0, 0, 0, 191, 0, 0, 0, 51, 0, 0, 0, 217, 0, 0, 0, 129, 0, 0, 0, 218, 0, 0, 0, 178, 0, 0, 0, 79, 0, 0, 0, 130, 0, 0, 0, 157, 0, 0, 0, 67, 0, 0, 0, 129, 0, 0, 0, 9, 0, 0, 0, 241, 0, 0, 0, 210, 0, 0, 0, 1, 0, 0, 0, 239, 0, 0, 0, 172, 0, 0, 0, 244, 0, 0, 0, 45, +0, 0, 0, 125, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, 241, 0, 0, 0, 255, 0, 0, 0, 165, 0, 0, 0, 159, 0, 0, 0, 229, 0, 0, 0, 202, 0, 0, 0, 39, 0, 0, 0, 99, 0, 0, 0, 219, 0, 0, 0, 32, 0, 0, 0, 177, 0, 0, 0, 83, 0, 0, 0, 103, 0, 0, 0, 2, 0, 0, 0, 232, 0, 0, 0, 173, 0, 0, 0, 169, 0, 0, 0, 52, 0, 0, 0, 212, 0, 0, 0, 240, 0, 0, 0, 21, 0, 0, 0, 129, 0, 0, 0, 170, 0, 0, 0, 199, 0, 0, 0, 77, 0, 0, 0, 135, 0, 0, 0, 148, 0, 0, 0, 234, 0, 0, 0, 117, 0, 0, 0, 231, 0, 0, 0, 76, 0, 0, 0, 148, 0, 0, 0, 4, 0, 0, 0, 14, +0, 0, 0, 105, 0, 0, 0, 135, 0, 0, 0, 231, 0, 0, 0, 81, 0, 0, 0, 145, 0, 0, 0, 16, 0, 0, 0, 3, 0, 0, 0, 199, 0, 0, 0, 190, 0, 0, 0, 86, 0, 0, 0, 50, 0, 0, 0, 251, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 51, 0, 0, 0, 107, 0, 0, 0, 46, 0, 0, 0, 81, 0, 0, 0, 43, 0, 0, 0, 200, 0, 0, 0, 250, 0, 0, 0, 108, 0, 0, 0, 112, 0, 0, 0, 71, 0, 0, 0, 126, 0, 0, 0, 206, 0, 0, 0, 5, 0, 0, 0, 12, 0, 0, 0, 113, 0, 0, 0, 243, 0, 0, 0, 180, 0, 0, 0, 86, 0, 0, 0, 166, 0, 0, 0, 220, 0, 0, 0, 204, 0, 0, 0, 120, 0, 0, 0, 7, +0, 0, 0, 117, 0, 0, 0, 208, 0, 0, 0, 221, 0, 0, 0, 178, 0, 0, 0, 106, 0, 0, 0, 198, 0, 0, 0, 239, 0, 0, 0, 185, 0, 0, 0, 192, 0, 0, 0, 43, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 30, 0, 0, 0, 113, 0, 0, 0, 112, 0, 0, 0, 179, 0, 0, 0, 53, 0, 0, 0, 156, 0, 0, 0, 122, 0, 0, 0, 1, 0, 0, 0, 146, 0, 0, 0, 68, 0, 0, 0, 154, 0, 0, 0, 246, 0, 0, 0, 176, 0, 0, 0, 88, 0, 0, 0, 149, 0, 0, 0, 193, 0, 0, 0, 155, 0, 0, 0, 2, 0, 0, 0, 237, 0, 0, 0, 45, 0, 0, 0, 124, 0, 0, 0, 52, 0, 0, 0, 41, 0, 0, 0, 73, 0, 0, 0, 68, +0, 0, 0, 69, 0, 0, 0, 98, 0, 0, 0, 29, 0, 0, 0, 46, 0, 0, 0, 255, 0, 0, 0, 42, 0, 0, 0, 28, 0, 0, 0, 33, 0, 0, 0, 164, 0, 0, 0, 37, 0, 0, 0, 123, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 0, 21, 0, 0, 0, 57, 0, 0, 0, 252, 0, 0, 0, 143, 0, 0, 0, 124, 0, 0, 0, 165, 0, 0, 0, 125, 0, 0, 0, 30, 0, 0, 0, 37, 0, 0, 0, 163, 0, 0, 0, 69, 0, 0, 0, 214, 0, 0, 0, 171, 0, 0, 0, 189, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 94, 0, 0, 0, 120, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 66, 0, 0, 0, 237, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 21, 0, 0, 0, 44, 0, 0, 0, 156, 0, 0, 0, 119, 0, 0, 0, 129, 0, 0, 0, 210, 0, 0, 0, 115, 0, 0, 0, 209, 0, 0, 0, 6, 0, 0, 0, 213, 0, 0, 0, 196, 0, 0, 0, 127, 0, 0, 0, 148, 0, 0, 0, 187, 0, 0, 0, 146, 0, 0, +0, 45, 0, 0, 0, 44, 0, 0, 0, 75, 0, 0, 0, 69, 0, 0, 0, 75, 0, 0, 0, 233, 0, 0, 0, 42, 0, 0, 0, 137, 0, 0, 0, 107, 0, 0, 0, 43, 0, 0, 0, 210, 0, 0, 0, 12, 0, 0, 0, 136, 0, 0, 0, 197, 0, 0, 0, 72, 0, 0, 0, 77, 0, 0, 0, 234, 0, 0, 0, 13, 0, 0, 0, 74, 0, 0, 0, 201, 0, 0, 0, 82, 0, 0, 0, 106, 0, 0, 0, 97, 0, 0, 0, 121, 0, 0, 0, 233, 0, 0, 0, 118, 0, 0, 0, 243, 0, 0, 0, 133, 0, 0, 0, 82, 0, 0, 0, 92, 0, 0, 0, 27, 0, 0, 0, 44, 0, 0, 0, 225, 0, 0, 0, 214, 0, 0, 0, 196, 0, 0, 0, 15, 0, 0, 0, 24, 0, 0, 0, +14, 0, 0, 0, 78, 0, 0, 0, 246, 0, 0, 0, 28, 0, 0, 0, 127, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 46, 0, 0, 0, 66, 0, 0, 0, 203, 0, 0, 0, 31, 0, 0, 0, 43, 0, 0, 0, 17, 0, 0, 0, 81, 0, 0, 0, 123, 0, 0, 0, 8, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 62, 0, 0, 0, 158, 0, 0, 0, 82, 0, 0, 0, 96, 0, 0, 0, 183, 0, 0, 0, 194, 0, 0, 0, 97, 0, 0, 0, 87, 0, 0, 0, 140, 0, 0, 0, 132, 0, 0, 0, 213, 0, 0, 0, 24, 0, 0, 0, 166, 0, 0, 0, 25, 0, 0, 0, 252, 0, 0, 0, 183, 0, 0, 0, 117, 0, 0, 0, 145, 0, 0, 0, 27, 0, 0, 0, 232, +0, 0, 0, 104, 0, 0, 0, 202, 0, 0, 0, 68, 0, 0, 0, 200, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 204, 0, 0, 0, 83, 0, 0, 0, 10, 0, 0, 0, 50, 0, 0, 0, 53, 0, 0, 0, 204, 0, 0, 0, 82, 0, 0, 0, 203, 0, 0, 0, 14, 0, 0, 0, 247, 0, 0, 0, 197, 0, 0, 0, 231, 0, 0, 0, 236, 0, 0, 0, 61, 0, 0, 0, 133, 0, 0, 0, 204, 0, 0, 0, 88, 0, 0, 0, 226, 0, 0, 0, 23, 0, 0, 0, 71, 0, 0, 0, 255, 0, 0, 0, 159, 0, 0, 0, 165, 0, 0, 0, 48, 0, 0, 0, 23, 0, 0, 0, 227, 0, 0, 0, 174, 0, 0, 0, 200, 0, 0, 0, 193, 0, 0, 0, 113, 0, 0, 0, 117, +0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 65, 0, 0, 0, 92, 0, 0, 0, 14, 0, 0, 0, 57, 0, 0, 0, 218, 0, 0, 0, 115, 0, 0, 0, 160, 0, 0, 0, 199, 0, 0, 0, 151, 0, 0, 0, 54, 0, 0, 0, 108, 0, 0, 0, 91, 0, 0, 0, 242, 0, 0, 0, 238, 0, 0, 0, 100, 0, 0, 0, 10, 0, 0, 0, 61, 0, 0, 0, 137, 0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 73, 0, 0, 0, 140, 0, 0, 0, 55, 0, 0, 0, 76, 0, 0, 0, 230, 0, 0, 0, 176, 0, 0, 0, 193, 0, 0, 0, 165, 0, 0, 0, 42, 0, 0, 0, 130, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 173, 0, 0, 0, 121, 0, 0, +0, 156, 0, 0, 0, 86, 0, 0, 0, 246, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 215, 0, 0, 0, 124, 0, 0, 0, 57, 0, 0, 0, 127, 0, 0, 0, 147, 0, 0, 0, 202, 0, 0, 0, 17, 0, 0, 0, 85, 0, 0, 0, 191, 0, 0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 130, 0, 0, 0, 41, 0, 0, 0, 105, 0, 0, 0, 149, 0, 0, 0, 92, 0, 0, 0, 135, 0, 0, 0, 238, 0, 0, 0, 166, 0, 0, 0, 86, 0, 0, 0, 158, 0, 0, 0, 194, 0, 0, 0, 154, 0, 0, 0, 86, 0, 0, 0, 36, 0, 0, 0, 66, 0, 0, 0, 133, 0, 0, 0, 77, 0, 0, 0, 152, 0, 0, 0, 49, 0, 0, 0, 30, 0, 0, 0, 96, 0, 0, +0, 77, 0, 0, 0, 135, 0, 0, 0, 133, 0, 0, 0, 4, 0, 0, 0, 174, 0, 0, 0, 70, 0, 0, 0, 18, 0, 0, 0, 249, 0, 0, 0, 142, 0, 0, 0, 127, 0, 0, 0, 228, 0, 0, 0, 127, 0, 0, 0, 246, 0, 0, 0, 28, 0, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 115, 0, 0, 0, 76, 0, 0, 0, 182, 0, 0, 0, 197, 0, 0, 0, 196, 0, 0, 0, 233, 0, 0, 0, 108, 0, 0, 0, 133, 0, 0, 0, 72, 0, 0, 0, 74, 0, 0, 0, 90, 0, 0, 0, 172, 0, 0, 0, 217, 0, 0, 0, 31, 0, 0, 0, 67, 0, 0, 0, 248, 0, 0, 0, 98, 0, 0, 0, 91, 0, 0, 0, 238, 0, 0, 0, 152, 0, 0, 0, 42, 0, 0, 0, +51, 0, 0, 0, 142, 0, 0, 0, 121, 0, 0, 0, 206, 0, 0, 0, 97, 0, 0, 0, 6, 0, 0, 0, 53, 0, 0, 0, 216, 0, 0, 0, 215, 0, 0, 0, 202, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 211, 0, 0, 0, 174, 0, 0, 0, 166, 0, 0, 0, 202, 0, 0, 0, 143, 0, 0, 0, 205, +0, 0, 0, 204, 0, 0, 0, 120, 0, 0, 0, 142, 0, 0, 0, 25, 0, 0, 0, 77, 0, 0, 0, 167, 0, 0, 0, 210, 0, 0, 0, 39, 0, 0, 0, 233, 0, 0, 0, 164, 0, 0, 0, 60, 0, 0, 0, 22, 0, 0, 0, 91, 0, 0, 0, 132, 0, 0, 0, 128, 0, 0, 0, 249, 0, 0, 0, 208, 0, 0, 0, 204, 0, 0, 0, 106, 0, 0, 0, 30, 0, 0, 0, 202, 0, 0, 0, 30, 0, 0, 0, 103, 0, 0, 0, 189, 0, 0, 0, 99, 0, 0, 0, 123, 0, 0, 0, 110, 0, 0, 0, 42, 0, 0, 0, 210, 0, 0, 0, 135, 0, 0, 0, 72, 0, 0, 0, 255, 0, 0, 0, 161, 0, 0, 0, 202, 0, 0, 0, 233, 0, 0, 0, 21, 0, 0, 0, +133, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 44, 0, 0, 0, 57, 0, 0, 0, 18, 0, 0, 0, 145, 0, 0, 0, 169, 0, 0, 0, 32, 0, 0, 0, 170, 0, 0, 0, 79, 0, 0, 0, 41, 0, 0, 0, 244, 0, 0, 0, 21, 0, 0, 0, 122, 0, 0, 0, 210, 0, 0, 0, 245, 0, 0, 0, 50, 0, 0, 0, 204, 0, 0, 0, 96, 0, 0, 0, 4, 0, 0, 0, 229, 0, 0, 0, 16, 0, 0, 0, 71, 0, 0, 0, 59, 0, 0, 0, 250, 0, 0, 0, 144, 0, 0, 0, 252, 0, 0, 0, 48, 0, 0, 0, 181, 0, 0, 0, 234, 0, 0, 0, 111, 0, 0, 0, 86, 0, 0, 0, 143, 0, 0, 0, 251, 0, 0, 0, 14, 0, 0, 0, 167, 0, 0, 0, +59, 0, 0, 0, 200, 0, 0, 0, 178, 0, 0, 0, 255, 0, 0, 0, 2, 0, 0, 0, 122, 0, 0, 0, 51, 0, 0, 0, 148, 0, 0, 0, 147, 0, 0, 0, 42, 0, 0, 0, 3, 0, 0, 0, 224, 0, 0, 0, 150, 0, 0, 0, 58, 0, 0, 0, 108, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 99, 0, 0, 0, 103, 0, 0, 0, 225, 0, 0, 0, 155, 0, 0, 0, 71, 0, 0, 0, 120, 0, 0, 0, 159, 0, 0, 0, 56, 0, 0, 0, 121, 0, 0, 0, 172, 0, 0, 0, 151, 0, 0, 0, 102, 0, 0, 0, 29, 0, 0, 0, 94, 0, 0, 0, 81, 0, 0, 0, 238, 0, 0, 0, 36, 0, 0, 0, 66, 0, 0, 0, 232, 0, 0, 0, 88, 0, 0, 0, 75, +0, 0, 0, 138, 0, 0, 0, 3, 0, 0, 0, 117, 0, 0, 0, 134, 0, 0, 0, 55, 0, 0, 0, 134, 0, 0, 0, 226, 0, 0, 0, 151, 0, 0, 0, 78, 0, 0, 0, 61, 0, 0, 0, 63, 0, 0, 0, 117, 0, 0, 0, 142, 0, 0, 0, 180, 0, 0, 0, 255, 0, 0, 0, 216, 0, 0, 0, 221, 0, 0, 0, 214, 0, 0, 0, 55, 0, 0, 0, 87, 0, 0, 0, 157, 0, 0, 0, 109, 0, 0, 0, 59, 0, 0, 0, 189, 0, 0, 0, 213, 0, 0, 0, 96, 0, 0, 0, 136, 0, 0, 0, 101, 0, 0, 0, 154, 0, 0, 0, 185, 0, 0, 0, 74, 0, 0, 0, 104, 0, 0, 0, 132, 0, 0, 0, 162, 0, 0, 0, 103, 0, 0, 0, 221, 0, 0, 0, +23, 0, 0, 0, 37, 0, 0, 0, 151, 0, 0, 0, 4, 0, 0, 0, 139, 0, 0, 0, 94, 0, 0, 0, 187, 0, 0, 0, 64, 0, 0, 0, 94, 0, 0, 0, 188, 0, 0, 0, 22, 0, 0, 0, 146, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 192, 0, 0, 0, 78, 0, 0, 0, 114, 0, 0, 0, 144, 0, 0, 0, 14, 0, 0, 0, 171, 0, 0, 0, 207, 0, 0, 0, 138, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 185, 0, 0, 0, 45, 0, 0, 0, 59, 0, 0, 0, 248, 0, 0, 0, 67, 0, 0, 0, 91, 0, 0, 0, 186, 0, 0, 0, 45, 0, 0, 0, 235, 0, 0, 0, 47, 0, 0, 0, 82, 0, 0, 0, 210, 0, 0, 0, 209, 0, 0, 0, 90, +0, 0, 0, 64, 0, 0, 0, 180, 0, 0, 0, 171, 0, 0, 0, 230, 0, 0, 0, 173, 0, 0, 0, 159, 0, 0, 0, 70, 0, 0, 0, 105, 0, 0, 0, 74, 0, 0, 0, 179, 0, 0, 0, 142, 0, 0, 0, 170, 0, 0, 0, 234, 0, 0, 0, 156, 0, 0, 0, 138, 0, 0, 0, 32, 0, 0, 0, 22, 0, 0, 0, 93, 0, 0, 0, 140, 0, 0, 0, 19, 0, 0, 0, 189, 0, 0, 0, 246, 0, 0, 0, 29, 0, 0, 0, 197, 0, 0, 0, 36, 0, 0, 0, 189, 0, 0, 0, 144, 0, 0, 0, 42, 0, 0, 0, 28, 0, 0, 0, 199, 0, 0, 0, 19, 0, 0, 0, 59, 0, 0, 0, 84, 0, 0, 0, 220, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0, 24, +0, 0, 0, 190, 0, 0, 0, 53, 0, 0, 0, 100, 0, 0, 0, 97, 0, 0, 0, 82, 0, 0, 0, 2, 0, 0, 0, 128, 0, 0, 0, 175, 0, 0, 0, 5, 0, 0, 0, 247, 0, 0, 0, 166, 0, 0, 0, 66, 0, 0, 0, 211, 0, 0, 0, 143, 0, 0, 0, 46, 0, 0, 0, 121, 0, 0, 0, 38, 0, 0, 0, 168, 0, 0, 0, 187, 0, 0, 0, 178, 0, 0, 0, 23, 0, 0, 0, 72, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 10, 0, 0, 0, 137, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 168, 0, 0, 0, 136, 0, 0, 0, 227, 0, 0, 0, 145, 0, 0, 0, 192, 0, 0, 0, 110, 0, 0, 0, 187, 0, 0, 0, 138, 0, 0, 0, 39, 0, 0, 0, 130, 0, 0, 0, 81, 0, 0, 0, 131, 0, 0, 0, 178, 0, 0, 0, 40, 0, 0, 0, 169, 0, 0, 0, 131, 0, 0, 0, 235, 0, 0, 0, 166, 0, 0, 0, 169, 0, 0, 0, 77, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 0, 34, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, +0, 69, 0, 0, 0, 203, 0, 0, 0, 72, 0, 0, 0, 75, 0, 0, 0, 24, 0, 0, 0, 51, 0, 0, 0, 124, 0, 0, 0, 231, 0, 0, 0, 38, 0, 0, 0, 186, 0, 0, 0, 77, 0, 0, 0, 50, 0, 0, 0, 254, 0, 0, 0, 83, 0, 0, 0, 244, 0, 0, 0, 250, 0, 0, 0, 131, 0, 0, 0, 227, 0, 0, 0, 165, 0, 0, 0, 121, 0, 0, 0, 102, 0, 0, 0, 115, 0, 0, 0, 239, 0, 0, 0, 128, 0, 0, 0, 35, 0, 0, 0, 104, 0, 0, 0, 194, 0, 0, 0, 96, 0, 0, 0, 221, 0, 0, 0, 169, 0, 0, 0, 51, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 122, 0, 0, 0, 224, 0, 0, 0, 224, 0, 0, 0, 62, 0, 0, +0, 52, 0, 0, 0, 92, 0, 0, 0, 19, 0, 0, 0, 251, 0, 0, 0, 192, 0, 0, 0, 227, 0, 0, 0, 120, 0, 0, 0, 43, 0, 0, 0, 84, 0, 0, 0, 88, 0, 0, 0, 34, 0, 0, 0, 155, 0, 0, 0, 118, 0, 0, 0, 129, 0, 0, 0, 127, 0, 0, 0, 147, 0, 0, 0, 156, 0, 0, 0, 37, 0, 0, 0, 60, 0, 0, 0, 210, 0, 0, 0]).concat([233, 0, 0, 0, 150, 0, 0, 0, 33, 0, 0, 0, 38, 0, 0, 0, 8, 0, 0, 0, 245, 0, 0, 0, 237, 0, 0, 0, 149, 0, 0, 0, 17, 0, 0, 0, 174, 0, 0, 0, 4, 0, 0, 0, 90, 0, 0, 0, 185, 0, 0, 0, 232, 0, 0, 0, 197, 0, 0, 0, 18, 0, 0, 0, 151, +0, 0, 0, 31, 0, 0, 0, 131, 0, 0, 0, 254, 0, 0, 0, 62, 0, 0, 0, 148, 0, 0, 0, 153, 0, 0, 0, 212, 0, 0, 0, 45, 0, 0, 0, 249, 0, 0, 0, 82, 0, 0, 0, 89, 0, 0, 0, 92, 0, 0, 0, 130, 0, 0, 0, 166, 0, 0, 0, 240, 0, 0, 0, 117, 0, 0, 0, 126, 0, 0, 0, 232, 0, 0, 0, 236, 0, 0, 0, 204, 0, 0, 0, 172, 0, 0, 0, 24, 0, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 103, 0, 0, 0, 102, 0, 0, 0, 103, 0, 0, 0, 179, 0, 0, 0, 64, 0, 0, 0, 41, 0, 0, 0, 209, 0, 0, 0, 203, 0, 0, 0, 27, 0, 0, 0, 8, 0, 0, 0, 158, 0, 0, 0, 156, 0, 0, 0, 183, +0, 0, 0, 83, 0, 0, 0, 185, 0, 0, 0, 59, 0, 0, 0, 113, 0, 0, 0, 8, 0, 0, 0, 149, 0, 0, 0, 18, 0, 0, 0, 26, 0, 0, 0, 88, 0, 0, 0, 175, 0, 0, 0, 126, 0, 0, 0, 130, 0, 0, 0, 82, 0, 0, 0, 67, 0, 0, 0, 79, 0, 0, 0, 17, 0, 0, 0, 57, 0, 0, 0, 244, 0, 0, 0, 147, 0, 0, 0, 26, 0, 0, 0, 38, 0, 0, 0, 5, 0, 0, 0, 110, 0, 0, 0, 68, 0, 0, 0, 163, 0, 0, 0, 249, 0, 0, 0, 100, 0, 0, 0, 175, 0, 0, 0, 231, 0, 0, 0, 109, 0, 0, 0, 125, 0, 0, 0, 223, 0, 0, 0, 30, 0, 0, 0, 172, 0, 0, 0, 4, 0, 0, 0, 234, 0, 0, 0, 59, 0, 0, +0, 95, 0, 0, 0, 155, 0, 0, 0, 232, 0, 0, 0, 36, 0, 0, 0, 157, 0, 0, 0, 14, 0, 0, 0, 229, 0, 0, 0, 46, 0, 0, 0, 62, 0, 0, 0, 223, 0, 0, 0, 169, 0, 0, 0, 247, 0, 0, 0, 212, 0, 0, 0, 80, 0, 0, 0, 113, 0, 0, 0, 240, 0, 0, 0, 120, 0, 0, 0, 62, 0, 0, 0, 168, 0, 0, 0, 56, 0, 0, 0, 194, 0, 0, 0, 87, 0, 0, 0, 86, 0, 0, 0, 66, 0, 0, 0, 154, 0, 0, 0, 177, 0, 0, 0, 226, 0, 0, 0, 248, 0, 0, 0, 69, 0, 0, 0, 170, 0, 0, 0, 17, 0, 0, 0, 72, 0, 0, 0, 95, 0, 0, 0, 23, 0, 0, 0, 196, 0, 0, 0, 84, 0, 0, 0, 39, 0, 0, 0, +220, 0, 0, 0, 93, 0, 0, 0, 170, 0, 0, 0, 221, 0, 0, 0, 65, 0, 0, 0, 188, 0, 0, 0, 223, 0, 0, 0, 129, 0, 0, 0, 185, 0, 0, 0, 83, 0, 0, 0, 238, 0, 0, 0, 82, 0, 0, 0, 195, 0, 0, 0, 241, 0, 0, 0, 167, 0, 0, 0, 109, 0, 0, 0, 179, 0, 0, 0, 95, 0, 0, 0, 146, 0, 0, 0, 111, 0, 0, 0, 204, 0, 0, 0, 145, 0, 0, 0, 184, 0, 0, 0, 149, 0, 0, 0, 5, 0, 0, 0, 223, 0, 0, 0, 60, 0, 0, 0, 100, 0, 0, 0, 87, 0, 0, 0, 57, 0, 0, 0, 97, 0, 0, 0, 81, 0, 0, 0, 173, 0, 0, 0, 140, 0, 0, 0, 56, 0, 0, 0, 123, 0, 0, 0, 200, 0, 0, +0, 222, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 190, 0, 0, 0, 161, 0, 0, 0, 176, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 29, 0, 0, 0, 138, 0, 0, 0, 103, 0, 0, 0, 32, 0, 0, 0, 238, 0, 0, 0, 66, 0, 0, 0, 235, 0, 0, 0, 56, 0, 0, 0, 237, +0, 0, 0, 11, 0, 0, 0, 139, 0, 0, 0, 205, 0, 0, 0, 70, 0, 0, 0, 157, 0, 0, 0, 94, 0, 0, 0, 107, 0, 0, 0, 30, 0, 0, 0, 36, 0, 0, 0, 157, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 26, 0, 0, 0, 204, 0, 0, 0, 5, 0, 0, 0, 78, 0, 0, 0, 146, 0, 0, 0, 56, 0, 0, 0, 225, 0, 0, 0, 31, 0, 0, 0, 80, 0, 0, 0, 78, 0, 0, 0, 238, 0, 0, 0, 28, 0, 0, 0, 145, 0, 0, 0, 230, 0, 0, 0, 17, 0, 0, 0, 189, 0, 0, 0, 142, 0, 0, 0, 85, 0, 0, 0, 26, 0, 0, 0, 24, 0, 0, 0, 117, 0, 0, 0, 102, 0, 0, 0, 175, 0, 0, 0, 77, 0, 0, 0, 123, 0, 0, +0, 15, 0, 0, 0, 174, 0, 0, 0, 109, 0, 0, 0, 133, 0, 0, 0, 202, 0, 0, 0, 130, 0, 0, 0, 88, 0, 0, 0, 33, 0, 0, 0, 156, 0, 0, 0, 24, 0, 0, 0, 224, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 34, 0, 0, 0, 128, 0, 0, 0, 47, 0, 0, 0, 104, 0, 0, 0, 59, 0, 0, 0, 10, 0, 0, 0, 57, 0, 0, 0, 29, 0, 0, 0, 106, 0, 0, 0, 21, 0, 0, 0, 87, 0, 0, 0, 252, 0, 0, 0, 240, 0, 0, 0, 99, 0, 0, 0, 84, 0, 0, 0, 219, 0, 0, 0, 57, 0, 0, 0, 219, 0, 0, 0, 232, 0, 0, 0, 92, 0, 0, 0, 100, 0, 0, 0, 255, 0, 0, 0, 160, 0, 0, 0, 9, 0, 0, 0, +79, 0, 0, 0, 59, 0, 0, 0, 183, 0, 0, 0, 50, 0, 0, 0, 96, 0, 0, 0, 153, 0, 0, 0, 148, 0, 0, 0, 253, 0, 0, 0, 148, 0, 0, 0, 130, 0, 0, 0, 45, 0, 0, 0, 36, 0, 0, 0, 246, 0, 0, 0, 90, 0, 0, 0, 68, 0, 0, 0, 241, 0, 0, 0, 85, 0, 0, 0, 44, 0, 0, 0, 219, 0, 0, 0, 234, 0, 0, 0, 124, 0, 0, 0, 132, 0, 0, 0, 124, 0, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 227, 0, 0, 0, 253, 0, 0, 0, 201, 0, 0, 0, 39, 0, 0, 0, 193, 0, 0, 0, 90, 0, 0, 0, 185, 0, 0, 0, 222, 0, 0, 0, 79, 0, 0, 0, 90, 0, 0, 0, 144, 0, 0, 0, 221, 0, 0, 0, +198, 0, 0, 0, 103, 0, 0, 0, 170, 0, 0, 0, 111, 0, 0, 0, 138, 0, 0, 0, 58, 0, 0, 0, 120, 0, 0, 0, 82, 0, 0, 0, 135, 0, 0, 0, 201, 0, 0, 0, 151, 0, 0, 0, 99, 0, 0, 0, 177, 0, 0, 0, 221, 0, 0, 0, 84, 0, 0, 0, 95, 0, 0, 0, 193, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 6, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 163, 0, 0, 0, 136, 0, 0, 0, 130, 0, 0, 0, 212, 0, 0, 0, 203, 0, 0, 0, 166, 0, 0, 0, 25, 0, 0, 0, 221, 0, 0, 0, 209, 0, 0, 0, 17, 0, 0, 0, 135, 0, 0, 0, 8, 0, 0, 0, 23, 0, 0, 0, 76, 0, 0, 0, 55, 0, 0, +0, 42, 0, 0, 0, 161, 0, 0, 0, 12, 0, 0, 0, 243, 0, 0, 0, 8, 0, 0, 0, 67, 0, 0, 0, 217, 0, 0, 0, 36, 0, 0, 0, 30, 0, 0, 0, 131, 0, 0, 0, 167, 0, 0, 0, 223, 0, 0, 0, 145, 0, 0, 0, 202, 0, 0, 0, 189, 0, 0, 0, 105, 0, 0, 0, 71, 0, 0, 0, 141, 0, 0, 0, 27, 0, 0, 0, 226, 0, 0, 0, 185, 0, 0, 0, 78, 0, 0, 0, 181, 0, 0, 0, 225, 0, 0, 0, 118, 0, 0, 0, 179, 0, 0, 0, 28, 0, 0, 0, 147, 0, 0, 0, 3, 0, 0, 0, 206, 0, 0, 0, 95, 0, 0, 0, 179, 0, 0, 0, 90, 0, 0, 0, 29, 0, 0, 0, 218, 0, 0, 0, 228, 0, 0, 0, 97, 0, 0, +0, 3, 0, 0, 0, 80, 0, 0, 0, 169, 0, 0, 0, 139, 0, 0, 0, 104, 0, 0, 0, 24, 0, 0, 0, 239, 0, 0, 0, 178, 0, 0, 0, 28, 0, 0, 0, 132, 0, 0, 0, 59, 0, 0, 0, 162, 0, 0, 0, 68, 0, 0, 0, 149, 0, 0, 0, 163, 0, 0, 0, 4, 0, 0, 0, 59, 0, 0, 0, 214, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 118, 0, 0, 0, 66, 0, 0, 0, 103, 0, 0, 0, 2, 0, 0, 0, 125, 0, 0, 0, 133, 0, 0, 0, 86, 0, 0, 0, 206, 0, 0, 0, 114, 0, 0, 0, 14, 0, 0, 0, 41, 0, 0, 0, 132, 0, 0, 0, 178, 0, 0, 0, 125, 0, 0, 0, 210, 0, 0, 0, 69, 0, 0, 0, +190, 0, 0, 0, 87, 0, 0, 0, 6, 0, 0, 0, 237, 0, 0, 0, 127, 0, 0, 0, 207, 0, 0, 0, 237, 0, 0, 0, 205, 0, 0, 0, 239, 0, 0, 0, 25, 0, 0, 0, 214, 0, 0, 0, 188, 0, 0, 0, 21, 0, 0, 0, 121, 0, 0, 0, 100, 0, 0, 0, 210, 0, 0, 0, 24, 0, 0, 0, 227, 0, 0, 0, 32, 0, 0, 0, 103, 0, 0, 0, 58, 0, 0, 0, 84, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 253, 0, 0, 0, 4, 0, 0, 0, 197, 0, 0, 0, 251, 0, 0, 0, 153, 0, 0, 0, 231, 0, 0, 0, 232, 0, 0, 0, 251, 0, 0, 0, 140, 0, 0, 0, 225, 0, 0, 0, 66, 0, 0, 0, 3, 0, 0, 0, 239, 0, 0, 0, 157, 0, 0, 0, 217, 0, 0, 0, 158, 0, 0, 0, 77, 0, 0, 0, 247, 0, 0, 0, 128, 0, 0, 0, 207, 0, 0, 0, 46, 0, 0, 0, 204, 0, 0, 0, 155, 0, 0, 0, 69, 0, 0, 0, 201, 0, 0, 0, 123, 0, 0, 0, 122, 0, 0, 0, 188, 0, 0, 0, 55, 0, 0, 0, 168, 0, 0, 0, +82, 0, 0, 0, 150, 0, 0, 0, 17, 0, 0, 0, 65, 0, 0, 0, 138, 0, 0, 0, 71, 0, 0, 0, 145, 0, 0, 0, 254, 0, 0, 0, 182, 0, 0, 0, 218, 0, 0, 0, 122, 0, 0, 0, 84, 0, 0, 0, 99, 0, 0, 0, 209, 0, 0, 0, 20, 0, 0, 0, 53, 0, 0, 0, 5, 0, 0, 0, 134, 0, 0, 0, 140, 0, 0, 0, 169, 0, 0, 0, 54, 0, 0, 0, 63, 0, 0, 0, 242, 0, 0, 0, 133, 0, 0, 0, 84, 0, 0, 0, 78, 0, 0, 0, 146, 0, 0, 0, 216, 0, 0, 0, 133, 0, 0, 0, 1, 0, 0, 0, 70, 0, 0, 0, 214, 0, 0, 0, 80, 0, 0, 0, 83, 0, 0, 0, 205, 0, 0, 0, 243, 0, 0, 0, 134, 0, 0, 0, 64, +0, 0, 0, 230, 0, 0, 0, 57, 0, 0, 0, 66, 0, 0, 0, 149, 0, 0, 0, 214, 0, 0, 0, 203, 0, 0, 0, 69, 0, 0, 0, 26, 0, 0, 0, 32, 0, 0, 0, 200, 0, 0, 0, 69, 0, 0, 0, 75, 0, 0, 0, 50, 0, 0, 0, 105, 0, 0, 0, 4, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 32, 0, 0, 0, 70, 0, 0, 0, 199, 0, 0, 0, 107, 0, 0, 0, 35, 0, 0, 0, 91, 0, 0, 0, 105, 0, 0, 0, 238, 0, 0, 0, 48, 0, 0, 0, 63, 0, 0, 0, 112, 0, 0, 0, 131, 0, 0, 0, 71, 0, 0, 0, 192, 0, 0, 0, 219, 0, 0, 0, 85, 0, 0, 0, 8, 0, 0, 0, 168, 0, 0, 0, 123, 0, 0, 0, 24, 0, 0, +0, 109, 0, 0, 0, 245, 0, 0, 0, 4, 0, 0, 0, 90, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0, 74, 0, 0, 0, 140, 0, 0, 0, 96, 0, 0, 0, 174, 0, 0, 0, 174, 0, 0, 0, 15, 0, 0, 0, 100, 0, 0, 0, 85, 0, 0, 0, 85, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 29, 0, 0, 0, 83, 0, 0, 0, 49, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 136, 0, 0, 0, 107, 0, 0, 0, 150, 0, 0, 0, 120, 0, 0, 0, 10, 0, 0, 0, 139, 0, 0, 0, 131, 0, 0, 0, 220, 0, 0, 0, 188, 0, 0, 0, 175, 0, 0, 0, 64, 0, 0, 0, 182, 0, 0, 0, 141, 0, 0, 0, +127, 0, 0, 0, 239, 0, 0, 0, 180, 0, 0, 0, 209, 0, 0, 0, 63, 0, 0, 0, 204, 0, 0, 0, 162, 0, 0, 0, 116, 0, 0, 0, 201, 0, 0, 0, 194, 0, 0, 0, 146, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 219, 0, 0, 0, 191, 0, 0, 0, 79, 0, 0, 0, 147, 0, 0, 0, 28, 0, 0, 0, 6, 0, 0, 0, 45, 0, 0, 0, 102, 0, 0, 0, 101, 0, 0, 0, 2, 0, 0, 0, 164, 0, 0, 0, 151, 0, 0, 0, 24, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 171, 0, 0, 0, 3, 0, 0, 0, 236, 0, 0, 0, 206, 0, 0, 0, 193, 0, 0, 0, 191, 0, 0, 0, 55, 0, 0, 0, +248, 0, 0, 0, 19, 0, 0, 0, 83, 0, 0, 0, 165, 0, 0, 0, 229, 0, 0, 0, 12, 0, 0, 0, 58, 0, 0, 0, 168, 0, 0, 0, 85, 0, 0, 0, 185, 0, 0, 0, 255, 0, 0, 0, 104, 0, 0, 0, 228, 0, 0, 0, 230, 0, 0, 0, 109, 0, 0, 0, 48, 0, 0, 0, 125, 0, 0, 0, 48, 0, 0, 0, 53, 0, 0, 0, 194, 0, 0, 0, 120, 0, 0, 0, 135, 0, 0, 0, 249, 0, 0, 0, 252, 0, 0, 0, 107, 0, 0, 0, 90, 0, 0, 0, 195, 0, 0, 0, 183, 0, 0, 0, 101, 0, 0, 0, 216, 0, 0, 0, 46, 0, 0, 0, 199, 0, 0, 0, 165, 0, 0, 0, 12, 0, 0, 0, 198, 0, 0, 0, 220, 0, 0, 0, 18, 0, 0, +0, 170, 0, 0, 0, 214, 0, 0, 0, 79, 0, 0, 0, 197, 0, 0, 0, 56, 0, 0, 0, 188, 0, 0, 0, 14, 0, 0, 0, 226, 0, 0, 0, 60, 0, 0, 0, 118, 0, 0, 0, 134, 0, 0, 0, 56, 0, 0, 0, 242, 0, 0, 0, 123, 0, 0, 0, 44, 0, 0, 0, 22, 0, 0, 0, 120, 0, 0, 0, 141, 0, 0, 0, 245, 0, 0, 0, 164, 0, 0, 0, 21, 0, 0, 0, 218, 0, 0, 0, 219, 0, 0, 0, 38, 0, 0, 0, 133, 0, 0, 0, 160, 0, 0, 0, 86, 0, 0, 0, 221, 0, 0, 0, 29, 0, 0, 0, 227, 0, 0, 0, 179, 0, 0, 0, 253, 0, 0, 0, 64, 0, 0, 0, 239, 0, 0, 0, 242, 0, 0, 0, 217, 0, 0, 0, 161, 0, +0, 0, 179, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 73, 0, 0, 0, 14, 0, 0, 0, 230, 0, 0, 0, 88, 0, 0, 0, 16, 0, 0, 0, 122, 0, 0, 0, 82, 0, 0, 0, 218, 0, 0, 0, 181, 0, 0, 0, 125, 0, 0, 0, 55, 0, 0, 0, 106, 0, 0, 0, 62, 0, 0, 0, 161, 0, 0, 0, 120, +0, 0, 0, 206, 0, 0, 0, 199, 0, 0, 0, 28, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 219, 0, 0, 0, 125, 0, 0, 0, 251, 0, 0, 0, 140, 0, 0, 0, 141, 0, 0, 0, 220, 0, 0, 0, 48, 0, 0, 0, 103, 0, 0, 0, 105, 0, 0, 0, 117, 0, 0, 0, 59, 0, 0, 0, 169, 0, 0, 0, 234, 0, 0, 0, 109, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 96, 0, 0, 0, 244, 0, 0, 0, 96, 0, 0, 0, 135, 0, 0, 0, 25, 0, 0, 0, 68, 0, 0, 0, 140, 0, 0, 0, 74, 0, 0, 0, 139, 0, 0, 0, 62, 0, 0, 0, 251, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 166, 0, +0, 0, 158, 0, 0, 0, 159, 0, 0, 0, 239, 0, 0, 0, 207, 0, 0, 0, 217, 0, 0, 0, 210, 0, 0, 0, 76, 0, 0, 0, 116, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 52, 0, 0, 0, 164, 0, 0, 0, 235, 0, 0, 0, 4, 0, 0, 0, 164, 0, 0, 0, 140, 0, 0, 0, 143, 0, 0, 0, 113, 0, 0, 0, 39, 0, 0, 0, 149, 0, 0, 0, 133, 0, 0, 0, 93, 0, 0, 0, 85, 0, 0, 0, 75, 0, 0, 0, 177, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 200, 0, 0, 0, 174, 0, 0, 0, 106, 0, 0, 0, 125, 0, 0, 0, 162, 0, 0, 0, 33, 0, 0, 0, 202, 0, 0, 0, 206, 0, 0, 0, 56, 0, 0, 0, 171, +0, 0, 0, 15, 0, 0, 0, 208, 0, 0, 0, 213, 0, 0, 0, 43, 0, 0, 0, 107, 0, 0, 0, 0, 0, 0, 0, 229, 0, 0, 0, 103, 0, 0, 0, 12, 0, 0, 0, 241, 0, 0, 0, 58, 0, 0, 0, 154, 0, 0, 0, 234, 0, 0, 0, 9, 0, 0, 0, 57, 0, 0, 0, 239, 0, 0, 0, 209, 0, 0, 0, 48, 0, 0, 0, 188, 0, 0, 0, 51, 0, 0, 0, 186, 0, 0, 0, 177, 0, 0, 0, 106, 0, 0, 0, 197, 0, 0, 0, 39, 0, 0, 0, 8, 0, 0, 0, 127, 0, 0, 0, 84, 0, 0, 0, 128, 0, 0, 0, 61, 0, 0, 0, 171, 0, 0, 0, 246, 0, 0, 0, 21, 0, 0, 0, 122, 0, 0, 0, 194, 0, 0, 0, 64, 0, 0, 0, 115, 0, +0, 0, 114, 0, 0, 0, 132, 0, 0, 0, 86, 0, 0, 0, 130, 0, 0, 0, 182, 0, 0, 0, 18, 0, 0, 0, 112, 0, 0, 0, 127, 0, 0, 0, 247, 0, 0, 0, 240, 0, 0, 0, 189, 0, 0, 0, 91, 0, 0, 0, 169, 0, 0, 0, 213, 0, 0, 0, 197, 0, 0, 0, 95, 0, 0, 0, 89, 0, 0, 0, 191, 0, 0, 0, 127, 0, 0, 0, 179, 0, 0, 0, 85, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 201, 0, 0, 0, 68, 0, 0, 0, 85, 0, 0, 0, 135, 0, 0, 0, 143, 0, 0, 0, 150, 0, 0, 0, 152, 0, 0, 0, 100, 0, 0, 0, 109, 0, 0, 0, 21, 0, 0, 0, 176, 0, 0, 0, 139, 0, 0, 0, 170, 0, 0, 0, 30, +0, 0, 0, 236, 0, 0, 0, 199, 0, 0, 0, 165, 0, 0, 0, 143, 0, 0, 0, 31, 0, 0, 0, 146, 0, 0, 0, 4, 0, 0, 0, 198, 0, 0, 0, 5, 0, 0, 0, 246, 0, 0, 0, 223, 0, 0, 0, 161, 0, 0, 0, 204, 0, 0, 0, 31, 0, 0, 0, 129, 0, 0, 0, 245, 0, 0, 0, 14, 0, 0, 0, 156, 0, 0, 0, 87, 0, 0, 0, 220, 0, 0, 0, 227, 0, 0, 0, 187, 0, 0, 0, 6, 0, 0, 0, 135, 0, 0, 0, 30, 0, 0, 0, 254, 0, 0, 0, 35, 0, 0, 0, 108, 0, 0, 0, 216, 0, 0, 0, 43, 0, 0, 0, 91, 0, 0, 0, 22, 0, 0, 0, 234, 0, 0, 0, 32, 0, 0, 0, 241, 0, 0, 0, 211, 0, 0, 0, 104, +0, 0, 0, 143, 0, 0, 0, 174, 0, 0, 0, 91, 0, 0, 0, 208, 0, 0, 0, 169, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 168, 0, 0, 0, 54, 0, 0, 0, 251, 0, 0, 0, 43, 0, 0, 0, 87, 0, 0, 0, 136, 0, 0, 0, 125, 0, 0, 0, 144, 0, 0, 0, 213, 0, 0, 0, 166, 0, 0, 0, 243, 0, 0, 0, 220, 0, 0, 0, 56, 0, 0, 0, 137, 0, 0, 0, 78, 0, 0, 0, 31, 0, 0, 0, 204, 0, 0, 0, 25, 0, 0, 0, 218, 0, 0, 0, 155, 0, 0, 0, 59, 0, 0, 0, 67, 0, 0, 0, 72, 0, 0, 0, 33, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 0, 77, 0, 0, 0, 61, 0, 0, 0, 174, 0, 0, 0, 248, 0, +0, 0, 140, 0, 0, 0, 252, 0, 0, 0, 221, 0, 0, 0, 166, 0, 0, 0, 116, 0, 0, 0, 55, 0, 0, 0, 101, 0, 0, 0, 202, 0, 0, 0, 238, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 142, 0, 0, 0, 159, 0, 0, 0, 100, 0, 0, 0, 111, 0, 0, 0, 12, 0, 0, 0, 139, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 185, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 114, 0, 0, 0, 184, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 204, 0, 0, 0, 141, 0, 0, 0, 60, 0, 0, 0, 111, 0, 0, 0, 37, 0, 0, 0, 237, 0, 0, 0, 244, 0, 0, 0, 70, 0, 0, 0, 46, 0, 0, 0, 12, 0, 0, 0, 96, 0, 0, 0, 15, 0, 0, 0, 226, 0, 0, 0, 132, 0, 0, 0, 52, 0, 0, 0, 85, 0, 0, 0, 137, 0, 0, 0, 89, 0, 0, 0, 52, 0, 0, 0, 27, 0, 0, 0, 245, 0, 0, 0, 141, 0, 0, 0, 254, 0, 0, 0, 8, 0, 0, 0, 248, 0, 0, 0, 171, 0, 0, 0, 147, 0, 0, 0, 188, 0, 0, +0, 68, 0, 0, 0, 186, 0, 0, 0, 27, 0, 0, 0, 117, 0, 0, 0, 75, 0, 0, 0, 73, 0, 0, 0, 111, 0, 0, 0, 208, 0, 0, 0, 84, 0, 0, 0, 46, 0, 0, 0, 99, 0, 0, 0, 186, 0, 0, 0, 181, 0, 0, 0, 234, 0, 0, 0, 237, 0, 0, 0, 50, 0, 0, 0, 20, 0, 0, 0, 201, 0, 0, 0, 148, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 206, 0, 0, 0, 244, 0, 0, 0, 16, 0, 0, 0, 104, 0, 0, 0, 224, 0, 0, 0, 56, 0, 0, 0, 39, 0, 0, 0, 116, 0, 0, 0, 28, 0, 0, 0, 20, 0, 0, 0, 155, 0, 0, 0, 212, 0, 0, 0, 100, 0, 0, 0, 97, 0, 0, 0, 113, 0, 0, 0, 90, 0, 0, +0, 182, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 79, 0, 0, 0, 247, 0, 0, 0, 142, 0, 0, 0, 186, 0, 0, 0, 165, 0, 0, 0, 72, 0, 0, 0, 154, 0, 0, 0, 199, 0, 0, 0, 250, 0, 0, 0, 154, 0, 0, 0, 240, 0, 0, 0, 180, 0, 0, 0, 98, 0, 0, 0, 173, 0, 0, 0, 242, 0, 0, 0, 94, 0, 0, 0, 204, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 26, 0, 0, 0, 245, 0, 0, 0, 118, 0, 0, 0, 253, 0, 0, 0, 228, 0, 0, 0, 175, 0, 0, 0, 185, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 0, 206, 0, 0, 0, 99, 0, 0, 0, 210, 0, 0, 0, 59, 0, 0, 0, 31, 0, 0, 0, 205, 0, 0, +0, 33, 0, 0, 0, 12, 0, 0, 0, 173, 0, 0, 0, 68, 0, 0, 0, 165, 0, 0, 0, 151, 0, 0, 0, 172, 0, 0, 0, 128, 0, 0, 0, 17, 0, 0, 0, 2, 0, 0, 0, 155, 0, 0, 0, 12, 0, 0, 0, 229, 0, 0, 0, 139, 0, 0, 0, 205, 0, 0, 0, 251, 0, 0, 0, 121, 0, 0, 0, 119, 0, 0, 0, 21, 0, 0, 0, 190, 0, 0, 0, 154, 0, 0, 0, 13, 0, 0, 0, 186, 0, 0, 0, 56, 0, 0, 0, 114, 0, 0, 0, 32, 0, 0, 0, 138, 0, 0, 0, 245, 0, 0, 0, 190, 0, 0, 0, 89, 0, 0, 0, 147, 0, 0, 0, 121, 0, 0, 0, 183, 0, 0, 0, 246, 0, 0, 0, 106, 0, 0, 0, 12, 0, 0, 0, 56, 0, +0, 0, 39, 0, 0, 0, 26, 0, 0, 0, 96, 0, 0, 0, 244, 0, 0, 0, 134, 0, 0, 0, 59, 0, 0, 0, 171, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 206, 0, 0, 0, 33, 0, 0, 0, 125, 0, 0, 0, 108, 0, 0, 0, 186, 0, 0, 0, 20, 0, 0, 0, 197, 0, 0, 0, 234, 0, 0, 0, 18, 0, 0, 0, 158, 0, 0, 0, 46, 0, 0, 0, 130, 0, 0, 0, 99, 0, 0, 0, 206, 0, 0, 0, 155, 0, 0, 0, 74, 0, 0, 0, 231, 0, 0, 0, 29, 0, 0, 0, 236, 0, 0, 0, 241, 0, 0, 0, 46, 0, 0, 0, 81, 0, 0, 0, 28, 0, 0, 0, 244, 0, 0, 0, 208, 0, 0, 0, 105, 0, 0, 0, 21, 0, 0, +0, 66, 0, 0, 0, 157, 0, 0, 0, 163, 0, 0, 0, 63, 0, 0, 0, 14, 0, 0, 0, 191, 0, 0, 0, 233, 0, 0, 0, 92, 0, 0, 0, 228, 0, 0, 0, 13, 0, 0, 0, 244, 0, 0, 0, 189, 0, 0, 0, 238, 0, 0, 0, 49, 0, 0, 0, 16, 0, 0, 0, 237, 0, 0, 0, 203, 0, 0, 0, 18, 0, 0, 0, 134, 0, 0, 0, 173, 0, 0, 0, 212, 0, 0, 0, 47, 0, 0, 0, 144, 0, 0, 0, 55, 0, 0, 0, 50, 0, 0, 0, 195, 0, 0, 0, 11, 0, 0, 0, 115, 0, 0, 0, 236, 0, 0, 0, 151, 0, 0, 0, 133, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 118, 0, 0, 0, 53, 0, 0, 0, 254, 0, 0, +0, 117, 0, 0, 0, 221, 0, 0, 0, 113, 0, 0, 0, 17, 0, 0, 0, 164, 0, 0, 0, 136, 0, 0, 0, 159, 0, 0, 0, 62, 0, 0, 0, 83, 0, 0, 0, 105, 0, 0, 0, 59, 0, 0, 0, 27, 0, 0, 0, 224, 0, 0, 0, 247, 0, 0, 0, 186, 0, 0, 0, 155, 0, 0, 0, 173, 0, 0, 0, 78, 0, 0, 0, 129, 0, 0, 0, 95, 0, 0, 0, 181, 0, 0, 0, 92, 0, 0, 0, 174, 0, 0, 0, 190, 0, 0, 0, 103, 0, 0, 0, 134, 0, 0, 0, 55, 0, 0, 0, 52, 0, 0, 0, 142, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 69, 0, 0, 0, 74, 0, 0, 0, 103, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 112, 0, 0, 0, 88, 0, 0, 0, 32, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 103, 0, 0, 0, 178, 0, 0, 0, 200, 0, 0, 0, 155, 0, 0, 0, 88, 0, 0, 0, 197, 0, 0, 0, 177, 0, 0, 0, 235, 0, 0, 0, 45, 0, 0, 0, 74, 0, 0, 0, 222, 0, 0, 0, 130, 0, 0, 0, 140, 0, 0, 0, +242, 0, 0, 0, 210, 0, 0, 0, 20, 0, 0, 0, 184, 0, 0, 0, 112, 0, 0, 0, 97, 0, 0, 0, 78, 0, 0, 0, 115, 0, 0, 0, 214, 0, 0, 0, 11, 0, 0, 0, 107, 0, 0, 0, 13, 0, 0, 0, 48, 0, 0, 0, 129, 0, 0, 0, 252, 0, 0, 0, 85, 0, 0, 0, 92, 0, 0, 0, 191, 0, 0, 0, 167, 0, 0, 0, 196, 0, 0, 0, 189, 0, 0, 0, 226, 0, 0, 0, 240, 0, 0, 0, 75, 0, 0, 0, 143, 0, 0, 0, 233, 0, 0, 0, 125, 0, 0, 0, 153, 0, 0, 0, 250, 0, 0, 0, 211, 0, 0, 0, 171, 0, 0, 0, 188, 0, 0, 0, 199, 0, 0, 0, 131, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 127, 0, 0, +0, 12, 0, 0, 0, 25, 0, 0, 0, 67, 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 0, 7, 0, 0, 0, 202, 0, 0, 0, 64, 0, 0, 0, 249, 0, 0, 0, 200, 0, 0, 0, 190, 0, 0, 0, 140, 0, 0, 0, 22, 0, 0, 0, 129, 0, 0, 0, 57, 0, 0, 0, 150, 0, 0, 0, 246, 0, 0, 0, 23, 0, 0, 0, 88, 0, 0, 0, 200, 0, 0, 0, 48, 0, 0, 0, 88, 0, 0, 0, 251, 0, 0, 0, 194, 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 0, 210, 0, 0, 0, 82, 0, 0, 0, 118, 0, 0, 0, 224, 0, 0, 0, 106, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 92, 0, 0, 0, 136, 0, 0, 0, 89, 0, 0, 0, 106, 0, 0, 0, 90, +0, 0, 0, 84, 0, 0, 0, 66, 0, 0, 0, 7, 0, 0, 0, 181, 0, 0, 0, 46, 0, 0, 0, 44, 0, 0, 0, 103, 0, 0, 0, 21, 0, 0, 0, 155, 0, 0, 0, 251, 0, 0, 0, 131, 0, 0, 0, 105, 0, 0, 0, 30, 0, 0, 0, 15, 0, 0, 0, 218, 0, 0, 0, 214, 0, 0, 0, 41, 0, 0, 0, 177, 0, 0, 0, 96, 0, 0, 0, 224, 0, 0, 0, 178, 0, 0, 0, 186, 0, 0, 0, 105, 0, 0, 0, 162, 0, 0, 0, 158, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 224, 0, 0, 0, 28, 0, 0, 0, 189, 0, 0, 0, 205, 0, 0, 0, 6, 0, 0, 0, 100, 0, 0, 0, 112, 0, 0, 0, 65, 0, 0, 0, 250, 0, 0, 0, 140, +0, 0, 0, 225, 0, 0, 0, 137, 0, 0, 0, 143, 0, 0, 0, 39, 0, 0, 0, 200, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, 0, 111, 0, 0, 0, 95, 0, 0, 0, 85, 0, 0, 0, 248, 0, 0, 0, 222, 0, 0, 0, 149, 0, 0, 0, 109, 0, 0, 0, 47, 0, 0, 0, 117, 0, 0, 0, 22, 0, 0, 0, 43, 0, 0, 0, 78, 0, 0, 0, 68, 0, 0, 0, 253, 0, 0, 0, 134, 0, 0, 0, 110, 0, 0, 0, 233, 0, 0, 0, 112, 0, 0, 0, 57, 0, 0, 0, 118, 0, 0, 0, 151, 0, 0, 0, 126, 0, 0, 0, 23, 0, 0, 0, 98, 0, 0, 0, 107, 0, 0, 0, 20, 0, 0, 0, 161, 0, 0, 0, 124, 0, 0, 0, 208, 0, 0, 0, 121, +0, 0, 0, 110, 0, 0, 0, 216, 0, 0, 0, 138, 0, 0, 0, 165, 0, 0, 0, 109, 0, 0, 0, 140, 0, 0, 0, 147, 0, 0, 0, 210, 0, 0, 0, 63, 0, 0, 0, 236, 0, 0, 0, 68, 0, 0, 0, 141, 0, 0, 0, 110, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 140, 0, 0, 0, 143, 0, 0, 0, 238, 0, 0, 0, 1, 0, 0, 0, 143, 0, 0, 0, 192, 0, 0, 0, 180, 0, 0, 0, 133, 0, 0, 0, 14, 0, 0, 0, 2, 0, 0, 0, 58, 0, 0, 0, 112, 0, 0, 0, 65, 0, 0, 0, 228, 0, 0, 0, 17, 0, 0, 0, 87, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 230, 0, 0, 0, 252, 0, 0, 0, 84, 0, 0, 0, 126, +0, 0, 0, 205, 0, 0, 0, 215, 0, 0, 0, 34, 0, 0, 0, 203, 0, 0, 0, 118, 0, 0, 0, 159, 0, 0, 0, 32, 0, 0, 0, 206, 0, 0, 0, 160, 0, 0, 0, 115, 0, 0, 0, 118, 0, 0, 0, 81, 0, 0, 0, 59, 0, 0, 0, 164, 0, 0, 0, 248, 0, 0, 0, 227, 0, 0, 0, 98, 0, 0, 0, 18, 0, 0, 0, 108, 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 111, 0, 0, 0, 72, 0, 0, 0, 127, 0, 0, 0, 58, 0, 0, 0, 1, 0, 0, 0, 237, 0, 0, 0, 197, 0, 0, 0, 150, 0, 0, 0, 176, 0, 0, 0, 31, 0, 0, 0, 79, 0, 0, 0, 168, 0, 0, 0, 2, 0, +0, 0, 98, 0, 0, 0, 39, 0, 0, 0, 138, 0, 0, 0, 80, 0, 0, 0, 141, 0, 0, 0, 154, 0, 0, 0, 139, 0, 0, 0, 82, 0, 0, 0, 15, 0, 0, 0, 30, 0, 0, 0, 207, 0, 0, 0, 65, 0, 0, 0, 56, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 108, 0, 0, 0, 212, 0, 0, 0, +47, 0, 0, 0, 15, 0, 0, 0, 105, 0, 0, 0, 15, 0, 0, 0, 135, 0, 0, 0, 63, 0, 0, 0, 97, 0, 0, 0, 101, 0, 0, 0, 30, 0, 0, 0, 53, 0, 0, 0, 52, 0, 0, 0, 133, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 172, 0, 0, 0, 37, 0, 0, 0, 61, 0, 0, 0, 226, 0, 0, 0, 98, 0, 0, 0, 241, 0, 0, 0, 204, 0, 0, 0, 233, 0, 0, 0, 27, 0, 0, 0, 194, 0, 0, 0, 239, 0, 0, 0, 106, 0, 0, 0, 66, 0, 0, 0, 87, 0, 0, 0, 52, 0, 0, 0, 31, 0, 0, 0, 46, 0, 0, 0, 172, 0, 0, 0, 209, 0, 0, 0, 199, 0, 0, 0, 4, 0, 0, 0, 82, 0, 0, 0, 50, 0, +0, 0, 102, 0, 0, 0, 178, 0, 0, 0, 51, 0, 0, 0, 115, 0, 0, 0, 33, 0, 0, 0, 52, 0, 0, 0, 84, 0, 0, 0, 247, 0, 0, 0, 113, 0, 0, 0, 237, 0, 0, 0, 6, 0, 0, 0, 176, 0, 0, 0, 255, 0, 0, 0, 166, 0, 0, 0, 89, 0, 0, 0, 111, 0, 0, 0, 138, 0, 0, 0, 78, 0, 0, 0, 251, 0, 0, 0, 2, 0, 0, 0, 176, 0, 0, 0, 69, 0, 0, 0, 107, 0, 0, 0, 245, 0, 0, 0, 72, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 197, 0, 0, 0, 34, 0, 0, 0, 125, 0, 0, 0, 128, 0, 0, 0, 8, 0, 0, 0, 83, 0, 0, 0, 254, 0, 0, 0, 50, 0, 0, 0, 177, 0, 0, 0, 161, 0, 0, +0, 138, 0, 0, 0, 116, 0, 0, 0, 111, 0, 0, 0, 189, 0, 0, 0, 63, 0, 0, 0, 133, 0, 0, 0, 244, 0, 0, 0, 207, 0, 0, 0, 245, 0, 0, 0, 96, 0, 0, 0, 175, 0, 0, 0, 65, 0, 0, 0, 126, 0, 0, 0, 62, 0, 0, 0, 70, 0, 0, 0, 163, 0, 0, 0, 90, 0, 0, 0, 32, 0, 0, 0, 170, 0, 0, 0, 53, 0, 0, 0, 135, 0, 0, 0, 68, 0, 0, 0, 99, 0, 0, 0, 102, 0, 0, 0, 151, 0, 0, 0, 248, 0, 0, 0, 110, 0, 0, 0, 85, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 62, 0, 0, 0, 53, 0, 0, 0, 80, 0, 0, 0, 191, 0, 0, 0, 147, 0, 0, 0, 105, 0, 0, 0, 210, 0, 0, +0, 139, 0, 0, 0, 5, 0, 0, 0, 85, 0, 0, 0, 153, 0, 0, 0, 190, 0, 0, 0, 226, 0, 0, 0, 83, 0, 0, 0, 97, 0, 0, 0, 236, 0, 0, 0, 232, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 50, 0, 0, 0, 179, 0, 0, 0, 16, 0, 0, 0, 69, 0, 0, 0, 2, 0, 0, 0, 105, 0, 0, 0, 89, 0, 0, 0, 46, 0, 0, 0, 151, 0, 0, 0, 217, 0, 0, 0, 100, 0, 0, 0, 248, 0, 0, 0, 219, 0, 0, 0, 37, 0, 0, 0, 128, 0, 0, 0, 220, 0, 0, 0, 196, 0, 0, 0, 213, 0, 0, 0, 98, 0, 0, 0, 60, 0, 0, 0, 237, 0, 0, 0, 101, 0, 0, 0, 145, 0, 0, 0, 173, 0, 0, 0, 209, 0, 0, 0, +87, 0, 0, 0, 129, 0, 0, 0, 148, 0, 0, 0, 170, 0, 0, 0, 161, 0, 0, 0, 41, 0, 0, 0, 252, 0, 0, 0, 104, 0, 0, 0, 221, 0, 0, 0, 181, 0, 0, 0, 125, 0, 0, 0, 171, 0, 0, 0, 90, 0, 0, 0, 33, 0, 0, 0, 65, 0, 0, 0, 83, 0, 0, 0, 187, 0, 0, 0, 23, 0, 0, 0, 121, 0, 0, 0, 13, 0, 0, 0, 209, 0, 0, 0, 168, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 32, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 233, 0, 0, 0, 132, 0, 0, 0, 232, 0, 0, 0, 37, 0, 0, 0, 17, 0, 0, 0, 103, 0, 0, 0, 122, 0, 0, 0, 139, 0, 0, 0, 26, 0, 0, 0, 228, 0, 0, 0, +93, 0, 0, 0, 225, 0, 0, 0, 93, 0, 0, 0, 55, 0, 0, 0, 234, 0, 0, 0, 254, 0, 0, 0, 101, 0, 0, 0, 59, 0, 0, 0, 37, 0, 0, 0, 232, 0, 0, 0, 225, 0, 0, 0, 194, 0, 0, 0, 197, 0, 0, 0, 2, 0, 0, 0, 164, 0, 0, 0, 190, 0, 0, 0, 152, 0, 0, 0, 10, 0, 0, 0, 43, 0, 0, 0, 97, 0, 0, 0, 193, 0, 0, 0, 155, 0, 0, 0, 226, 0, 0, 0, 213, 0, 0, 0, 146, 0, 0, 0, 230, 0, 0, 0, 158, 0, 0, 0, 125, 0, 0, 0, 31, 0, 0, 0, 202, 0, 0, 0, 67, 0, 0, 0, 136, 0, 0, 0, 139, 0, 0, 0, 44, 0, 0, 0, 89, 0, 0, 0, 224, 0, 0, 0, 181, 0, 0, +0, 0, 0, 0, 0, 29, 0, 0, 0, 42, 0, 0, 0, 111, 0, 0, 0, 175, 0, 0, 0, 121, 0, 0, 0, 134, 0, 0, 0, 47, 0, 0, 0, 166, 0, 0, 0, 90, 0, 0, 0, 147, 0, 0, 0, 209, 0, 0, 0, 254, 0, 0, 0, 174, 0, 0, 0, 58, 0, 0, 0, 238, 0, 0, 0, 219, 0, 0, 0, 124, 0, 0, 0, 97, 0, 0, 0, 190, 0, 0, 0, 124, 0, 0, 0, 1, 0, 0, 0, 249, 0, 0, 0, 254, 0, 0, 0, 82, 0, 0, 0, 220, 0, 0, 0, 216, 0, 0, 0, 82, 0, 0, 0, 163, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 175, 0, 0, 0, 19, 0, 0, 0, 55, 0, 0, 0, 189, 0, 0, 0, 55, 0, 0, 0, 113, 0, 0, 0, 172, 0, 0, 0, 4, 0, 0, 0, 70, 0, 0, 0, 99, 0, 0, 0, 172, 0, 0, 0, 164, 0, 0, 0, 119, 0, 0, 0, 237, 0, 0, 0, 37, 0, 0, 0, 56, 0, 0, 0, 224, 0, 0, 0, 21, 0, 0, 0, 168, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 206, 0, 0, 0, 81, 0, +0, 0, 1, 0, 0, 0, 169, 0, 0, 0, 188, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 4, 0, 0, 0, 137, 0, 0, 0, 249, 0, 0, 0, 128, 0, 0, 0, 7, 0, 0, 0, 207, 0, 0, 0, 63, 0, 0, 0, 179, 0, 0, 0, 233, 0, 0, 0, 231, 0, 0, 0, 69, 0, 0, 0, 68, 0, 0, 0, 61, 0, 0, 0, 42, 0, 0, 0, 124, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 22, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 101, 0, 0, 0, 28, 0, 0, 0, 199, 0, 0, 0, 125, 0, 0, 0, 198, 0, 0, 0, 122, 0, 0, 0, 251, 0, 0, 0, 67, 0, 0, 0, 238, 0, 0, 0, 37, 0, 0, 0, 118, 0, 0, 0, +70, 0, 0, 0, 114, 0, 0, 0, 2, 0, 0, 0, 162, 0, 0, 0, 237, 0, 0, 0, 244, 0, 0, 0, 143, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 62, 0, 0, 0, 235, 0, 0, 0, 53, 0, 0, 0, 26, 0, 0, 0, 213, 0, 0, 0, 126, 0, 0, 0, 219, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 138, 0, 0, 0, 160, 0, 0, 0, 180, 0, 0, 0, 207, 0, 0, 0, 96, 0, 0, 0, 75, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 249, 0, 0, 0, 45, 0, 0, 0, 191, 0, 0, 0, 136, 0, 0, 0, 189, 0, 0, 0, 34, 0, 0, 0, 98, 0, 0, 0, 19, 0, 0, 0, 83, 0, 0, 0, 228, 0, 0, 0, +130, 0, 0, 0, 87, 0, 0, 0, 250, 0, 0, 0, 30, 0, 0, 0, 143, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 144, 0, 0, 0, 186, 0, 0, 0, 8, 0, 0, 0, 182, 0, 0, 0, 16, 0, 0, 0, 84, 0, 0, 0, 79, 0, 0, 0, 124, 0, 0, 0, 27, 0, 0, 0, 38, 0, 0, 0, 237, 0, 0, 0, 218, 0, 0, 0, 107, 0, 0, 0, 221, 0, 0, 0, 37, 0, 0, 0, 208, 0, 0, 0, 78, 0, 0, 0, 234, 0, 0, 0, 66, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 3, 0, 0, 0, 81, 0, 0, 0, 22, 0, 0, 0, 80, 0, 0, 0, 124, 0, 0, 0, 213, 0, 0, 0, 93, 0, 0, 0, 246, 0, 0, 0, 153, 0, 0, 0, 232, +0, 0, 0, 119, 0, 0, 0, 114, 0, 0, 0, 78, 0, 0, 0, 250, 0, 0, 0, 98, 0, 0, 0, 203, 0, 0, 0, 118, 0, 0, 0, 117, 0, 0, 0, 12, 0, 0, 0, 226, 0, 0, 0, 113, 0, 0, 0, 152, 0, 0, 0, 146, 0, 0, 0, 213, 0, 0, 0, 250, 0, 0, 0, 69, 0, 0, 0, 223, 0, 0, 0, 92, 0, 0, 0, 111, 0, 0, 0, 30, 0, 0, 0, 158, 0, 0, 0, 40, 0, 0, 0, 105, 0, 0, 0, 13, 0, 0, 0, 172, 0, 0, 0, 102, 0, 0, 0, 109, 0, 0, 0, 195, 0, 0, 0, 139, 0, 0, 0, 186, 0, 0, 0, 22, 0, 0, 0, 181, 0, 0, 0, 226, 0, 0, 0, 160, 0, 0, 0, 13, 0, 0, 0, 12, 0, 0, 0, +189, 0, 0, 0, 164, 0, 0, 0, 142, 0, 0, 0, 24, 0, 0, 0, 108, 0, 0, 0, 242, 0, 0, 0, 220, 0, 0, 0, 249, 0, 0, 0, 220, 0, 0, 0, 74, 0, 0, 0, 134, 0, 0, 0, 37, 0, 0, 0, 149, 0, 0, 0, 20, 0, 0, 0, 203, 0, 0, 0, 216, 0, 0, 0, 26, 0, 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 151, 0, 0, 0, 165, 0, 0, 0, 219, 0, 0, 0, 139, 0, 0, 0, 45, 0, 0, 0, 170, 0, 0, 0, 66, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 242, 0, 0, 0, 147, 0, 0, 0, 187, 0, 0, 0, 217, 0, 0, 0, 6, 0, 0, 0, 132, 0, 0, 0, 78, 0, 0, 0, 17, 0, 0, 0, 168, 0, 0, 0, +160, 0, 0, 0, 37, 0, 0, 0, 43, 0, 0, 0, 166, 0, 0, 0, 95, 0, 0, 0, 174, 0, 0, 0, 196, 0, 0, 0, 180, 0, 0, 0, 76, 0, 0, 0, 200, 0, 0, 0, 171, 0, 0, 0, 199, 0, 0, 0, 59, 0, 0, 0, 2, 0, 0, 0, 238, 0, 0, 0, 201, 0, 0, 0, 41, 0, 0, 0, 15, 0, 0, 0, 223, 0, 0, 0, 17, 0, 0, 0, 133, 0, 0, 0, 237, 0, 0, 0, 206, 0, 0, 0, 13, 0, 0, 0, 98, 0, 0, 0, 44, 0, 0, 0, 143, 0, 0, 0, 75, 0, 0, 0, 249, 0, 0, 0, 4, 0, 0, 0, 233, 0, 0, 0, 6, 0, 0, 0, 114, 0, 0, 0, 29, 0, 0, 0, 55, 0, 0, 0, 32, 0, 0, 0, 80, 0, 0, 0, 201, +0, 0, 0, 20, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 57, 0, 0, 0, 167, 0, 0, 0, 151, 0, 0, 0, 43, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 209, 0, 0, 0, 57, 0, 0, 0, 189, 0, 0, 0, 251, 0, 0, 0, 51, 0, 0, 0, 190, 0, 0, 0, 196, 0, 0, 0, 240, 0, +0, 0, 92, 0, 0, 0, 239, 0, 0, 0, 240, 0, 0, 0, 86, 0, 0, 0, 104, 0, 0, 0, 252, 0, 0, 0, 151, 0, 0, 0, 71, 0, 0, 0, 200, 0, 0, 0, 114, 0, 0, 0, 182, 0, 0, 0, 83, 0, 0, 0, 164, 0, 0, 0, 10, 0, 0, 0, 152, 0, 0, 0, 165, 0, 0, 0, 180, 0, 0, 0, 55, 0, 0, 0, 113, 0, 0, 0, 207, 0, 0, 0, 102, 0, 0, 0, 80, 0, 0, 0, 109, 0, 0, 0, 23, 0, 0, 0, 164, 0, 0, 0, 25, 0, 0, 0, 82, 0, 0, 0, 17, 0, 0, 0, 71, 0, 0, 0, 179, 0, 0, 0, 92, 0, 0, 0, 91, 0, 0, 0, 169, 0, 0, 0, 46, 0, 0, 0, 34, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, +0, 82, 0, 0, 0, 249, 0, 0, 0, 87, 0, 0, 0, 24, 0, 0, 0, 184, 0, 0, 0, 190, 0, 0, 0, 90, 0, 0, 0, 227, 0, 0, 0, 171, 0, 0, 0, 131, 0, 0, 0, 200, 0, 0, 0, 135, 0, 0, 0, 10, 0, 0, 0, 42, 0, 0, 0, 216, 0, 0, 0, 140, 0, 0, 0, 187, 0, 0, 0, 84, 0, 0, 0, 169, 0, 0, 0, 98, 0, 0, 0, 147, 0, 0, 0, 133, 0, 0, 0, 190, 0, 0, 0, 232, 0, 0, 0, 115, 0, 0, 0, 74, 0, 0, 0, 14, 0, 0, 0, 176, 0, 0, 0, 181, 0, 0, 0, 45, 0, 0, 0, 148, 0, 0, 0, 80, 0, 0, 0, 170, 0, 0, 0, 211, 0, 0, 0, 178, 0, 0, 0, 234, 0, 0, 0, 157, 0, +0, 0, 98, 0, 0, 0]).concat([118, 0, 0, 0, 59, 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 0, 78, 0, 0, 0, 45, 0, 0, 0, 112, 0, 0, 0, 200, 0, 0, 0, 154, 0, 0, 0, 21, 0, 0, 0, 102, 0, 0, 0, 107, 0, 0, 0, 197, 0, 0, 0, 150, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 34, 0, 0, 0, 26, 0, 0, 0, 238, 0, 0, 0, 95, 0, 0, 0, 231, 0, 0, 0, 49, 0, 0, 0, 96, 0, 0, 0, 34, 0, 0, 0, 131, 0, 0, 0, 8, 0, 0, 0, 99, 0, 0, 0, 206, 0, 0, 0, 185, 0, 0, 0, 50, 0, 0, 0, 68, 0, 0, 0, 88, 0, 0, 0, 93, 0, 0, 0, 58, 0, 0, 0, 155, 0, 0, 0, 228, +0, 0, 0, 4, 0, 0, 0, 213, 0, 0, 0, 239, 0, 0, 0, 56, 0, 0, 0, 239, 0, 0, 0, 75, 0, 0, 0, 221, 0, 0, 0, 25, 0, 0, 0, 77, 0, 0, 0, 194, 0, 0, 0, 23, 0, 0, 0, 117, 0, 0, 0, 161, 0, 0, 0, 104, 0, 0, 0, 205, 0, 0, 0, 195, 0, 0, 0, 198, 0, 0, 0, 3, 0, 0, 0, 68, 0, 0, 0, 227, 0, 0, 0, 120, 0, 0, 0, 9, 0, 0, 0, 145, 0, 0, 0, 71, 0, 0, 0, 63, 0, 0, 0, 15, 0, 0, 0, 228, 0, 0, 0, 146, 0, 0, 0, 88, 0, 0, 0, 250, 0, 0, 0, 125, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 148, 0, 0, 0, 88, 0, 0, 0, 94, 0, 0, 0, 188, 0, +0, 0, 25, 0, 0, 0, 2, 0, 0, 0, 111, 0, 0, 0, 32, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 145, 0, 0, 0, 84, 0, 0, 0, 167, 0, 0, 0, 243, 0, 0, 0, 32, 0, 0, 0, 75, 0, 0, 0, 52, 0, 0, 0, 6, 0, 0, 0, 250, 0, 0, 0, 48, 0, 0, 0, 200, 0, 0, 0, 111, 0, 0, 0, 20, 0, 0, 0, 16, 0, 0, 0, 101, 0, 0, 0, 116, 0, 0, 0, 19, 0, 0, 0, 78, 0, 0, 0, 240, 0, 0, 0, 105, 0, 0, 0, 38, 0, 0, 0, 206, 0, 0, 0, 207, 0, 0, 0, 144, 0, 0, 0, 244, 0, 0, 0, 208, 0, 0, 0, 197, 0, 0, 0, 200, 0, 0, 0, 100, 0, 0, 0, 38, 0, 0, 0, 162, 0, +0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 114, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 78, 0, 0, 0, 45, 0, 0, 0, 147, 0, 0, 0, 213, 0, 0, 0, 8, 0, 0, 0, 231, 0, 0, 0, 174, 0, 0, 0, 56, 0, 0, 0, 247, 0, 0, 0, 24, 0, 0, 0, 165, 0, 0, 0, 50, 0, 0, 0, 52, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 166, 0, 0, 0, 236, 0, 0, 0, 185, 0, 0, 0, 97, 0, 0, 0, 123, 0, 0, 0, 100, 0, 0, 0, 153, 0, 0, 0, 172, 0, 0, 0, 113, 0, 0, 0, 37, 0, 0, 0, 207, 0, 0, 0, 116, 0, 0, 0, 85, 0, 0, 0, 27, 0, 0, 0, 170, 0, 0, 0, 169, 0, +0, 0, 56, 0, 0, 0, 65, 0, 0, 0, 64, 0, 0, 0, 213, 0, 0, 0, 149, 0, 0, 0, 149, 0, 0, 0, 171, 0, 0, 0, 28, 0, 0, 0, 94, 0, 0, 0, 188, 0, 0, 0, 65, 0, 0, 0, 126, 0, 0, 0, 20, 0, 0, 0, 48, 0, 0, 0, 190, 0, 0, 0, 19, 0, 0, 0, 137, 0, 0, 0, 244, 0, 0, 0, 229, 0, 0, 0, 235, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 194, 0, 0, 0, 150, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 119, 0, 0, 0, 69, 0, 0, 0, 236, 0, 0, 0, 103, 0, 0, 0, 118, 0, 0, 0, 50, 0, 0, 0, 76, 0, 0, 0, 185, 0, 0, 0, 223, 0, 0, 0, 37, 0, 0, 0, 50, 0, 0, 0, 107, 0, 0, 0, 203, 0, 0, 0, 231, 0, 0, 0, 20, 0, 0, 0, 97, 0, 0, 0, 67, 0, 0, 0, 238, 0, 0, 0, 186, 0, 0, 0, 155, 0, 0, 0, 113, 0, 0, 0, 239, 0, 0, 0, 210, 0, 0, 0, 72, 0, 0, 0, 101, 0, 0, 0, 187, 0, 0, 0, 27, 0, 0, 0, 138, 0, 0, +0, 19, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 132, 0, 0, 0, 173, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 0, 186, 0, 0, 0, 208, 0, 0, 0, 152, 0, 0, 0, 89, 0, 0, 0, 191, 0, 0, 0, 55, 0, 0, 0, 176, 0, 0, 0, 79, 0, 0, 0, 151, 0, 0, 0, 96, 0, 0, 0, 32, 0, 0, 0, 179, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 246, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 164, 0, 0, 0, 255, 0, 0, 0, 251, 0, 0, 0, 183, 0, 0, 0, 250, 0, 0, 0, 149, 0, 0, 0, 178, 0, 0, 0, 81, 0, 0, 0, 121, 0, 0, 0, 40, 0, 0, 0, 92, 0, 0, +0, 63, 0, 0, 0, 219, 0, 0, 0, 107, 0, 0, 0, 24, 0, 0, 0, 59, 0, 0, 0, 92, 0, 0, 0, 209, 0, 0, 0, 4, 0, 0, 0, 40, 0, 0, 0, 222, 0, 0, 0, 133, 0, 0, 0, 82, 0, 0, 0, 49, 0, 0, 0, 181, 0, 0, 0, 187, 0, 0, 0, 246, 0, 0, 0, 169, 0, 0, 0, 237, 0, 0, 0, 190, 0, 0, 0, 40, 0, 0, 0, 79, 0, 0, 0, 179, 0, 0, 0, 126, 0, 0, 0, 5, 0, 0, 0, 106, 0, 0, 0, 219, 0, 0, 0, 149, 0, 0, 0, 13, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 213, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 154, 0, 0, 0, 10, 0, 0, 0, 208, 0, 0, 0, 49, 0, 0, 0, +62, 0, 0, 0, 7, 0, 0, 0, 54, 0, 0, 0, 142, 0, 0, 0, 192, 0, 0, 0, 138, 0, 0, 0, 98, 0, 0, 0, 177, 0, 0, 0, 202, 0, 0, 0, 214, 0, 0, 0, 14, 0, 0, 0, 30, 0, 0, 0, 157, 0, 0, 0, 239, 0, 0, 0, 171, 0, 0, 0, 152, 0, 0, 0, 77, 0, 0, 0, 187, 0, 0, 0, 108, 0, 0, 0, 5, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 93, 0, 0, 0, 189, 0, 0, 0, 87, 0, 0, 0, 204, 0, 0, 0, 33, 0, 0, 0, 39, 0, 0, 0, 206, 0, 0, 0, 253, 0, 0, 0, 169, 0, 0, 0, 148, 0, 0, 0, 142, 0, 0, 0, 225, 0, 0, 0, 171, 0, 0, 0, 73, 0, 0, 0, 224, 0, 0, 0, +70, 0, 0, 0, 38, 0, 0, 0, 161, 0, 0, 0, 168, 0, 0, 0, 140, 0, 0, 0, 161, 0, 0, 0, 153, 0, 0, 0, 29, 0, 0, 0, 180, 0, 0, 0, 39, 0, 0, 0, 109, 0, 0, 0, 45, 0, 0, 0, 200, 0, 0, 0, 57, 0, 0, 0, 48, 0, 0, 0, 94, 0, 0, 0, 55, 0, 0, 0, 82, 0, 0, 0, 196, 0, 0, 0, 110, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 244, 0, 0, 0, 231, 0, 0, 0, 176, 0, 0, 0, 21, 0, 0, 0, 51, 0, 0, 0, 132, 0, 0, 0, 27, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 2, 0, 0, 0, 217, 0, 0, 0, 59, 0, 0, 0, 173, 0, 0, 0, 15, 0, 0, 0, 67, 0, 0, 0, 108, +0, 0, 0, 234, 0, 0, 0, 62, 0, 0, 0, 15, 0, 0, 0, 126, 0, 0, 0, 218, 0, 0, 0, 221, 0, 0, 0, 107, 0, 0, 0, 76, 0, 0, 0, 127, 0, 0, 0, 110, 0, 0, 0, 212, 0, 0, 0, 107, 0, 0, 0, 191, 0, 0, 0, 15, 0, 0, 0, 71, 0, 0, 0, 159, 0, 0, 0, 124, 0, 0, 0, 86, 0, 0, 0, 124, 0, 0, 0, 67, 0, 0, 0, 145, 0, 0, 0, 28, 0, 0, 0, 187, 0, 0, 0, 78, 0, 0, 0, 114, 0, 0, 0, 62, 0, 0, 0, 100, 0, 0, 0, 171, 0, 0, 0, 160, 0, 0, 0, 160, 0, 0, 0, 223, 0, 0, 0, 180, 0, 0, 0, 216, 0, 0, 0, 135, 0, 0, 0, 58, 0, 0, 0, 189, 0, 0, 0, +168, 0, 0, 0, 72, 0, 0, 0, 201, 0, 0, 0, 184, 0, 0, 0, 239, 0, 0, 0, 46, 0, 0, 0, 173, 0, 0, 0, 111, 0, 0, 0, 132, 0, 0, 0, 79, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 240, 0, 0, 0, 27, 0, 0, 0, 126, 0, 0, 0, 42, 0, 0, 0, 108, 0, 0, 0, 248, 0, 0, 0, 169, 0, 0, 0, 106, 0, 0, 0, 225, 0, 0, 0, 240, 0, 0, 0, 153, 0, 0, 0, 161, 0, 0, 0, 103, 0, 0, 0, 154, 0, 0, 0, 212, 0, 0, 0, 19, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 186, 0, 0, 0, 39, 0, 0, 0, 146, 0, 0, 0, 170, 0, 0, 0, 161, 0, 0, 0, 93, 0, 0, 0, 80, 0, +0, 0, 222, 0, 0, 0, 204, 0, 0, 0, 64, 0, 0, 0, 38, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 62, 0, 0, 0, 242, 0, 0, 0, 178, 0, 0, 0, 144, 0, 0, 0, 206, 0, 0, 0, 219, 0, 0, 0, 100, 0, 0, 0, 62, 0, 0, 0, 3, 0, 0, 0, 221, 0, 0, 0, 55, 0, 0, 0, +54, 0, 0, 0, 84, 0, 0, 0, 112, 0, 0, 0, 118, 0, 0, 0, 36, 0, 0, 0, 181, 0, 0, 0, 105, 0, 0, 0, 3, 0, 0, 0, 252, 0, 0, 0, 160, 0, 0, 0, 43, 0, 0, 0, 116, 0, 0, 0, 178, 0, 0, 0, 5, 0, 0, 0, 14, 0, 0, 0, 204, 0, 0, 0, 216, 0, 0, 0, 31, 0, 0, 0, 106, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 105, 0, 0, 0, 88, 0, 0, 0, 134, 0, 0, 0, 160, 0, 0, 0, 49, 0, 0, 0, 189, 0, 0, 0, 50, 0, 0, 0, 233, 0, 0, 0, 44, 0, 0, 0, 92, 0, 0, 0, 210, 0, 0, 0, 133, 0, 0, 0, 186, 0, 0, 0, 64, 0, 0, 0, 100, +0, 0, 0, 168, 0, 0, 0, 116, 0, 0, 0, 248, 0, 0, 0, 14, 0, 0, 0, 28, 0, 0, 0, 179, 0, 0, 0, 169, 0, 0, 0, 105, 0, 0, 0, 232, 0, 0, 0, 30, 0, 0, 0, 64, 0, 0, 0, 100, 0, 0, 0, 153, 0, 0, 0, 119, 0, 0, 0, 108, 0, 0, 0, 50, 0, 0, 0, 79, 0, 0, 0, 253, 0, 0, 0, 187, 0, 0, 0, 92, 0, 0, 0, 187, 0, 0, 0, 141, 0, 0, 0, 100, 0, 0, 0, 102, 0, 0, 0, 74, 0, 0, 0, 113, 0, 0, 0, 31, 0, 0, 0, 121, 0, 0, 0, 163, 0, 0, 0, 173, 0, 0, 0, 141, 0, 0, 0, 249, 0, 0, 0, 212, 0, 0, 0, 236, 0, 0, 0, 207, 0, 0, 0, 103, 0, 0, +0, 112, 0, 0, 0, 250, 0, 0, 0, 5, 0, 0, 0, 74, 0, 0, 0, 15, 0, 0, 0, 110, 0, 0, 0, 175, 0, 0, 0, 135, 0, 0, 0, 10, 0, 0, 0, 111, 0, 0, 0, 198, 0, 0, 0, 54, 0, 0, 0, 110, 0, 0, 0, 108, 0, 0, 0, 140, 0, 0, 0, 36, 0, 0, 0, 9, 0, 0, 0, 96, 0, 0, 0, 190, 0, 0, 0, 38, 0, 0, 0, 210, 0, 0, 0, 76, 0, 0, 0, 94, 0, 0, 0, 23, 0, 0, 0, 202, 0, 0, 0, 95, 0, 0, 0, 29, 0, 0, 0, 204, 0, 0, 0, 135, 0, 0, 0, 232, 0, 0, 0, 66, 0, 0, 0, 106, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 125, 0, 0, 0, 146, 0, 0, 0, 5, 0, 0, 0, +53, 0, 0, 0, 129, 0, 0, 0, 19, 0, 0, 0, 96, 0, 0, 0, 107, 0, 0, 0, 244, 0, 0, 0, 21, 0, 0, 0, 205, 0, 0, 0, 15, 0, 0, 0, 10, 0, 0, 0, 175, 0, 0, 0, 78, 0, 0, 0, 107, 0, 0, 0, 81, 0, 0, 0, 253, 0, 0, 0, 20, 0, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 19, 0, 0, 0, 134, 0, 0, 0, 116, 0, 0, 0, 68, 0, 0, 0, 203, 0, 0, 0, 102, 0, 0, 0, 107, 0, 0, 0, 182, 0, 0, 0, 157, 0, 0, 0, 116, 0, 0, 0, 86, 0, 0, 0, 50, 0, 0, 0, 172, 0, 0, 0, 141, 0, 0, 0, 142, 0, 0, 0, 140, 0, 0, 0, 140, 0, 0, 0, 140, 0, 0, 0, 57, 0, 0, 0, +202, 0, 0, 0, 89, 0, 0, 0, 116, 0, 0, 0, 26, 0, 0, 0, 17, 0, 0, 0, 239, 0, 0, 0, 109, 0, 0, 0, 247, 0, 0, 0, 57, 0, 0, 0, 92, 0, 0, 0, 59, 0, 0, 0, 31, 0, 0, 0, 250, 0, 0, 0, 227, 0, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0, 158, 0, 0, 0, 246, 0, 0, 0, 209, 0, 0, 0, 33, 0, 0, 0, 162, 0, 0, 0, 191, 0, 0, 0, 173, 0, 0, 0, 101, 0, 0, 0, 66, 0, 0, 0, 107, 0, 0, 0, 89, 0, 0, 0, 138, 0, 0, 0, 232, 0, 0, 0, 197, 0, 0, 0, 127, 0, 0, 0, 100, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 132, 0, 0, 0, 74, 0, 0, 0, +19, 0, 0, 0, 195, 0, 0, 0, 246, 0, 0, 0, 176, 0, 0, 0, 110, 0, 0, 0, 154, 0, 0, 0, 107, 0, 0, 0, 83, 0, 0, 0, 107, 0, 0, 0, 50, 0, 0, 0, 218, 0, 0, 0, 217, 0, 0, 0, 116, 0, 0, 0, 117, 0, 0, 0, 196, 0, 0, 0, 186, 0, 0, 0, 100, 0, 0, 0, 61, 0, 0, 0, 59, 0, 0, 0, 8, 0, 0, 0, 221, 0, 0, 0, 16, 0, 0, 0, 70, 0, 0, 0, 239, 0, 0, 0, 199, 0, 0, 0, 144, 0, 0, 0, 31, 0, 0, 0, 123, 0, 0, 0, 47, 0, 0, 0, 58, 0, 0, 0, 206, 0, 0, 0, 200, 0, 0, 0, 161, 0, 0, 0, 121, 0, 0, 0, 60, 0, 0, 0, 48, 0, 0, 0, 18, 0, 0, 0, +68, 0, 0, 0, 40, 0, 0, 0, 246, 0, 0, 0, 188, 0, 0, 0, 255, 0, 0, 0, 253, 0, 0, 0, 244, 0, 0, 0, 192, 0, 0, 0, 151, 0, 0, 0, 176, 0, 0, 0, 204, 0, 0, 0, 195, 0, 0, 0, 19, 0, 0, 0, 122, 0, 0, 0, 185, 0, 0, 0, 154, 0, 0, 0, 22, 0, 0, 0, 228, 0, 0, 0, 203, 0, 0, 0, 76, 0, 0, 0, 52, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 78, 0, 0, 0, 211, 0, 0, 0, 45, 0, 0, 0, 9, 0, 0, 0, 51, 0, 0, 0, 14, 0, 0, 0, 210, 0, 0, 0, 13, 0, 0, 0, 190, 0, 0, 0, 62, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 170, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 232, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 122, 0, 0, 0, 141, 0, 0, 0, 52, 0, 0, 0, 40, 0, 0, 0, 169, 0, 0, 0, 129, 0, 0, 0, 148, 0, 0, 0, 197, 0, 0, 0, 231, 0, 0, 0, 66, 0, 0, 0, 172, 0, 0, 0, 71, 0, 0, 0, 36, +0, 0, 0, 137, 0, 0, 0, 122, 0, 0, 0, 143, 0, 0, 0, 181, 0, 0, 0, 155, 0, 0, 0, 240, 0, 0, 0, 194, 0, 0, 0, 3, 0, 0, 0, 100, 0, 0, 0, 208, 0, 0, 0, 30, 0, 0, 0, 245, 0, 0, 0, 164, 0, 0, 0, 178, 0, 0, 0, 243, 0, 0, 0, 116, 0, 0, 0, 233, 0, 0, 0, 26, 0, 0, 0, 22, 0, 0, 0, 253, 0, 0, 0, 203, 0, 0, 0, 21, 0, 0, 0, 234, 0, 0, 0, 235, 0, 0, 0, 16, 0, 0, 0, 108, 0, 0, 0, 53, 0, 0, 0, 209, 0, 0, 0, 193, 0, 0, 0, 166, 0, 0, 0, 40, 0, 0, 0, 204, 0, 0, 0, 213, 0, 0, 0, 57, 0, 0, 0, 252, 0, 0, 0, 165, 0, 0, 0, +164, 0, 0, 0, 173, 0, 0, 0, 50, 0, 0, 0, 21, 0, 0, 0, 206, 0, 0, 0, 25, 0, 0, 0, 232, 0, 0, 0, 52, 0, 0, 0, 43, 0, 0, 0, 28, 0, 0, 0, 96, 0, 0, 0, 145, 0, 0, 0, 252, 0, 0, 0, 5, 0, 0, 0, 169, 0, 0, 0, 179, 0, 0, 0, 220, 0, 0, 0, 128, 0, 0, 0, 41, 0, 0, 0, 196, 0, 0, 0, 32, 0, 0, 0, 121, 0, 0, 0, 6, 0, 0, 0, 57, 0, 0, 0, 192, 0, 0, 0, 226, 0, 0, 0, 34, 0, 0, 0, 187, 0, 0, 0, 168, 0, 0, 0, 225, 0, 0, 0, 137, 0, 0, 0, 112, 0, 0, 0, 87, 0, 0, 0, 24, 0, 0, 0, 84, 0, 0, 0, 60, 0, 0, 0, 246, 0, 0, 0, 13, +0, 0, 0, 130, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 135, 0, 0, 0, 150, 0, 0, 0, 6, 0, 0, 0, 57, 0, 0, 0, 227, 0, 0, 0, 248, 0, 0, 0, 179, 0, 0, 0, 149, 0, 0, 0, 229, 0, 0, 0, 215, 0, 0, 0, 38, 0, 0, 0, 191, 0, 0, 0, 9, 0, 0, 0, 90, 0, 0, 0, 148, 0, 0, 0, 249, 0, 0, 0, 28, 0, 0, 0, 99, 0, 0, 0, 43, 0, 0, 0, 140, 0, 0, 0, 45, 0, 0, 0, 154, 0, 0, 0, 139, 0, 0, 0, 132, 0, 0, 0, 242, 0, 0, 0, 86, 0, 0, 0, 251, 0, 0, 0, 173, 0, 0, 0, 46, 0, 0, 0, 127, 0, 0, 0, 183, 0, 0, 0, 252, 0, 0, 0, 48, 0, 0, 0, 225, +0, 0, 0, 53, 0, 0, 0, 137, 0, 0, 0, 186, 0, 0, 0, 77, 0, 0, 0, 168, 0, 0, 0, 109, 0, 0, 0, 206, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 48, 0, 0, 0, 224, 0, 0, 0, 218, 0, 0, 0, 41, 0, 0, 0, 24, 0, 0, 0, 17, 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 166, 0, 0, 0, 90, 0, 0, 0, 101, 0, 0, 0, 147, 0, 0, 0, 195, 0, 0, 0, 181, 0, 0, 0, 49, 0, 0, 0, 34, 0, 0, 0, 79, 0, 0, 0, 243, 0, 0, 0, 246, 0, 0, 0, 15, 0, 0, 0, 235, 0, 0, 0, 40, 0, 0, 0, 195, 0, 0, 0, 124, 0, 0, 0, 235, 0, 0, 0, 206, 0, 0, 0, 134, 0, 0, 0, 236, +0, 0, 0, 103, 0, 0, 0, 118, 0, 0, 0, 110, 0, 0, 0, 53, 0, 0, 0, 69, 0, 0, 0, 123, 0, 0, 0, 216, 0, 0, 0, 107, 0, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 0, 61, 0, 0, 0, 213, 0, 0, 0, 154, 0, 0, 0, 100, 0, 0, 0, 115, 0, 0, 0, 54, 0, 0, 0, 177, 0, 0, 0, 214, 0, 0, 0, 134, 0, 0, 0, 152, 0, 0, 0, 66, 0, 0, 0, 63, 0, 0, 0, 138, 0, 0, 0, 241, 0, 0, 0, 199, 0, 0, 0, 245, 0, 0, 0, 66, 0, 0, 0, 168, 0, 0, 0, 156, 0, 0, 0, 82, 0, 0, 0, 168, 0, 0, 0, 220, 0, 0, 0, 249, 0, 0, 0, 36, 0, 0, 0, 63, 0, 0, 0, +74, 0, 0, 0, 161, 0, 0, 0, 164, 0, 0, 0, 91, 0, 0, 0, 232, 0, 0, 0, 98, 0, 0, 0, 26, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 200, 0, 0, 0, 20, 0, 0, 0, 213, 0, 0, 0, 13, 0, 0, 0, 235, 0, 0, 0, 225, 0, 0, 0, 165, 0, 0, 0, 230, 0, 0, 0, 131, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 85, 0, 0, 0, 131, 0, 0, 0, 81, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 185, 0, 0, 0, 203, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 229, 0, 0, 0, 161, 0, 0, 0, 217, 0, 0, 0, 23, 0, 0, 0, +109, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 233, 0, 0, 0, 225, 0, 0, 0, 82, 0, 0, 0, 63, 0, 0, 0, 81, 0, 0, 0, 25, 0, 0, 0, 13, 0, 0, 0, 221, 0, 0, 0, 217, 0, 0, 0, 157, 0, 0, 0, 147, 0, 0, 0, 49, 0, 0, 0, 135, +0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 213, 0, 0, 0, 131, 0, 0, 0, 235, 0, 0, 0, 146, 0, 0, 0, 9, 0, 0, 0, 118, 0, 0, 0, 110, 0, 0, 0, 227, 0, 0, 0, 248, 0, 0, 0, 192, 0, 0, 0, 162, 0, 0, 0, 102, 0, 0, 0, 181, 0, 0, 0, 54, 0, 0, 0, 58, 0, 0, 0, 187, 0, 0, 0, 57, 0, 0, 0, 237, 0, 0, 0, 50, 0, 0, 0, 2, 0, 0, 0, 231, 0, 0, 0, 67, 0, 0, 0, 122, 0, 0, 0, 56, 0, 0, 0, 20, 0, 0, 0, 132, 0, 0, 0, 227, 0, 0, 0, 68, 0, 0, 0, 210, 0, 0, 0, 94, 0, 0, 0, 148, 0, 0, 0, 221, 0, 0, 0, 120, 0, 0, 0, 137, 0, 0, 0, 85, +0, 0, 0, 76, 0, 0, 0, 115, 0, 0, 0, 158, 0, 0, 0, 225, 0, 0, 0, 228, 0, 0, 0, 62, 0, 0, 0, 67, 0, 0, 0, 208, 0, 0, 0, 74, 0, 0, 0, 222, 0, 0, 0, 27, 0, 0, 0, 178, 0, 0, 0, 231, 0, 0, 0, 143, 0, 0, 0, 227, 0, 0, 0, 163, 0, 0, 0, 197, 0, 0, 0, 203, 0, 0, 0, 114, 0, 0, 0, 238, 0, 0, 0, 121, 0, 0, 0, 65, 0, 0, 0, 248, 0, 0, 0, 223, 0, 0, 0, 238, 0, 0, 0, 101, 0, 0, 0, 197, 0, 0, 0, 69, 0, 0, 0, 119, 0, 0, 0, 39, 0, 0, 0, 60, 0, 0, 0, 189, 0, 0, 0, 88, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 226, 0, 0, 0, +4, 0, 0, 0, 75, 0, 0, 0, 187, 0, 0, 0, 101, 0, 0, 0, 243, 0, 0, 0, 200, 0, 0, 0, 15, 0, 0, 0, 36, 0, 0, 0, 123, 0, 0, 0, 147, 0, 0, 0, 52, 0, 0, 0, 181, 0, 0, 0, 226, 0, 0, 0, 116, 0, 0, 0, 72, 0, 0, 0, 205, 0, 0, 0, 160, 0, 0, 0, 11, 0, 0, 0, 146, 0, 0, 0, 151, 0, 0, 0, 102, 0, 0, 0, 57, 0, 0, 0, 244, 0, 0, 0, 176, 0, 0, 0, 226, 0, 0, 0, 93, 0, 0, 0, 57, 0, 0, 0, 106, 0, 0, 0, 91, 0, 0, 0, 69, 0, 0, 0, 23, 0, 0, 0, 120, 0, 0, 0, 30, 0, 0, 0, 219, 0, 0, 0, 145, 0, 0, 0, 129, 0, 0, 0, 28, 0, 0, 0, +249, 0, 0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 223, 0, 0, 0, 209, 0, 0, 0, 90, 0, 0, 0, 213, 0, 0, 0, 233, 0, 0, 0, 78, 0, 0, 0, 88, 0, 0, 0, 149, 0, 0, 0, 147, 0, 0, 0, 95, 0, 0, 0, 81, 0, 0, 0, 9, 0, 0, 0, 195, 0, 0, 0, 42, 0, 0, 0, 201, 0, 0, 0, 212, 0, 0, 0, 85, 0, 0, 0, 72, 0, 0, 0, 121, 0, 0, 0, 164, 0, 0, 0, 163, 0, 0, 0, 178, 0, 0, 0, 195, 0, 0, 0, 98, 0, 0, 0, 170, 0, 0, 0, 140, 0, 0, 0, 232, 0, 0, 0, 173, 0, 0, 0, 71, 0, 0, 0, 57, 0, 0, 0, 27, 0, 0, 0, 70, 0, 0, 0, 218, 0, 0, 0, 158, 0, 0, 0, +81, 0, 0, 0, 58, 0, 0, 0, 230, 0, 0, 0, 209, 0, 0, 0, 166, 0, 0, 0, 187, 0, 0, 0, 77, 0, 0, 0, 123, 0, 0, 0, 8, 0, 0, 0, 190, 0, 0, 0, 140, 0, 0, 0, 213, 0, 0, 0, 243, 0, 0, 0, 63, 0, 0, 0, 253, 0, 0, 0, 247, 0, 0, 0, 68, 0, 0, 0, 128, 0, 0, 0, 45, 0, 0, 0, 83, 0, 0, 0, 75, 0, 0, 0, 208, 0, 0, 0, 135, 0, 0, 0, 104, 0, 0, 0, 193, 0, 0, 0, 181, 0, 0, 0, 216, 0, 0, 0, 247, 0, 0, 0, 7, 0, 0, 0, 244, 0, 0, 0, 16, 0, 0, 0, 70, 0, 0, 0, 190, 0, 0, 0, 183, 0, 0, 0, 210, 0, 0, 0, 209, 0, 0, 0, 206, 0, 0, +0, 94, 0, 0, 0, 118, 0, 0, 0, 162, 0, 0, 0, 215, 0, 0, 0, 3, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 129, 0, 0, 0, 90, 0, 0, 0, 246, 0, 0, 0, 60, 0, 0, 0, 222, 0, 0, 0, 174, 0, 0, 0, 122, 0, 0, 0, 157, 0, 0, 0, 33, 0, 0, 0, 52, 0, 0, 0, 165, 0, 0, 0, 246, 0, 0, 0, 169, 0, 0, 0, 115, 0, 0, 0, 226, 0, 0, 0, 141, 0, 0, 0, 96, 0, 0, 0, 250, 0, 0, 0, 68, 0, 0, 0, 113, 0, 0, 0, 246, 0, 0, 0, 65, 0, 0, 0, 216, 0, 0, 0, 198, 0, 0, 0, 88, 0, 0, 0, 19, 0, 0, 0, 55, 0, 0, 0, 235, 0, 0, 0, 132, 0, 0, 0, 15, 0, +0, 0, 150, 0, 0, 0, 199, 0, 0, 0, 220, 0, 0, 0, 200, 0, 0, 0, 169, 0, 0, 0, 122, 0, 0, 0, 131, 0, 0, 0, 178, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 177, 0, 0, 0, 26, 0, 0, 0, 216, 0, 0, 0, 152, 0, 0, 0, 63, 0, 0, 0, 17, 0, 0, 0, 208, 0, 0, 0, 49, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 213, 0, 0, 0, 52, 0, 0, 0, 22, 0, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 147, 0, 0, 0, 234, 0, 0, 0, 82, 0, 0, 0, 148, 0, 0, 0, 236, 0, 0, 0, 147, 0, 0, 0, 183, 0, 0, 0, 129, 0, 0, 0, 17, 0, 0, 0, 45, 0, 0, 0, 88, 0, 0, 0, 249, 0, 0, 0, 181, 0, 0, 0, 10, 0, 0, 0, 170, 0, 0, 0, 79, 0, 0, 0, 246, 0, 0, 0, 46, 0, 0, 0, 63, 0, 0, 0, 54, 0, 0, 0, 191, 0, 0, 0, 51, 0, 0, 0, 90, 0, 0, 0, 231, 0, 0, 0, 209, 0, 0, 0, 8, 0, 0, 0, 26, 0, 0, 0, 207, 0, 0, 0, 66, 0, 0, 0, +174, 0, 0, 0, 204, 0, 0, 0, 181, 0, 0, 0, 119, 0, 0, 0, 57, 0, 0, 0, 196, 0, 0, 0, 91, 0, 0, 0, 91, 0, 0, 0, 208, 0, 0, 0, 38, 0, 0, 0, 89, 0, 0, 0, 39, 0, 0, 0, 208, 0, 0, 0, 85, 0, 0, 0, 113, 0, 0, 0, 18, 0, 0, 0, 157, 0, 0, 0, 136, 0, 0, 0, 61, 0, 0, 0, 156, 0, 0, 0, 234, 0, 0, 0, 65, 0, 0, 0, 106, 0, 0, 0, 240, 0, 0, 0, 80, 0, 0, 0, 147, 0, 0, 0, 147, 0, 0, 0, 221, 0, 0, 0, 71, 0, 0, 0, 111, 0, 0, 0, 201, 0, 0, 0, 81, 0, 0, 0, 109, 0, 0, 0, 28, 0, 0, 0, 170, 0, 0, 0, 245, 0, 0, 0, 165, 0, 0, +0, 144, 0, 0, 0, 63, 0, 0, 0, 20, 0, 0, 0, 226, 0, 0, 0, 110, 0, 0, 0, 142, 0, 0, 0, 100, 0, 0, 0, 253, 0, 0, 0, 172, 0, 0, 0, 224, 0, 0, 0, 78, 0, 0, 0, 34, 0, 0, 0, 229, 0, 0, 0, 193, 0, 0, 0, 188, 0, 0, 0, 41, 0, 0, 0, 10, 0, 0, 0, 106, 0, 0, 0, 158, 0, 0, 0, 161, 0, 0, 0, 96, 0, 0, 0, 203, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 220, 0, 0, 0, 57, 0, 0, 0, 50, 0, 0, 0, 243, 0, 0, 0, 161, 0, 0, 0, 68, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 120, 0, 0, 0, 251, 0, 0, 0, 149, 0, 0, 0, 71, 0, +0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 52, 0, 0, 0, 232, 0, 0, 0, 37, 0, 0, 0, 222, 0, 0, 0, 147, 0, 0, 0, 198, 0, 0, 0, 180, 0, 0, 0, 118, 0, 0, 0, 109, 0, 0, 0, 134, 0, 0, 0, 19, 0, 0, 0, 198, 0, 0, 0, 233, 0, 0, 0, 104, 0, 0, 0, 181, 0, 0, 0, 1, 0, 0, 0, 99, 0, 0, 0, 31, 0, 0, 0, 154, 0, 0, 0, 82, 0, 0, 0, 100, 0, 0, 0, 151, 0, 0, 0, 217, 0, 0, 0, 28, 0, 0, 0, 8, 0, 0, 0, 81, 0, 0, 0, 111, 0, 0, 0, 38, 0, 0, 0, 157, 0, 0, 0, 170, 0, 0, 0, 147, 0, 0, 0, 51, 0, 0, 0, 67, 0, 0, 0, 250, 0, 0, 0, 119, 0, +0, 0, 233, 0, 0, 0, 98, 0, 0, 0, 155, 0, 0, 0, 93, 0, 0, 0, 24, 0, 0, 0, 117, 0, 0, 0, 235, 0, 0, 0, 120, 0, 0, 0, 247, 0, 0, 0, 135, 0, 0, 0, 143, 0, 0, 0, 65, 0, 0, 0, 180, 0, 0, 0, 77, 0, 0, 0, 19, 0, 0, 0, 168, 0, 0, 0, 130, 0, 0, 0, 62, 0, 0, 0, 233, 0, 0, 0, 19, 0, 0, 0, 173, 0, 0, 0, 235, 0, 0, 0, 1, 0, 0, 0, 202, 0, 0, 0, 207, 0, 0, 0, 218, 0, 0, 0, 205, 0, 0, 0, 247, 0, 0, 0, 108, 0, 0, 0, 199, 0, 0, 0, 122, 0, 0, 0, 220, 0, 0, 0, 30, 0, 0, 0, 110, 0, 0, 0, 200, 0, 0, 0, 78, 0, 0, 0, 85, +0, 0, 0, 98, 0, 0, 0, 128, 0, 0, 0, 234, 0, 0, 0, 120, 0, 0, 0, 12, 0, 0, 0, 134, 0, 0, 0, 185, 0, 0, 0, 64, 0, 0, 0, 81, 0, 0, 0, 39, 0, 0, 0, 174, 0, 0, 0, 211, 0, 0, 0, 13, 0, 0, 0, 76, 0, 0, 0, 143, 0, 0, 0, 52, 0, 0, 0, 234, 0, 0, 0, 125, 0, 0, 0, 60, 0, 0, 0, 229, 0, 0, 0, 138, 0, 0, 0, 207, 0, 0, 0, 91, 0, 0, 0, 146, 0, 0, 0, 216, 0, 0, 0, 48, 0, 0, 0, 22, 0, 0, 0, 180, 0, 0, 0, 163, 0, 0, 0, 117, 0, 0, 0, 255, 0, 0, 0, 235, 0, 0, 0, 39, 0, 0, 0, 200, 0, 0, 0, 92, 0, 0, 0, 108, 0, 0, 0, 194, +0, 0, 0, 238, 0, 0, 0, 108, 0, 0, 0, 33, 0, 0, 0, 11, 0, 0, 0, 195, 0, 0, 0, 186, 0, 0, 0, 18, 0, 0, 0, 83, 0, 0, 0, 42, 0, 0, 0, 170, 0, 0, 0, 119, 0, 0, 0, 173, 0, 0, 0, 25, 0, 0, 0, 120, 0, 0, 0, 85, 0, 0, 0, 138, 0, 0, 0, 46, 0, 0, 0, 96, 0, 0, 0, 135, 0, 0, 0, 194, 0, 0, 0, 110, 0, 0, 0, 145, 0, 0, 0, 56, 0, 0, 0, 145, 0, 0, 0, 63, 0, 0, 0, 122, 0, 0, 0, 197, 0, 0, 0, 36, 0, 0, 0, 143, 0, 0, 0, 81, 0, 0, 0, 197, 0, 0, 0, 222, 0, 0, 0, 176, 0, 0, 0, 83, 0, 0, 0, 48, 0, 0, 0, 86, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 254, 0, 0, 0, 84, 0, 0, 0, 18, 0, 0, 0, 24, 0, 0, 0, 202, 0, 0, 0, 125, 0, 0, 0, 165, 0, 0, 0, 104, 0, 0, 0, 67, 0, 0, 0, 163, 0, 0, 0, 109, 0, 0, 0, 20, 0, 0, 0, 42, 0, 0, 0, 106, 0, 0, 0, 165, 0, 0, 0, 142, 0, 0, 0, 50, 0, 0, +0, 231, 0, 0, 0, 99, 0, 0, 0, 79, 0, 0, 0, 227, 0, 0, 0, 198, 0, 0, 0, 68, 0, 0, 0, 62, 0, 0, 0, 171, 0, 0, 0, 99, 0, 0, 0, 202, 0, 0, 0, 23, 0, 0, 0, 134, 0, 0, 0, 116, 0, 0, 0, 63, 0, 0, 0, 30, 0, 0, 0, 100, 0, 0, 0, 193, 0, 0, 0, 125, 0, 0, 0, 82, 0, 0, 0, 220, 0, 0, 0, 19, 0, 0, 0, 90, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 78, 0, 0, 0, 238, 0, 0, 0, 153, 0, 0, 0, 40, 0, 0, 0, 187, 0, 0, 0, 76, 0, 0, 0, 238, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 27, 0, 0, 0, 137, 0, 0, 0, 162, 0, 0, 0, 56, 0, 0, +0, 57, 0, 0, 0, 123, 0, 0, 0, 196, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 230, 0, 0, 0, 137, 0, 0, 0, 237, 0, 0, 0, 15, 0, 0, 0, 243, 0, 0, 0, 60, 0, 0, 0, 140, 0, 0, 0, 128, 0, 0, 0, 131, 0, 0, 0, 16, 0, 0, 0, 138, 0, 0, 0, 55, 0, 0, 0, 80, 0, 0, 0, 156, 0, 0, 0, 180, 0, 0, 0, 223, 0, 0, 0, 63, 0, 0, 0, 140, 0, 0, 0, 247, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0, 214, 0, 0, 0, 255, 0, 0, 0, 160, 0, 0, 0, 130, 0, 0, 0, 108, 0, 0, 0, 117, 0, 0, 0, 59, 0, 0, 0, 228, 0, 0, 0, 181, 0, 0, 0, 187, 0, 0, 0, 228, 0, +0, 0, 230, 0, 0, 0, 80, 0, 0, 0, 240, 0, 0, 0, 8, 0, 0, 0, 98, 0, 0, 0, 238, 0, 0, 0, 117, 0, 0, 0, 72, 0, 0, 0, 146, 0, 0, 0, 51, 0, 0, 0, 242, 0, 0, 0, 244, 0, 0, 0, 173, 0, 0, 0, 21, 0, 0, 0, 122, 0, 0, 0, 161, 0, 0, 0, 1, 0, 0, 0, 70, 0, 0, 0, 169, 0, 0, 0, 50, 0, 0, 0, 6, 0, 0, 0, 136, 0, 0, 0, 182, 0, 0, 0, 54, 0, 0, 0, 71, 0, 0, 0, 53, 0, 0, 0, 185, 0, 0, 0, 180, 0, 0, 0, 66, 0, 0, 0, 133, 0, 0, 0, 118, 0, 0, 0, 240, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 56, 0, 0, 0, 81, 0, 0, 0, +21, 0, 0, 0, 157, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 209, 0, 0, 0, 57, 0, 0, 0, 187, 0, 0, 0, 100, 0, 0, 0, 157, 0, 0, 0, 21, 0, 0, 0, 129, 0, 0, 0, 193, 0, 0, 0, 104, 0, 0, 0, 208, 0, 0, 0, 182, 0, 0, 0, 164, 0, 0, 0, 44, 0, 0, 0, 125, 0, 0, 0, 94, 0, 0, 0, 2, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 59, 0, 0, 0, 164, 0, 0, 0, 204, 0, 0, 0, 202, 0, 0, 0, 29, 0, 0, 0, 129, 0, 0, 0, 36, 0, 0, 0, 16, 0, 0, 0, 231, 0, 0, 0, 41, 0, 0, 0, 249, 0, 0, 0, 55, 0, 0, 0, 217, 0, 0, 0, 70, 0, 0, 0, +90, 0, 0, 0, 205, 0, 0, 0, 112, 0, 0, 0, 254, 0, 0, 0, 77, 0, 0, 0, 91, 0, 0, 0, 191, 0, 0, 0, 165, 0, 0, 0, 207, 0, 0, 0, 145, 0, 0, 0, 244, 0, 0, 0, 239, 0, 0, 0, 238, 0, 0, 0, 138, 0, 0, 0, 41, 0, 0, 0, 208, 0, 0, 0, 231, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 146, 0, 0, 0, 138, 0, 0, 0, 255, 0, 0, 0, 54, 0, 0, 0, 252, 0, 0, 0, 228, 0, 0, 0, 73, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 185, 0, 0, 0, 4, 0, 0, 0, 125, 0, 0, 0, 53, 0, 0, 0, 252, 0, 0, 0, 235, 0, 0, 0, 208, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, +50, 0, 0, 0, 82, 0, 0, 0, 122, 0, 0, 0, 137, 0, 0, 0, 36, 0, 0, 0, 117, 0, 0, 0, 80, 0, 0, 0, 225, 0, 0, 0, 99, 0, 0, 0, 2, 0, 0, 0, 130, 0, 0, 0, 142, 0, 0, 0, 231, 0, 0, 0, 133, 0, 0, 0, 12, 0, 0, 0, 242, 0, 0, 0, 86, 0, 0, 0, 68, 0, 0, 0, 55, 0, 0, 0, 131, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, 0, 161, 0, 0, 0, 206, 0, 0, 0, 203, 0, 0, 0, 96, 0, 0, 0, 218, 0, 0, 0, 18, 0, 0, 0, 2, 0, 0, 0, 30, 0, 0, 0, 41, 0, 0, 0, 57, 0, 0, 0, 42, 0, 0, 0, 3, 0, 0, 0, 183, 0, 0, 0, 235, 0, 0, 0, 119, 0, 0, 0, 64, 0, +0, 0, 234, 0, 0, 0, 201, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 213, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 44, 0, 0, 0, 199, 0, 0, 0, 90, 0, 0, 0, 253, 0, 0, 0, 255, 0, 0, 0, 196, 0, 0, 0, 209, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 136, 0, 0, +0, 152, 0, 0, 0, 91, 0, 0, 0, 78, 0, 0, 0, 252, 0, 0, 0, 65, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 230, 0, 0, 0, 80, 0, 0, 0, 43, 0, 0, 0, 174, 0, 0, 0, 150, 0, 0, 0, 81, 0, 0, 0, 217, 0, 0, 0, 107, 0, 0, 0, 114, 0, 0, 0, 178, 0, 0, 0, 51, 0, 0, 0, 66, 0, 0, 0, 152, 0, 0, 0, 104, 0, 0, 0, 187, 0, 0, 0, 16, 0, 0, 0, 90, 0, 0, 0, 122, 0, 0, 0, 140, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 180, 0, 0, 0, 5, 0, 0, 0, 47, 0, 0, 0, 97, 0, 0, 0, 159, 0, 0, 0, 215, 0, 0, 0, 168, 0, 0, 0, 63, 0, 0, 0, 131, 0, 0, 0, +140, 0, 0, 0, 16, 0, 0, 0, 105, 0, 0, 0, 144, 0, 0, 0, 230, 0, 0, 0, 207, 0, 0, 0, 210, 0, 0, 0, 99, 0, 0, 0, 163, 0, 0, 0, 228, 0, 0, 0, 84, 0, 0, 0, 126, 0, 0, 0, 229, 0, 0, 0, 105, 0, 0, 0, 19, 0, 0, 0, 28, 0, 0, 0, 144, 0, 0, 0, 87, 0, 0, 0, 170, 0, 0, 0, 233, 0, 0, 0, 83, 0, 0, 0, 34, 0, 0, 0, 67, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 0, 229, 0, 0, 0, 28, 0, 0, 0, 248, 0, 0, 0, 10, 0, 0, 0, 253, 0, 0, 0, 45, 0, 0, 0, 126, 0, 0, 0, 245, 0, 0, 0, 245, 0, 0, 0, 112, 0, 0, 0, 125, 0, 0, 0, 65, 0, 0, 0, +107, 0, 0, 0, 17, 0, 0, 0, 254, 0, 0, 0, 190, 0, 0, 0, 153, 0, 0, 0, 209, 0, 0, 0, 85, 0, 0, 0, 41, 0, 0, 0, 49, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 151, 0, 0, 0, 108, 0, 0, 0, 213, 0, 0, 0, 53, 0, 0, 0, 204, 0, 0, 0, 94, 0, 0, 0, 139, 0, 0, 0, 217, 0, 0, 0, 105, 0, 0, 0, 142, 0, 0, 0, 78, 0, 0, 0, 159, 0, 0, 0, 37, 0, 0, 0, 248, 0, 0, 0, 129, 0, 0, 0, 84, 0, 0, 0, 45, 0, 0, 0, 14, 0, 0, 0, 213, 0, 0, 0, 84, 0, 0, 0, 129, 0, 0, 0, 155, 0, 0, 0, 166, 0, 0, 0, 146, 0, 0, 0, 206, 0, 0, 0, 75, 0, 0, +0, 233, 0, 0, 0, 143, 0, 0, 0, 36, 0, 0, 0, 59, 0, 0, 0, 202, 0, 0, 0, 224, 0, 0, 0, 68, 0, 0, 0, 171, 0, 0, 0, 54, 0, 0, 0, 254, 0, 0, 0, 251, 0, 0, 0, 135, 0, 0, 0, 212, 0, 0, 0, 38, 0, 0, 0, 62, 0, 0, 0, 15, 0, 0, 0, 147, 0, 0, 0, 156, 0, 0, 0, 17, 0, 0, 0, 231, 0, 0, 0, 219, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 0, 0, 67, 0, 0, 0, 40, 0, 0, 0, 21, 0, 0, 0, 55, 0, 0, 0, 221, 0, 0, 0, 222, 0, 0, 0, 39, 0, 0, 0, 223, 0, 0, 0, 173, 0, 0, 0, 62, 0, 0, 0, 73, 0, 0, 0, 79, 0, 0, 0, 224, 0, 0, +0, 91, 0, 0, 0, 246, 0, 0, 0, 128, 0, 0, 0, 89, 0, 0, 0, 21, 0, 0, 0, 60, 0, 0, 0, 133, 0, 0, 0, 183, 0, 0, 0, 62, 0, 0, 0, 18, 0, 0, 0, 245, 0, 0, 0, 255, 0, 0, 0, 204, 0, 0, 0, 240, 0, 0, 0, 180, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 0, 201, 0, 0, 0, 132, 0, 0, 0, 203, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 224, 0, 0, 0, 188, 0, 0, 0, 204, 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 0, 169, 0, 0, 0, 139, 0, 0, 0, 148, 0, 0, 0, 166, 0, 0, 0, 170, 0, 0, 0, 24, 0, 0, 0, 203, 0, 0, 0, 39, 0, 0, 0, 141, 0, 0, +0, 73, 0, 0, 0, 166, 0, 0, 0, 23, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 217, 0, 0, 0, 182, 0, 0, 0, 212, 0, 0, 0, 157, 0, 0, 0, 212, 0, 0, 0, 106, 0, 0, 0, 175, 0, 0, 0, 112, 0, 0, 0, 7, 0, 0, 0, 44, 0, 0, 0, 16, 0, 0, 0, 158, 0, 0, 0, 189, 0, 0, 0, 17, 0, 0, 0, 173, 0, 0, 0, 228, 0, 0, 0, 38, 0, 0, 0, 51, 0, 0, 0, 112, 0, 0, 0, 146, 0, 0, 0, 120, 0, 0, 0, 28, 0, 0, 0, 116, 0, 0, 0, 159, 0, 0, 0, 117, 0, 0, 0, 96, 0, 0, 0, 86, 0, 0, 0, 244, 0, 0, 0, 57, 0, 0, 0, 168, 0, 0, 0, 168, 0, 0, 0, 98, 0, 0, +0, 59, 0, 0, 0, 191, 0, 0, 0, 85, 0, 0, 0, 53, 0, 0, 0, 97, 0, 0, 0, 139, 0, 0, 0, 68, 0, 0, 0, 151, 0, 0, 0, 232, 0, 0, 0, 58, 0, 0, 0, 85, 0, 0, 0, 193, 0, 0, 0, 200, 0, 0, 0, 59, 0, 0, 0, 253, 0, 0, 0, 149, 0, 0, 0, 41, 0, 0, 0, 17, 0, 0, 0, 96, 0, 0, 0, 150, 0, 0, 0, 30, 0, 0, 0, 203, 0, 0, 0, 17, 0, 0, 0, 157, 0, 0, 0, 194, 0, 0, 0, 3, 0, 0, 0, 138, 0, 0, 0, 27, 0, 0, 0, 198, 0, 0, 0, 214, 0, 0, 0, 69, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 14, 0, 0, 0, 80, 0, 0, 0, 178, 0, 0, 0, 204, 0, 0, 0, 13, 0, 0, 0, 107, 0, 0, 0, 166, 0, 0, 0, 113, 0, 0, 0, 91, 0, 0, 0, 66, 0, 0, 0, 237, 0, 0, 0, 189, 0, 0, 0, 175, 0, 0, 0, 172, 0, 0, 0, 240, 0, 0, 0, 252, 0, 0, 0, 18, 0, 0, 0, 162, 0, 0, 0, 63, 0, 0, 0, 78, 0, 0, 0, 218, 0, 0, 0, 232, +0, 0, 0, 17, 0, 0, 0, 243, 0, 0, 0, 35, 0, 0, 0, 225, 0, 0, 0, 4, 0, 0, 0, 98, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 78, 0, 0, 0, 200, 0, 0, 0, 177, 0, 0, 0, 27, 0, 0, 0, 111, 0, 0, 0, 115, 0, 0, 0, 97, 0, 0, 0, 61, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 95, 0, 0, 0, 115, 0, 0, 0, 14, 0, 0, 0, 47, 0, 0, 0, 147, 0, 0, 0, 246, 0, 0, 0, 36, 0, 0, 0, 216, 0, 0, 0, 79, 0, 0, 0, 144, 0, 0, 0, 172, 0, 0, 0, 162, 0, 0, 0, 98, 0, 0, 0, 10, 0, 0, 0, 240, 0, 0, 0, 97, 0, 0, +0, 217, 0, 0, 0, 8, 0, 0, 0, 89, 0, 0, 0, 106, 0, 0, 0, 111, 0, 0, 0, 45, 0, 0, 0, 85, 0, 0, 0, 248, 0, 0, 0, 47, 0, 0, 0, 142, 0, 0, 0, 240, 0, 0, 0, 24, 0, 0, 0, 59, 0, 0, 0, 234, 0, 0, 0, 221, 0, 0, 0, 38, 0, 0, 0, 114, 0, 0, 0, 209, 0, 0, 0, 245, 0, 0, 0, 254, 0, 0, 0, 229, 0, 0, 0, 184, 0, 0, 0, 230, 0, 0, 0, 211, 0, 0, 0]).concat([16, 0, 0, 0, 72, 0, 0, 0, 70, 0, 0, 0, 73, 0, 0, 0, 58, 0, 0, 0, 159, 0, 0, 0, 94, 0, 0, 0, 69, 0, 0, 0, 107, 0, 0, 0, 144, 0, 0, 0, 232, 0, 0, 0, 127, 0, 0, 0, 211, +0, 0, 0, 118, 0, 0, 0, 105, 0, 0, 0, 51, 0, 0, 0, 123, 0, 0, 0, 185, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 238, 0, 0, 0, 166, 0, 0, 0, 41, 0, 0, 0, 107, 0, 0, 0, 221, 0, 0, 0, 208, 0, 0, 0, 93, 0, 0, 0, 141, 0, 0, 0, 193, 0, 0, 0, 62, 0, 0, 0, 74, 0, 0, 0, 234, 0, 0, 0, 55, 0, 0, 0, 177, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 0, 241, 0, 0, 0, 40, 0, 0, 0, 157, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 122, 0, 0, 0, 219, 0, 0, 0, 18, 0, 0, 0, 210, 0, 0, 0, 138, 0, 0, 0, 130, 0, +0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 30, 0, 0, 0, 175, 0, 0, 0, 249, 0, 0, 0, 75, 0, 0, 0, 156, 0, 0, 0, 190, 0, 0, 0, 174, 0, 0, 0, 124, 0, 0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 42, 0, 0, 0, 35, 0, 0, 0, 179, 0, 0, 0, 98, 0, 0, 0, 134, 0, 0, 0, 231, 0, 0, 0, 253, 0, 0, 0, 35, 0, 0, 0, 170, 0, 0, 0, 153, 0, 0, 0, 189, 0, 0, 0, 43, 0, 0, 0, 17, 0, 0, 0, 108, 0, 0, 0, 141, 0, 0, 0, 166, 0, 0, 0, 213, 0, 0, 0, 172, 0, 0, 0, 157, 0, 0, 0, 204, 0, 0, 0, 104, 0, 0, 0, 117, 0, 0, 0, 127, 0, 0, 0, 195, 0, 0, 0, 77, +0, 0, 0, 75, 0, 0, 0, 221, 0, 0, 0, 108, 0, 0, 0, 187, 0, 0, 0, 17, 0, 0, 0, 90, 0, 0, 0, 96, 0, 0, 0, 229, 0, 0, 0, 189, 0, 0, 0, 125, 0, 0, 0, 39, 0, 0, 0, 139, 0, 0, 0, 218, 0, 0, 0, 180, 0, 0, 0, 149, 0, 0, 0, 246, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 164, 0, 0, 0, 146, 0, 0, 0, 63, 0, 0, 0, 34, 0, 0, 0, 214, 0, 0, 0, 181, 0, 0, 0, 23, 0, 0, 0, 132, 0, 0, 0, 191, 0, 0, 0, 18, 0, 0, 0, 204, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 74, 0, 0, 0, 223, 0, 0, 0, 20, 0, 0, 0, 49, 0, 0, 0, 188, 0, 0, 0, 161, +0, 0, 0, 172, 0, 0, 0, 110, 0, 0, 0, 171, 0, 0, 0, 250, 0, 0, 0, 87, 0, 0, 0, 17, 0, 0, 0, 83, 0, 0, 0, 179, 0, 0, 0, 39, 0, 0, 0, 230, 0, 0, 0, 249, 0, 0, 0, 71, 0, 0, 0, 51, 0, 0, 0, 68, 0, 0, 0, 52, 0, 0, 0, 30, 0, 0, 0, 121, 0, 0, 0, 252, 0, 0, 0, 166, 0, 0, 0, 180, 0, 0, 0, 11, 0, 0, 0, 53, 0, 0, 0, 32, 0, 0, 0, 201, 0, 0, 0, 77, 0, 0, 0, 34, 0, 0, 0, 132, 0, 0, 0, 196, 0, 0, 0, 169, 0, 0, 0, 32, 0, 0, 0, 236, 0, 0, 0, 137, 0, 0, 0, 148, 0, 0, 0, 186, 0, 0, 0, 102, 0, 0, 0, 86, 0, 0, 0, 72, +0, 0, 0, 185, 0, 0, 0, 135, 0, 0, 0, 127, 0, 0, 0, 202, 0, 0, 0, 30, 0, 0, 0, 6, 0, 0, 0, 237, 0, 0, 0, 165, 0, 0, 0, 85, 0, 0, 0, 89, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 241, 0, 0, 0, 213, 0, 0, 0, 171, 0, 0, +0, 168, 0, 0, 0, 43, 0, 0, 0, 174, 0, 0, 0, 137, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 86, 0, 0, 0, 159, 0, 0, 0, 242, 0, 0, 0, 75, 0, 0, 0, 49, 0, 0, 0, 188, 0, 0, 0, 24, 0, 0, 0, 169, 0, 0, 0, 6, 0, 0, 0, 91, 0, 0, 0, 190, 0, 0, 0, 180, 0, 0, 0, 97, 0, 0, 0, 248, 0, 0, 0, 178, 0, 0, 0, 6, 0, 0, 0, 156, 0, 0, 0, 129, 0, 0, 0, 171, 0, 0, 0, 76, 0, 0, 0, 31, 0, 0, 0, 104, 0, 0, 0, 118, 0, 0, 0, 1, 0, 0, 0, 22, 0, 0, 0, 56, 0, 0, 0, 43, 0, 0, 0, 15, 0, 0, 0, 119, 0, 0, 0, 151, 0, 0, 0, 146, 0, 0, 0, +103, 0, 0, 0, 78, 0, 0, 0, 134, 0, 0, 0, 106, 0, 0, 0, 139, 0, 0, 0, 229, 0, 0, 0, 232, 0, 0, 0, 12, 0, 0, 0, 247, 0, 0, 0, 54, 0, 0, 0, 57, 0, 0, 0, 181, 0, 0, 0, 51, 0, 0, 0, 230, 0, 0, 0, 207, 0, 0, 0, 94, 0, 0, 0, 189, 0, 0, 0, 24, 0, 0, 0, 251, 0, 0, 0, 16, 0, 0, 0, 31, 0, 0, 0, 131, 0, 0, 0, 240, 0, 0, 0, 13, 0, 0, 0, 99, 0, 0, 0, 239, 0, 0, 0, 83, 0, 0, 0, 107, 0, 0, 0, 181, 0, 0, 0, 107, 0, 0, 0, 249, 0, 0, 0, 131, 0, 0, 0, 207, 0, 0, 0, 222, 0, 0, 0, 4, 0, 0, 0, 34, 0, 0, 0, 155, 0, 0, 0, +44, 0, 0, 0, 10, 0, 0, 0, 224, 0, 0, 0, 165, 0, 0, 0, 216, 0, 0, 0, 199, 0, 0, 0, 156, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, 246, 0, 0, 0, 111, 0, 0, 0, 207, 0, 0, 0, 144, 0, 0, 0, 107, 0, 0, 0, 104, 0, 0, 0, 124, 0, 0, 0, 51, 0, 0, 0, 21, 0, 0, 0, 215, 0, 0, 0, 127, 0, 0, 0, 26, 0, 0, 0, 213, 0, 0, 0, 33, 0, 0, 0, 88, 0, 0, 0, 196, 0, 0, 0, 24, 0, 0, 0, 165, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 115, 0, 0, 0, 168, 0, 0, 0, 253, 0, 0, 0, 250, 0, 0, 0, 24, 0, 0, 0, 209, 0, 0, 0, 3, 0, 0, 0, 145, 0, +0, 0, 141, 0, 0, 0, 82, 0, 0, 0, 210, 0, 0, 0, 163, 0, 0, 0, 164, 0, 0, 0, 211, 0, 0, 0, 177, 0, 0, 0, 234, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 72, 0, 0, 0, 131, 0, 0, 0, 144, 0, 0, 0, 229, 0, 0, 0, 253, 0, 0, 0, 63, 0, 0, 0, 132, 0, 0, 0, 170, 0, 0, 0, 249, 0, 0, 0, 139, 0, 0, 0, 130, 0, 0, 0, 89, 0, 0, 0, 36, 0, 0, 0, 52, 0, 0, 0, 104, 0, 0, 0, 79, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 0, 217, 0, 0, 0, 204, 0, 0, 0, 113, 0, 0, 0, 225, 0, 0, 0, 127, 0, 0, 0, 140, 0, 0, 0, 175, +0, 0, 0, 241, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 160, 0, 0, 0, 119, 0, 0, 0, 245, 0, 0, 0, 26, 0, 0, 0, 97, 0, 0, 0, 247, 0, 0, 0, 55, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 242, 0, 0, 0, 105, 0, 0, 0, 111, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 0, 133, 0, 0, 0, 25, 0, 0, 0, 69, 0, 0, 0, 77, 0, 0, 0, 127, 0, 0, 0, 2, 0, 0, 0, 124, 0, 0, 0, 106, 0, 0, 0, 5, 0, 0, 0, 71, 0, 0, 0, 108, 0, 0, 0, 31, 0, 0, 0, 129, 0, 0, 0, 32, 0, 0, 0, 212, 0, 0, 0, 232, 0, 0, 0, 80, 0, 0, 0, 39, 0, 0, +0, 114, 0, 0, 0, 44, 0, 0, 0, 58, 0, 0, 0, 229, 0, 0, 0, 173, 0, 0, 0, 244, 0, 0, 0, 221, 0, 0, 0, 45, 0, 0, 0, 247, 0, 0, 0, 92, 0, 0, 0, 68, 0, 0, 0, 181, 0, 0, 0, 91, 0, 0, 0, 33, 0, 0, 0, 163, 0, 0, 0, 137, 0, 0, 0, 95, 0, 0, 0, 150, 0, 0, 0, 69, 0, 0, 0, 202, 0, 0, 0, 77, 0, 0, 0, 164, 0, 0, 0, 33, 0, 0, 0, 153, 0, 0, 0, 112, 0, 0, 0, 218, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 160, 0, 0, 0, 229, 0, 0, 0, 244, 0, 0, 0, 236, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 104, 0, 0, 0, 33, 0, 0, 0, 101, 0, 0, +0, 233, 0, 0, 0, 8, 0, 0, 0, 160, 0, 0, 0, 11, 0, 0, 0, 106, 0, 0, 0, 74, 0, 0, 0, 186, 0, 0, 0, 181, 0, 0, 0, 128, 0, 0, 0, 175, 0, 0, 0, 208, 0, 0, 0, 27, 0, 0, 0, 197, 0, 0, 0, 245, 0, 0, 0, 75, 0, 0, 0, 115, 0, 0, 0, 80, 0, 0, 0, 96, 0, 0, 0, 45, 0, 0, 0, 113, 0, 0, 0, 105, 0, 0, 0, 97, 0, 0, 0, 14, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 117, 0, 0, 0, 87, 0, 0, 0, 59, 0, 0, 0, 235, 0, 0, 0, 92, 0, 0, 0, 20, 0, 0, 0, 86, 0, 0, 0, 80, 0, 0, 0, 201, 0, 0, 0, 79, 0, 0, 0, 184, 0, 0, 0, 184, 0, 0, 0, 30, 0, 0, 0, 163, 0, 0, 0, 244, 0, 0, 0, 171, 0, 0, 0, 245, 0, 0, 0, 169, 0, 0, 0, 32, 0, 0, 0, 21, 0, 0, 0, 148, 0, 0, 0, 130, 0, 0, 0, 218, 0, 0, 0, 150, 0, 0, 0, 28, 0, 0, 0, 155, +0, 0, 0, 89, 0, 0, 0, 140, 0, 0, 0, 255, 0, 0, 0, 244, 0, 0, 0, 81, 0, 0, 0, 193, 0, 0, 0, 58, 0, 0, 0, 134, 0, 0, 0, 215, 0, 0, 0, 176, 0, 0, 0, 6, 0, 0, 0, 132, 0, 0, 0, 127, 0, 0, 0, 27, 0, 0, 0, 189, 0, 0, 0, 212, 0, 0, 0, 7, 0, 0, 0, 120, 0, 0, 0, 128, 0, 0, 0, 46, 0, 0, 0, 177, 0, 0, 0, 180, 0, 0, 0, 238, 0, 0, 0, 82, 0, 0, 0, 56, 0, 0, 0, 238, 0, 0, 0, 154, 0, 0, 0, 249, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 65, 0, 0, 0, 110, 0, 0, 0, 212, 0, 0, 0, 136, 0, 0, 0, 149, 0, 0, 0, 172, 0, 0, 0, +53, 0, 0, 0, 65, 0, 0, 0, 151, 0, 0, 0, 191, 0, 0, 0, 113, 0, 0, 0, 106, 0, 0, 0, 155, 0, 0, 0, 114, 0, 0, 0, 236, 0, 0, 0, 243, 0, 0, 0, 248, 0, 0, 0, 107, 0, 0, 0, 230, 0, 0, 0, 14, 0, 0, 0, 108, 0, 0, 0, 105, 0, 0, 0, 165, 0, 0, 0, 47, 0, 0, 0, 104, 0, 0, 0, 82, 0, 0, 0, 216, 0, 0, 0, 97, 0, 0, 0, 129, 0, 0, 0, 192, 0, 0, 0, 99, 0, 0, 0, 63, 0, 0, 0, 166, 0, 0, 0, 60, 0, 0, 0, 19, 0, 0, 0, 144, 0, 0, 0, 230, 0, 0, 0, 141, 0, 0, 0, 86, 0, 0, 0, 232, 0, 0, 0, 57, 0, 0, 0, 48, 0, 0, 0, 119, 0, 0, +0, 35, 0, 0, 0, 177, 0, 0, 0, 253, 0, 0, 0, 27, 0, 0, 0, 61, 0, 0, 0, 62, 0, 0, 0, 116, 0, 0, 0, 77, 0, 0, 0, 127, 0, 0, 0, 174, 0, 0, 0, 91, 0, 0, 0, 58, 0, 0, 0, 180, 0, 0, 0, 101, 0, 0, 0, 14, 0, 0, 0, 58, 0, 0, 0, 67, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 65, 0, 0, 0, 71, 0, 0, 0, 230, 0, 0, 0, 232, 0, 0, 0, 146, 0, 0, 0, 9, 0, 0, 0, 34, 0, 0, 0, 72, 0, 0, 0, 76, 0, 0, 0, 133, 0, 0, 0, 87, 0, 0, 0, 159, 0, 0, 0, 181, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 178, 0, 0, 0, 159, 0, 0, 0, 71, 0, 0, 0, 63, +0, 0, 0, 240, 0, 0, 0, 250, 0, 0, 0, 230, 0, 0, 0, 169, 0, 0, 0, 177, 0, 0, 0, 155, 0, 0, 0, 111, 0, 0, 0, 150, 0, 0, 0, 125, 0, 0, 0, 249, 0, 0, 0, 164, 0, 0, 0, 101, 0, 0, 0, 9, 0, 0, 0, 117, 0, 0, 0, 50, 0, 0, 0, 166, 0, 0, 0, 108, 0, 0, 0, 127, 0, 0, 0, 71, 0, 0, 0, 75, 0, 0, 0, 47, 0, 0, 0, 79, 0, 0, 0, 52, 0, 0, 0, 233, 0, 0, 0, 89, 0, 0, 0, 147, 0, 0, 0, 157, 0, 0, 0, 38, 0, 0, 0, 128, 0, 0, 0, 84, 0, 0, 0, 242, 0, 0, 0, 204, 0, 0, 0, 60, 0, 0, 0, 194, 0, 0, 0, 37, 0, 0, 0, 133, 0, 0, 0, 227, +0, 0, 0, 106, 0, 0, 0, 193, 0, 0, 0, 98, 0, 0, 0, 4, 0, 0, 0, 167, 0, 0, 0, 8, 0, 0, 0, 50, 0, 0, 0, 109, 0, 0, 0, 161, 0, 0, 0, 57, 0, 0, 0, 132, 0, 0, 0, 138, 0, 0, 0, 59, 0, 0, 0, 135, 0, 0, 0, 95, 0, 0, 0, 17, 0, 0, 0, 19, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 0, 102, 0, 0, 0, 196, 0, 0, 0, 12, 0, 0, 0, 115, 0, 0, 0, 110, 0, 0, 0, 188, 0, 0, 0, 36, 0, 0, 0, 181, 0, 0, 0, 249, 0, 0, 0, 112, 0, 0, 0, 129, 0, 0, 0, 82, 0, 0, 0, 233, 0, 0, 0, 244, 0, 0, 0, 124, 0, 0, 0, 35, 0, 0, 0, 221, 0, +0, 0, 159, 0, 0, 0, 184, 0, 0, 0, 70, 0, 0, 0, 239, 0, 0, 0, 29, 0, 0, 0, 34, 0, 0, 0, 85, 0, 0, 0, 125, 0, 0, 0, 113, 0, 0, 0, 196, 0, 0, 0, 66, 0, 0, 0, 51, 0, 0, 0, 197, 0, 0, 0, 55, 0, 0, 0, 105, 0, 0, 0, 91, 0, 0, 0, 168, 0, 0, 0, 198, 0, 0, 0, 157, 0, 0, 0, 164, 0, 0, 0, 252, 0, 0, 0, 97, 0, 0, 0, 110, 0, 0, 0, 104, 0, 0, 0, 70, 0, 0, 0, 234, 0, 0, 0, 215, 0, 0, 0, 28, 0, 0, 0, 103, 0, 0, 0, 210, 0, 0, 0, 125, 0, 0, 0, 250, 0, 0, 0, 241, 0, 0, 0, 204, 0, 0, 0, 84, 0, 0, 0, 141, 0, 0, 0, 54, +0, 0, 0, 53, 0, 0, 0, 201, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 108, 0, 0, 0, 103, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 77, 0, 0, 0, 66, 0, 0, 0, 41, 0, 0, 0, 93, 0, 0, 0, 164, 0, 0, 0, 107, 0, 0, 0, 111, 0, 0, 0, 168, 0, 0, 0, 138, 0, 0, +0, 77, 0, 0, 0, 145, 0, 0, 0, 123, 0, 0, 0, 210, 0, 0, 0, 223, 0, 0, 0, 54, 0, 0, 0, 239, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 141, 0, 0, 0, 235, 0, 0, 0, 88, 0, 0, 0, 61, 0, 0, 0, 179, 0, 0, 0, 80, 0, 0, 0, 252, 0, 0, 0, 139, 0, 0, 0, 151, 0, 0, 0, 150, 0, 0, 0, 51, 0, 0, 0, 147, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 74, 0, 0, 0, 202, 0, 0, 0, 208, 0, 0, 0, 177, 0, 0, 0, 171, 0, 0, 0, 189, 0, 0, 0, 221, 0, 0, 0, 167, 0, 0, 0, 124, 0, 0, 0, 172, 0, 0, 0, 62, 0, +0, 0, 69, 0, 0, 0, 203, 0, 0, 0, 204, 0, 0, 0, 7, 0, 0, 0, 145, 0, 0, 0, 191, 0, 0, 0, 53, 0, 0, 0, 157, 0, 0, 0, 203, 0, 0, 0, 125, 0, 0, 0, 18, 0, 0, 0, 60, 0, 0, 0, 17, 0, 0, 0, 89, 0, 0, 0, 19, 0, 0, 0, 207, 0, 0, 0, 92, 0, 0, 0, 69, 0, 0, 0, 184, 0, 0, 0, 65, 0, 0, 0, 215, 0, 0, 0, 171, 0, 0, 0, 7, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 142, 0, 0, 0, 206, 0, 0, 0, 223, 0, 0, 0, 178, 0, 0, 0, 67, 0, 0, 0, 92, 0, 0, 0, 1, 0, 0, 0, 220, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 0, 0, 149, 0, 0, 0, 16, +0, 0, 0, 90, 0, 0, 0, 246, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 160, 0, 0, 0, 25, 0, 0, 0, 58, 0, 0, 0, 9, 0, 0, 0, 42, 0, 0, 0, 170, 0, 0, 0, 63, 0, 0, 0, 220, 0, 0, 0, 142, 0, 0, 0, 235, 0, 0, 0, 198, 0, 0, 0, 191, 0, 0, 0, 221, 0, 0, 0, 17, 0, 0, 0, 123, 0, 0, 0, 231, 0, 0, 0, 71, 0, 0, 0, 230, 0, 0, 0, 206, 0, 0, 0, 231, 0, 0, 0, 182, 0, 0, 0, 197, 0, 0, 0, 232, 0, 0, 0, 138, 0, 0, 0, 220, 0, 0, 0, 75, 0, 0, 0, 87, 0, 0, 0, 21, 0, 0, 0, 59, 0, 0, 0, 102, 0, 0, 0, 202, 0, 0, 0, 137, 0, 0, 0, 163, +0, 0, 0, 253, 0, 0, 0, 172, 0, 0, 0, 13, 0, 0, 0, 225, 0, 0, 0, 29, 0, 0, 0, 122, 0, 0, 0, 137, 0, 0, 0, 239, 0, 0, 0, 191, 0, 0, 0, 3, 0, 0, 0, 117, 0, 0, 0, 208, 0, 0, 0, 41, 0, 0, 0, 80, 0, 0, 0, 203, 0, 0, 0, 125, 0, 0, 0, 214, 0, 0, 0, 190, 0, 0, 0, 173, 0, 0, 0, 95, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 170, 0, 0, 0, 152, 0, 0, 0, 237, 0, 0, 0, 63, 0, 0, 0, 143, 0, 0, 0, 146, 0, 0, 0, 203, 0, 0, 0, 129, 0, 0, 0, 86, 0, 0, 0, 1, 0, 0, 0, 99, 0, 0, 0, 100, 0, 0, 0, 163, 0, 0, 0, 56, +0, 0, 0, 57, 0, 0, 0, 139, 0, 0, 0, 164, 0, 0, 0, 214, 0, 0, 0, 80, 0, 0, 0, 180, 0, 0, 0, 170, 0, 0, 0, 93, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 118, 0, 0, 0, 46, 0, 0, 0, 161, 0, 0, 0, 166, 0, 0, 0, 179, 0, 0, 0, 184, 0, 0, 0, 124, 0, 0, 0, 122, 0, 0, 0, 86, 0, 0, 0, 245, 0, 0, 0, 92, 0, 0, 0, 78, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 251, 0, 0, 0, 221, 0, 0, 0, 202, 0, 0, 0, 72, 0, 0, 0, 139, 0, 0, 0, 72, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 52, 0, 0, 0, 197, 0, 0, 0, 227, 0, 0, 0, 232, 0, 0, 0, +174, 0, 0, 0, 23, 0, 0, 0, 39, 0, 0, 0, 227, 0, 0, 0, 100, 0, 0, 0, 96, 0, 0, 0, 113, 0, 0, 0, 71, 0, 0, 0, 41, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 146, 0, 0, 0, 93, 0, 0, 0, 16, 0, 0, 0, 147, 0, 0, 0, 200, 0, 0, 0, 14, 0, 0, 0, 161, 0, 0, 0, 237, 0, 0, 0, 186, 0, 0, 0, 169, 0, 0, 0, 150, 0, 0, 0, 28, 0, 0, 0, 197, 0, 0, 0, 118, 0, 0, 0, 48, 0, 0, 0, 205, 0, 0, 0, 249, 0, 0, 0, 48, 0, 0, 0, 149, 0, 0, 0, 176, 0, 0, 0, 189, 0, 0, 0, 140, 0, 0, 0, 188, 0, 0, 0, 167, 0, 0, 0, 79, 0, 0, 0, 126, 0, 0, 0, +253, 0, 0, 0, 78, 0, 0, 0, 58, 0, 0, 0, 191, 0, 0, 0, 95, 0, 0, 0, 4, 0, 0, 0, 121, 0, 0, 0, 128, 0, 0, 0, 43, 0, 0, 0, 90, 0, 0, 0, 159, 0, 0, 0, 79, 0, 0, 0, 104, 0, 0, 0, 33, 0, 0, 0, 25, 0, 0, 0, 113, 0, 0, 0, 198, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 66, 0, 0, 0, 170, 0, 0, 0, 223, 0, 0, 0, 174, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 110, 0, 0, 0, 126, 0, 0, 0, 75, 0, 0, 0, 113, 0, 0, 0, 147, 0, 0, 0, 192, 0, 0, 0, 114, 0, 0, 0, 237, 0, 0, 0, 235, 0, 0, 0, 113, 0, 0, 0, 36, 0, 0, 0, 151, 0, 0, 0, 38, 0, 0, 0, 156, 0, 0, 0, 254, 0, 0, 0, 203, 0, 0, 0, 62, 0, 0, 0, 89, 0, 0, 0, 25, 0, 0, 0, 168, 0, 0, 0, 15, 0, 0, 0, 117, 0, 0, 0, 125, 0, 0, 0, 190, 0, 0, 0, 24, 0, 0, 0, 230, 0, 0, 0, 150, 0, 0, 0, 30, 0, 0, 0, 149, 0, 0, 0, 112, +0, 0, 0, 96, 0, 0, 0, 137, 0, 0, 0, 102, 0, 0, 0, 62, 0, 0, 0, 29, 0, 0, 0, 76, 0, 0, 0, 95, 0, 0, 0, 254, 0, 0, 0, 192, 0, 0, 0, 4, 0, 0, 0, 67, 0, 0, 0, 214, 0, 0, 0, 68, 0, 0, 0, 25, 0, 0, 0, 181, 0, 0, 0, 173, 0, 0, 0, 199, 0, 0, 0, 34, 0, 0, 0, 220, 0, 0, 0, 113, 0, 0, 0, 40, 0, 0, 0, 100, 0, 0, 0, 222, 0, 0, 0, 65, 0, 0, 0, 56, 0, 0, 0, 39, 0, 0, 0, 143, 0, 0, 0, 44, 0, 0, 0, 107, 0, 0, 0, 8, 0, 0, 0, 184, 0, 0, 0, 184, 0, 0, 0, 123, 0, 0, 0, 61, 0, 0, 0, 112, 0, 0, 0, 39, 0, 0, 0, 157, 0, +0, 0, 217, 0, 0, 0, 175, 0, 0, 0, 177, 0, 0, 0, 39, 0, 0, 0, 175, 0, 0, 0, 227, 0, 0, 0, 93, 0, 0, 0, 30, 0, 0, 0, 58, 0, 0, 0, 48, 0, 0, 0, 84, 0, 0, 0, 97, 0, 0, 0, 96, 0, 0, 0, 232, 0, 0, 0, 195, 0, 0, 0, 38, 0, 0, 0, 58, 0, 0, 0, 188, 0, 0, 0, 126, 0, 0, 0, 245, 0, 0, 0, 129, 0, 0, 0, 221, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 235, 0, 0, 0, 192, 0, 0, 0, 30, 0, 0, 0, 218, 0, 0, 0, 44, 0, 0, 0, 164, 0, 0, 0, 209, 0, 0, 0, 161, 0, 0, 0, 195, 0, 0, 0, 92, 0, 0, 0, 110, 0, 0, 0, 50, 0, 0, +0, 7, 0, 0, 0, 31, 0, 0, 0, 184, 0, 0, 0, 14, 0, 0, 0, 25, 0, 0, 0, 158, 0, 0, 0, 153, 0, 0, 0, 41, 0, 0, 0, 51, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 122, 0, 0, 0, 237, 0, 0, 0, 104, 0, 0, 0, 66, 0, 0, 0, 105, 0, 0, 0, 124, 0, 0, 0, 7, 0, 0, 0, 179, 0, 0, 0, 56, 0, 0, 0, 44, 0, 0, 0, 246, 0, 0, 0, 61, 0, 0, 0, 100, 0, 0, 0, 170, 0, 0, 0, 181, 0, 0, 0, 136, 0, 0, 0, 121, 0, 0, 0, 101, 0, 0, 0, 56, 0, 0, 0, 140, 0, 0, 0, 148, 0, 0, 0, 214, 0, 0, 0, 98, 0, 0, 0, 55, 0, 0, 0, 125, 0, 0, 0, 100, 0, 0, +0, 205, 0, 0, 0, 58, 0, 0, 0, 235, 0, 0, 0, 255, 0, 0, 0, 232, 0, 0, 0, 129, 0, 0, 0, 9, 0, 0, 0, 199, 0, 0, 0, 106, 0, 0, 0, 80, 0, 0, 0, 9, 0, 0, 0, 13, 0, 0, 0, 40, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 154, 0, 0, 0, 147, 0, 0, 0, 10, 0, 0, 0, 66, 0, 0, 0, 163, 0, 0, 0, 241, 0, 0, 0, 197, 0, 0, 0, 180, 0, 0, 0, 15, 0, 0, 0, 216, 0, 0, 0, 200, 0, 0, 0, 141, 0, 0, 0, 21, 0, 0, 0, 49, 0, 0, 0, 189, 0, 0, 0, 248, 0, 0, 0, 7, 0, 0, 0, 139, 0, 0, 0, 205, 0, 0, 0, 8, 0, 0, 0, 138, 0, 0, 0, 251, 0, 0, 0, +24, 0, 0, 0, 7, 0, 0, 0, 254, 0, 0, 0, 142, 0, 0, 0, 82, 0, 0, 0, 134, 0, 0, 0, 239, 0, 0, 0, 190, 0, 0, 0, 236, 0, 0, 0, 73, 0, 0, 0, 82, 0, 0, 0, 153, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 169, 0, 0, 0, 213, 0, 0, 0, 1, 0, 0, 0, 170, 0, 0, 0, 72, 0, 0, 0, 79, 0, 0, 0, 40, 0, 0, 0, 102, 0, 0, 0, 50, 0, 0, 0, 26, 0, 0, 0, 186, 0, 0, 0, 124, 0, 0, 0, 234, 0, 0, 0, 17, 0, 0, 0, 128, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 155, 0, 0, 0, 86, 0, 0, 0, 136, 0, 0, 0, 37, 0, 0, 0, 6, 0, 0, 0, 105, 0, 0, 0, 18, 0, +0, 0, 44, 0, 0, 0, 234, 0, 0, 0, 86, 0, 0, 0, 105, 0, 0, 0, 65, 0, 0, 0, 36, 0, 0, 0, 25, 0, 0, 0, 222, 0, 0, 0, 33, 0, 0, 0, 240, 0, 0, 0, 218, 0, 0, 0, 138, 0, 0, 0, 251, 0, 0, 0, 177, 0, 0, 0, 184, 0, 0, 0, 205, 0, 0, 0, 200, 0, 0, 0, 106, 0, 0, 0, 130, 0, 0, 0, 25, 0, 0, 0, 115, 0, 0, 0, 219, 0, 0, 0, 199, 0, 0, 0, 207, 0, 0, 0, 136, 0, 0, 0, 235, 0, 0, 0, 150, 0, 0, 0, 238, 0, 0, 0, 111, 0, 0, 0, 251, 0, 0, 0, 6, 0, 0, 0, 210, 0, 0, 0, 205, 0, 0, 0, 125, 0, 0, 0, 123, 0, 0, 0, 18, 0, 0, 0, 40, +0, 0, 0, 142, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 68, 0, 0, 0, 151, 0, 0, 0, 206, 0, 0, 0, 40, 0, 0, 0, 255, 0, 0, 0, 58, 0, 0, 0, 64, 0, 0, 0, 196, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 155, 0, 0, 0, 244, 0, 0, 0, 107, 0, 0, 0, 7, 0, +0, 0, 132, 0, 0, 0, 251, 0, 0, 0, 152, 0, 0, 0, 216, 0, 0, 0, 236, 0, 0, 0, 140, 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 0, 236, 0, 0, 0, 73, 0, 0, 0, 237, 0, 0, 0, 99, 0, 0, 0, 182, 0, 0, 0, 170, 0, 0, 0, 255, 0, 0, 0, 152, 0, 0, 0, 40, 0, 0, 0, 61, 0, 0, 0, 22, 0, 0, 0, 53, 0, 0, 0, 243, 0, 0, 0, 70, 0, 0, 0, 188, 0, 0, 0, 179, 0, 0, 0, 244, 0, 0, 0, 198, 0, 0, 0, 182, 0, 0, 0, 79, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 160, 0, 0, 0, 19, 0, 0, 0, 230, 0, 0, 0, 87, 0, 0, 0, 69, 0, 0, 0, 147, 0, 0, 0, 185, +0, 0, 0, 188, 0, 0, 0, 214, 0, 0, 0, 89, 0, 0, 0, 231, 0, 0, 0, 119, 0, 0, 0, 148, 0, 0, 0, 108, 0, 0, 0, 171, 0, 0, 0, 150, 0, 0, 0, 59, 0, 0, 0, 79, 0, 0, 0, 9, 0, 0, 0, 90, 0, 0, 0, 247, 0, 0, 0, 107, 0, 0, 0, 1, 0, 0, 0, 18, 0, 0, 0, 79, 0, 0, 0, 81, 0, 0, 0, 193, 0, 0, 0, 112, 0, 0, 0, 132, 0, 0, 0, 148, 0, 0, 0, 71, 0, 0, 0, 178, 0, 0, 0, 1, 0, 0, 0, 108, 0, 0, 0, 113, 0, 0, 0, 215, 0, 0, 0, 204, 0, 0, 0, 23, 0, 0, 0, 102, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 93, 0, 0, 0, 93, 0, 0, 0, 16, 0, +0, 0, 1, 0, 0, 0, 87, 0, 0, 0, 17, 0, 0, 0, 245, 0, 0, 0, 221, 0, 0, 0, 226, 0, 0, 0, 52, 0, 0, 0, 38, 0, 0, 0, 217, 0, 0, 0, 31, 0, 0, 0, 92, 0, 0, 0, 88, 0, 0, 0, 172, 0, 0, 0, 139, 0, 0, 0, 3, 0, 0, 0, 210, 0, 0, 0, 195, 0, 0, 0, 133, 0, 0, 0, 15, 0, 0, 0, 58, 0, 0, 0, 195, 0, 0, 0, 127, 0, 0, 0, 109, 0, 0, 0, 142, 0, 0, 0, 134, 0, 0, 0, 205, 0, 0, 0, 82, 0, 0, 0, 116, 0, 0, 0, 143, 0, 0, 0, 85, 0, 0, 0, 119, 0, 0, 0, 23, 0, 0, 0, 183, 0, 0, 0, 142, 0, 0, 0, 183, 0, 0, 0, 136, 0, 0, 0, 234, 0, +0, 0, 218, 0, 0, 0, 27, 0, 0, 0, 182, 0, 0, 0, 234, 0, 0, 0, 14, 0, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 32, 0, 0, 0, 121, 0, 0, 0, 53, 0, 0, 0, 106, 0, 0, 0, 97, 0, 0, 0, 132, 0, 0, 0, 90, 0, 0, 0, 7, 0, 0, 0, 109, 0, 0, 0, 249, 0, 0, 0, 119, 0, 0, 0, 111, 0, 0, 0, 237, 0, 0, 0, 105, 0, 0, 0, 28, 0, 0, 0, 13, 0, 0, 0, 37, 0, 0, 0, 118, 0, 0, 0, 204, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 187, 0, 0, 0, 197, 0, 0, 0, 173, 0, 0, 0, 226, 0, 0, 0, 38, 0, 0, 0, 87, 0, 0, 0, 207, 0, 0, 0, 232, 0, 0, 0, 14, 0, +0, 0, 107, 0, 0, 0, 150, 0, 0, 0, 125, 0, 0, 0, 237, 0, 0, 0, 39, 0, 0, 0, 209, 0, 0, 0, 60, 0, 0, 0, 169, 0, 0, 0, 217, 0, 0, 0, 80, 0, 0, 0, 169, 0, 0, 0, 152, 0, 0, 0, 132, 0, 0, 0, 94, 0, 0, 0, 134, 0, 0, 0, 239, 0, 0, 0, 214, 0, 0, 0, 240, 0, 0, 0, 248, 0, 0, 0, 14, 0, 0, 0, 137, 0, 0, 0, 5, 0, 0, 0, 47, 0, 0, 0, 217, 0, 0, 0, 95, 0, 0, 0, 21, 0, 0, 0, 95, 0, 0, 0, 115, 0, 0, 0, 121, 0, 0, 0, 200, 0, 0, 0, 92, 0, 0, 0, 22, 0, 0, 0, 254, 0, 0, 0, 237, 0, 0, 0, 159, 0, 0, 0, 38, 0, 0, 0, 86, 0, +0, 0, 246, 0, 0, 0, 75, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 10, 0, 0, 0, 133, 0, 0, 0, 254, 0, 0, 0, 165, 0, 0, 0, 140, 0, 0, 0, 135, 0, 0, 0, 221, 0, 0, 0, 152, 0, 0, 0, 206, 0, 0, 0, 78, 0, 0, 0, 195, 0, 0, 0, 88, 0, 0, 0, 85, 0, 0, 0, 178, 0, 0, 0, 123, 0, 0, 0, 61, 0, 0, 0, 216, 0, 0, 0, 107, 0, 0, 0, 181, 0, 0, 0, 76, 0, 0, 0, 101, 0, 0, 0, 56, 0, 0, 0, 160, 0, 0, 0, 21, 0, 0, 0, 250, 0, 0, 0, 167, 0, 0, 0, 180, 0, 0, 0, 143, 0, 0, 0, 235, 0, 0, 0, 196, 0, 0, 0, 134, 0, 0, 0, 155, 0, 0, 0, +48, 0, 0, 0, 165, 0, 0, 0, 94, 0, 0, 0, 77, 0, 0, 0, 234, 0, 0, 0, 138, 0, 0, 0, 154, 0, 0, 0, 159, 0, 0, 0, 26, 0, 0, 0, 216, 0, 0, 0, 91, 0, 0, 0, 83, 0, 0, 0, 20, 0, 0, 0, 25, 0, 0, 0, 37, 0, 0, 0, 99, 0, 0, 0, 180, 0, 0, 0, 111, 0, 0, 0, 31, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 143, 0, 0, 0, 188, 0, 0, 0, 30, 0, 0, 0, 125, 0, 0, 0, 139, 0, 0, 0, 90, 0, 0, 0, 11, 0, 0, 0, 141, 0, 0, 0, 175, 0, 0, 0, 118, 0, 0, 0, 46, 0, 0, 0, 113, 0, 0, 0, 227, 0, 0, 0, 59, 0, 0, 0, 111, 0, 0, 0, 83, 0, 0, 0, 47, 0, 0, 0, 62, 0, 0, 0, 144, 0, 0, 0, 149, 0, 0, 0, 212, 0, 0, 0, 53, 0, 0, 0, 20, 0, 0, 0, 79, 0, 0, 0, 140, 0, 0, 0, 60, 0, 0, 0, 206, 0, 0, 0, 87, 0, 0, 0, 28, 0, 0, 0, 118, 0, 0, 0, 73, 0, 0, 0, 168, 0, 0, 0, 80, 0, 0, 0, 225, 0, +0, 0, 97, 0, 0, 0, 107, 0, 0, 0, 87, 0, 0, 0, 53, 0, 0, 0, 235, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 110, 0, 0, 0, 249, 0, 0, 0, 37, 0, 0, 0, 128, 0, 0, 0, 116, 0, 0, 0, 242, 0, 0, 0, 143, 0, 0, 0, 111, 0, 0, 0, 122, 0, 0, 0, 62, 0, 0, 0, 127, 0, 0, 0, 45, 0, 0, 0, 243, 0, 0, 0, 78, 0, 0, 0, 9, 0, 0, 0, 101, 0, 0, 0, 16, 0, 0, 0, 94, 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 0, 50, 0, 0, 0, 169, 0, 0, 0, 96, 0, 0, 0, 220, 0, 0, 0, 15, 0, 0, 0, 100, 0, 0, 0, 229, 0, 0, 0, 29, 0, 0, 0, 226, 0, 0, 0, +141, 0, 0, 0, 79, 0, 0, 0, 121, 0, 0, 0, 47, 0, 0, 0, 14, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 119, 0, 0, 0, 67, 0, 0, 0, 37, 0, 0, 0, 61, 0, 0, 0, 106, 0, 0, 0, 199, 0, 0, 0, 183, 0, 0, 0, 191, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 101, 0, 0, 0, 244, 0, 0, 0, 57, 0, 0, 0, 75, 0, 0, 0, 101, 0, 0, 0, 150, 0, 0, 0, 25, 0, 0, 0, 18, 0, 0, 0, 107, 0, 0, 0, 106, 0, 0, 0, 183, 0, 0, 0, 227, 0, 0, 0, 220, 0, 0, 0, 69, 0, 0, 0, 155, 0, 0, 0, 219, 0, 0, 0, 180, 0, 0, 0, 168, 0, 0, 0, 174, +0, 0, 0, 220, 0, 0, 0, 168, 0, 0, 0, 20, 0, 0, 0, 68, 0, 0, 0, 101, 0, 0, 0, 98, 0, 0, 0, 206, 0, 0, 0, 52, 0, 0, 0, 154, 0, 0, 0, 132, 0, 0, 0, 24, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 241, 0, 0, 0, 226, 0, 0, 0, 123, 0, 0, 0, 206, 0, 0, 0, 80, 0, 0, 0, 65, 0, 0, 0, 33, 0, 0, 0, 48, 0, 0, 0, 83, 0, 0, 0, 27, 0, 0, 0, 71, 0, 0, 0, 1, 0, 0, 0, 183, 0, 0, 0, 24, 0, 0, 0, 216, 0, 0, 0, 130, 0, 0, 0, 87, 0, 0, 0, 189, 0, 0, 0, 163, 0, 0, 0, 96, 0, 0, 0, 240, 0, 0, 0, 50, 0, 0, 0, 246, 0, 0, 0, 91, 0, 0, +0, 240, 0, 0, 0, 48, 0, 0, 0, 136, 0, 0, 0, 145, 0, 0, 0, 89, 0, 0, 0, 253, 0, 0, 0, 144, 0, 0, 0, 162, 0, 0, 0, 185, 0, 0, 0, 85, 0, 0, 0, 147, 0, 0, 0, 33, 0, 0, 0, 52, 0, 0, 0, 151, 0, 0, 0, 103, 0, 0, 0, 158, 0, 0, 0, 235, 0, 0, 0, 106, 0, 0, 0, 249, 0, 0, 0, 110, 0, 0, 0, 214, 0, 0, 0, 115, 0, 0, 0, 232, 0, 0, 0, 107, 0, 0, 0, 41, 0, 0, 0, 236, 0, 0, 0, 99, 0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 153, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 48, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 0, 82, 0, +0, 0, 144, 0, 0, 0, 182, 0, 0, 0, 106, 0, 0, 0, 128, 0, 0, 0, 78, 0, 0, 0, 255, 0, 0, 0, 75, 0, 0, 0, 81, 0, 0, 0, 15, 0, 0, 0, 125, 0, 0, 0, 99, 0, 0, 0, 140, 0, 0, 0, 110, 0, 0, 0, 92, 0, 0, 0, 222, 0, 0, 0, 48, 0, 0, 0, 223, 0, 0, 0, 101, 0, 0, 0, 250, 0, 0, 0, 46, 0, 0, 0, 176, 0, 0, 0, 163, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 84, 0, 0, 0, 189, 0, 0, 0, 37, 0, 0, 0, 186, 0, 0, 0, 6, 0, 0, 0, 174, 0, 0, 0, 223, 0, 0, 0, 139, 0, 0, 0, 217, 0, 0, 0, 27, 0, 0, 0, 234, 0, 0, 0, 56, 0, 0, 0, 179, 0, +0, 0, 5, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 199, 0, 0, 0, 140, 0, 0, 0, 191, 0, 0, 0, 100, 0, 0, 0, 40, 0, 0, 0, 173, 0, 0, 0, 248, 0, 0, 0, 165, 0, 0, 0, 90, 0, 0, 0, 111, 0, 0, 0, 201, 0, 0, 0, 186, 0, 0, 0, 213, 0, 0, 0, 127, 0, 0, 0, 213, 0, 0, 0, 214, 0, 0, 0, 189, 0, 0, 0, 102, 0, 0, 0, 47, 0, 0, 0, 61, 0, 0, 0, 170, 0, 0, 0, 84, 0, 0, 0, 246, 0, 0, 0, 186, 0, 0, 0, 50, 0, 0, 0, 34, 0, 0, 0, 154, 0, 0, 0, 30, 0, 0, 0, 82, 0, 0, 0, 5, 0, 0, 0, 244, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 0, 0, 0, 31, 0, 0, 0, 187, 0, 0, 0, 235, 0, 0, 0, 254, 0, 0, 0, 228, 0, 0, 0, 135, 0, 0, 0, 252, 0, 0, 0, 177, 0, 0, 0, 44, 0, 0, 0, 183, 0, 0, 0, 136, 0, 0, 0, 244, 0, 0, 0, 198, 0, 0, 0, 185, 0, 0, 0, 245, 0, 0, 0, 36, 0, 0, 0, 70, 0, 0, 0, 242, 0, 0, +0, 165, 0, 0, 0, 159, 0, 0, 0, 143, 0, 0, 0, 138, 0, 0, 0, 147, 0, 0, 0, 112, 0, 0, 0, 105, 0, 0, 0, 212, 0, 0, 0, 86, 0, 0, 0, 236, 0, 0, 0, 253, 0, 0, 0, 6, 0, 0, 0, 70, 0, 0, 0, 78, 0, 0, 0, 102, 0, 0, 0, 207, 0, 0, 0, 78, 0, 0, 0, 52, 0, 0, 0, 206, 0, 0, 0, 12, 0, 0, 0, 217, 0, 0, 0, 166, 0, 0, 0, 80, 0, 0, 0, 214, 0, 0, 0, 94, 0, 0, 0, 149, 0, 0, 0, 175, 0, 0, 0, 233, 0, 0, 0, 88, 0, 0, 0, 250, 0, 0, 0, 238, 0, 0, 0, 155, 0, 0, 0, 184, 0, 0, 0, 165, 0, 0, 0, 15, 0, 0, 0, 53, 0, 0, 0, 224, 0, +0, 0, 67, 0, 0, 0, 130, 0, 0, 0, 109, 0, 0, 0, 101, 0, 0, 0, 230, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 123, 0, 0, 0, 117, 0, 0, 0, 58, 0, 0, 0, 252, 0, 0, 0, 100, 0, 0, 0, 211, 0, 0, 0, 41, 0, 0, 0, 126, 0, 0, 0, 221, 0, 0, 0, 73, 0, 0, 0, 154, 0, 0, 0, 89, 0, 0, 0, 83, 0, 0, 0, 191, 0, 0, 0, 180, 0, 0, 0, 167, 0, 0, 0, 82, 0, 0, 0, 179, 0, 0, 0, 5, 0, 0, 0, 171, 0, 0, 0, 195, 0, 0, 0, 175, 0, 0, 0, 22, 0, 0, 0, 26, 0, 0, 0, 133, 0, 0, 0, 66, 0, 0, 0, 50, 0, 0, 0, 162, 0, 0, 0, 134, 0, +0, 0, 250, 0, 0, 0, 57, 0, 0, 0, 67, 0, 0, 0, 14, 0, 0, 0, 75, 0, 0, 0, 163, 0, 0, 0, 99, 0, 0, 0, 138, 0, 0, 0, 254, 0, 0, 0, 165, 0, 0, 0, 88, 0, 0, 0, 241, 0, 0, 0, 19, 0, 0, 0, 189, 0, 0, 0, 157, 0, 0, 0, 170, 0, 0, 0, 127, 0, 0, 0, 118, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 129, 0, 0, 0, 16, 0, 0, 0, 117, 0, 0, 0, 153, 0, 0, 0, 187, 0, 0, 0, 190, 0, 0, 0, 11, 0, 0, 0, 22, 0, 0, 0, 233, 0, 0, 0, 186, 0, 0, 0, 98, 0, 0, 0, 52, 0, 0, 0, 204, 0, 0, 0, 7, 0, 0, 0, 109, 0, 0, 0, 195, 0, 0, 0, 241, 0, +0, 0, 198, 0, 0, 0, 147, 0, 0, 0, 101, 0, 0, 0, 238, 0, 0, 0, 11, 0, 0, 0, 188, 0, 0, 0, 234, 0, 0, 0, 20, 0, 0, 0, 240, 0, 0, 0, 193, 0, 0, 0, 248, 0, 0, 0, 132, 0, 0, 0, 137, 0, 0, 0, 194, 0, 0, 0, 201, 0, 0, 0, 215, 0, 0, 0, 234, 0, 0, 0, 52, 0, 0, 0, 202, 0, 0, 0, 167, 0, 0, 0, 196, 0, 0, 0, 153, 0, 0, 0, 213, 0, 0, 0, 80, 0, 0, 0, 105, 0, 0, 0, 203, 0, 0, 0, 214, 0, 0, 0, 33, 0, 0, 0, 99, 0, 0, 0, 124, 0, 0, 0, 153, 0, 0, 0, 235, 0, 0, 0, 124, 0, 0, 0, 49, 0, 0, 0, 115, 0, 0, 0, 100, 0, 0, 0, +103, 0, 0, 0, 127, 0, 0, 0, 12, 0, 0, 0, 102, 0, 0, 0, 170, 0, 0, 0, 140, 0, 0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 226, 0, 0, 0, 38, 0, 0, 0, 211, 0, 0, 0, 35, 0, 0, 0, 226, 0, 0, 0, 118, 0, 0, 0, 93, 0, 0, 0, 50, 0, 0, 0, 82, 0, 0, 0, 223, 0, 0, 0, 93, 0, 0, 0, 197, 0, 0, 0, 143, 0, 0, 0, 183, 0, 0, 0, 124, 0, 0, 0, 132, 0, 0, 0, 179, 0, 0, 0, 112, 0, 0, 0, 235, 0, 0, 0, 1, 0, 0, 0, 199, 0, 0, 0, 54, 0, 0, 0, 151, 0, 0, 0, 78, 0, 0, 0, 182, 0, 0, 0, 171, 0, 0, 0, 95, 0, 0, 0, 13, 0, 0, 0, 44, 0, 0, +0, 186, 0, 0, 0, 103, 0, 0, 0, 100, 0, 0, 0, 85, 0, 0, 0, 222, 0, 0, 0, 188, 0, 0, 0, 255, 0, 0, 0, 166, 0, 0, 0, 236, 0, 0, 0, 4, 0, 0, 0, 211, 0, 0, 0, 141, 0, 0, 0, 57, 0, 0, 0, 86, 0, 0, 0, 94, 0, 0, 0, 238, 0, 0, 0, 248, 0, 0, 0, 228, 0, 0, 0, 46, 0, 0, 0, 51, 0, 0, 0, 98, 0, 0, 0, 101, 0, 0, 0, 239, 0, 0, 0, 184, 0, 0, 0, 159, 0, 0, 0, 200, 0, 0, 0, 75, 0, 0, 0, 167, 0, 0, 0, 253, 0, 0, 0, 33, 0, 0, 0, 73, 0, 0, 0, 155, 0, 0, 0, 146, 0, 0, 0, 53, 0, 0, 0, 130, 0, 0, 0, 214, 0, 0, 0, 10, 0, +0, 0, 155, 0, 0, 0, 242, 0, 0, 0, 121, 0, 0, 0, 241, 0, 0, 0, 71, 0, 0, 0, 47, 0, 0, 0, 106, 0, 0, 0, 126, 0, 0, 0, 159, 0, 0, 0, 207, 0, 0, 0, 24, 0, 0, 0, 2, 0, 0, 0, 60, 0, 0, 0, 251, 0, 0, 0, 27, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, +139, 0, 0, 0, 200, 0, 0, 0, 64, 0, 0, 0, 81, 0, 0, 0, 209, 0, 0, 0, 172, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 228, 0, 0, 0, 169, 0, 0, 0, 162, 0, 0, 0, 66, 0, 0, 0, 33, 0, 0, 0, 25, 0, 0, 0, 47, 0, 0, 0, 123, 0, 0, 0, 151, 0, 0, 0, 191, 0, 0, 0, 247, 0, 0, 0, 87, 0, 0, 0, 109, 0, 0, 0, 63, 0, 0, 0, 61, 0, 0, 0, 79, 0, 0, 0, 15, 0, 0, 0, 226, 0, 0, 0, 178, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 123, 0, 0, 0, 140, 0, 0, 0, 133, 0, 0, 0, 43, 0, 0, 0, 196, 0, 0, 0, 252, 0, 0, 0, 241, 0, 0, 0, +171, 0, 0, 0, 232, 0, 0, 0, 121, 0, 0, 0, 34, 0, 0, 0, 196, 0, 0, 0, 132, 0, 0, 0, 23, 0, 0, 0, 58, 0, 0, 0, 250, 0, 0, 0, 134, 0, 0, 0, 166, 0, 0, 0, 125, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 111, 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 0, 32, 0, 0, 0, 77, 0, 0, 0, 121, 0, 0, 0, 249, 0, 0, 0, 110, 0, 0, 0, 113, 0, 0, 0, 84, 0, 0, 0, 56, 0, 0, 0, 9, 0, 0, 0, 64, 0, 0, 0, 41, 0, 0, 0, 116, 0, 0, 0, 168, 0, 0, 0, 47, 0, 0, 0, 94, 0, 0, 0, 249, 0, 0, 0, 121, 0, 0, 0, 164, 0, 0, 0, 243, 0, 0, 0, 62, 0, 0, 0, +185, 0, 0, 0, 253, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 172, 0, 0, 0, 154, 0, 0, 0, 105, 0, 0, 0, 136, 0, 0, 0, 30, 0, 0, 0]).concat([119, 0, 0, 0, 33, 0, 0, 0, 45, 0, 0, 0, 243, 0, 0, 0, 145, 0, 0, 0, 82, 0, 0, 0, 38, 0, 0, 0, 21, 0, 0, 0, 178, 0, 0, 0, 166, 0, 0, 0, 207, 0, 0, 0, 126, 0, 0, 0, 198, 0, 0, 0, 32, 0, 0, 0, 71, 0, 0, 0, 108, 0, 0, 0, 164, 0, 0, 0, 125, 0, 0, 0, 203, 0, 0, 0, 99, 0, 0, 0, 234, 0, 0, 0, 91, 0, 0, 0, 3, 0, 0, 0, 223, 0, 0, 0, 62, 0, 0, 0, 136, 0, 0, 0, 129, 0, 0, 0, 109, +0, 0, 0, 206, 0, 0, 0, 7, 0, 0, 0, 66, 0, 0, 0, 24, 0, 0, 0, 96, 0, 0, 0, 126, 0, 0, 0, 123, 0, 0, 0, 85, 0, 0, 0, 254, 0, 0, 0, 106, 0, 0, 0, 243, 0, 0, 0, 218, 0, 0, 0, 92, 0, 0, 0, 139, 0, 0, 0, 149, 0, 0, 0, 16, 0, 0, 0, 98, 0, 0, 0, 228, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 180, 0, 0, 0, 215, 0, 0, 0, 205, 0, 0, 0, 250, 0, 0, 0, 189, 0, 0, 0, 70, 0, 0, 0, 223, 0, 0, 0, 147, 0, 0, 0, 113, 0, 0, 0, 16, 0, 0, 0, 44, 0, 0, 0, 168, 0, 0, 0, 59, 0, 0, 0, 182, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 112, 0, +0, 0, 132, 0, 0, 0, 67, 0, 0, 0, 41, 0, 0, 0, 168, 0, 0, 0, 89, 0, 0, 0, 245, 0, 0, 0, 142, 0, 0, 0, 16, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 32, 0, 0, 0, 87, 0, 0, 0, 130, 0, 0, 0, 28, 0, 0, 0, 171, 0, 0, 0, 191, 0, 0, 0, 98, 0, 0, 0, 112, 0, 0, 0, 232, 0, 0, 0, 196, 0, 0, 0, 207, 0, 0, 0, 240, 0, 0, 0, 40, 0, 0, 0, 110, 0, 0, 0, 22, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 120, 0, 0, 0, 137, 0, 0, 0, 133, 0, 0, 0, 70, 0, 0, 0, 15, 0, 0, 0, 246, 0, 0, 0, 127, 0, 0, 0, 207, 0, 0, 0, 203, 0, 0, 0, 126, 0, +0, 0, 184, 0, 0, 0, 37, 0, 0, 0, 233, 0, 0, 0, 90, 0, 0, 0, 250, 0, 0, 0, 3, 0, 0, 0, 251, 0, 0, 0, 149, 0, 0, 0, 146, 0, 0, 0, 99, 0, 0, 0, 80, 0, 0, 0, 252, 0, 0, 0, 98, 0, 0, 0, 240, 0, 0, 0, 164, 0, 0, 0, 94, 0, 0, 0, 140, 0, 0, 0, 24, 0, 0, 0, 194, 0, 0, 0, 23, 0, 0, 0, 36, 0, 0, 0, 183, 0, 0, 0, 120, 0, 0, 0, 194, 0, 0, 0, 169, 0, 0, 0, 231, 0, 0, 0, 106, 0, 0, 0, 50, 0, 0, 0, 214, 0, 0, 0, 41, 0, 0, 0, 133, 0, 0, 0, 175, 0, 0, 0, 203, 0, 0, 0, 141, 0, 0, 0, 145, 0, 0, 0, 19, 0, 0, 0, 218, +0, 0, 0, 107, 0, 0, 0, 54, 0, 0, 0, 10, 0, 0, 0, 194, 0, 0, 0, 182, 0, 0, 0, 75, 0, 0, 0, 165, 0, 0, 0, 93, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 65, 0, 0, 0, 49, 0, 0, 0, 95, 0, 0, 0, 98, 0, 0, 0, 70, 0, 0, 0, 248, 0, 0, 0, 146, 0, 0, 0, 249, 0, 0, 0, 102, 0, 0, 0, 72, 0, 0, 0, 115, 0, 0, 0, 166, 0, 0, 0, 151, 0, 0, 0, 13, 0, 0, 0, 125, 0, 0, 0, 136, 0, 0, 0, 238, 0, 0, 0, 98, 0, 0, 0, 177, 0, 0, 0, 3, 0, 0, 0, 168, 0, 0, 0, 63, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 177, 0, 0, 0, 112, 0, 0, 0, 138, 0, 0, 0, 169, 0, 0, 0, 232, 0, 0, 0, 99, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 37, 0, 0, 0, 22, 0, 0, 0, 202, 0, 0, 0, 75, 0, 0, 0, 15, 0, 0, 0, 164, 0, 0, 0, 102, 0, 0, 0, 173, 0, 0, 0, 25, 0, 0, 0, 159, 0, 0, 0, 136, 0, 0, 0, +103, 0, 0, 0, 12, 0, 0, 0, 139, 0, 0, 0, 194, 0, 0, 0, 74, 0, 0, 0, 91, 0, 0, 0, 43, 0, 0, 0, 109, 0, 0, 0, 149, 0, 0, 0, 175, 0, 0, 0, 25, 0, 0, 0, 139, 0, 0, 0, 157, 0, 0, 0, 182, 0, 0, 0, 204, 0, 0, 0, 96, 0, 0, 0, 180, 0, 0, 0, 114, 0, 0, 0, 79, 0, 0, 0, 23, 0, 0, 0, 105, 0, 0, 0, 90, 0, 0, 0, 74, 0, 0, 0, 104, 0, 0, 0, 52, 0, 0, 0, 171, 0, 0, 0, 161, 0, 0, 0, 69, 0, 0, 0, 50, 0, 0, 0, 60, 0, 0, 0, 131, 0, 0, 0, 135, 0, 0, 0, 114, 0, 0, 0, 48, 0, 0, 0, 84, 0, 0, 0, 119, 0, 0, 0, 104, 0, 0, 0, +174, 0, 0, 0, 251, 0, 0, 0, 181, 0, 0, 0, 139, 0, 0, 0, 34, 0, 0, 0, 94, 0, 0, 0, 241, 0, 0, 0, 185, 0, 0, 0, 135, 0, 0, 0, 53, 0, 0, 0, 197, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 207, 0, 0, 0, 245, 0, 0, 0, 214, 0, 0, 0, 205, 0, 0, 0, 213, 0, 0, 0, 12, 0, 0, 0, 124, 0, 0, 0, 14, 0, 0, 0, 230, 0, 0, 0, 144, 0, 0, 0, 52, 0, 0, 0, 251, 0, 0, 0, 81, 0, 0, 0, 66, 0, 0, 0, 30, 0, 0, 0, 109, 0, 0, 0, 172, 0, 0, 0, 154, 0, 0, 0, 70, 0, 0, 0, 196, 0, 0, 0, 151, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 191, 0, 0, +0, 69, 0, 0, 0, 102, 0, 0, 0, 158, 0, 0, 0, 198, 0, 0, 0, 36, 0, 0, 0, 192, 0, 0, 0, 237, 0, 0, 0, 165, 0, 0, 0, 93, 0, 0, 0, 136, 0, 0, 0, 212, 0, 0, 0, 240, 0, 0, 0, 115, 0, 0, 0, 151, 0, 0, 0, 123, 0, 0, 0, 234, 0, 0, 0, 127, 0, 0, 0, 66, 0, 0, 0, 255, 0, 0, 0, 33, 0, 0, 0, 160, 0, 0, 0, 155, 0, 0, 0, 47, 0, 0, 0, 154, 0, 0, 0, 253, 0, 0, 0, 83, 0, 0, 0, 87, 0, 0, 0, 7, 0, 0, 0, 132, 0, 0, 0, 72, 0, 0, 0, 136, 0, 0, 0, 157, 0, 0, 0, 82, 0, 0, 0, 198, 0, 0, 0, 150, 0, 0, 0, 72, 0, 0, 0, 52, 0, +0, 0, 42, 0, 0, 0, 6, 0, 0, 0, 175, 0, 0, 0, 148, 0, 0, 0, 61, 0, 0, 0, 244, 0, 0, 0, 26, 0, 0, 0, 207, 0, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 33, 0, 0, 0, 194, 0, 0, 0, 66, 0, 0, 0, 94, 0, 0, 0, 200, 0, 0, 0, 47, 0, 0, 0, 53, 0, 0, 0, 162, 0, 0, 0, 62, 0, 0, 0, 41, 0, 0, 0, 250, 0, 0, 0, 12, 0, 0, 0, 132, 0, 0, 0, 229, 0, 0, 0, 137, 0, 0, 0, 114, 0, 0, 0, 124, 0, 0, 0, 6, 0, 0, 0, 50, 0, 0, 0, 101, 0, 0, 0, 3, 0, 0, 0, 229, 0, 0, 0, 137, 0, 0, 0, 166, 0, 0, 0, 110, 0, 0, 0, 179, 0, 0, 0, 91, 0, 0, +0, 142, 0, 0, 0, 202, 0, 0, 0, 235, 0, 0, 0, 254, 0, 0, 0, 34, 0, 0, 0, 86, 0, 0, 0, 139, 0, 0, 0, 93, 0, 0, 0, 20, 0, 0, 0, 75, 0, 0, 0, 77, 0, 0, 0, 249, 0, 0, 0, 190, 0, 0, 0, 181, 0, 0, 0, 245, 0, 0, 0, 230, 0, 0, 0, 92, 0, 0, 0, 123, 0, 0, 0, 139, 0, 0, 0, 244, 0, 0, 0, 19, 0, 0, 0, 17, 0, 0, 0, 52, 0, 0, 0, 7, 0, 0, 0, 198, 0, 0, 0, 34, 0, 0, 0, 21, 0, 0, 0, 226, 0, 0, 0, 156, 0, 0, 0, 96, 0, 0, 0, 162, 0, 0, 0, 25, 0, 0, 0, 217, 0, 0, 0, 39, 0, 0, 0, 174, 0, 0, 0, 55, 0, 0, 0, 78, 0, 0, 0, +166, 0, 0, 0, 201, 0, 0, 0, 128, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 143, 0, 0, 0, 18, 0, 0, 0, 73, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 71, 0, 0, 0, 209, 0, 0, 0, 215, 0, 0, 0, 40, 0, 0, 0, 34, 0, 0, 0, 99, 0, 0, 0, 57, 0, 0, 0, 232, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 242, 0, 0, 0, 158, 0, 0, 0, 30, 0, 0, 0, 153, 0, 0, 0, 57, 0, 0, 0, 149, 0, 0, 0, 4, 0, 0, 0, 189, 0, 0, 0, 30, 0, 0, 0, 103, 0, 0, 0, 123, 0, 0, 0, 178, 0, 0, 0, 38, 0, 0, 0, 172, 0, 0, 0, 230, 0, 0, 0, 170, +0, 0, 0, 226, 0, 0, 0, 70, 0, 0, 0, 213, 0, 0, 0, 228, 0, 0, 0, 232, 0, 0, 0, 134, 0, 0, 0, 189, 0, 0, 0, 171, 0, 0, 0, 124, 0, 0, 0, 85, 0, 0, 0, 89, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 100, 0, 0, 0, 110, 0, 0, 0, 155, 0, 0, 0, 53, 0, +0, 0, 113, 0, 0, 0, 120, 0, 0, 0, 206, 0, 0, 0, 51, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 54, 0, 0, 0, 241, 0, 0, 0, 115, 0, 0, 0, 155, 0, 0, 0, 185, 0, 0, 0, 21, 0, 0, 0, 139, 0, 0, 0, 44, 0, 0, 0, 105, 0, 0, 0, 207, 0, 0, 0, 77, 0, 0, 0, 237, 0, 0, 0, 79, 0, 0, 0, 77, 0, 0, 0, 87, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 130, 0, 0, 0, 164, 0, 0, 0, 77, 0, 0, 0, 101, 0, 0, 0, 110, 0, 0, 0, 10, 0, 0, 0, 164, 0, 0, 0, 89, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 242, 0, 0, 0, 107, 0, 0, 0, 74, 0, 0, 0, +31, 0, 0, 0, 110, 0, 0, 0, 246, 0, 0, 0, 181, 0, 0, 0, 188, 0, 0, 0, 98, 0, 0, 0, 228, 0, 0, 0, 182, 0, 0, 0, 218, 0, 0, 0, 162, 0, 0, 0, 147, 0, 0, 0, 188, 0, 0, 0, 41, 0, 0, 0, 5, 0, 0, 0, 210, 0, 0, 0, 210, 0, 0, 0, 115, 0, 0, 0, 70, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 0, 64, 0, 0, 0, 49, 0, 0, 0, 76, 0, 0, 0, 115, 0, 0, 0, 109, 0, 0, 0, 21, 0, 0, 0, 189, 0, 0, 0, 161, 0, 0, 0, 77, 0, 0, 0, 92, 0, 0, 0, 19, 0, 0, 0, 11, 0, 0, 0, 36, 0, 0, 0, 6, 0, 0, 0, 152, 0, 0, 0, 120, 0, 0, 0, 28, 0, 0, 0, 91, +0, 0, 0, 235, 0, 0, 0, 31, 0, 0, 0, 24, 0, 0, 0, 84, 0, 0, 0, 67, 0, 0, 0, 217, 0, 0, 0, 85, 0, 0, 0, 102, 0, 0, 0, 218, 0, 0, 0, 41, 0, 0, 0, 33, 0, 0, 0, 232, 0, 0, 0, 184, 0, 0, 0, 60, 0, 0, 0, 66, 0, 0, 0, 34, 0, 0, 0, 180, 0, 0, 0, 205, 0, 0, 0, 8, 0, 0, 0, 111, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 0, 11, 0, 0, 0, 34, 0, 0, 0, 237, 0, 0, 0, 209, 0, 0, 0, 241, 0, 0, 0, 167, 0, 0, 0, 199, 0, 0, 0, 115, 0, 0, 0, 69, 0, 0, 0, 243, 0, 0, 0, 158, 0, 0, 0, 206, 0, 0, 0, 118, 0, 0, 0, 183, 0, +0, 0, 246, 0, 0, 0, 57, 0, 0, 0, 182, 0, 0, 0, 142, 0, 0, 0, 121, 0, 0, 0, 190, 0, 0, 0, 233, 0, 0, 0, 155, 0, 0, 0, 207, 0, 0, 0, 125, 0, 0, 0, 98, 0, 0, 0, 146, 0, 0, 0, 91, 0, 0, 0, 252, 0, 0, 0, 114, 0, 0, 0, 253, 0, 0, 0, 186, 0, 0, 0, 241, 0, 0, 0, 253, 0, 0, 0, 166, 0, 0, 0, 124, 0, 0, 0, 149, 0, 0, 0, 227, 0, 0, 0, 97, 0, 0, 0, 63, 0, 0, 0, 233, 0, 0, 0, 3, 0, 0, 0, 212, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 32, 0, 0, 0, 217, 0, 0, 0, 219, 0, 0, 0, 77, 0, 0, 0, 50, 0, 0, 0, 62, 0, 0, 0, 245, +0, 0, 0, 17, 0, 0, 0, 100, 0, 0, 0, 227, 0, 0, 0, 180, 0, 0, 0, 190, 0, 0, 0, 50, 0, 0, 0, 134, 0, 0, 0, 23, 0, 0, 0, 144, 0, 0, 0, 231, 0, 0, 0, 201, 0, 0, 0, 31, 0, 0, 0, 16, 0, 0, 0, 165, 0, 0, 0, 106, 0, 0, 0, 45, 0, 0, 0, 57, 0, 0, 0, 208, 0, 0, 0, 59, 0, 0, 0, 196, 0, 0, 0, 166, 0, 0, 0, 233, 0, 0, 0, 89, 0, 0, 0, 19, 0, 0, 0, 218, 0, 0, 0, 26, 0, 0, 0, 230, 0, 0, 0, 160, 0, 0, 0, 185, 0, 0, 0, 60, 0, 0, 0, 80, 0, 0, 0, 184, 0, 0, 0, 64, 0, 0, 0, 124, 0, 0, 0, 21, 0, 0, 0, 54, 0, 0, 0, 90, +0, 0, 0, 66, 0, 0, 0, 180, 0, 0, 0, 11, 0, 0, 0, 50, 0, 0, 0, 171, 0, 0, 0, 220, 0, 0, 0, 4, 0, 0, 0, 81, 0, 0, 0, 85, 0, 0, 0, 33, 0, 0, 0, 30, 0, 0, 0, 11, 0, 0, 0, 117, 0, 0, 0, 153, 0, 0, 0, 137, 0, 0, 0, 115, 0, 0, 0, 53, 0, 0, 0, 58, 0, 0, 0, 145, 0, 0, 0, 43, 0, 0, 0, 254, 0, 0, 0, 231, 0, 0, 0, 73, 0, 0, 0, 234, 0, 0, 0, 118, 0, 0, 0, 193, 0, 0, 0, 249, 0, 0, 0, 70, 0, 0, 0, 185, 0, 0, 0, 83, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 252, 0, 0, 0, 90, 0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, +116, 0, 0, 0, 88, 0, 0, 0, 149, 0, 0, 0, 166, 0, 0, 0, 143, 0, 0, 0, 123, 0, 0, 0, 151, 0, 0, 0, 62, 0, 0, 0, 23, 0, 0, 0, 59, 0, 0, 0, 121, 0, 0, 0, 45, 0, 0, 0, 166, 0, 0, 0, 87, 0, 0, 0, 239, 0, 0, 0, 69, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 77, 0, 0, 0, 110, 0, 0, 0, 158, 0, 0, 0, 147, 0, 0, 0, 141, 0, 0, 0, 47, 0, 0, 0, 217, 0, 0, 0, 157, 0, 0, 0, 219, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 215, 0, 0, 0, 86, 0, 0, 0, 151, 0, 0, 0, 88, 0, 0, 0, 145, 0, 0, 0, 222, 0, 0, 0, 9, 0, 0, 0, 79, 0, 0, 0, 159, 0, 0, 0, 190, 0, 0, 0, 99, 0, 0, 0, 176, 0, 0, 0, 131, 0, 0, 0, 134, 0, 0, 0, 67, 0, 0, 0, 93, 0, 0, 0, 188, 0, 0, 0, 224, 0, 0, 0, 243, 0, 0, 0, 192, 0, 0, 0, 117, 0, 0, 0, 191, 0, 0, 0, 139, 0, 0, 0, 142, 0, 0, 0, 170, 0, 0, 0, 247, +0, 0, 0, 139, 0, 0, 0, 100, 0, 0, 0, 110, 0, 0, 0, 176, 0, 0, 0, 99, 0, 0, 0, 22, 0, 0, 0, 174, 0, 0, 0, 139, 0, 0, 0, 224, 0, 0, 0, 155, 0, 0, 0, 36, 0, 0, 0, 104, 0, 0, 0, 92, 0, 0, 0, 68, 0, 0, 0, 194, 0, 0, 0, 208, 0, 0, 0, 8, 0, 0, 0, 183, 0, 0, 0, 123, 0, 0, 0, 98, 0, 0, 0, 253, 0, 0, 0, 127, 0, 0, 0, 216, 0, 0, 0, 212, 0, 0, 0, 183, 0, 0, 0, 80, 0, 0, 0, 253, 0, 0, 0, 44, 0, 0, 0, 27, 0, 0, 0, 191, 0, 0, 0, 65, 0, 0, 0, 149, 0, 0, 0, 217, 0, 0, 0, 142, 0, 0, 0, 216, 0, 0, 0, 23, 0, 0, 0, 27, +0, 0, 0, 134, 0, 0, 0, 85, 0, 0, 0, 55, 0, 0, 0, 142, 0, 0, 0, 195, 0, 0, 0, 56, 0, 0, 0, 72, 0, 0, 0, 20, 0, 0, 0, 181, 0, 0, 0, 151, 0, 0, 0, 210, 0, 0, 0, 167, 0, 0, 0, 84, 0, 0, 0, 69, 0, 0, 0, 241, 0, 0, 0, 53, 0, 0, 0, 68, 0, 0, 0, 56, 0, 0, 0, 158, 0, 0, 0, 241, 0, 0, 0, 27, 0, 0, 0, 182, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 150, 0, 0, 0, 238, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 44, 0, 0, 0, 11, 0, 0, 0, 234, 0, 0, 0, 218, 0, 0, 0, 153, 0, 0, 0, 158, 0, 0, 0, 25, 0, 0, +0, 131, 0, 0, 0, 102, 0, 0, 0, 109, 0, 0, 0, 233, 0, 0, 0, 118, 0, 0, 0, 135, 0, 0, 0, 80, 0, 0, 0, 209, 0, 0, 0, 253, 0, 0, 0, 60, 0, 0, 0, 96, 0, 0, 0, 135, 0, 0, 0, 198, 0, 0, 0, 65, 0, 0, 0, 217, 0, 0, 0, 142, 0, 0, 0, 219, 0, 0, 0, 94, 0, 0, 0, 222, 0, 0, 0, 170, 0, 0, 0, 154, 0, 0, 0, 211, 0, 0, 0, 40, 0, 0, 0, 218, 0, 0, 0, 149, 0, 0, 0, 234, 0, 0, 0, 71, 0, 0, 0, 208, 0, 0, 0, 128, 0, 0, 0, 186, 0, 0, 0, 25, 0, 0, 0, 174, 0, 0, 0, 29, 0, 0, 0, 169, 0, 0, 0, 121, 0, 0, 0, 246, 0, 0, 0, 63, +0, 0, 0, 172, 0, 0, 0, 93, 0, 0, 0, 111, 0, 0, 0, 150, 0, 0, 0, 31, 0, 0, 0, 42, 0, 0, 0, 206, 0, 0, 0, 41, 0, 0, 0, 178, 0, 0, 0, 255, 0, 0, 0, 55, 0, 0, 0, 241, 0, 0, 0, 148, 0, 0, 0, 143, 0, 0, 0, 12, 0, 0, 0, 181, 0, 0, 0, 40, 0, 0, 0, 186, 0, 0, 0, 154, 0, 0, 0, 33, 0, 0, 0, 246, 0, 0, 0, 102, 0, 0, 0, 2, 0, 0, 0, 251, 0, 0, 0, 84, 0, 0, 0, 184, 0, 0, 0, 5, 0, 0, 0, 243, 0, 0, 0, 129, 0, 0, 0, 82, 0, 0, 0, 105, 0, 0, 0, 52, 0, 0, 0, 70, 0, 0, 0, 157, 0, 0, 0, 134, 0, 0, 0, 118, 0, 0, 0, 143, +0, 0, 0, 215, 0, 0, 0, 248, 0, 0, 0, 106, 0, 0, 0, 102, 0, 0, 0, 255, 0, 0, 0, 230, 0, 0, 0, 167, 0, 0, 0, 144, 0, 0, 0, 247, 0, 0, 0, 94, 0, 0, 0, 205, 0, 0, 0, 106, 0, 0, 0, 155, 0, 0, 0, 85, 0, 0, 0, 252, 0, 0, 0, 157, 0, 0, 0, 72, 0, 0, 0, 189, 0, 0, 0, 170, 0, 0, 0, 19, 0, 0, 0, 230, 0, 0, 0, 205, 0, 0, 0, 69, 0, 0, 0, 74, 0, 0, 0, 164, 0, 0, 0, 89, 0, 0, 0, 10, 0, 0, 0, 100, 0, 0, 0, 177, 0, 0, 0, 152, 0, 0, 0, 214, 0, 0, 0, 52, 0, 0, 0, 19, 0, 0, 0, 4, 0, 0, 0, 230, 0, 0, 0, 151, 0, 0, 0, +148, 0, 0, 0, 6, 0, 0, 0, 203, 0, 0, 0, 212, 0, 0, 0, 78, 0, 0, 0, 187, 0, 0, 0, 150, 0, 0, 0, 205, 0, 0, 0, 209, 0, 0, 0, 87, 0, 0, 0, 209, 0, 0, 0, 227, 0, 0, 0, 6, 0, 0, 0, 122, 0, 0, 0, 108, 0, 0, 0, 69, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 147, 0, 0, 0, 127, 0, 0, 0, 125, 0, 0, 0, 124, 0, 0, 0, 98, 0, 0, 0, 80, 0, 0, 0, 56, 0, 0, 0, 58, 0, 0, 0, 107, 0, 0, 0, 181, 0, 0, 0, 136, 0, 0, 0, 198, 0, 0, 0, 217, 0, 0, 0, 241, 0, 0, 0, 120, 0, 0, 0, 25, 0, 0, 0, 185, 0, 0, 0, 57, 0, 0, 0, 147, 0, 0, +0, 61, 0, 0, 0, 201, 0, 0, 0, 224, 0, 0, 0, 156, 0, 0, 0, 60, 0, 0, 0, 206, 0, 0, 0, 245, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 234, 0, 0, 0, 35, 0, 0, 0, 125, 0, 0, 0, 86, 0, 0, 0, 44, 0, 0, 0, 226, 0, 0, 0, 89, 0, 0, 0, 14, 0, 0, 0, 133, +0, 0, 0, 96, 0, 0, 0, 4, 0, 0, 0, 136, 0, 0, 0, 90, 0, 0, 0, 116, 0, 0, 0, 30, 0, 0, 0, 75, 0, 0, 0, 239, 0, 0, 0, 19, 0, 0, 0, 218, 0, 0, 0, 76, 0, 0, 0, 255, 0, 0, 0, 131, 0, 0, 0, 69, 0, 0, 0, 133, 0, 0, 0, 63, 0, 0, 0, 8, 0, 0, 0, 149, 0, 0, 0, 44, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 31, 0, 0, 0, 72, 0, 0, 0, 95, 0, 0, 0, 39, 0, 0, 0, 144, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0, 0, 66, 0, 0, 0, 173, 0, 0, 0, 120, 0, 0, 0, 71, 0, 0, 0, 92, 0, 0, 0, 181, 0, 0, 0, 126, 0, 0, 0, 8, 0, 0, 0, 133, 0, 0, 0, 0, +0, 0, 0, 250, 0, 0, 0, 127, 0, 0, 0, 253, 0, 0, 0, 253, 0, 0, 0, 231, 0, 0, 0, 9, 0, 0, 0, 17, 0, 0, 0, 242, 0, 0, 0, 126, 0, 0, 0, 27, 0, 0, 0, 56, 0, 0, 0, 108, 0, 0, 0, 53, 0, 0, 0, 109, 0, 0, 0, 51, 0, 0, 0, 102, 0, 0, 0, 147, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 0, 129, 0, 0, 0, 172, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 53, 0, 0, 0, 76, 0, 0, 0, 69, 0, 0, 0, 178, 0, 0, 0, 30, 0, 0, 0, 76, 0, 0, 0, 20, 0, 0, 0, 33, 0, 0, 0, 230, 0, 0, 0, 233, 0, 0, 0, 138, 0, 0, 0, 123, 0, 0, 0, 141, 0, +0, 0, 254, 0, 0, 0, 30, 0, 0, 0, 198, 0, 0, 0, 62, 0, 0, 0, 193, 0, 0, 0, 53, 0, 0, 0, 250, 0, 0, 0, 231, 0, 0, 0, 112, 0, 0, 0, 78, 0, 0, 0, 29, 0, 0, 0, 97, 0, 0, 0, 46, 0, 0, 0, 194, 0, 0, 0, 221, 0, 0, 0, 149, 0, 0, 0, 87, 0, 0, 0, 209, 0, 0, 0, 171, 0, 0, 0, 128, 0, 0, 0, 232, 0, 0, 0, 99, 0, 0, 0, 23, 0, 0, 0, 181, 0, 0, 0, 72, 0, 0, 0, 228, 0, 0, 0, 138, 0, 0, 0, 17, 0, 0, 0, 158, 0, 0, 0, 114, 0, 0, 0, 190, 0, 0, 0, 133, 0, 0, 0, 141, 0, 0, 0, 81, 0, 0, 0, 10, 0, 0, 0, 242, 0, 0, 0, 159, +0, 0, 0, 224, 0, 0, 0, 28, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 187, 0, 0, 0, 113, 0, 0, 0, 20, 0, 0, 0, 94, 0, 0, 0, 38, 0, 0, 0, 140, 0, 0, 0, 61, 0, 0, 0, 200, 0, 0, 0, 233, 0, 0, 0, 124, 0, 0, 0, 211, 0, 0, 0, 214, 0, 0, 0, 209, 0, 0, 0, 47, 0, 0, 0, 7, 0, 0, 0, 109, 0, 0, 0, 230, 0, 0, 0, 223, 0, 0, 0, 251, 0, 0, 0, 121, 0, 0, 0, 214, 0, 0, 0, 153, 0, 0, 0, 89, 0, 0, 0, 150, 0, 0, 0, 72, 0, 0, 0, 64, 0, 0, 0, 15, 0, 0, 0, 58, 0, 0, 0, 123, 0, 0, 0, 178, 0, 0, 0, 160, +0, 0, 0, 114, 0, 0, 0, 78, 0, 0, 0, 59, 0, 0, 0, 105, 0, 0, 0, 200, 0, 0, 0, 67, 0, 0, 0, 117, 0, 0, 0, 81, 0, 0, 0, 108, 0, 0, 0, 121, 0, 0, 0, 86, 0, 0, 0, 228, 0, 0, 0, 203, 0, 0, 0, 247, 0, 0, 0, 166, 0, 0, 0, 81, 0, 0, 0, 194, 0, 0, 0, 44, 0, 0, 0, 66, 0, 0, 0, 11, 0, 0, 0, 212, 0, 0, 0, 130, 0, 0, 0, 32, 0, 0, 0, 28, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 102, 0, 0, 0, 215, 0, 0, 0, 191, 0, 0, 0, 4, 0, 0, 0, 86, 0, 0, 0, 252, 0, 0, 0, 2, 0, 0, 0, 36, 0, 0, 0, 232, 0, 0, 0, 183, 0, 0, 0, 96, 0, 0, +0, 174, 0, 0, 0, 71, 0, 0, 0, 128, 0, 0, 0, 252, 0, 0, 0, 229, 0, 0, 0, 35, 0, 0, 0, 231, 0, 0, 0, 194, 0, 0, 0, 201, 0, 0, 0, 133, 0, 0, 0, 230, 0, 0, 0, 152, 0, 0, 0, 160, 0, 0, 0, 41, 0, 0, 0, 78, 0, 0, 0, 225, 0, 0, 0, 132, 0, 0, 0, 57, 0, 0, 0, 45, 0, 0, 0, 149, 0, 0, 0, 44, 0, 0, 0, 243, 0, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 255, 0, 0, 0, 175, 0, 0, 0, 39, 0, 0, 0, 76, 0, 0, 0, 107, 0, 0, 0, 166, 0, 0, 0, 245, 0, 0, 0, 75, 0, 0, 0, 17, 0, 0, 0, 189, 0, 0, 0, 186, 0, 0, 0, 91, 0, 0, 0, 158, 0, +0, 0, 196, 0, 0, 0, 164, 0, 0, 0, 81, 0, 0, 0, 30, 0, 0, 0, 190, 0, 0, 0, 208, 0, 0, 0, 144, 0, 0, 0, 58, 0, 0, 0, 156, 0, 0, 0, 194, 0, 0, 0, 38, 0, 0, 0, 182, 0, 0, 0, 30, 0, 0, 0, 241, 0, 0, 0, 149, 0, 0, 0, 125, 0, 0, 0, 200, 0, 0, 0, 109, 0, 0, 0, 82, 0, 0, 0, 230, 0, 0, 0, 153, 0, 0, 0, 44, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, 0, 0, 224, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 180, 0, 0, 0, 209, 0, 0, 0, 239, 0, 0, 0, 252, 0, 0, 0, 105, 0, 0, 0, 162, 0, 0, 0, 191, 0, 0, 0, 143, 0, 0, 0, 114, 0, 0, 0, 44, 0, 0, 0, 149, 0, 0, 0, 246, 0, 0, 0, 228, 0, 0, 0, 110, 0, 0, 0, 125, 0, 0, 0, 144, 0, 0, 0, 247, 0, 0, 0, 87, 0, 0, 0, 129, 0, 0, 0, 160, 0, 0, 0, 247, 0, 0, 0, 218, 0, 0, 0, 239, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 227, 0, 0, 0, 107, +0, 0, 0, 120, 0, 0, 0, 54, 0, 0, 0, 39, 0, 0, 0, 62, 0, 0, 0, 198, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 171, 0, 0, 0, 78, 0, 0, 0, 190, 0, 0, 0, 105, 0, 0, 0, 157, 0, 0, 0, 179, 0, 0, 0, 190, 0, 0, 0, 8, 0, 0, 0, 124, 0, 0, 0, 42, 0, 0, 0, 71, 0, 0, 0, 8, 0, 0, 0, 253, 0, 0, 0, 212, 0, 0, 0, 205, 0, 0, 0, 14, 0, 0, 0, 39, 0, 0, 0, 52, 0, 0, 0, 91, 0, 0, 0, 152, 0, 0, 0, 52, 0, 0, 0, 47, 0, 0, 0, 119, 0, 0, 0, 95, 0, 0, 0, 58, 0, 0, 0, 101, 0, 0, 0, 19, 0, 0, 0, 170, 0, 0, 0, 46, 0, 0, 0, 76, 0, 0, 0, +240, 0, 0, 0, 34, 0, 0, 0, 184, 0, 0, 0, 108, 0, 0, 0, 179, 0, 0, 0, 25, 0, 0, 0, 77, 0, 0, 0, 235, 0, 0, 0, 107, 0, 0, 0, 208, 0, 0, 0, 164, 0, 0, 0, 198, 0, 0, 0, 156, 0, 0, 0, 221, 0, 0, 0, 200, 0, 0, 0, 91, 0, 0, 0, 129, 0, 0, 0, 87, 0, 0, 0, 137, 0, 0, 0, 223, 0, 0, 0, 51, 0, 0, 0, 169, 0, 0, 0, 104, 0, 0, 0, 73, 0, 0, 0, 128, 0, 0, 0, 228, 0, 0, 0, 254, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 144, 0, 0, 0, 48, 0, 0, 0, 233, 0, 0, 0, 211, 0, 0, 0, 96, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, +194, 0, 0, 0, 114, 0, 0, 0, 137, 0, 0, 0, 122, 0, 0, 0, 54, 0, 0, 0, 165, 0, 0, 0, 189, 0, 0, 0, 57, 0, 0, 0, 131, 0, 0, 0, 133, 0, 0, 0, 80, 0, 0, 0, 161, 0, 0, 0, 93, 0, 0, 0, 108, 0, 0, 0, 65, 0, 0, 0, 29, 0, 0, 0, 181, 0, 0, 0, 44, 0, 0, 0, 7, 0, 0, 0, 64, 0, 0, 0, 119, 0, 0, 0, 11, 0, 0, 0, 80, 0, 0, 0, 100, 0, 0, 0, 52, 0, 0, 0, 236, 0, 0, 0, 192, 0, 0, 0, 158, 0, 0, 0, 68, 0, 0, 0, 65, 0, 0, 0, 175, 0, 0, 0, 160, 0, 0, 0, 54, 0, 0, 0, 5, 0, 0, 0, 109, 0, 0, 0, 234, 0, 0, 0, 48, 0, 0, 0, 37, +0, 0, 0, 70, 0, 0, 0, 53, 0, 0, 0, 36, 0, 0, 0, 157, 0, 0, 0, 134, 0, 0, 0, 189, 0, 0, 0, 149, 0, 0, 0, 241, 0, 0, 0, 106, 0, 0, 0, 70, 0, 0, 0, 215, 0, 0, 0, 148, 0, 0, 0, 84, 0, 0, 0, 249, 0, 0, 0, 59, 0, 0, 0, 189, 0, 0, 0, 93, 0, 0, 0, 119, 0, 0, 0, 91, 0, 0, 0, 226, 0, 0, 0, 55, 0, 0, 0, 199, 0, 0, 0, 225, 0, 0, 0, 124, 0, 0, 0, 19, 0, 0, 0, 140, 0, 0, 0, 159, 0, 0, 0, 123, 0, 0, 0, 123, 0, 0, 0, 42, 0, 0, 0, 206, 0, 0, 0, 66, 0, 0, 0, 163, 0, 0, 0, 185, 0, 0, 0, 42, 0, 0, 0, 153, 0, 0, 0, 168, +0, 0, 0, 192, 0, 0, 0, 216, 0, 0, 0, 60, 0, 0, 0, 134, 0, 0, 0, 176, 0, 0, 0, 251, 0, 0, 0, 233, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 247, 0, 0, 0, 245, 0, 0, 0, 86, 0, 0, 0, 223, 0, 0, 0, 179, 0, 0, 0, 70, 0, 0, 0, 17, 0, 0, 0, 110, 0, 0, 0, 19, 0, 0, 0, 183, 0, 0, 0, 40, 0, 0, 0, 78, 0, 0, 0, 86, 0, 0, 0, 221, 0, 0, 0, 241, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 88, 0, 0, 0, 195, 0, 0, 0, 248, 0, 0, 0, 136, 0, 0, 0, 148, 0, 0, 0, 94, 0, 0, 0, 6, 0, 0, 0, 152, 0, 0, 0, 161, 0, 0, 0, 228, 0, 0, 0, +106, 0, 0, 0, 251, 0, 0, 0, 10, 0, 0, 0, 73, 0, 0, 0, 93, 0, 0, 0, 138, 0, 0, 0, 254, 0, 0, 0, 119, 0, 0, 0, 70, 0, 0, 0, 2, 0, 0, 0, 245, 0, 0, 0, 165, 0, 0, 0, 175, 0, 0, 0, 197, 0, 0, 0, 117, 0, 0, 0, 109, 0, 0, 0, 186, 0, 0, 0, 69, 0, 0, 0, 53, 0, 0, 0, 10, 0, 0, 0, 254, 0, 0, 0, 201, 0, 0, 0, 172, 0, 0, 0, 34, 0, 0, 0, 145, 0, 0, 0, 141, 0, 0, 0, 33, 0, 0, 0, 149, 0, 0, 0, 51, 0, 0, 0, 3, 0, 0, 0, 192, 0, 0, 0, 138, 0, 0, 0, 22, 0, 0, 0, 243, 0, 0, 0, 57, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 15, +0, 0, 0, 83, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 117, 0, 0, 0, 55, 0, 0, 0, 31, 0, 0, 0, 52, 0, 0, 0, 78, 0, 0, 0, 169, 0, 0, 0, 29, 0, 0, 0, 104, 0, 0, 0, 103, 0, 0, 0, 248, 0, 0, 0, 73, 0, 0, 0, 152, 0, 0, 0, 150, 0, 0, 0, 252, 0, 0, 0, +76, 0, 0, 0, 101, 0, 0, 0, 151, 0, 0, 0, 247, 0, 0, 0, 2, 0, 0, 0, 74, 0, 0, 0, 82, 0, 0, 0, 108, 0, 0, 0, 1, 0, 0, 0, 189, 0, 0, 0, 72, 0, 0, 0, 187, 0, 0, 0, 27, 0, 0, 0, 237, 0, 0, 0, 164, 0, 0, 0, 226, 0, 0, 0, 83, 0, 0, 0, 89, 0, 0, 0, 213, 0, 0, 0, 155, 0, 0, 0, 90, 0, 0, 0, 162, 0, 0, 0, 144, 0, 0, 0, 211, 0, 0, 0, 184, 0, 0, 0, 55, 0, 0, 0, 76, 0, 0, 0, 85, 0, 0, 0, 130, 0, 0, 0, 40, 0, 0, 0, 8, 0, 0, 0, 15, 0, 0, 0, 127, 0, 0, 0, 170, 0, 0, 0, 129, 0, 0, 0, 101, 0, 0, 0, 224, 0, 0, 0, 12, +0, 0, 0, 82, 0, 0, 0, 201, 0, 0, 0, 163, 0, 0, 0, 50, 0, 0, 0, 39, 0, 0, 0, 100, 0, 0, 0, 218, 0, 0, 0, 253, 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 0, 181, 0, 0, 0, 176, 0, 0, 0, 12, 0, 0, 0, 77, 0, 0, 0, 179, 0, 0, 0, 123, 0, 0, 0, 35, 0, 0, 0, 200, 0, 0, 0, 31, 0, 0, 0, 138, 0, 0, 0, 57, 0, 0, 0, 102, 0, 0, 0, 230, 0, 0, 0, 186, 0, 0, 0, 76, 0, 0, 0, 16, 0, 0, 0, 55, 0, 0, 0, 202, 0, 0, 0, 156, 0, 0, 0, 124, 0, 0, 0, 5, 0, 0, 0, 158, 0, 0, 0, 255, 0, 0, 0, 192, 0, 0, 0, 248, 0, 0, 0, 142, +0, 0, 0, 177, 0, 0, 0, 143, 0, 0, 0, 111, 0, 0, 0, 103, 0, 0, 0, 24, 0, 0, 0, 38, 0, 0, 0, 75, 0, 0, 0, 65, 0, 0, 0, 19, 0, 0, 0, 84, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 0, 164, 0, 0, 0, 78, 0, 0, 0, 169, 0, 0, 0, 139, 0, 0, 0, 30, 0, 0, 0, 75, 0, 0, 0, 252, 0, 0, 0, 21, 0, 0, 0, 36, 0, 0, 0, 187, 0, 0, 0, 126, 0, 0, 0, 203, 0, 0, 0, 182, 0, 0, 0, 30, 0, 0, 0, 27, 0, 0, 0, 245, 0, 0, 0, 242, 0, 0, 0, 200, 0, 0, 0, 86, 0, 0, 0, 236, 0, 0, 0, 50, 0, 0, 0, 162, 0, 0, 0, 96, 0, 0, 0, 91, 0, 0, 0, 160, 0, +0, 0, 42, 0, 0, 0, 164, 0, 0, 0, 41, 0, 0, 0, 71, 0, 0, 0, 134, 0, 0, 0, 46, 0, 0, 0, 146, 0, 0, 0, 79, 0, 0, 0, 17, 0, 0, 0, 79, 0, 0, 0, 243, 0, 0, 0, 178, 0, 0, 0, 92, 0, 0, 0, 213, 0, 0, 0, 62, 0, 0, 0, 166, 0, 0, 0, 185, 0, 0, 0, 200, 0, 0, 0, 226, 0, 0, 0, 51, 0, 0, 0, 17, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 0, 143, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 199, 0, 0, 0, 165, 0, 0, 0, 255, 0, 0, 0, 131, 0, 0, 0, 15, 0, 0, 0, 30, 0, 0, 0, 40, 0, 0, 0, 29, 0, 0, 0, 41, 0, 0, 0, 122, 0, 0, 0, 161, 0, 0, +0, 236, 0, 0, 0, 142, 0, 0, 0, 181, 0, 0, 0, 173, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 104, 0, 0, 0, 96, 0, 0, 0, 116, 0, 0, 0, 41, 0, 0, 0, 28, 0, 0, 0, 165, 0, 0, 0, 207, 0, 0, 0, 200, 0, 0, 0, 59, 0, 0, 0, 125, 0, 0, 0, 139, 0, 0, 0, 43, 0, 0, 0, 124, 0, 0, 0, 173, 0, 0, 0, 164, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 81, 0, 0, 0, 89, 0, 0, 0, 124, 0, 0, 0, 46, 0, 0, 0, 93, 0, 0, 0, 10, 0, 0, 0, 108, 0, 0, 0, 79, 0, 0, 0, 188, 0, 0, 0, 62, 0, 0, 0, 50, 0, 0, 0, 231, 0, 0, 0, 74, 0, 0, 0, 26, 0, 0, 0, +19, 0, 0, 0, 193, 0, 0, 0, 73, 0, 0, 0, 56, 0, 0, 0, 191, 0, 0, 0, 247, 0, 0, 0, 194, 0, 0, 0, 211, 0, 0, 0, 143, 0, 0, 0, 107, 0, 0, 0, 173, 0, 0, 0, 82, 0, 0, 0, 247, 0, 0, 0, 207, 0, 0, 0, 188, 0, 0, 0, 39, 0, 0, 0, 203, 0, 0, 0, 64, 0, 0, 0, 103, 0, 0, 0, 118, 0, 0, 0, 205, 0, 0, 0, 109, 0, 0, 0, 86, 0, 0, 0, 229, 0, 0, 0, 176, 0, 0, 0, 39, 0, 0, 0, 173, 0, 0, 0, 190, 0, 0, 0, 155, 0, 0, 0, 242, 0, 0, 0, 181, 0, 0, 0, 99, 0, 0, 0, 222, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 0, 149, 0, 0, 0, 183, 0, +0, 0, 10, 0, 0, 0, 126, 0, 0, 0, 243, 0, 0, 0, 158, 0, 0, 0, 69, 0, 0, 0, 111, 0, 0, 0, 25, 0, 0, 0, 57, 0, 0, 0, 117, 0, 0, 0, 143, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 15, 0, 0, 0, 192, 0, 0, 0, 159, 0, 0, 0, 241, 0, 0, 0, 233, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 136, 0, 0, 0, 170, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 134, 0, 0, 0, 148, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 62, 0, 0, 0, 26, 0, 0, 0, 181, 0, 0, 0, 204, 0, 0, 0, 187, 0, 0, 0, 224, 0, 0, 0, 156, 0, 0, 0, 213, 0, 0, 0, 156, 0, 0, 0, 109, 0, 0, 0, 186, 0, 0, 0, 88, 0, 0, 0, 114, 0, 0, 0, 141, 0, 0, 0, 251, 0, 0, 0, 34, 0, 0, 0, 123, 0, 0, 0, 159, 0, 0, 0, 124, 0, 0, 0, 148, 0, 0, 0, 48, 0, 0, 0, 179, 0, 0, 0, 81, 0, 0, 0, 33, 0, 0, 0, 246, 0, 0, 0, 116, 0, 0, 0, 61, 0, 0, 0, 242, 0, +0, 0, 175, 0, 0, 0, 208, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 124, 0, 0, 0, 35, 0, 0, 0, 107, 0, 0, 0, 201, 0, 0, 0, 252, 0, 0, 0, 37, 0, 0, 0, 112, 0, 0, 0, 144, 0, 0, 0, 220, 0, 0, 0, 154, 0, 0, 0, 164, 0, 0, 0, 251, 0, 0, 0, 73, 0, 0, 0, 252, 0, 0, 0, 61, 0, 0, 0, 10, 0, 0, 0, 53, 0, 0, 0, 56, 0, 0, 0, 111, 0, 0, 0, 228, 0, 0, 0, 126, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 214, 0, 0, 0, 227, 0, 0, 0, 150, 0, 0, 0, 97, 0, 0, 0, 58, 0, 0, 0, 253, 0, 0, 0, 239, 0, 0, 0, 155, 0, 0, 0, 31, 0, +0, 0, 144, 0, 0, 0, 164, 0, 0, 0, 36, 0, 0, 0, 20, 0, 0, 0, 91, 0, 0, 0, 200, 0, 0, 0, 222, 0, 0, 0, 80, 0, 0, 0, 177, 0, 0, 0, 29, 0, 0, 0, 175, 0, 0, 0, 232, 0, 0, 0, 85, 0, 0, 0, 138, 0, 0, 0, 135, 0, 0, 0, 13, 0, 0, 0, 254, 0, 0, 0, 170, 0, 0, 0, 59, 0, 0, 0, 130, 0, 0, 0, 44, 0, 0, 0, 141, 0, 0, 0, 123, 0, 0, 0, 133, 0, 0, 0, 12, 0, 0, 0, 175, 0, 0, 0, 248, 0, 0, 0, 131, 0, 0, 0, 68, 0, 0, 0, 73, 0, 0, 0, 217, 0, 0, 0, 69, 0, 0, 0, 207, 0, 0, 0, 247, 0, 0, 0, 72, 0, 0, 0, 217, 0, 0, 0, 83, 0, +0, 0, 180, 0, 0, 0, 241, 0, 0, 0, 101, 0, 0, 0, 160, 0, 0, 0, 225, 0, 0, 0, 195, 0, 0, 0, 179, 0, 0, 0, 21, 0, 0, 0, 237, 0, 0, 0, 137, 0, 0, 0, 155, 0, 0, 0, 79, 0, 0, 0, 98, 0, 0, 0, 179, 0, 0, 0, 87, 0, 0, 0, 165, 0, 0, 0, 69, 0, 0, 0, 28, 0, 0, 0, 143, 0, 0, 0, 18, 0, 0, 0, 234, 0, 0, 0, 175, 0, 0, 0, 209, 0, 0, 0, 31, 0, 0, 0, 121, 0, 0, 0, 16, 0, 0, 0, 11, 0, 0, 0, 246, 0, 0, 0, 163, 0, 0, 0, 123, 0, 0, 0, 234, 0, 0, 0, 172, 0, 0, 0, 139, 0, 0, 0, 87, 0, 0, 0, 50, 0, 0, 0, 98, 0, 0, 0, 231, +0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 81, 0, 0, 0, 160, 0, 0, 0, 59, 0, 0, 0, 67, 0, 0, 0, 94, 0, 0, 0, 164, 0, 0, 0, 32, 0, 0, 0, 120, 0, 0, 0, 49, 0, 0, 0, 206, 0, 0, 0, 13, 0, 0, 0, 132, 0, 0, 0, 124, 0, 0, 0, 194, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 35, 0, 0, 0, 206, 0, 0, 0, 189, 0, 0, 0, 220, 0, 0, 0, 249, 0, 0, 0, 206, 0, 0, 0, 213, 0, 0, 0, 117, 0, 0, 0, 48, 0, 0, 0, 34, 0, 0, 0, 230, 0, 0, 0, 249, 0, 0, 0, 67, 0, 0, 0, 98, 0, 0, 0, 13, 0, 0, 0, 247, 0, 0, 0, 117, 0, 0, 0, 157, 0, 0, 0, 127, +0, 0, 0, 140, 0, 0, 0, 255, 0, 0, 0, 125, 0, 0, 0, 228, 0, 0, 0, 114, 0, 0, 0, 172, 0, 0, 0, 159, 0, 0, 0, 28, 0, 0, 0, 136, 0, 0, 0, 193, 0, 0, 0, 153, 0, 0, 0, 208, 0, 0, 0, 60, 0, 0, 0, 28, 0, 0, 0, 93, 0, 0, 0, 180, 0, 0, 0, 239, 0, 0, 0, 19, 0, 0, 0, 15, 0, 0, 0, 144, 0, 0, 0, 185, 0, 0, 0, 54, 0, 0, 0, 47, 0, 0, 0, 149, 0, 0, 0, 149, 0, 0, 0, 198, 0, 0, 0, 220, 0, 0, 0, 222, 0, 0, 0, 10, 0, 0, 0, 81, 0, 0, 0, 226, 0, 0, 0, 141, 0, 0, 0, 243, 0, 0, 0, 188, 0, 0, 0, 81, 0, 0, 0, 236, 0, 0, 0, +223, 0, 0, 0, 177, 0, 0, 0, 162, 0, 0, 0, 95, 0, 0, 0, 46, 0, 0, 0, 104, 0, 0, 0, 161, 0, 0, 0, 35, 0, 0, 0, 125, 0, 0, 0, 155, 0, 0, 0, 64, 0, 0, 0, 105, 0, 0, 0, 133, 0, 0, 0, 123, 0, 0, 0, 66, 0, 0, 0, 191, 0, 0, 0, 144, 0, 0, 0, 75, 0, 0, 0, 214, 0, 0, 0, 64, 0, 0, 0, 47, 0, 0, 0, 215, 0, 0, 0, 82, 0, 0, 0, 82, 0, 0, 0, 178, 0, 0, 0, 33, 0, 0, 0, 222, 0, 0, 0, 100, 0, 0, 0, 189, 0, 0, 0, 136, 0, 0, 0, 195, 0, 0, 0, 109, 0, 0, 0, 165, 0, 0, 0, 250, 0, 0, 0, 129, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 253, 0, 0, 0, 71, 0, 0, 0, 123, 0, 0, 0, 138, 0, 0, 0, 102, 0, 0, 0, 158, 0, 0, 0, 121, 0, 0, 0, 46, 0, 0, 0, 100, 0, 0, 0, 130, 0, 0, 0, 239, 0, 0, 0, 247, 0, 0, 0, 33, 0, 0, 0, 236, 0, 0, 0, 246, 0, 0, 0, 216, 0, 0, 0, 134, 0, +0, 0, 9, 0, 0, 0, 49, 0, 0, 0, 124, 0, 0, 0, 221, 0, 0, 0, 3, 0, 0, 0, 106, 0, 0, 0, 88, 0, 0, 0, 160, 0, 0, 0, 119, 0, 0, 0, 183, 0, 0, 0, 155, 0, 0, 0, 140, 0, 0, 0, 135, 0, 0, 0, 31, 0, 0, 0, 85, 0, 0, 0, 71, 0, 0, 0, 228, 0, 0, 0, 168, 0, 0, 0, 61, 0, 0, 0, 85, 0, 0, 0, 33, 0, 0, 0, 52, 0, 0, 0, 171, 0, 0, 0, 29, 0, 0, 0, 174, 0, 0, 0, 224, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 219, 0, 0, 0, 197, 0, 0, 0, 185, 0, 0, 0, 88, 0, 0, 0, 191, 0, 0, 0, 196, 0, 0, 0, 42, 0, 0, 0, 137, 0, 0, 0, 49, 0, +0, 0, 26, 0, 0, 0, 244, 0, 0, 0, 45, 0, 0, 0, 225, 0, 0, 0, 202, 0, 0, 0, 55, 0, 0, 0, 153, 0, 0, 0, 71, 0, 0, 0, 89, 0, 0, 0, 199, 0, 0, 0, 202, 0, 0, 0, 99, 0, 0, 0, 193, 0, 0, 0, 73, 0, 0, 0, 169, 0, 0, 0, 53, 0, 0, 0, 69, 0, 0, 0, 85, 0, 0, 0, 126, 0, 0, 0, 218, 0, 0, 0, 100, 0, 0, 0, 50, 0, 0, 0, 7, 0, 0, 0, 80, 0, 0, 0, 247, 0, 0, 0, 50, 0, 0, 0, 172, 0, 0, 0, 222, 0, 0, 0, 117, 0, 0, 0]).concat([88, 0, 0, 0, 155, 0, 0, 0, 17, 0, 0, 0, 178, 0, 0, 0, 58, 0, 0, 0, 31, 0, 0, 0, 245, 0, 0, 0, 247, +0, 0, 0, 121, 0, 0, 0, 4, 0, 0, 0, 230, 0, 0, 0, 8, 0, 0, 0, 70, 0, 0, 0, 250, 0, 0, 0, 34, 0, 0, 0, 75, 0, 0, 0, 250, 0, 0, 0, 225, 0, 0, 0, 254, 0, 0, 0, 150, 0, 0, 0, 252, 0, 0, 0, 103, 0, 0, 0, 186, 0, 0, 0, 103, 0, 0, 0, 151, 0, 0, 0, 196, 0, 0, 0, 231, 0, 0, 0, 27, 0, 0, 0, 134, 0, 0, 0, 144, 0, 0, 0, 95, 0, 0, 0, 238, 0, 0, 0, 244, 0, 0, 0, 91, 0, 0, 0, 17, 0, 0, 0, 178, 0, 0, 0, 205, 0, 0, 0, 173, 0, 0, 0, 238, 0, 0, 0, 194, 0, 0, 0, 72, 0, 0, 0, 108, 0, 0, 0, 43, 0, 0, 0, 27, 0, 0, 0, 227, +0, 0, 0, 57, 0, 0, 0, 98, 0, 0, 0, 180, 0, 0, 0, 79, 0, 0, 0, 49, 0, 0, 0, 4, 0, 0, 0, 201, 0, 0, 0, 218, 0, 0, 0, 213, 0, 0, 0, 115, 0, 0, 0, 81, 0, 0, 0, 87, 0, 0, 0, 197, 0, 0, 0, 184, 0, 0, 0, 243, 0, 0, 0, 163, 0, 0, 0, 67, 0, 0, 0, 112, 0, 0, 0, 228, 0, 0, 0, 97, 0, 0, 0, 129, 0, 0, 0, 132, 0, 0, 0, 226, 0, 0, 0, 187, 0, 0, 0, 191, 0, 0, 0, 79, 0, 0, 0, 158, 0, 0, 0, 164, 0, 0, 0, 94, 0, 0, 0, 116, 0, 0, 0, 6, 0, 0, 0, 41, 0, 0, 0, 172, 0, 0, 0, 255, 0, 0, 0, 39, 0, 0, 0, 224, 0, 0, 0, 89, +0, 0, 0, 190, 0, 0, 0, 57, 0, 0, 0, 156, 0, 0, 0, 13, 0, 0, 0, 131, 0, 0, 0, 215, 0, 0, 0, 16, 0, 0, 0, 11, 0, 0, 0, 21, 0, 0, 0, 183, 0, 0, 0, 225, 0, 0, 0, 194, 0, 0, 0, 44, 0, 0, 0, 48, 0, 0, 0, 115, 0, 0, 0, 128, 0, 0, 0, 58, 0, 0, 0, 125, 0, 0, 0, 93, 0, 0, 0, 171, 0, 0, 0, 88, 0, 0, 0, 107, 0, 0, 0, 193, 0, 0, 0, 240, 0, 0, 0, 244, 0, 0, 0, 34, 0, 0, 0, 254, 0, 0, 0, 127, 0, 0, 0, 251, 0, 0, 0, 53, 0, 0, 0, 125, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 196, 0, 0, 0, 2, 0, +0, 0, 172, 0, 0, 0, 31, 0, 0, 0, 66, 0, 0, 0, 180, 0, 0, 0, 157, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 165, 0, 0, 0, 238, 0, 0, 0, 202, 0, 0, 0, 218, 0, 0, 0, 151, 0, 0, 0, 9, 0, 0, 0, 65, 0, 0, 0, 119, 0, 0, 0, 135, 0, 0, 0, 93, 0, 0, 0, 123, 0, 0, 0, 135, 0, 0, 0, 120, 0, 0, 0, 245, 0, 0, 0, 251, 0, 0, 0, 144, 0, 0, 0, 45, 0, 0, 0, 129, 0, 0, 0, 25, 0, 0, 0, 158, 0, 0, 0, 47, 0, 0, 0, 109, 0, 0, 0, 133, 0, 0, 0, 136, 0, 0, 0, 140, 0, 0, 0, 64, 0, 0, 0, 92, 0, 0, 0, 119, 0, 0, 0, 65, +0, 0, 0, 77, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 118, 0, 0, 0, 96, 0, 0, 0, 232, 0, 0, 0, 76, 0, 0, 0, 72, 0, 0, 0, 228, 0, 0, 0, 51, 0, 0, 0, 131, 0, 0, 0, 50, 0, 0, 0, 108, 0, 0, 0, 180, 0, 0, 0, 65, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 16, +0, 0, 0, 194, 0, 0, 0, 9, 0, 0, 0, 79, 0, 0, 0, 110, 0, 0, 0, 244, 0, 0, 0, 210, 0, 0, 0, 223, 0, 0, 0, 126, 0, 0, 0, 202, 0, 0, 0, 123, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 186, 0, 0, 0, 163, 0, 0, 0, 182, 0, 0, 0, 218, 0, 0, 0, 103, 0, 0, 0, 51, 0, 0, 0, 212, 0, 0, 0, 135, 0, 0, 0, 54, 0, 0, 0, 75, 0, 0, 0, 17, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 166, 0, 0, 0, 41, 0, 0, 0, 193, 0, 0, 0, 135, 0, 0, 0, 23, 0, 0, 0, 246, 0, 0, 0, 150, 0, 0, 0, 202, 0, 0, 0, 47, 0, 0, 0, 218, 0, 0, 0, 56, 0, 0, 0, 167, +0, 0, 0, 27, 0, 0, 0, 252, 0, 0, 0, 202, 0, 0, 0, 125, 0, 0, 0, 254, 0, 0, 0, 8, 0, 0, 0, 137, 0, 0, 0, 226, 0, 0, 0, 71, 0, 0, 0, 43, 0, 0, 0, 106, 0, 0, 0, 93, 0, 0, 0, 75, 0, 0, 0, 250, 0, 0, 0, 161, 0, 0, 0, 180, 0, 0, 0, 222, 0, 0, 0, 182, 0, 0, 0, 194, 0, 0, 0, 49, 0, 0, 0, 81, 0, 0, 0, 245, 0, 0, 0, 224, 0, 0, 0, 164, 0, 0, 0, 11, 0, 0, 0, 92, 0, 0, 0, 229, 0, 0, 0, 198, 0, 0, 0, 4, 0, 0, 0, 142, 0, 0, 0, 43, 0, 0, 0, 87, 0, 0, 0, 190, 0, 0, 0, 56, 0, 0, 0, 133, 0, 0, 0, 35, 0, 0, 0, 203, +0, 0, 0, 183, 0, 0, 0, 190, 0, 0, 0, 79, 0, 0, 0, 169, 0, 0, 0, 211, 0, 0, 0, 110, 0, 0, 0, 18, 0, 0, 0, 170, 0, 0, 0, 213, 0, 0, 0, 178, 0, 0, 0, 46, 0, 0, 0, 147, 0, 0, 0, 41, 0, 0, 0, 154, 0, 0, 0, 74, 0, 0, 0, 136, 0, 0, 0, 24, 0, 0, 0, 67, 0, 0, 0, 245, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 252, 0, 0, 0, 219, 0, 0, 0, 162, 0, 0, 0, 89, 0, 0, 0, 33, 0, 0, 0, 141, 0, 0, 0, 189, 0, 0, 0, 126, 0, 0, 0, 51, 0, 0, 0, 174, 0, 0, 0, 47, 0, 0, 0, 135, 0, 0, 0, 26, 0, 0, 0, 208, 0, 0, 0, 151, 0, 0, 0, 199, +0, 0, 0, 13, 0, 0, 0, 77, 0, 0, 0, 99, 0, 0, 0, 1, 0, 0, 0, 239, 0, 0, 0, 5, 0, 0, 0, 132, 0, 0, 0, 236, 0, 0, 0, 64, 0, 0, 0, 221, 0, 0, 0, 168, 0, 0, 0, 10, 0, 0, 0, 79, 0, 0, 0, 112, 0, 0, 0, 11, 0, 0, 0, 65, 0, 0, 0, 105, 0, 0, 0, 1, 0, 0, 0, 103, 0, 0, 0, 92, 0, 0, 0, 211, 0, 0, 0, 138, 0, 0, 0, 197, 0, 0, 0, 207, 0, 0, 0, 63, 0, 0, 0, 209, 0, 0, 0, 87, 0, 0, 0, 209, 0, 0, 0, 103, 0, 0, 0, 62, 0, 0, 0, 1, 0, 0, 0, 57, 0, 0, 0, 181, 0, 0, 0, 203, 0, 0, 0, 129, 0, 0, 0, 86, 0, 0, 0, 150, 0, 0, +0, 38, 0, 0, 0, 182, 0, 0, 0, 194, 0, 0, 0, 231, 0, 0, 0, 92, 0, 0, 0, 251, 0, 0, 0, 99, 0, 0, 0, 151, 0, 0, 0, 88, 0, 0, 0, 6, 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 243, 0, 0, 0, 186, 0, 0, 0, 240, 0, 0, 0, 229, 0, 0, 0, 186, 0, 0, 0, 178, 0, 0, 0, 87, 0, 0, 0, 119, 0, 0, 0, 198, 0, 0, 0, 32, 0, 0, 0, 155, 0, 0, 0, 137, 0, 0, 0, 36, 0, 0, 0, 190, 0, 0, 0, 242, 0, 0, 0, 156, 0, 0, 0, 138, 0, 0, 0, 186, 0, 0, 0, 105, 0, 0, 0, 193, 0, 0, 0, 241, 0, 0, 0, 176, 0, 0, 0, 79, 0, 0, 0, 42, 0, 0, 0, 5, 0, 0, +0, 154, 0, 0, 0, 238, 0, 0, 0, 16, 0, 0, 0, 126, 0, 0, 0, 54, 0, 0, 0, 63, 0, 0, 0, 38, 0, 0, 0, 233, 0, 0, 0, 64, 0, 0, 0, 233, 0, 0, 0, 3, 0, 0, 0, 173, 0, 0, 0, 6, 0, 0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 224, 0, 0, 0, 209, 0, 0, 0, 137, 0, 0, 0, 96, 0, 0, 0, 132, 0, 0, 0, 121, 0, 0, 0, 222, 0, 0, 0, 39, 0, 0, 0, 109, 0, 0, 0, 230, 0, 0, 0, 118, 0, 0, 0, 189, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 174, 0, 0, 0, 72, 0, 0, 0, 195, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 87, 0, 0, 0, 205, 0, 0, 0, 47, 0, +0, 0, 127, 0, 0, 0, 193, 0, 0, 0, 220, 0, 0, 0, 185, 0, 0, 0, 199, 0, 0, 0, 188, 0, 0, 0, 134, 0, 0, 0, 61, 0, 0, 0, 85, 0, 0, 0, 75, 0, 0, 0, 40, 0, 0, 0, 122, 0, 0, 0, 251, 0, 0, 0, 77, 0, 0, 0, 199, 0, 0, 0, 248, 0, 0, 0, 188, 0, 0, 0, 103, 0, 0, 0, 42, 0, 0, 0, 96, 0, 0, 0, 77, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 11, 0, 0, 0, 26, 0, 0, 0, 23, 0, 0, 0, 191, 0, 0, 0, 250, 0, 0, 0, 172, 0, 0, 0, 167, 0, 0, 0, 61, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 63, 0, 0, 0, 237, 0, 0, 0, 94, 0, 0, 0, 24, 0, 0, 0, 120, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 0, 13, 0, 0, 0, 140, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 251, 0, 0, 0, 233, 0, 0, 0, 142, 0, 0, 0, 214, 0, 0, 0, 209, 0, 0, 0, 54, 0, 0, 0, 88, 0, 0, 0, 87, 0, 0, 0, 158, +0, 0, 0, 174, 0, 0, 0, 75, 0, 0, 0, 92, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 188, 0, 0, 0, 107, 0, 0, 0, 85, 0, 0, 0, 43, 0, 0, 0, 111, 0, 0, 0, 77, 0, 0, 0, 23, 0, 0, 0, 215, 0, 0, 0, 225, 0, 0, 0, 132, 0, 0, 0, 217, 0, 0, 0, 120, 0, 0, 0, 177, 0, 0, 0, 144, 0, 0, 0, 253, 0, 0, 0, 46, 0, 0, 0, 179, 0, 0, 0, 181, 0, 0, 0, 25, 0, 0, 0, 63, 0, 0, 0, 27, 0, 0, 0, 250, 0, 0, 0, 192, 0, 0, 0, 104, 0, 0, 0, 179, 0, 0, 0, 221, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 137, 0, 0, 0, 189, 0, 0, 0, 126, 0, 0, 0, 128, +0, 0, 0, 50, 0, 0, 0, 19, 0, 0, 0, 160, 0, 0, 0, 123, 0, 0, 0, 26, 0, 0, 0, 111, 0, 0, 0, 64, 0, 0, 0, 175, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 176, 0, 0, 0, 67, 0, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 208, 0, 0, 0, 30, 0, 0, 0, 196, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 93, 0, 0, 0, 142, 0, 0, 0, 254, 0, 0, 0, 193, 0, 0, 0, 243, 0, 0, 0, 197, 0, 0, 0, 92, 0, 0, 0, 145, 0, 0, 0, 248, 0, 0, 0, 4, 0, 0, 0, 78, 0, 0, 0, 190, 0, 0, 0, 144, 0, 0, 0, 180, 0, 0, 0, 71, 0, 0, 0, 92, 0, 0, 0, 63, 0, 0, 0, 176, 0, +0, 0, 59, 0, 0, 0, 44, 0, 0, 0, 243, 0, 0, 0, 254, 0, 0, 0, 50, 0, 0, 0, 113, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 170, 0, 0, 0, 186, 0, 0, 0, 69, 0, 0, 0, 96, 0, 0, 0, 168, 0, 0, 0, 141, 0, 0, 0, 234, 0, 0, 0, 84, 0, 0, 0, 203, 0, 0, 0, 57, 0, 0, 0, 16, 0, 0, 0, 180, 0, 0, 0, 242, 0, 0, 0, 139, 0, 0, 0, 210, 0, 0, 0, 20, 0, 0, 0, 130, 0, 0, 0, 66, 0, 0, 0, 7, 0, 0, 0, 142, 0, 0, 0, 233, 0, 0, 0, 124, 0, 0, 0, 83, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 193, 0, 0, 0, 141, 0, 0, 0, 201, 0, 0, 0, 143, 0, +0, 0, 185, 0, 0, 0, 122, 0, 0, 0, 119, 0, 0, 0, 239, 0, 0, 0, 186, 0, 0, 0, 121, 0, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 168, 0, 0, 0, 245, 0, 0, 0, 106, 0, 0, 0, 226, 0, 0, 0, 63, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 75, 0, 0, 0, 69, 0, 0, 0, 36, 0, 0, 0, 123, 0, 0, 0, 67, 0, 0, 0, 120, 0, 0, 0, 85, 0, 0, 0, 29, 0, 0, 0, 43, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 184, 0, 0, 0, 214, 0, 0, 0, 22, 0, 0, 0, 103, 0, 0, 0, 160, 0, 0, 0, 21, 0, 0, 0, 185, 0, 0, 0, 225, 0, 0, 0, 88, 0, 0, 0, 164, 0, 0, +0, 167, 0, 0, 0, 49, 0, 0, 0, 55, 0, 0, 0, 119, 0, 0, 0, 47, 0, 0, 0, 139, 0, 0, 0, 18, 0, 0, 0, 159, 0, 0, 0, 244, 0, 0, 0, 63, 0, 0, 0, 199, 0, 0, 0, 54, 0, 0, 0, 102, 0, 0, 0, 210, 0, 0, 0, 168, 0, 0, 0, 86, 0, 0, 0, 247, 0, 0, 0, 127, 0, 0, 0, 116, 0, 0, 0, 198, 0, 0, 0, 65, 0, 0, 0, 93, 0, 0, 0, 248, 0, 0, 0, 180, 0, 0, 0, 168, 0, 0, 0, 48, 0, 0, 0, 221, 0, 0, 0, 204, 0, 0, 0, 56, 0, 0, 0, 165, 0, 0, 0, 211, 0, 0, 0, 202, 0, 0, 0, 216, 0, 0, 0, 209, 0, 0, 0, 248, 0, 0, 0, 178, 0, 0, 0, 49, 0, +0, 0, 145, 0, 0, 0, 212, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 87, 0, 0, 0, 74, 0, 0, 0, 59, 0, 0, 0, 130, 0, 0, 0, 74, 0, 0, 0, 198, 0, 0, 0, 104, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 24, 0, 0, 0, 65, 0, 0, 0, 97, 0, 0, 0, 25, 0, 0, 0, 212, 0, 0, 0, 141, 0, 0, 0, 71, 0, 0, 0, 41, 0, 0, 0, 18, 0, 0, 0, 101, 0, 0, 0, 176, 0, 0, 0, 17, 0, 0, 0, 120, 0, 0, 0, 71, 0, 0, 0, 181, 0, 0, 0, 203, 0, 0, 0, 163, 0, 0, 0, 165, 0, 0, 0, 250, 0, 0, 0, 5, 0, 0, 0, 133, 0, 0, 0, 84, 0, 0, 0, 169, 0, 0, 0, 51, 0, 0, +0, 151, 0, 0, 0, 141, 0, 0, 0, 43, 0, 0, 0, 194, 0, 0, 0, 254, 0, 0, 0, 153, 0, 0, 0, 53, 0, 0, 0, 40, 0, 0, 0, 229, 0, 0, 0, 235, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 239, 0, 0, 0, 216, 0, 0, 0, 244, 0, 0, 0, +252, 0, 0, 0, 179, 0, 0, 0, 160, 0, 0, 0, 96, 0, 0, 0, 80, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 82, 0, 0, 0, 112, 0, 0, 0, 21, 0, 0, 0, 11, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 248, 0, 0, 0, 95, 0, 0, 0, 121, 0, 0, 0, 24, 0, 0, 0, 204, 0, 0, 0, 255, 0, 0, 0, 137, 0, 0, 0, 153, 0, 0, 0, 132, 0, 0, 0, 161, 0, 0, 0, 174, 0, 0, 0, 19, 0, 0, 0, 68, 0, 0, 0, 31, 0, 0, 0, 184, 0, 0, 0, 194, 0, 0, 0, 1, 0, 0, 0, 193, 0, 0, 0, 48, 0, 0, 0, 25, 0, 0, 0, 85, 0, 0, 0, 5, 0, 0, 0, 96, 0, 0, 0, 16, 0, +0, 0, 164, 0, 0, 0, 108, 0, 0, 0, 45, 0, 0, 0, 103, 0, 0, 0, 112, 0, 0, 0, 229, 0, 0, 0, 37, 0, 0, 0, 27, 0, 0, 0, 242, 0, 0, 0, 191, 0, 0, 0, 221, 0, 0, 0, 251, 0, 0, 0, 112, 0, 0, 0, 43, 0, 0, 0, 161, 0, 0, 0, 140, 0, 0, 0, 156, 0, 0, 0, 148, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 231, 0, 0, 0, 196, 0, 0, 0, 67, 0, 0, 0, 77, 0, 0, 0, 201, 0, 0, 0, 43, 0, 0, 0, 105, 0, 0, 0, 93, 0, 0, 0, 29, 0, 0, 0, 60, 0, 0, 0, 175, 0, 0, 0, 187, 0, 0, 0, 67, 0, 0, 0, 56, 0, 0, 0, 78, 0, 0, 0, 152, 0, 0, 0, 61, 0, +0, 0, 237, 0, 0, 0, 13, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 253, 0, 0, 0, 240, 0, 0, 0, 153, 0, 0, 0, 71, 0, 0, 0, 4, 0, 0, 0, 176, 0, 0, 0, 152, 0, 0, 0, 105, 0, 0, 0, 85, 0, 0, 0, 114, 0, 0, 0, 15, 0, 0, 0, 94, 0, 0, 0, 223, 0, 0, 0, 21, 0, 0, 0, 83, 0, 0, 0, 59, 0, 0, 0, 134, 0, 0, 0, 128, 0, 0, 0, 176, 0, 0, 0, 241, 0, 0, 0, 112, 0, 0, 0, 104, 0, 0, 0, 143, 0, 0, 0, 102, 0, 0, 0, 124, 0, 0, 0, 14, 0, 0, 0, 73, 0, 0, 0, 26, 0, 0, 0, 216, 0, 0, 0, 107, 0, 0, 0, 254, 0, 0, 0, 78, 0, 0, 0, 239, 0, +0, 0, 202, 0, 0, 0, 71, 0, 0, 0, 212, 0, 0, 0, 3, 0, 0, 0, 193, 0, 0, 0, 55, 0, 0, 0, 80, 0, 0, 0, 156, 0, 0, 0, 193, 0, 0, 0, 22, 0, 0, 0, 205, 0, 0, 0, 36, 0, 0, 0, 198, 0, 0, 0, 62, 0, 0, 0, 12, 0, 0, 0, 130, 0, 0, 0, 155, 0, 0, 0, 145, 0, 0, 0, 43, 0, 0, 0, 97, 0, 0, 0, 74, 0, 0, 0, 178, 0, 0, 0, 15, 0, 0, 0, 136, 0, 0, 0, 85, 0, 0, 0, 95, 0, 0, 0, 90, 0, 0, 0, 87, 0, 0, 0, 255, 0, 0, 0, 229, 0, 0, 0, 116, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 107, 0, 0, 0, +207, 0, 0, 0, 210, 0, 0, 0, 21, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 220, 0, 0, 0, 255, 0, 0, 0, 21, 0, 0, 0, 97, 0, 0, 0, 47, 0, 0, 0, 74, 0, 0, 0, 47, 0, 0, 0, 98, 0, 0, 0, 242, 0, 0, 0, 4, 0, 0, 0, 47, 0, 0, 0, 181, 0, 0, 0, 12, 0, 0, 0, 183, 0, 0, 0, 30, 0, 0, 0, 63, 0, 0, 0, 116, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 215, 0, 0, 0, 234, 0, 0, 0, 205, 0, 0, 0, 217, 0, 0, 0, 125, 0, 0, 0, 246, 0, 0, 0, 18, 0, 0, 0, 14, 0, 0, 0, 47, 0, 0, 0, 219, 0, 0, 0, 90, 0, 0, 0, 59, 0, 0, 0, 22, 0, 0, 0, 27, 0, +0, 0, 55, 0, 0, 0, 71, 0, 0, 0, 227, 0, 0, 0, 245, 0, 0, 0, 158, 0, 0, 0, 234, 0, 0, 0, 44, 0, 0, 0, 42, 0, 0, 0, 231, 0, 0, 0, 130, 0, 0, 0, 54, 0, 0, 0, 244, 0, 0, 0, 31, 0, 0, 0, 129, 0, 0, 0, 71, 0, 0, 0, 146, 0, 0, 0, 75, 0, 0, 0, 105, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 140, 0, 0, 0, 93, 0, 0, 0, 83, 0, 0, 0, 91, 0, 0, 0, 129, 0, 0, 0, 39, 0, 0, 0, 8, 0, 0, 0, 188, 0, 0, 0, 160, 0, 0, 0, 174, 0, 0, 0, 37, 0, 0, 0, 105, 0, 0, 0, 50, 0, 0, 0, 161, 0, 0, 0, 5, 0, 0, 0, 17, 0, 0, 0, 66, 0, 0, 0, +0, 0, 0, 0, 210, 0, 0, 0, 89, 0, 0, 0, 172, 0, 0, 0, 77, 0, 0, 0, 98, 0, 0, 0, 139, 0, 0, 0, 19, 0, 0, 0, 226, 0, 0, 0, 80, 0, 0, 0, 93, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 155, 0, 0, 0, 253, 0, 0, 0, 187, 0, 0, 0, 18, 0, 0, 0, 65, 0, 0, 0, 117, 0, 0, 0, 65, 0, 0, 0, 158, 0, 0, 0, 204, 0, 0, 0, 220, 0, 0, 0, 199, 0, 0, 0, 220, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 227, 0, 0, 0, 56, 0, 0, 0, 6, 0, 0, 0, 70, 0, 0, 0, 112, 0, 0, 0, 130, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 73, 0, 0, 0, 121, 0, 0, 0, 255, 0, 0, 0, 37, 0, 0, 0, 210, 0, 0, 0, 78, 0, 0, 0, 41, 0, 0, 0, 141, 0, 0, 0, 6, 0, 0, 0, 176, 0, 0, 0, 35, 0, 0, 0, 174, 0, 0, 0, 155, 0, 0, 0, 102, 0, 0, 0, 228, 0, 0, 0, 125, 0, 0, 0, 192, 0, 0, 0, 112, 0, 0, 0, 145, 0, 0, 0, 163, +0, 0, 0, 252, 0, 0, 0, 236, 0, 0, 0, 78, 0, 0, 0, 98, 0, 0, 0, 18, 0, 0, 0, 55, 0, 0, 0, 106, 0, 0, 0, 48, 0, 0, 0, 246, 0, 0, 0, 30, 0, 0, 0, 251, 0, 0, 0, 20, 0, 0, 0, 92, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 183, 0, 0, 0, 129, 0, 0, 0, 106, 0, 0, 0, 231, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 56, 0, 0, 0, 70, 0, 0, 0, 226, 0, 0, 0, 115, 0, 0, 0, 234, 0, 0, 0, 75, 0, 0, 0, 7, 0, 0, 0, 129, 0, 0, 0, 67, 0, 0, 0, 124, 0, 0, 0, 158, 0, 0, 0, 94, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, +0, 33, 0, 0, 0, 79, 0, 0, 0, 46, 0, 0, 0, 118, 0, 0, 0, 155, 0, 0, 0, 31, 0, 0, 0, 40, 0, 0, 0, 96, 0, 0, 0, 119, 0, 0, 0, 67, 0, 0, 0, 50, 0, 0, 0, 157, 0, 0, 0, 190, 0, 0, 0, 23, 0, 0, 0, 48, 0, 0, 0, 42, 0, 0, 0, 198, 0, 0, 0, 24, 0, 0, 0, 146, 0, 0, 0, 102, 0, 0, 0, 98, 0, 0, 0, 48, 0, 0, 0, 152, 0, 0, 0, 64, 0, 0, 0, 17, 0, 0, 0, 166, 0, 0, 0, 127, 0, 0, 0, 24, 0, 0, 0, 132, 0, 0, 0, 40, 0, 0, 0, 63, 0, 0, 0, 171, 0, 0, 0, 211, 0, 0, 0, 244, 0, 0, 0, 138, 0, 0, 0, 118, 0, 0, 0, 161, 0, 0, 0, +60, 0, 0, 0, 202, 0, 0, 0, 45, 0, 0, 0, 73, 0, 0, 0, 195, 0, 0, 0, 234, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 133, 0, 0, 0, 23, 0, 0, 0, 42, 0, 0, 0, 195, 0, 0, 0, 108, 0, 0, 0, 8, 0, 0, 0, 253, 0, 0, 0, 87, 0, 0, 0, 159, 0, 0, 0, 61, 0, 0, 0, 95, 0, 0, 0, 223, 0, 0, 0, 103, 0, 0, 0, 104, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 81, 0, 0, 0, 96, 0, 0, 0, 27, 0, 0, 0, 6, 0, 0, 0, 79, 0, 0, 0, 138, 0, 0, 0, 33, 0, 0, 0, 186, 0, 0, 0, 56, 0, 0, 0, 168, 0, 0, 0, 186, 0, 0, 0, 214, 0, 0, 0, 64, 0, 0, +0, 246, 0, 0, 0, 233, 0, 0, 0, 155, 0, 0, 0, 118, 0, 0, 0, 77, 0, 0, 0, 86, 0, 0, 0, 33, 0, 0, 0, 91, 0, 0, 0, 10, 0, 0, 0, 155, 0, 0, 0, 46, 0, 0, 0, 79, 0, 0, 0, 61, 0, 0, 0, 129, 0, 0, 0, 50, 0, 0, 0, 8, 0, 0, 0, 159, 0, 0, 0, 151, 0, 0, 0, 91, 0, 0, 0, 229, 0, 0, 0, 68, 0, 0, 0, 236, 0, 0, 0, 6, 0, 0, 0, 157, 0, 0, 0, 144, 0, 0, 0, 121, 0, 0, 0, 159, 0, 0, 0, 211, 0, 0, 0, 224, 0, 0, 0, 121, 0, 0, 0, 175, 0, 0, 0, 143, 0, 0, 0, 16, 0, 0, 0, 253, 0, 0, 0, 221, 0, 0, 0, 4, 0, 0, 0, 174, 0, 0, 0, +39, 0, 0, 0, 151, 0, 0, 0, 70, 0, 0, 0, 51, 0, 0, 0, 121, 0, 0, 0, 234, 0, 0, 0, 184, 0, 0, 0, 78, 0, 0, 0, 202, 0, 0, 0, 90, 0, 0, 0, 89, 0, 0, 0, 87, 0, 0, 0, 225, 0, 0, 0, 14, 0, 0, 0, 26, 0, 0, 0, 218, 0, 0, 0, 243, 0, 0, 0, 165, 0, 0, 0, 65, 0, 0, 0, 67, 0, 0, 0, 40, 0, 0, 0, 252, 0, 0, 0, 126, 0, 0, 0, 231, 0, 0, 0, 113, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 0, 204, 0, 0, 0, 46, 0, 0, 0, 211, 0, 0, 0, 64, 0, 0, 0, 236, 0, 0, 0, 179, 0, 0, 0, 19, 0, 0, 0, 111, 0, 0, 0, +68, 0, 0, 0, 205, 0, 0, 0, 19, 0, 0, 0, 178, 0, 0, 0, 55, 0, 0, 0, 242, 0, 0, 0, 110, 0, 0, 0, 217, 0, 0, 0, 28, 0, 0, 0, 227, 0, 0, 0, 219, 0, 0, 0, 96, 0, 0, 0, 205, 0, 0, 0, 92, 0, 0, 0, 74, 0, 0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 239, 0, 0, 0, 115, 0, 0, 0, 54, 0, 0, 0, 113, 0, 0, 0, 140, 0, 0, 0, 246, 0, 0, 0, 17, 0, 0, 0, 180, 0, 0, 0, 216, 0, 0, 0, 206, 0, 0, 0, 23, 0, 0, 0, 94, 0, 0, 0, 79, 0, 0, 0, 38, 0, 0, 0, 119, 0, 0, 0, 151, 0, 0, 0, 95, 0, 0, 0, 203, 0, 0, 0, 239, 0, 0, 0, 145, 0, 0, 0, +235, 0, 0, 0, 106, 0, 0, 0, 98, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 74, 0, 0, 0, 162, 0, 0, 0, 151, 0, 0, 0, 8, 0, 0, 0, 129, 0, 0, 0, 45, 0, 0, 0, 131, 0, 0, 0, 196, 0, 0, 0, 204, 0, 0, 0, 240, 0, 0, 0, 131, 0, 0, 0, 126, 0, 0, 0, 236, +0, 0, 0, 13, 0, 0, 0, 149, 0, 0, 0, 76, 0, 0, 0, 91, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 152, 0, 0, 0, 128, 0, 0, 0, 74, 0, 0, 0, 102, 0, 0, 0, 86, 0, 0, 0, 12, 0, 0, 0, 81, 0, 0, 0, 179, 0, 0, 0, 242, 0, 0, 0, 4, 0, 0, 0, 93, 0, 0, 0, 39, 0, 0, 0, 59, 0, 0, 0, 185, 0, 0, 0, 184, 0, 0, 0, 6, 0, 0, 0, 90, 0, 0, 0, 46, 0, 0, 0, 254, 0, 0, 0, 195, 0, 0, 0, 130, 0, 0, 0, 55, 0, 0, 0, 156, 0, 0, 0, 163, 0, 0, 0, 17, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 166, 0, 0, 0, 218, 0, 0, 0, 99, 0, 0, 0, 72, 0, 0, +0, 155, 0, 0, 0, 173, 0, 0, 0, 222, 0, 0, 0, 45, 0, 0, 0, 166, 0, 0, 0, 188, 0, 0, 0, 110, 0, 0, 0, 50, 0, 0, 0, 218, 0, 0, 0, 39, 0, 0, 0, 101, 0, 0, 0, 221, 0, 0, 0, 87, 0, 0, 0, 132, 0, 0, 0, 79, 0, 0, 0, 55, 0, 0, 0, 49, 0, 0, 0, 125, 0, 0, 0, 46, 0, 0, 0, 188, 0, 0, 0, 173, 0, 0, 0, 135, 0, 0, 0, 7, 0, 0, 0, 42, 0, 0, 0, 107, 0, 0, 0, 55, 0, 0, 0, 252, 0, 0, 0, 95, 0, 0, 0, 235, 0, 0, 0, 78, 0, 0, 0, 117, 0, 0, 0, 53, 0, 0, 0, 166, 0, 0, 0, 222, 0, 0, 0, 171, 0, 0, 0, 10, 0, 0, 0, 25, 0, 0, +0, 58, 0, 0, 0, 183, 0, 0, 0, 177, 0, 0, 0, 239, 0, 0, 0, 146, 0, 0, 0, 106, 0, 0, 0, 59, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 178, 0, 0, 0, 148, 0, 0, 0, 109, 0, 0, 0, 57, 0, 0, 0, 96, 0, 0, 0, 172, 0, 0, 0, 238, 0, 0, 0, 231, 0, 0, 0, 129, 0, 0, 0, 26, 0, 0, 0, 59, 0, 0, 0, 118, 0, 0, 0, 135, 0, 0, 0, 92, 0, 0, 0, 5, 0, 0, 0, 148, 0, 0, 0, 42, 0, 0, 0, 69, 0, 0, 0, 185, 0, 0, 0, 128, 0, 0, 0, 233, 0, 0, 0, 34, 0, 0, 0, 177, 0, 0, 0, 7, 0, 0, 0, 203, 0, 0, 0, 64, 0, 0, 0, 158, 0, 0, 0, 112, 0, 0, +0, 73, 0, 0, 0, 109, 0, 0, 0, 18, 0, 0, 0, 253, 0, 0, 0, 24, 0, 0, 0, 120, 0, 0, 0, 132, 0, 0, 0, 168, 0, 0, 0, 76, 0, 0, 0, 125, 0, 0, 0, 110, 0, 0, 0, 89, 0, 0, 0, 166, 0, 0, 0, 229, 0, 0, 0, 116, 0, 0, 0, 241, 0, 0, 0, 25, 0, 0, 0, 166, 0, 0, 0, 132, 0, 0, 0, 46, 0, 0, 0, 81, 0, 0, 0, 193, 0, 0, 0, 41, 0, 0, 0, 19, 0, 0, 0, 242, 0, 0, 0, 20, 0, 0, 0, 107, 0, 0, 0, 93, 0, 0, 0, 83, 0, 0, 0, 81, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, 191, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 164, 0, 0, 0, 75, 0, 0, 0, +98, 0, 0, 0, 76, 0, 0, 0, 230, 0, 0, 0, 253, 0, 0, 0, 114, 0, 0, 0, 7, 0, 0, 0, 242, 0, 0, 0, 129, 0, 0, 0, 252, 0, 0, 0, 242, 0, 0, 0, 189, 0, 0, 0, 18, 0, 0, 0, 124, 0, 0, 0, 104, 0, 0, 0, 118, 0, 0, 0, 42, 0, 0, 0, 186, 0, 0, 0, 245, 0, 0, 0, 101, 0, 0, 0, 177, 0, 0, 0, 31, 0, 0, 0, 23, 0, 0, 0, 10, 0, 0, 0, 56, 0, 0, 0, 176, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 248, 0, 0, 0, 244, 0, 0, 0, 42, 0, 0, 0, 85, 0, 0, 0, 96, 0, 0, 0, 85, 0, 0, 0, 91, 0, 0, 0, 228, 0, 0, 0, 29, 0, 0, 0, 113, 0, 0, 0, +76, 0, 0, 0, 157, 0, 0, 0, 91, 0, 0, 0, 159, 0, 0, 0, 112, 0, 0, 0, 166, 0, 0, 0, 133, 0, 0, 0, 154, 0, 0, 0, 44, 0, 0, 0, 160, 0, 0, 0, 226, 0, 0, 0, 50, 0, 0, 0, 72, 0, 0, 0, 206, 0, 0, 0, 158, 0, 0, 0, 42, 0, 0, 0, 165, 0, 0, 0, 7, 0, 0, 0, 59, 0, 0, 0, 199, 0, 0, 0, 108, 0, 0, 0, 134, 0, 0, 0, 119, 0, 0, 0, 222, 0, 0, 0, 60, 0, 0, 0, 247, 0, 0, 0, 24, 0, 0, 0, 122, 0, 0, 0, 150, 0, 0, 0, 126, 0, 0, 0, 67, 0, 0, 0, 87, 0, 0, 0, 169, 0, 0, 0, 85, 0, 0, 0, 252, 0, 0, 0, 78, 0, 0, 0, 182, 0, 0, 0, +114, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 82, 0, 0, 0, 211, 0, 0, 0, 211, 0, 0, 0, 182, 0, 0, 0, 133, 0, 0, 0, 246, 0, 0, 0, 113, 0, 0, 0, 199, 0, 0, 0, 68, 0, 0, 0, 63, 0, 0, 0, 127, 0, 0, 0, 215, 0, 0, 0, 179, 0, 0, 0, 242, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 202, 0, 0, 0, 167, 0, 0, 0, 85, 0, 0, 0, 123, 0, 0, 0, 121, 0, 0, 0, 243, 0, 0, 0, 202, 0, 0, 0, 90, 0, 0, 0, 101, 0, 0, 0, 246, 0, 0, 0, 237, 0, 0, 0, 80, 0, 0, 0, 20, 0, 0, 0, 123, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 42, 0, 0, 0, 101, 0, 0, 0, 158, 0, 0, 0, 226, 0, 0, 0, 249, 0, 0, 0, 202, 0, 0, 0, 167, 0, 0, 0, 34, 0, 0, 0, 38, 0, 0, 0, 83, 0, 0, 0, 203, 0, 0, 0, 33, 0, 0, 0, 91, 0, 0, 0, 167, 0, 0, 0, 49, 0, 0, 0, 144, 0, 0, 0, 215, 0, 0, 0, +197, 0, 0, 0, 38, 0, 0, 0, 8, 0, 0, 0, 189, 0, 0, 0, 176, 0, 0, 0, 83, 0, 0, 0, 99, 0, 0, 0, 88, 0, 0, 0, 195, 0, 0, 0, 49, 0, 0, 0, 94, 0, 0, 0, 117, 0, 0, 0, 70, 0, 0, 0, 21, 0, 0, 0, 145, 0, 0, 0, 166, 0, 0, 0, 248, 0, 0, 0, 47, 0, 0, 0, 26, 0, 0, 0, 8, 0, 0, 0, 101, 0, 0, 0, 136, 0, 0, 0, 47, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 241, 0, 0, 0, 124, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, 0, 129, 0, 0, 0, 33, 0, 0, 0, 97, 0, 0, 0, 9, 0, 0, 0, 246, 0, 0, 0, 78, 0, 0, 0, 241, 0, 0, 0, 146, 0, +0, 0, 238, 0, 0, 0, 99, 0, 0, 0, 97, 0, 0, 0, 115, 0, 0, 0, 135, 0, 0, 0, 199, 0, 0, 0, 84, 0, 0, 0, 14, 0, 0, 0, 66, 0, 0, 0, 75, 0, 0, 0, 201, 0, 0, 0, 71, 0, 0, 0, 209, 0, 0, 0, 184, 0, 0, 0, 126, 0, 0, 0, 145, 0, 0, 0, 117, 0, 0, 0, 55, 0, 0, 0, 153, 0, 0, 0, 40, 0, 0, 0, 184, 0, 0, 0, 221, 0, 0, 0, 127, 0, 0, 0, 80, 0, 0, 0, 137, 0, 0, 0, 143, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 93, 0, 0, 0, 214, 0, 0, 0, 159, 0, 0, 0, 160, 0, 0, 0, 240, 0, 0, 0, 157, 0, 0, 0, 129, 0, 0, 0, 206, 0, 0, 0, 58, +0, 0, 0, 123, 0, 0, 0, 152, 0, 0, 0, 88, 0, 0, 0, 187, 0, 0, 0, 215, 0, 0, 0, 120, 0, 0, 0, 200, 0, 0, 0, 63, 0, 0, 0, 19, 0, 0, 0, 241, 0, 0, 0, 116, 0, 0, 0, 25, 0, 0, 0, 223, 0, 0, 0, 248, 0, 0, 0, 152, 0, 0, 0, 137, 0, 0, 0, 93, 0, 0, 0, 250, 0, 0, 0, 95, 0, 0, 0, 158, 0, 0, 0, 53, 0, 0, 0, 133, 0, 0, 0, 148, 0, 0, 0, 71, 0, 0, 0, 31, 0, 0, 0, 144, 0, 0, 0, 21, 0, 0, 0, 38, 0, 0, 0, 208, 0, 0, 0, 132, 0, 0, 0, 237, 0, 0, 0, 138, 0, 0, 0, 128, 0, 0, 0, 247, 0, 0, 0, 99, 0, 0, 0, 66, 0, 0, 0, 134, +0, 0, 0, 39, 0, 0, 0, 215, 0, 0, 0, 244, 0, 0, 0, 117, 0, 0, 0, 88, 0, 0, 0, 220, 0, 0, 0, 156, 0, 0, 0, 192, 0, 0, 0, 34, 0, 0, 0, 126, 0, 0, 0, 32, 0, 0, 0, 53, 0, 0, 0, 253, 0, 0, 0, 31, 0, 0, 0, 104, 0, 0, 0, 14, 0, 0, 0, 111, 0, 0, 0, 151, 0, 0, 0, 186, 0, 0, 0, 112, 0, 0, 0, 187, 0, 0, 0, 163, 0, 0, 0, 14, 0, 0, 0, 229, 0, 0, 0, 11, 0, 0, 0, 18, 0, 0, 0, 244, 0, 0, 0, 162, 0, 0, 0, 220, 0, 0, 0, 71, 0, 0, 0, 248, 0, 0, 0, 230, 0, 0, 0, 208, 0, 0, 0, 35, 0, 0, 0, 108, 0, 0, 0, 51, 0, 0, 0, 168, +0, 0, 0, 153, 0, 0, 0, 70, 0, 0, 0, 110, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 186, 0, 0, 0, 118, 0, 0, 0, 72, 0, 0, 0, 15, 0, 0, 0, 163, 0, 0, 0, 42, 0, 0, 0, 97, 0, 0, 0, 55, 0, 0, 0, 226, 0, 0, 0, 89, 0, 0, 0, 18, 0, 0, 0, 14, 0, 0, 0, 39, 0, 0, 0, 186, 0, 0, 0, 100, 0, 0, 0, 67, 0, 0, 0, 174, 0, 0, 0, 192, 0, 0, 0, 66, 0, 0, 0, 105, 0, 0, 0, 121, 0, 0, 0, 164, 0, 0, 0, 30, 0, 0, 0, 41, 0, 0, 0, 139, 0, 0, 0, 21, 0, 0, 0, 235, 0, 0, 0, 248, 0, 0, 0, 175, 0, 0, 0, 212, 0, 0, 0, 162, 0, 0, 0, 104, +0, 0, 0, 51, 0, 0, 0, 181, 0, 0, 0, 122, 0, 0, 0, 36, 0, 0, 0, 44, 0, 0, 0, 25, 0, 0, 0, 51, 0, 0, 0, 221, 0, 0, 0, 27, 0, 0, 0, 171, 0, 0, 0, 236, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 35, 0, 0, 0, 248, 0, 0, 0, 66, 0, 0, 0, 43, 0, 0, 0, 6, 0, 0, 0, 136, 0, 0, 0, 234, 0, 0, 0, 61, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 120, 0, 0, 0, 69, 0, 0, 0, 77, 0, 0, 0, 56, 0, 0, 0, 237, 0, 0, 0, 46, 0, 0, 0, 46, 0, 0, 0, 68, 0, 0, 0, 73, 0, 0, 0, 237, 0, 0, 0, 203, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 0, 0, 0, 104, 0, 0, 0, 232, 0, 0, 0, 65, 0, 0, 0, 143, 0, 0, 0, 145, 0, 0, 0, 248, 0, 0, 0, 17, 0, 0, 0, 19, 0, 0, 0, 144, 0, 0, 0, 46, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 48, 0, 0, 0, 239, 0, 0, 0, 173, 0, 0, 0, 160, 0, 0, 0, 97, 0, 0, 0, 0, +0, 0, 0, 136, 0, 0, 0, 239, 0, 0, 0, 219, 0, 0, 0, 206, 0, 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 187, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 86, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 63, 0, 0, 0, 96, 0, 0, 0, 193, 0, 0, 0, 130, 0, 0, 0, 45, 0, 0, 0, 163, 0, 0, 0, 40, 0, 0, 0, 88, 0, 0, 0, 36, 0, 0, 0, 158, 0, 0, 0, 159, 0, 0, 0, 227, 0, 0, 0, 112, 0, 0, 0, 204, 0, 0, 0, 9, 0, 0, 0, 78, 0, 0, 0, 26, 0, 0, 0, 63, 0, 0, 0, 17, 0, 0, 0, 17, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 0, 0, +0, 65, 0, 0, 0, 224, 0, 0, 0, 101, 0, 0, 0, 163, 0, 0, 0, 10, 0, 0, 0, 65, 0, 0, 0, 109, 0, 0, 0, 17, 0, 0, 0, 49, 0, 0, 0, 64, 0, 0, 0, 1, 0, 0, 0, 82, 0, 0, 0, 86, 0, 0, 0, 148, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 138, 0, 0, 0, 170, 0, 0, 0, 82, 0, 0, 0, 238, 0, 0, 0, 216, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 0, 0, 0, 181, 0, 0, 0, 170, 0, 0, 0, 46, 0, 0, 0, 56, 0, 0, 0, 170, 0, 0, 0, 183, 0, 0, 0, 135, 0, 0, 0, 247, 0, 0, 0, 43, 0, 0, 0, 251, 0, 0, 0, 4, 0, 0, 0, 203, 0, 0, 0, 132, +0, 0, 0, 61, 0, 0, 0, 84, 0, 0, 0, 32, 0, 0, 0, 239, 0, 0, 0, 89, 0, 0, 0, 222, 0, 0, 0, 164, 0, 0, 0, 43, 0, 0, 0, 147, 0, 0, 0, 110, 0, 0, 0, 46, 0, 0, 0, 236, 0, 0, 0, 66, 0, 0, 0, 154, 0, 0, 0, 212, 0, 0, 0, 45, 0, 0, 0, 244, 0, 0, 0, 70, 0, 0, 0, 88, 0, 0, 0, 39, 0, 0, 0, 43, 0, 0, 0, 24, 0, 0, 0, 143, 0, 0, 0, 131, 0, 0, 0, 61, 0, 0, 0, 105, 0, 0, 0, 158, 0, 0, 0, 212, 0, 0, 0, 62, 0, 0, 0, 182, 0, 0, 0, 197, 0, 0, 0, 253, 0, 0, 0, 88, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0, 137, 0, 0, 0, 201, 0, +0, 0, 99, 0, 0, 0, 98, 0, 0, 0, 28, 0, 0, 0, 23, 0, 0, 0, 180, 0, 0, 0, 96, 0, 0, 0, 196, 0, 0, 0, 38, 0, 0, 0, 104, 0, 0, 0, 9, 0, 0, 0, 195, 0, 0, 0, 46, 0, 0, 0, 55, 0, 0, 0, 15, 0, 0, 0, 123, 0, 0, 0, 180, 0, 0, 0, 156, 0, 0, 0, 182, 0, 0, 0, 249, 0, 0, 0, 251, 0, 0, 0, 212, 0, 0, 0, 81, 0, 0, 0, 120, 0, 0, 0, 200, 0, 0, 0, 99, 0, 0, 0, 234, 0, 0, 0, 119, 0, 0, 0, 71, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 180, 0, 0, 0, 24, 0, 0, 0, 71, 0, 0, 0, 121, 0, 0, 0, 203, 0, 0, 0, 212, 0, 0, 0, 90, 0, 0, +0, 7, 0, 0, 0, 20, 0, 0, 0, 15, 0, 0, 0, 160, 0, 0, 0, 213, 0, 0, 0, 172, 0, 0, 0, 208, 0, 0, 0, 65, 0, 0, 0, 64, 0, 0, 0, 171, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 0, 229, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 111, 0, 0, 0, 247, 0, 0, 0, 168, 0, 0, 0, 212, 0, 0, 0, 118, 0, 0, 0, 239, 0, 0, 0, 231, 0, 0, 0, 69, 0, 0, 0, 108, 0, 0, 0, 161, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 79, 0, 0, 0, 251, 0, 0, 0, 225, 0, 0, 0, 112, 0, 0, 0, 106, 0, 0, 0, 31, 0, 0, 0, 85, 0, 0, 0, 79, 0, 0, 0, 9, 0, 0, 0, 180, 0, 0, 0, +149, 0, 0, 0, 51, 0, 0, 0, 54, 0, 0, 0, 198, 0, 0, 0, 129, 0, 0, 0, 1, 0, 0, 0, 24, 0, 0, 0, 6, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 164, 0, 0, 0, 180, 0, 0, 0, 36, 0, 0, 0, 164, 0, 0, 0, 134, 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 0, 172, 0, 0, 0, 2, 0, 0, 0, 119, 0, 0, 0, 56, 0, 0, 0, 222, 0, 0, 0, 215, 0, 0, 0, 96, 0, 0, 0, 72, 0, 0, 0, 7, 0, 0, 0, 240, 0, 0, 0, 116, 0, 0, 0, 168, 0, 0, 0, 255, 0, 0, 0, 84, 0, 0, 0, 229, 0, 0, 0, 48, 0, 0, 0, 67, 0, 0, 0, 255, 0, 0, 0, 119, 0, 0, 0, 251, 0, 0, 0, 33, 0, +0, 0, 7, 0, 0, 0, 255, 0, 0, 0, 178, 0, 0, 0, 7, 0, 0, 0, 107, 0, 0, 0, 228, 0, 0, 0, 229, 0, 0, 0, 48, 0, 0, 0, 252, 0, 0, 0, 25, 0, 0, 0, 108, 0, 0, 0, 163, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 197, 0, 0, 0, 44, 0, 0, 0, 172, 0, 0, 0, +211, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 124, 0, 0, 0, 41, 0, 0, 0, 247, 0, 0, 0, 5, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 31, 0, 0, 0, 134, 0, 0, 0, 85, 0, 0, 0, 244, 0, 0, 0, 214, 0, 0, 0, 47, 0, 0, 0, 12, 0, 0, 0, 153, 0, 0, 0, 208, 0, 0, 0, 101, 0, 0, 0, 155, 0, 0, 0, 107, 0, 0, 0, 70, 0, 0, 0, 13, 0, 0, 0, 67, 0, 0, 0, 248, 0, 0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 30, 0, 0, 0, 127, 0, 0, 0, 180, 0, 0, 0, 116, 0, 0, 0, 126, 0, 0, 0, 177, 0, 0, 0, 137, 0, 0, 0, 79, 0, 0, 0, 24, 0, 0, 0, +90, 0, 0, 0, 171, 0, 0, 0, 100, 0, 0, 0, 6, 0, 0, 0, 223, 0, 0, 0, 69, 0, 0, 0, 135, 0, 0, 0, 224, 0, 0, 0, 106, 0, 0, 0, 198, 0, 0, 0, 240, 0, 0, 0, 14, 0, 0, 0, 201, 0, 0, 0, 36, 0, 0, 0, 53, 0, 0, 0, 56, 0, 0, 0, 234, 0, 0, 0, 48, 0, 0, 0, 84, 0, 0, 0, 180, 0, 0, 0, 196, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 0, 233, 0, 0, 0, 159, 0, 0, 0, 220, 0, 0, 0, 63, 0, 0, 0, 193, 0, 0, 0, 137, 0, 0, 0, 68, 0, 0, 0, 116, 0, 0, 0, 39, 0, 0, 0, 228, 0, 0, 0, 193, 0, 0, 0, 144, 0, 0, 0, 255, 0, 0, 0, 74, 0, 0, 0, +167, 0, 0, 0, 60, 0, 0, 0, 238, 0, 0, 0, 205, 0, 0, 0, 244, 0, 0, 0, 29, 0, 0, 0]).concat([37, 0, 0, 0, 148, 0, 0, 0, 127, 0, 0, 0, 99, 0, 0, 0, 22, 0, 0, 0, 72, 0, 0, 0, 188, 0, 0, 0, 100, 0, 0, 0, 254, 0, 0, 0, 149, 0, 0, 0, 196, 0, 0, 0, 12, 0, 0, 0, 139, 0, 0, 0, 25, 0, 0, 0, 117, 0, 0, 0, 110, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 94, 0, 0, 0, 106, 0, 0, 0, 111, 0, 0, 0, 26, 0, 0, 0, 140, 0, 0, 0, 227, 0, 0, 0, 211, 0, 0, 0, 40, 0, 0, 0, 242, 0, 0, 0, 224, 0, 0, 0, 185, 0, 0, 0, 122, 0, 0, 0, 67, +0, 0, 0, 105, 0, 0, 0, 230, 0, 0, 0, 211, 0, 0, 0, 192, 0, 0, 0, 254, 0, 0, 0, 126, 0, 0, 0, 151, 0, 0, 0, 171, 0, 0, 0, 108, 0, 0, 0, 123, 0, 0, 0, 142, 0, 0, 0, 19, 0, 0, 0, 66, 0, 0, 0, 212, 0, 0, 0, 202, 0, 0, 0, 112, 0, 0, 0, 61, 0, 0, 0, 171, 0, 0, 0, 251, 0, 0, 0, 95, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 204, 0, 0, 0, 119, 0, 0, 0, 34, 0, 0, 0, 248, 0, 0, 0, 120, 0, 0, 0, 85, 0, 0, 0, 174, 0, 0, 0, 98, 0, 0, 0, 53, 0, 0, 0, 251, 0, 0, 0, 154, 0, 0, 0, 198, 0, 0, 0, 3, 0, 0, 0, 228, +0, 0, 0, 12, 0, 0, 0, 238, 0, 0, 0, 171, 0, 0, 0, 199, 0, 0, 0, 192, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 84, 0, 0, 0, 50, 0, 0, 0, 173, 0, 0, 0, 174, 0, 0, 0, 133, 0, 0, 0, 88, 0, 0, 0, 67, 0, 0, 0, 184, 0, 0, 0, 177, 0, 0, 0, 230, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 120, 0, 0, 0, 136, 0, 0, 0, 86, 0, 0, 0, 219, 0, 0, 0, 156, 0, 0, 0, 252, 0, 0, 0, 121, 0, 0, 0, 246, 0, 0, 0, 249, 0, 0, 0, 65, 0, 0, 0, 95, 0, 0, 0, 183, 0, 0, 0, 188, 0, 0, 0, 17, 0, 0, 0, 249, 0, 0, 0, 32, 0, 0, 0, 54, +0, 0, 0, 28, 0, 0, 0, 83, 0, 0, 0, 43, 0, 0, 0, 90, 0, 0, 0, 32, 0, 0, 0, 91, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 68, 0, 0, 0, 145, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 99, 0, 0, 0, 18, 0, 0, 0, 100, 0, 0, 0, 184, 0, 0, 0, 85, 0, 0, 0, 246, 0, 0, 0, 222, 0, 0, 0, 44, 0, 0, 0, 219, 0, 0, 0, 71, 0, 0, 0, 184, 0, 0, 0, 198, 0, 0, 0, 10, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 0, 147, 0, 0, 0, 216, 0, 0, 0, 245, 0, 0, 0, 245, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 10, 0, 0, 0, 214, 0, 0, 0, 27, 0, 0, +0, 154, 0, 0, 0, 108, 0, 0, 0, 229, 0, 0, 0, 70, 0, 0, 0, 234, 0, 0, 0, 112, 0, 0, 0, 150, 0, 0, 0, 141, 0, 0, 0, 78, 0, 0, 0, 42, 0, 0, 0, 82, 0, 0, 0, 33, 0, 0, 0, 38, 0, 0, 0, 75, 0, 0, 0, 177, 0, 0, 0, 187, 0, 0, 0, 15, 0, 0, 0, 124, 0, 0, 0, 169, 0, 0, 0, 155, 0, 0, 0, 4, 0, 0, 0, 187, 0, 0, 0, 81, 0, 0, 0, 8, 0, 0, 0, 241, 0, 0, 0, 154, 0, 0, 0, 164, 0, 0, 0, 118, 0, 0, 0, 124, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 148, 0, 0, 0, 247, 0, 0, 0, 64, 0, 0, 0, 208, 0, 0, 0, 215, 0, 0, 0, 235, 0, 0, 0, 169, 0, 0, 0, 130, 0, 0, 0, 54, 0, 0, 0, 213, 0, 0, 0, 21, 0, 0, 0, 185, 0, 0, 0, 51, 0, 0, 0, 122, 0, 0, 0, 191, 0, 0, 0, 138, 0, 0, 0, 242, 0, 0, 0, 99, 0, 0, 0, 170, 0, 0, 0, 55, 0, 0, 0, 245, 0, 0, 0, 89, 0, 0, 0, 172, 0, 0, 0, +189, 0, 0, 0, 187, 0, 0, 0, 50, 0, 0, 0, 54, 0, 0, 0, 190, 0, 0, 0, 115, 0, 0, 0, 153, 0, 0, 0, 56, 0, 0, 0, 44, 0, 0, 0, 179, 0, 0, 0, 218, 0, 0, 0, 122, 0, 0, 0, 216, 0, 0, 0, 61, 0, 0, 0, 153, 0, 0, 0, 202, 0, 0, 0, 210, 0, 0, 0, 244, 0, 0, 0, 218, 0, 0, 0, 153, 0, 0, 0, 142, 0, 0, 0, 79, 0, 0, 0, 152, 0, 0, 0, 183, 0, 0, 0, 244, 0, 0, 0, 174, 0, 0, 0, 62, 0, 0, 0, 159, 0, 0, 0, 142, 0, 0, 0, 53, 0, 0, 0, 96, 0, 0, 0, 164, 0, 0, 0, 51, 0, 0, 0, 117, 0, 0, 0, 164, 0, 0, 0, 4, 0, 0, 0, 147, 0, 0, +0, 177, 0, 0, 0, 107, 0, 0, 0, 77, 0, 0, 0, 151, 0, 0, 0, 157, 0, 0, 0, 168, 0, 0, 0, 205, 0, 0, 0, 151, 0, 0, 0, 123, 0, 0, 0, 157, 0, 0, 0, 185, 0, 0, 0, 231, 0, 0, 0, 165, 0, 0, 0, 239, 0, 0, 0, 253, 0, 0, 0, 168, 0, 0, 0, 66, 0, 0, 0, 107, 0, 0, 0, 195, 0, 0, 0, 98, 0, 0, 0, 100, 0, 0, 0, 125, 0, 0, 0, 165, 0, 0, 0, 27, 0, 0, 0, 201, 0, 0, 0, 158, 0, 0, 0, 210, 0, 0, 0, 69, 0, 0, 0, 185, 0, 0, 0, 238, 0, 0, 0, 3, 0, 0, 0, 176, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 104, 0, 0, 0, 237, 0, 0, 0, 183, +0, 0, 0, 132, 0, 0, 0, 44, 0, 0, 0, 246, 0, 0, 0, 211, 0, 0, 0, 161, 0, 0, 0, 107, 0, 0, 0, 36, 0, 0, 0, 109, 0, 0, 0, 135, 0, 0, 0, 86, 0, 0, 0, 151, 0, 0, 0, 89, 0, 0, 0, 121, 0, 0, 0, 98, 0, 0, 0, 159, 0, 0, 0, 172, 0, 0, 0, 237, 0, 0, 0, 243, 0, 0, 0, 201, 0, 0, 0, 137, 0, 0, 0, 33, 0, 0, 0, 46, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 204, 0, 0, 0, 47, 0, 0, 0, 190, 0, 0, 0, 214, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0, 57, 0, 0, 0, 97, 0, 0, 0, 5, 0, 0, 0, 237, 0, 0, 0, 37, 0, 0, 0, 137, 0, 0, 0, 139, +0, 0, 0, 93, 0, 0, 0, 27, 0, 0, 0, 203, 0, 0, 0, 12, 0, 0, 0, 85, 0, 0, 0, 244, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 70, 0, 0, 0, 232, 0, 0, 0, 30, 0, 0, 0, 198, 0, 0, 0, 131, 0, 0, 0, 200, 0, 0, 0, 90, 0, 0, 0, 118, 0, 0, 0, 219, 0, 0, 0, 204, 0, 0, 0, 25, 0, 0, 0, 122, 0, 0, 0, 204, 0, 0, 0, 103, 0, 0, 0, 70, 0, 0, 0, 11, 0, 0, 0, 83, 0, 0, 0, 207, 0, 0, 0, 194, 0, 0, 0, 161, 0, 0, 0, 173, 0, 0, 0, 106, 0, 0, 0, 243, 0, 0, 0, 205, 0, 0, 0, 143, 0, 0, 0, 201, 0, 0, 0, 222, 0, 0, 0, 28, +0, 0, 0, 248, 0, 0, 0, 108, 0, 0, 0, 143, 0, 0, 0, 248, 0, 0, 0, 118, 0, 0, 0, 66, 0, 0, 0, 231, 0, 0, 0, 254, 0, 0, 0, 178, 0, 0, 0, 114, 0, 0, 0, 33, 0, 0, 0, 10, 0, 0, 0, 102, 0, 0, 0, 116, 0, 0, 0, 143, 0, 0, 0, 183, 0, 0, 0, 235, 0, 0, 0, 228, 0, 0, 0, 111, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 140, 0, 0, 0, 107, 0, 0, 0, 190, 0, 0, 0, 252, 0, 0, 0, 77, 0, 0, 0, 112, 0, 0, 0, 98, 0, 0, 0, 110, 0, 0, 0, 82, 0, 0, 0, 119, 0, 0, 0, 153, 0, 0, 0, 136, 0, 0, 0, 126, 0, 0, 0, 123, 0, 0, 0, 87, 0, 0, 0, +122, 0, 0, 0, 13, 0, 0, 0, 254, 0, 0, 0, 220, 0, 0, 0, 114, 0, 0, 0, 146, 0, 0, 0, 241, 0, 0, 0, 104, 0, 0, 0, 29, 0, 0, 0, 151, 0, 0, 0, 215, 0, 0, 0, 124, 0, 0, 0, 141, 0, 0, 0, 83, 0, 0, 0, 16, 0, 0, 0, 55, 0, 0, 0, 83, 0, 0, 0, 136, 0, 0, 0, 119, 0, 0, 0, 2, 0, 0, 0, 202, 0, 0, 0, 39, 0, 0, 0, 168, 0, 0, 0, 229, 0, 0, 0, 69, 0, 0, 0, 226, 0, 0, 0, 168, 0, 0, 0, 72, 0, 0, 0, 42, 0, 0, 0, 171, 0, 0, 0, 24, 0, 0, 0, 202, 0, 0, 0, 234, 0, 0, 0, 45, 0, 0, 0, 42, 0, 0, 0, 84, 0, 0, 0, 23, 0, 0, 0, +55, 0, 0, 0, 50, 0, 0, 0, 9, 0, 0, 0, 220, 0, 0, 0, 224, 0, 0, 0, 74, 0, 0, 0, 183, 0, 0, 0, 125, 0, 0, 0, 130, 0, 0, 0, 16, 0, 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 100, 0, 0, 0, 30, 0, 0, 0, 20, 0, 0, 0, 10, 0, 0, 0, 87, 0, 0, 0, 212, 0, +0, 0, 218, 0, 0, 0, 92, 0, 0, 0, 150, 0, 0, 0, 155, 0, 0, 0, 1, 0, 0, 0, 76, 0, 0, 0, 103, 0, 0, 0, 191, 0, 0, 0, 139, 0, 0, 0, 48, 0, 0, 0, 254, 0, 0, 0, 8, 0, 0, 0, 219, 0, 0, 0, 13, 0, 0, 0, 213, 0, 0, 0, 168, 0, 0, 0, 215, 0, 0, 0, 9, 0, 0, 0, 17, 0, 0, 0, 133, 0, 0, 0, 162, 0, 0, 0, 211, 0, 0, 0, 69, 0, 0, 0, 251, 0, 0, 0, 126, 0, 0, 0, 218, 0, 0, 0, 140, 0, 0, 0, 194, 0, 0, 0, 208, 0, 0, 0, 172, 0, 0, 0, 24, 0, 0, 0, 232, 0, 0, 0, 82, 0, 0, 0, 54, 0, 0, 0, 212, 0, 0, 0, 33, 0, 0, 0, 163, 0, +0, 0, 221, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0, 121, 0, 0, 0, 183, 0, 0, 0, 248, 0, 0, 0, 113, 0, 0, 0, 157, 0, 0, 0, 198, 0, 0, 0, 145, 0, 0, 0, 112, 0, 0, 0, 134, 0, 0, 0, 86, 0, 0, 0, 191, 0, 0, 0, 161, 0, 0, 0, 17, 0, 0, 0, 139, 0, 0, 0, 25, 0, 0, 0, 225, 0, 0, 0, 15, 0, 0, 0, 24, 0, 0, 0, 50, 0, 0, 0, 152, 0, 0, 0, 44, 0, 0, 0, 143, 0, 0, 0, 145, 0, 0, 0, 174, 0, 0, 0, 18, 0, 0, 0, 240, 0, 0, 0, 140, 0, 0, 0, 234, 0, 0, 0, 243, 0, 0, 0, 60, 0, 0, 0, 185, 0, 0, 0, 93, 0, 0, 0, 228, 0, 0, 0, 105, +0, 0, 0, 237, 0, 0, 0, 178, 0, 0, 0, 71, 0, 0, 0, 24, 0, 0, 0, 189, 0, 0, 0, 206, 0, 0, 0, 22, 0, 0, 0, 82, 0, 0, 0, 92, 0, 0, 0, 35, 0, 0, 0, 226, 0, 0, 0, 165, 0, 0, 0, 37, 0, 0, 0, 82, 0, 0, 0, 93, 0, 0, 0, 185, 0, 0, 0, 177, 0, 0, 0, 231, 0, 0, 0, 93, 0, 0, 0, 78, 0, 0, 0, 188, 0, 0, 0, 238, 0, 0, 0, 187, 0, 0, 0, 64, 0, 0, 0, 129, 0, 0, 0, 119, 0, 0, 0, 130, 0, 0, 0, 25, 0, 0, 0, 171, 0, 0, 0, 181, 0, 0, 0, 198, 0, 0, 0, 238, 0, 0, 0, 171, 0, 0, 0, 91, 0, 0, 0, 107, 0, 0, 0, 99, 0, 0, 0, 146, +0, 0, 0, 138, 0, 0, 0, 52, 0, 0, 0, 141, 0, 0, 0, 205, 0, 0, 0, 238, 0, 0, 0, 79, 0, 0, 0, 73, 0, 0, 0, 229, 0, 0, 0, 201, 0, 0, 0, 126, 0, 0, 0, 33, 0, 0, 0, 172, 0, 0, 0, 139, 0, 0, 0, 34, 0, 0, 0, 205, 0, 0, 0, 195, 0, 0, 0, 154, 0, 0, 0, 233, 0, 0, 0, 94, 0, 0, 0, 120, 0, 0, 0, 189, 0, 0, 0, 222, 0, 0, 0, 186, 0, 0, 0, 173, 0, 0, 0, 171, 0, 0, 0, 191, 0, 0, 0, 117, 0, 0, 0, 65, 0, 0, 0, 9, 0, 0, 0, 197, 0, 0, 0, 88, 0, 0, 0, 164, 0, 0, 0, 125, 0, 0, 0, 146, 0, 0, 0, 176, 0, 0, 0, 127, 0, 0, 0, +242, 0, 0, 0, 161, 0, 0, 0, 209, 0, 0, 0, 192, 0, 0, 0, 179, 0, 0, 0, 109, 0, 0, 0, 98, 0, 0, 0, 79, 0, 0, 0, 208, 0, 0, 0, 117, 0, 0, 0, 119, 0, 0, 0, 186, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 215, 0, 0, 0, 184, 0, 0, 0, 216, 0, 0, 0, 146, 0, 0, 0, 111, 0, 0, 0, 152, 0, 0, 0, 52, 0, 0, 0, 61, 0, 0, 0, 214, 0, 0, 0, 78, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 240, 0, 0, 0, 143, 0, 0, 0, 46, 0, 0, 0, 241, 0, 0, 0, 179, 0, 0, 0, 189, 0, 0, 0, 177, 0, 0, 0, 185, 0, 0, 0, 236, 0, 0, 0, 153, 0, 0, 0, 180, +0, 0, 0, 7, 0, 0, 0, 96, 0, 0, 0, 87, 0, 0, 0, 46, 0, 0, 0, 154, 0, 0, 0, 114, 0, 0, 0, 29, 0, 0, 0, 107, 0, 0, 0, 110, 0, 0, 0, 88, 0, 0, 0, 51, 0, 0, 0, 36, 0, 0, 0, 140, 0, 0, 0, 72, 0, 0, 0, 57, 0, 0, 0, 70, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 106, 0, 0, 0, 136, 0, 0, 0, 81, 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 0, 181, 0, 0, 0, 50, 0, 0, 0, 9, 0, 0, 0, 54, 0, 0, 0, 227, 0, 0, 0, 87, 0, 0, 0, 245, 0, 0, 0, 152, 0, 0, 0, 222, 0, 0, 0, 111, 0, 0, 0, 139, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, +74, 0, 0, 0, 249, 0, 0, 0, 91, 0, 0, 0, 135, 0, 0, 0, 105, 0, 0, 0, 82, 0, 0, 0, 229, 0, 0, 0, 91, 0, 0, 0, 209, 0, 0, 0, 177, 0, 0, 0, 229, 0, 0, 0, 37, 0, 0, 0, 37, 0, 0, 0, 224, 0, 0, 0, 156, 0, 0, 0, 194, 0, 0, 0, 19, 0, 0, 0, 68, 0, 0, 0, 232, 0, 0, 0, 185, 0, 0, 0, 10, 0, 0, 0, 112, 0, 0, 0, 173, 0, 0, 0, 189, 0, 0, 0, 15, 0, 0, 0, 81, 0, 0, 0, 148, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, 220, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 37, 0, 0, 0, 45, 0, 0, 0, 172, 0, 0, 0, 95, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0, 8, 0, 0, 0, 231, 0, 0, 0, 126, 0, 0, 0, 254, 0, 0, 0, 149, 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 91, 0, 0, 0, 58, 0, 0, 0, 211, 0, 0, 0, 5, 0, 0, 0, 130, 0, 0, 0, 28, 0, 0, 0, 149, 0, 0, 0, 45, 0, 0, 0, 216, 0, 0, 0, 119, 0, +0, 0, 126, 0, 0, 0, 2, 0, 0, 0, 217, 0, 0, 0, 91, 0, 0, 0, 112, 0, 0, 0, 194, 0, 0, 0, 254, 0, 0, 0, 27, 0, 0, 0, 12, 0, 0, 0, 103, 0, 0, 0, 205, 0, 0, 0, 214, 0, 0, 0, 224, 0, 0, 0, 81, 0, 0, 0, 142, 0, 0, 0, 44, 0, 0, 0, 224, 0, 0, 0, 121, 0, 0, 0, 136, 0, 0, 0, 240, 0, 0, 0, 207, 0, 0, 0, 65, 0, 0, 0, 74, 0, 0, 0, 173, 0, 0, 0, 35, 0, 0, 0, 212, 0, 0, 0, 70, 0, 0, 0, 202, 0, 0, 0, 148, 0, 0, 0, 161, 0, 0, 0, 195, 0, 0, 0, 235, 0, 0, 0, 40, 0, 0, 0, 6, 0, 0, 0, 250, 0, 0, 0, 23, 0, 0, 0, 20, 0, +0, 0, 123, 0, 0, 0, 170, 0, 0, 0, 112, 0, 0, 0, 10, 0, 0, 0, 75, 0, 0, 0, 251, 0, 0, 0, 245, 0, 0, 0, 191, 0, 0, 0, 128, 0, 0, 0, 197, 0, 0, 0, 207, 0, 0, 0, 8, 0, 0, 0, 122, 0, 0, 0, 221, 0, 0, 0, 161, 0, 0, 0, 244, 0, 0, 0, 157, 0, 0, 0, 84, 0, 0, 0, 80, 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 0, 119, 0, 0, 0, 35, 0, 0, 0, 245, 0, 0, 0, 52, 0, 0, 0, 165, 0, 0, 0, 34, 0, 0, 0, 209, 0, 0, 0, 13, 0, 0, 0, 150, 0, 0, 0, 46, 0, 0, 0, 71, 0, 0, 0, 204, 0, 0, 0, 183, 0, 0, 0, 50, 0, 0, 0, 137, 0, 0, 0, 87, 0, +0, 0, 208, 0, 0, 0, 152, 0, 0, 0, 117, 0, 0, 0, 228, 0, 0, 0, 55, 0, 0, 0, 153, 0, 0, 0, 169, 0, 0, 0, 232, 0, 0, 0, 186, 0, 0, 0, 237, 0, 0, 0, 186, 0, 0, 0, 235, 0, 0, 0, 199, 0, 0, 0, 79, 0, 0, 0, 21, 0, 0, 0, 118, 0, 0, 0, 7, 0, 0, 0, 12, 0, 0, 0, 76, 0, 0, 0, 239, 0, 0, 0, 159, 0, 0, 0, 82, 0, 0, 0, 252, 0, 0, 0, 4, 0, 0, 0, 93, 0, 0, 0, 88, 0, 0, 0, 16, 0, 0, 0, 206, 0, 0, 0, 130, 0, 0, 0, 240, 0, 0, 0, 143, 0, 0, 0, 121, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 209, 0, 0, 0, 218, 0, 0, 0, 20, 0, +0, 0, 9, 0, 0, 0, 72, 0, 0, 0, 238, 0, 0, 0, 138, 0, 0, 0, 64, 0, 0, 0, 152, 0, 0, 0, 118, 0, 0, 0, 96, 0, 0, 0, 84, 0, 0, 0, 90, 0, 0, 0, 222, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 245, 0, 0, 0, 230, 0, 0, 0, 47, 0, 0, 0, 225, 0, 0, 0, 3, 0, 0, 0, 191, 0, 0, 0, 104, 0, 0, 0, 130, 0, 0, 0, 127, 0, 0, 0, 100, 0, 0, 0, 233, 0, 0, 0, 40, 0, 0, 0, 199, 0, 0, 0, 164, 0, 0, 0, 207, 0, 0, 0, 42, 0, 0, 0, 249, 0, 0, 0, 144, 0, 0, 0, 100, 0, 0, 0, 114, 0, 0, 0, 44, 0, 0, 0, 139, 0, 0, 0, 235, 0, 0, 0, 236, 0, +0, 0, 160, 0, 0, 0, 242, 0, 0, 0, 125, 0, 0, 0, 53, 0, 0, 0, 181, 0, 0, 0, 144, 0, 0, 0, 77, 0, 0, 0, 127, 0, 0, 0, 91, 0, 0, 0, 74, 0, 0, 0, 73, 0, 0, 0, 228, 0, 0, 0, 184, 0, 0, 0, 59, 0, 0, 0, 200, 0, 0, 0, 161, 0, 0, 0, 47, 0, 0, 0, 139, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 61, 0, 0, 0, 105, 0, 0, 0, 166, 0, 0, 0, 161, 0, 0, 0, 24, 0, 0, 0, 68, 0, 0, 0, 188, 0, 0, 0, 77, 0, 0, 0, 119, 0, 0, 0, 55, 0, 0, 0, 199, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 12, 0, 0, 0, 201, 0, 0, 0, 214, 0, 0, 0, 68, +0, 0, 0, 169, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 0, 185, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 0, 167, 0, 0, 0, 10, 0, 0, 0, 213, 0, 0, 0, 199, 0, 0, 0, 52, 0, 0, 0, 55, 0, 0, 0, 249, 0, 0, 0, 126, 0, 0, 0, 62, 0, 0, 0, 102, 0, 0, 0, 238, 0, 0, 0, 249, 0, 0, 0, 153, 0, 0, 0, 40, 0, 0, 0, 255, 0, 0, 0, 173, 0, 0, 0, 17, 0, 0, 0, 216, 0, 0, 0, 226, 0, 0, 0, 102, 0, 0, 0, 197, 0, 0, 0, 205, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 11, 0, 0, 0, 106, 0, 0, 0, 252, 0, 0, 0, 124, 0, 0, 0, 36, 0, 0, 0, 168, 0, 0, 0, 79, +0, 0, 0, 168, 0, 0, 0, 94, 0, 0, 0, 128, 0, 0, 0, 69, 0, 0, 0, 139, 0, 0, 0, 108, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 30, 0, 0, 0, 236, 0, 0, 0, 247, 0, 0, 0, 141, 0, 0, 0, 119, 0, 0, 0, 242, 0, 0, 0, 234, 0, 0, 0, 219, 0, 0, 0, 96, 0, +0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 192, 0, 0, 0, 255, 0, 0, 0, 94, 0, 0, 0, 103, 0, 0, 0, 195, 0, 0, 0, 113, 0, 0, 0, 11, 0, 0, 0, 33, 0, 0, 0, 180, 0, 0, 0, 65, 0, 0, 0, 160, 0, 0, 0, 104, 0, 0, 0, 56, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 211, 0, 0, 0, 81, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 146, 0, 0, 0, 248, 0, 0, 0, 214, 0, 0, 0, 75, 0, 0, 0, 239, 0, 0, 0, 66, 0, 0, 0, 19, 0, 0, 0, 178, 0, 0, 0, 74, 0, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 114, 0, 0, 0, 63, 0, 0, 0, 201, 0, 0, 0, 17, 0, 0, +0, 189, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 14, 0, 0, 0, 245, 0, 0, 0, 19, 0, 0, 0, 157, 0, 0, 0, 131, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 213, 0, 0, 0, 84, 0, 0, 0, 222, 0, 0, 0, 196, 0, 0, 0, 30, 0, 0, 0, 22, 0, 0, 0, 108, 0, 0, 0, 39, 0, 0, 0, 82, 0, 0, 0, 228, 0, 0, 0, 99, 0, 0, 0, 170, 0, 0, 0, 148, 0, 0, 0, 230, 0, 0, 0, 195, 0, 0, 0, 40, 0, 0, 0, 156, 0, 0, 0, 198, 0, 0, 0, 86, 0, 0, 0, 172, 0, 0, 0, 250, 0, 0, 0, 182, 0, 0, 0, 189, 0, 0, 0, 226, 0, 0, 0, 204, 0, 0, 0, 118, 0, 0, 0, 198, 0, +0, 0, 39, 0, 0, 0, 39, 0, 0, 0, 162, 0, 0, 0, 142, 0, 0, 0, 120, 0, 0, 0, 43, 0, 0, 0, 132, 0, 0, 0, 114, 0, 0, 0, 16, 0, 0, 0, 189, 0, 0, 0, 78, 0, 0, 0, 42, 0, 0, 0, 234, 0, 0, 0, 167, 0, 0, 0, 35, 0, 0, 0, 239, 0, 0, 0, 4, 0, 0, 0, 97, 0, 0, 0, 128, 0, 0, 0, 80, 0, 0, 0, 201, 0, 0, 0, 110, 0, 0, 0, 165, 0, 0, 0, 150, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 200, 0, 0, 0, 195, 0, 0, 0, 24, 0, 0, 0, 215, 0, 0, 0, 45, 0, 0, 0, 253, 0, 0, 0, 38, 0, 0, 0, 189, 0, 0, 0, 203, 0, 0, 0, 123, 0, 0, 0, 146, +0, 0, 0, 81, 0, 0, 0, 14, 0, 0, 0, 74, 0, 0, 0, 101, 0, 0, 0, 87, 0, 0, 0, 184, 0, 0, 0, 73, 0, 0, 0, 171, 0, 0, 0, 85, 0, 0, 0, 54, 0, 0, 0, 195, 0, 0, 0, 236, 0, 0, 0, 99, 0, 0, 0, 85, 0, 0, 0, 17, 0, 0, 0, 85, 0, 0, 0, 246, 0, 0, 0, 165, 0, 0, 0, 199, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 0, 254, 0, 0, 0, 121, 0, 0, 0, 216, 0, 0, 0, 10, 0, 0, 0, 247, 0, 0, 0, 3, 0, 0, 0, 216, 0, 0, 0, 152, 0, 0, 0, 153, 0, 0, 0, 245, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 107, 0, 0, 0, 102, 0, 0, 0, 40, 0, 0, +0, 245, 0, 0, 0, 37, 0, 0, 0, 122, 0, 0, 0, 141, 0, 0, 0, 161, 0, 0, 0, 93, 0, 0, 0, 112, 0, 0, 0, 93, 0, 0, 0, 81, 0, 0, 0, 39, 0, 0, 0, 238, 0, 0, 0, 48, 0, 0, 0, 101, 0, 0, 0, 86, 0, 0, 0, 149, 0, 0, 0, 70, 0, 0, 0, 222, 0, 0, 0, 189, 0, 0, 0, 3, 0, 0, 0, 117, 0, 0, 0, 180, 0, 0, 0, 87, 0, 0, 0, 89, 0, 0, 0, 137, 0, 0, 0, 235, 0, 0, 0, 2, 0, 0, 0, 158, 0, 0, 0, 204, 0, 0, 0, 137, 0, 0, 0, 25, 0, 0, 0, 167, 0, 0, 0, 203, 0, 0, 0, 23, 0, 0, 0, 103, 0, 0, 0, 106, 0, 0, 0, 235, 0, 0, 0, 252, 0, 0, +0, 154, 0, 0, 0, 154, 0, 0, 0, 16, 0, 0, 0, 206, 0, 0, 0, 219, 0, 0, 0, 58, 0, 0, 0, 28, 0, 0, 0, 60, 0, 0, 0, 106, 0, 0, 0, 157, 0, 0, 0, 234, 0, 0, 0, 70, 0, 0, 0, 188, 0, 0, 0, 69, 0, 0, 0, 73, 0, 0, 0, 172, 0, 0, 0, 227, 0, 0, 0, 65, 0, 0, 0, 18, 0, 0, 0, 124, 0, 0, 0, 240, 0, 0, 0, 247, 0, 0, 0, 79, 0, 0, 0, 249, 0, 0, 0, 247, 0, 0, 0, 255, 0, 0, 0, 44, 0, 0, 0, 137, 0, 0, 0, 4, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 84, 0, 0, 0, 26, 0, 0, 0, 70, 0, 0, 0, 202, 0, 0, 0, 230, 0, 0, 0, 198, 0, 0, 0, +203, 0, 0, 0, 226, 0, 0, 0, 195, 0, 0, 0, 193, 0, 0, 0, 139, 0, 0, 0, 117, 0, 0, 0, 129, 0, 0, 0, 190, 0, 0, 0, 238, 0, 0, 0, 248, 0, 0, 0, 163, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 37, 0, 0, 0, 163, 0, 0, 0, 167, 0, 0, 0, 53, 0, 0, 0, 81, 0, 0, 0, 85, 0, 0, 0, 226, 0, 0, 0, 37, 0, 0, 0, 170, 0, 0, 0, 226, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 72, 0, 0, 0, 16, 0, 0, 0, 159, 0, 0, 0, 138, 0, 0, 0, 9, 0, 0, 0, 118, 0, 0, 0, 250, 0, 0, 0, 240, 0, 0, 0, 122, 0, 0, 0, 176, 0, 0, 0, 112, 0, 0, 0, 247, 0, 0, 0, 131, 0, 0, 0, 128, 0, 0, 0, 82, 0, 0, 0, 132, 0, 0, 0, 43, 0, 0, 0, 38, 0, 0, 0, 162, 0, 0, 0, 196, 0, 0, 0, 93, 0, 0, 0, 79, 0, 0, 0, 186, 0, 0, 0, 177, 0, 0, 0, 200, 0, 0, 0, 64, 0, 0, 0, 13, 0, 0, 0, 120, 0, 0, 0, 151, 0, 0, 0, +196, 0, 0, 0, 96, 0, 0, 0, 212, 0, 0, 0, 177, 0, 0, 0, 108, 0, 0, 0, 8, 0, 0, 0, 199, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 115, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 243, 0, 0, 0, 118, 0, 0, 0, 93, 0, 0, 0, 178, 0, 0, 0, 165, 0, 0, 0, 47, 0, 0, 0, 87, 0, 0, 0, 87, 0, 0, 0, 7, 0, 0, 0, 237, 0, 0, 0, 8, 0, 0, 0, 162, 0, 0, 0, 108, 0, 0, 0, 79, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 181, 0, 0, 0, 14, 0, 0, 0, 238, 0, 0, 0, 68, 0, 0, 0, 250, 0, 0, 0, 34, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 166, 0, 0, +0, 4, 0, 0, 0, 25, 0, 0, 0, 86, 0, 0, 0, 101, 0, 0, 0, 49, 0, 0, 0, 127, 0, 0, 0, 139, 0, 0, 0, 235, 0, 0, 0, 13, 0, 0, 0, 225, 0, 0, 0, 71, 0, 0, 0, 137, 0, 0, 0, 151, 0, 0, 0, 22, 0, 0, 0, 83, 0, 0, 0, 250, 0, 0, 0, 129, 0, 0, 0, 167, 0, 0, 0, 170, 0, 0, 0, 178, 0, 0, 0, 191, 0, 0, 0, 103, 0, 0, 0, 235, 0, 0, 0, 114, 0, 0, 0, 96, 0, 0, 0, 129, 0, 0, 0, 13, 0, 0, 0, 72, 0, 0, 0, 126, 0, 0, 0, 19, 0, 0, 0, 51, 0, 0, 0, 205, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 86, 0, 0, 0, 30, 0, 0, 0, 103, 0, 0, +0, 175, 0, 0, 0, 107, 0, 0, 0, 67, 0, 0, 0, 172, 0, 0, 0, 23, 0, 0, 0, 175, 0, 0, 0, 22, 0, 0, 0, 192, 0, 0, 0, 82, 0, 0, 0, 153, 0, 0, 0, 73, 0, 0, 0, 91, 0, 0, 0, 135, 0, 0, 0, 115, 0, 0, 0, 126, 0, 0, 0, 181, 0, 0, 0, 67, 0, 0, 0, 218, 0, 0, 0, 107, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 45, 0, 0, 0, 85, 0, 0, 0, 233, 0, 0, 0, 88, 0, 0, 0, 31, 0, 0, 0, 255, 0, 0, 0, 132, 0, 0, 0, 63, 0, 0, 0, 147, 0, 0, 0, 28, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 48, 0, 0, 0, 105, 0, 0, 0, 165, 0, 0, 0, 117, 0, 0, +0, 25, 0, 0, 0, 126, 0, 0, 0, 20, 0, 0, 0, 95, 0, 0, 0, 248, 0, 0, 0, 252, 0, 0, 0, 9, 0, 0, 0, 221, 0, 0, 0, 168, 0, 0, 0, 120, 0, 0, 0, 157, 0, 0, 0, 202, 0, 0, 0, 89, 0, 0, 0, 139, 0, 0, 0, 209, 0, 0, 0, 48, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, 0, 255, 0, 0, 0, 118, 0, 0, 0, 3, 0, 0, 0, 197, 0, 0, 0, 75, 0, 0, 0, 137, 0, 0, 0, 153, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 112, 0, 0, 0, 156, 0, 0, 0, 213, 0, 0, 0, 217, 0, 0, 0, 17, 0, 0, 0, 137, 0, 0, 0, 90, 0, 0, 0, 70, 0, 0, 0, 254, 0, 0, 0, +239, 0, 0, 0, 220, 0, 0, 0, 217, 0, 0, 0, 85, 0, 0, 0, 43, 0, 0, 0, 69, 0, 0, 0, 167, 0, 0, 0, 176, 0, 0, 0, 45, 0, 0, 0, 251, 0, 0, 0, 36, 0, 0, 0, 194, 0, 0, 0, 41, 0, 0, 0, 56, 0, 0, 0, 6, 0, 0, 0, 248, 0, 0, 0, 11, 0, 0, 0, 172, 0, 0, 0, 130, 0, 0, 0, 196, 0, 0, 0, 151, 0, 0, 0, 43, 0, 0, 0, 144, 0, 0, 0, 224, 0, 0, 0, 247, 0, 0, 0, 168, 0, 0, 0, 171, 0, 0, 0, 108, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 102, 0, 0, 0, 144, 0, 0, 0, 70, 0, 0, 0, 247, 0, 0, 0, 38, 0, 0, 0, 45, 0, 0, 0, 248, 0, 0, 0, +241, 0, 0, 0, 196, 0, 0, 0, 107, 0, 0, 0, 74, 0, 0, 0, 130, 0, 0, 0, 152, 0, 0, 0, 142, 0, 0, 0, 55, 0, 0, 0, 142, 0, 0, 0, 180, 0, 0, 0, 238, 0, 0, 0, 184, 0, 0, 0, 212, 0, 0, 0, 63, 0, 0, 0, 178, 0, 0, 0, 27, 0, 0, 0, 224, 0, 0, 0, 10, 0, 0, 0, 61, 0, 0, 0, 117, 0, 0, 0, 52, 0, 0, 0, 40, 0, 0, 0, 162, 0, 0, 0, 142, 0, 0, 0, 196, 0, 0, 0, 146, 0, 0, 0, 123, 0, 0, 0, 254, 0, 0, 0, 96, 0, 0, 0, 110, 0, 0, 0, 109, 0, 0, 0, 184, 0, 0, 0, 49, 0, 0, 0, 29, 0, 0, 0, 98, 0, 0, 0, 13, 0, 0, 0, 120, 0, 0, +0, 20, 0, 0, 0, 66, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 168, 0, 0, 0, 216, 0, 0, 0, 4, 0, 0, 0, 155, 0, 0, 0, 115, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 220, 0, 0, 0, 13, 0, 0, 0, 115, 0, 0, 0, 191, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 115, +0, 0, 0, 255, 0, 0, 0, 24, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 81, 0, 0, 0, 170, 0, 0, 0, 198, 0, 0, 0, 241, 0, 0, 0, 131, 0, 0, 0, 37, 0, 0, 0, 253, 0, 0, 0, 171, 0, 0, 0, 163, 0, 0, 0, 17, 0, 0, 0, 211, 0, 0, 0, 1, 0, 0, 0, 36, 0, 0, 0, 77, 0, 0, 0, 227, 0, 0, 0, 126, 0, 0, 0, 56, 0, 0, 0, 98, 0, 0, 0, 94, 0, 0, 0, 100, 0, 0, 0, 187, 0, 0, 0, 43, 0, 0, 0, 83, 0, 0, 0, 181, 0, 0, 0, 3, 0, 0, 0, 104, 0, 0, 0, 196, 0, 0, 0, 242, 0, 0, 0, 43, 0, 0, 0, 90, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 0, 153, 0, 0, +0, 74, 0, 0, 0, 65, 0, 0, 0, 154, 0, 0, 0, 225, 0, 0, 0, 26, 0, 0, 0, 174, 0, 0, 0, 140, 0, 0, 0, 72, 0, 0, 0, 243, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 101, 0, 0, 0, 232, 0, 0, 0, 221, 0, 0, 0, 173, 0, 0, 0, 58, 0, 0, 0, 140, 0, 0, 0, 234, 0, 0, 0, 244, 0, 0, 0, 179, 0, 0, 0, 178, 0, 0, 0, 229, 0, 0, 0, 115, 0, 0, 0, 242, 0, 0, 0, 237, 0, 0, 0, 139, 0, 0, 0, 191, 0, 0, 0, 237, 0, 0, 0, 177, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 251, 0, 0, 0, 43, 0, 0, 0, 241, 0, 0, 0, 1, 0, 0, 0, 72, 0, 0, 0, 232, 0, +0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 142, 0, 0, 0, 39, 0, 0, 0, 77, 0, 0, 0, 150, 0, 0, 0, 114, 0, 0, 0, 200, 0, 0, 0, 9, 0, 0, 0, 59, 0, 0, 0, 96, 0, 0, 0, 201, 0, 0, 0, 38, 0, 0, 0, 77, 0, 0, 0, 124, 0, 0, 0, 242, 0, 0, 0, 156, 0, 0, 0, 212, 0, 0, 0, 161, 0, 0, 0, 59, 0, 0, 0, 38, 0, 0, 0, 194, 0, 0, 0, 4, 0, 0, 0, 51, 0, 0, 0, 68, 0, 0, 0, 118, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0, 0, 187, 0, 0, 0, 17, 0, 0, 0, 66, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 183, 0, 0, 0, 198, 0, 0, 0, 225, 0, 0, 0, 172, 0, 0, 0, 180, +0, 0, 0, 14, 0, 0, 0, 111, 0, 0, 0, 133, 0, 0, 0, 231, 0, 0, 0, 239, 0, 0, 0, 222, 0, 0, 0, 103, 0, 0, 0, 48, 0, 0, 0, 252, 0, 0, 0, 191, 0, 0, 0, 90, 0, 0, 0, 224, 0, 0, 0, 123, 0, 0, 0, 122, 0, 0, 0, 42, 0, 0, 0, 84, 0, 0, 0, 107, 0, 0, 0, 93, 0, 0, 0, 98, 0, 0, 0, 133, 0, 0, 0, 161, 0, 0, 0, 248, 0, 0, 0, 22, 0, 0, 0, 136, 0, 0, 0, 236, 0, 0, 0, 97, 0, 0, 0, 185, 0, 0, 0, 150, 0, 0, 0, 181, 0, 0, 0, 239, 0, 0, 0, 45, 0, 0, 0, 67, 0, 0, 0, 77, 0, 0, 0, 124, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 204, +0, 0, 0, 228, 0, 0, 0, 207, 0, 0, 0, 108, 0, 0, 0, 255, 0, 0, 0, 128, 0, 0, 0, 71, 0, 0, 0, 119, 0, 0, 0, 209, 0, 0, 0, 216, 0, 0, 0, 233, 0, 0, 0, 105, 0, 0, 0, 151, 0, 0, 0, 152, 0, 0, 0, 127, 0, 0, 0, 32, 0, 0, 0, 87, 0, 0, 0, 29, 0, 0, 0, 29, 0, 0, 0, 79, 0, 0, 0, 8, 0, 0, 0, 39, 0, 0, 0, 200, 0, 0, 0, 53, 0, 0, 0, 87, 0, 0, 0, 64, 0, 0, 0, 198, 0, 0, 0, 33, 0, 0, 0, 12, 0, 0, 0, 210, 0, 0, 0, 142, 0, 0, 0, 155, 0, 0, 0, 250, 0, 0, 0, 66, 0, 0, 0, 142, 0, 0, 0, 223, 0, 0, 0, 143, 0, 0, 0, 199, +0, 0, 0, 134, 0, 0, 0, 249, 0, 0, 0, 164, 0, 0, 0, 202, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 33, 0, 0, 0, 191, 0, 0, 0, 236, 0, 0, 0, 87, 0, 0, 0, 98, 0, 0, 0, 48, 0, 0, 0, 88, 0, 0, 0, 140, 0, 0, 0, 13, 0, 0, 0, 53, 0, 0, 0, 219, 0, 0, 0, 93, 0, 0, 0, 139, 0, 0, 0, 106, 0, 0, 0, 160, 0, 0, 0, 90, 0, 0, 0, 193, 0, 0, 0, 88, 0, 0, 0, 124, 0, 0, 0, 13, 0, 0, 0, 32, 0, 0, 0, 221, 0, 0, 0, 17, 0, 0, 0, 38, 0, 0, 0, 95, 0, 0, 0, 137, 0, 0, 0, 59, 0, 0, 0, 151, 0, 0, 0, 88, 0, 0, 0, 248, 0, +0, 0, 139, 0, 0, 0, 227, 0, 0, 0, 223, 0, 0, 0, 50, 0, 0, 0, 226, 0, 0, 0, 252, 0, 0, 0, 216, 0, 0, 0, 103, 0, 0, 0, 242, 0, 0, 0, 165, 0, 0, 0, 55, 0, 0, 0, 30, 0, 0, 0, 109, 0, 0, 0, 236, 0, 0, 0, 124, 0, 0, 0, 39, 0, 0, 0, 32, 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 233, 0, 0, 0, 192, 0, 0, 0, 250, 0, 0, 0, 149, 0, 0, 0, 69, 0, 0, 0, 35, 0, 0, 0, 150, 0, 0, 0, 241, 0, 0, 0, 44, 0, 0, 0, 121, 0, 0, 0, 37, 0, 0, 0, 20, 0, 0, 0, 206, 0, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 68, 0, 0, 0, 44, 0, 0, 0, 54, 0, 0, 0, 80, 0, 0, 0, 217, 0, 0, 0, 99, 0, 0, 0, 86, 0, 0, 0, 183, 0, 0, 0, 86, 0, 0, 0, 59, 0, 0, 0, 158, 0, 0, 0, 167, 0, 0, 0, 239, 0, 0, 0, 137, 0, 0, 0, 187, 0, 0, 0, 14, 0, 0, 0, 206, 0, 0, 0, 127, 0, 0, 0, 220, 0, 0, 0, 10, 0, 0, +0, 204, 0, 0, 0, 130, 0, 0, 0, 28, 0, 0, 0, 10, 0, 0, 0, 120, 0, 0, 0, 113, 0, 0, 0, 232, 0, 0, 0, 116, 0, 0, 0, 141, 0, 0, 0, 1, 0, 0, 0, 48, 0, 0, 0, 15, 0, 0, 0, 167, 0, 0, 0, 17, 0, 0, 0, 76, 0, 0, 0, 223, 0, 0, 0, 56, 0, 0, 0, 215, 0, 0, 0, 167, 0, 0, 0, 13, 0, 0, 0, 248, 0, 0, 0, 72, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 95, 0, 0, 0, 14, 0, 0, 0, 37, 0, 0, 0, 131, 0, 0, 0, 230, 0, 0, 0, 148, 0, 0, 0, 123, 0, 0, 0, 129, 0, 0, 0, 178, 0, 0, 0, 145, 0, 0, 0, 174, 0, 0, +0, 14, 0, 0, 0, 5, 0, 0, 0, 201, 0, 0, 0, 163, 0, 0, 0, 104, 0, 0, 0, 45, 0, 0, 0, 217, 0, 0, 0, 136, 0, 0, 0, 37, 0, 0, 0, 25, 0, 0, 0, 42, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 33, 0, 0, 0, 151, 0, 0, 0, 21, 0, 0, 0, 161, 0, 0, 0, 53, 0, 0, 0, 165, 0, 0, 0, 70, 0, 0, 0, 200, 0, 0, 0, 162, 0, 0, 0, 14, 0, 0, 0, 27, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 139, 0, 0, 0, 90, 0, 0, 0, 27, 0, 0, 0, 151, 0, 0, 0, 75, 0, 0, 0, 242, 0, 0, 0, 22, 0, 0, 0, 49, 0, 0, 0, 61, 0, 0, 0, 31, 0, 0, 0, 51, 0, 0, 0, 160, 0, +0, 0, 80, 0, 0, 0, 58, 0, 0, 0, 24, 0, 0, 0, 190, 0, 0, 0, 19, 0, 0, 0, 161, 0, 0, 0, 118, 0, 0, 0, 193, 0, 0, 0, 186, 0, 0, 0, 27, 0, 0, 0, 241, 0, 0, 0, 5, 0, 0, 0, 123, 0, 0, 0, 51, 0, 0, 0, 168, 0, 0, 0, 130, 0, 0, 0, 59, 0, 0, 0, 186, 0, 0, 0, 54, 0, 0, 0, 123, 0, 0, 0, 109, 0, 0, 0, 169, 0, 0, 0, 234, 0, 0, 0, 20, 0, 0, 0, 18, 0, 0, 0, 197, 0, 0, 0, 250, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 155, 0, 0, 0, 153, 0, 0, 0, 204, 0, 0, 0, 86, 0, 0, 0, 2, 0, 0, 0, 233, 0, 0, 0, 160, 0, +0, 0, 38, 0, 0, 0, 64, 0, 0, 0, 102, 0, 0, 0, 140, 0, 0, 0, 196, 0, 0, 0, 248, 0, 0, 0, 133, 0, 0, 0, 51, 0, 0, 0, 104, 0, 0, 0, 231, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 80, 0, 0, 0, 91, 0, 0, 0, 255, 0, 0, 0, 169, 0, 0, 0, 178, 0, 0, 0, 241, 0, 0, 0, 241, 0, 0, 0, 120, 0, 0, 0, 207, 0, 0, 0, 20, 0, 0, 0, 164, 0, 0, 0, 169, 0, 0, 0, 252, 0, 0, 0, 9, 0, 0, 0, 70, 0, 0, 0, 148, 0, 0, 0, 84, 0, 0, 0, 101, 0, 0, 0, 13, 0, 0, 0, 156, 0, 0, 0, 95, 0, 0, 0, 114, 0, 0, 0, 33, 0, 0, 0, 226, 0, 0, 0, 151, 0, +0, 0, 165, 0, 0, 0, 45, 0, 0, 0, 129, 0, 0, 0, 206, 0, 0, 0, 74, 0, 0, 0, 95, 0, 0, 0, 121, 0, 0, 0, 61, 0, 0, 0, 95, 0, 0, 0, 92, 0, 0, 0, 210, 0, 0, 0, 188, 0, 0, 0, 125, 0, 0, 0, 119, 0, 0, 0, 14, 0, 0, 0, 42, 0, 0, 0, 109, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0, 132, 0, 0, 0, 6, 0, 0, 0, 196, 0, 0, 0, 221, 0, 0, 0, 198, 0, 0, 0, 166, 0, 0, 0, 198, 0, 0, 0, 215, 0, 0, 0, 73, 0, 0, 0, 173, 0, 0, 0, 109, 0, 0, 0, 135, 0, 0, 0, 145, 0, 0, 0, 14, 0, 0, 0, 58, 0, 0, 0, 103, 0, 0, 0, 29, 0, 0, 0, 44, 0, +0, 0, 29, 0, 0, 0, 86, 0, 0, 0, 254, 0, 0, 0, 122, 0, 0, 0, 116, 0, 0, 0, 207, 0, 0, 0, 212, 0, 0, 0, 210, 0, 0, 0, 229, 0, 0, 0, 25, 0, 0, 0, 222, 0, 0, 0, 208, 0, 0, 0, 219, 0, 0, 0, 112, 0, 0, 0, 35, 0, 0, 0, 105, 0, 0, 0, 230, 0, 0, 0, 109, 0, 0, 0, 236, 0, 0, 0, 236, 0, 0, 0, 204, 0, 0, 0, 9, 0, 0, 0, 51, 0, 0, 0, 106, 0, 0, 0, 119, 0, 0, 0, 220, 0, 0, 0, 107, 0, 0, 0, 34, 0, 0, 0, 118, 0, 0, 0, 93, 0, 0, 0, 146, 0, 0, 0, 9, 0, 0, 0, 172, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 23, 0, 0, 0, 235, 0, 0, 0, 211, 0, 0, 0, 219, 0, 0, 0, 18, 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, 0, 240, 0, 0, 0, 145, 0, 0, 0, 171, 0, 0, 0, 44, 0, 0, 0, 65, 0, 0, 0, 206, 0, 0, 0, 172, 0, 0, 0, 237, 0, 0, 0, 27, 0, 0, 0, 75, 0, 0, 0, 45, 0, 0, 0, +188, 0, 0, 0, 219, 0, 0, 0, 23, 0, 0, 0, 102, 0, 0, 0, 137, 0, 0, 0, 70, 0, 0, 0, 173, 0, 0, 0, 75, 0, 0, 0, 30, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 20, 0, 0, 0, 17, 0, 0, 0, 206, 0, 0, 0, 191, 0, 0, 0, 182, 0, 0, 0, 119, 0, 0, 0, 45, 0, 0, 0, 72, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 79, 0, 0, 0, 163, 0, 0, 0, 93, 0, 0, 0, 74, 0, 0, 0, 176, 0, 0, 0, 112, 0, 0, 0, 18, 0, 0, 0, 62, 0, 0, 0, 84, 0, 0, 0, 215, 0, 0, 0, 216, 0, 0, 0, 14, 0, 0, 0, 43, 0, 0, 0, 39, 0, 0, 0, 220, 0, 0, 0, 83, 0, 0, 0, 255, +0, 0, 0, 202, 0, 0, 0, 140, 0, 0, 0, 89, 0, 0, 0, 179, 0, 0, 0, 78, 0, 0, 0, 68, 0, 0, 0, 7, 0, 0, 0, 118, 0, 0, 0, 97, 0, 0, 0, 15, 0, 0, 0, 102, 0, 0, 0, 178, 0, 0, 0, 33, 0, 0, 0, 57, 0, 0, 0, 126, 0, 0, 0, 192, 0, 0, 0, 236, 0, 0, 0, 69, 0, 0, 0, 40, 0, 0, 0, 130, 0, 0, 0, 161, 0, 0, 0, 41, 0, 0, 0, 50, 0, 0, 0, 68, 0, 0, 0, 53, 0, 0, 0, 19, 0, 0, 0]).concat([94, 0, 0, 0, 97, 0, 0, 0, 94, 0, 0, 0, 84, 0, 0, 0, 203, 0, 0, 0, 124, 0, 0, 0, 239, 0, 0, 0, 246, 0, 0, 0, 65, 0, 0, 0, 207, 0, 0, 0, +159, 0, 0, 0, 10, 0, 0, 0, 221, 0, 0, 0, 249, 0, 0, 0, 218, 0, 0, 0, 132, 0, 0, 0, 195, 0, 0, 0, 230, 0, 0, 0, 138, 0, 0, 0, 159, 0, 0, 0, 36, 0, 0, 0, 210, 0, 0, 0, 150, 0, 0, 0, 93, 0, 0, 0, 57, 0, 0, 0, 111, 0, 0, 0, 88, 0, 0, 0, 140, 0, 0, 0, 193, 0, 0, 0, 86, 0, 0, 0, 147, 0, 0, 0, 171, 0, 0, 0, 181, 0, 0, 0, 121, 0, 0, 0, 59, 0, 0, 0, 210, 0, 0, 0, 168, 0, 0, 0, 115, 0, 0, 0, 22, 0, 0, 0, 237, 0, 0, 0, 250, 0, 0, 0, 180, 0, 0, 0, 47, 0, 0, 0, 115, 0, 0, 0, 139, 0, 0, 0, 177, 0, 0, 0, 149, 0, +0, 0, 229, 0, 0, 0, 146, 0, 0, 0, 80, 0, 0, 0, 53, 0, 0, 0, 17, 0, 0, 0, 118, 0, 0, 0, 172, 0, 0, 0, 244, 0, 0, 0, 77, 0, 0, 0, 36, 0, 0, 0, 195, 0, 0, 0, 50, 0, 0, 0, 230, 0, 0, 0, 235, 0, 0, 0, 254, 0, 0, 0, 44, 0, 0, 0, 135, 0, 0, 0, 196, 0, 0, 0, 241, 0, 0, 0, 86, 0, 0, 0, 196, 0, 0, 0, 117, 0, 0, 0, 36, 0, 0, 0, 122, 0, 0, 0, 86, 0, 0, 0, 133, 0, 0, 0, 90, 0, 0, 0, 58, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 22, 0, 0, 0, 172, 0, 0, 0, 60, 0, 0, 0, 74, 0, 0, 0, 88, 0, 0, 0, 134, 0, 0, 0, 58, 0, 0, +0, 70, 0, 0, 0, 127, 0, 0, 0, 108, 0, 0, 0, 163, 0, 0, 0, 82, 0, 0, 0, 110, 0, 0, 0, 55, 0, 0, 0, 228, 0, 0, 0, 150, 0, 0, 0, 156, 0, 0, 0, 233, 0, 0, 0, 92, 0, 0, 0, 102, 0, 0, 0, 65, 0, 0, 0, 103, 0, 0, 0, 228, 0, 0, 0, 251, 0, 0, 0, 121, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 246, 0, 0, 0, 100, 0, 0, 0, 213, 0, 0, 0, 124, 0, 0, 0, 40, 0, 0, 0, 193, 0, 0, 0, 225, 0, 0, 0, 84, 0, 0, 0, 115, 0, 0, 0, 242, 0, 0, 0, 191, 0, 0, 0, 118, 0, 0, 0, 116, 0, 0, 0, 25, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 228, 0, +0, 0, 185, 0, 0, 0, 168, 0, 0, 0, 70, 0, 0, 0, 101, 0, 0, 0, 115, 0, 0, 0, 243, 0, 0, 0, 119, 0, 0, 0, 155, 0, 0, 0, 41, 0, 0, 0, 116, 0, 0, 0, 91, 0, 0, 0, 198, 0, 0, 0, 137, 0, 0, 0, 108, 0, 0, 0, 44, 0, 0, 0, 124, 0, 0, 0, 248, 0, 0, 0, 179, 0, 0, 0, 15, 0, 0, 0, 247, 0, 0, 0, 213, 0, 0, 0, 233, 0, 0, 0, 116, 0, 0, 0, 93, 0, 0, 0, 184, 0, 0, 0, 37, 0, 0, 0, 22, 0, 0, 0, 181, 0, 0, 0, 48, 0, 0, 0, 188, 0, 0, 0, 132, 0, 0, 0, 197, 0, 0, 0, 240, 0, 0, 0, 173, 0, 0, 0, 202, 0, 0, 0, 18, 0, 0, 0, 40, +0, 0, 0, 188, 0, 0, 0, 157, 0, 0, 0, 212, 0, 0, 0, 250, 0, 0, 0, 130, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 191, 0, 0, 0, 162, 0, 0, 0, 21, 0, 0, 0, 44, 0, 0, 0, 212, 0, 0, 0, 52, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 177, 0, 0, 0, 70, 0, +0, 0, 186, 0, 0, 0, 14, 0, 0, 0, 49, 0, 0, 0, 165, 0, 0, 0, 103, 0, 0, 0, 108, 0, 0, 0, 127, 0, 0, 0, 214, 0, 0, 0, 217, 0, 0, 0, 39, 0, 0, 0, 133, 0, 0, 0, 15, 0, 0, 0, 121, 0, 0, 0, 20, 0, 0, 0, 200, 0, 0, 0, 108, 0, 0, 0, 47, 0, 0, 0, 95, 0, 0, 0, 91, 0, 0, 0, 156, 0, 0, 0, 53, 0, 0, 0, 61, 0, 0, 0, 56, 0, 0, 0, 134, 0, 0, 0, 119, 0, 0, 0, 101, 0, 0, 0, 85, 0, 0, 0, 106, 0, 0, 0, 123, 0, 0, 0, 211, 0, 0, 0, 176, 0, 0, 0, 58, 0, 0, 0, 102, 0, 0, 0, 96, 0, 0, 0, 27, 0, 0, 0, 67, 0, 0, 0, 241, 0, +0, 0, 38, 0, 0, 0, 88, 0, 0, 0, 153, 0, 0, 0, 9, 0, 0, 0, 143, 0, 0, 0, 45, 0, 0, 0, 163, 0, 0, 0, 20, 0, 0, 0, 113, 0, 0, 0, 133, 0, 0, 0, 219, 0, 0, 0, 237, 0, 0, 0, 246, 0, 0, 0, 38, 0, 0, 0, 213, 0, 0, 0, 97, 0, 0, 0, 154, 0, 0, 0, 115, 0, 0, 0, 172, 0, 0, 0, 14, 0, 0, 0, 234, 0, 0, 0, 172, 0, 0, 0, 183, 0, 0, 0, 12, 0, 0, 0, 94, 0, 0, 0, 244, 0, 0, 0, 229, 0, 0, 0, 23, 0, 0, 0, 14, 0, 0, 0, 16, 0, 0, 0, 159, 0, 0, 0, 231, 0, 0, 0, 67, 0, 0, 0, 95, 0, 0, 0, 103, 0, 0, 0, 92, 0, 0, 0, 172, 0, +0, 0, 75, 0, 0, 0, 229, 0, 0, 0, 20, 0, 0, 0, 65, 0, 0, 0, 210, 0, 0, 0, 191, 0, 0, 0, 72, 0, 0, 0, 245, 0, 0, 0, 20, 0, 0, 0, 176, 0, 0, 0, 113, 0, 0, 0, 198, 0, 0, 0, 97, 0, 0, 0, 193, 0, 0, 0, 178, 0, 0, 0, 112, 0, 0, 0, 88, 0, 0, 0, 210, 0, 0, 0, 90, 0, 0, 0, 45, 0, 0, 0, 186, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 146, 0, 0, 0, 148, 0, 0, 0, 220, 0, 0, 0, 189, 0, 0, 0, 80, 0, 0, 0, 43, 0, 0, 0, 201, 0, 0, 0, 127, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 97, 0, 0, 0, 237, 0, 0, 0, 248, 0, 0, +0, 67, 0, 0, 0, 237, 0, 0, 0, 245, 0, 0, 0, 249, 0, 0, 0, 64, 0, 0, 0, 96, 0, 0, 0, 178, 0, 0, 0, 176, 0, 0, 0, 130, 0, 0, 0, 203, 0, 0, 0, 237, 0, 0, 0, 117, 0, 0, 0, 199, 0, 0, 0, 101, 0, 0, 0, 128, 0, 0, 0, 186, 0, 0, 0, 13, 0, 0, 0, 9, 0, 0, 0, 64, 0, 0, 0, 167, 0, 0, 0, 57, 0, 0, 0, 166, 0, 0, 0, 103, 0, 0, 0, 52, 0, 0, 0, 126, 0, 0, 0, 102, 0, 0, 0, 190, 0, 0, 0, 86, 0, 0, 0, 251, 0, 0, 0, 83, 0, 0, 0, 120, 0, 0, 0, 196, 0, 0, 0, 70, 0, 0, 0, 232, 0, 0, 0, 237, 0, 0, 0, 104, 0, 0, 0, 108, 0, +0, 0, 127, 0, 0, 0, 206, 0, 0, 0, 232, 0, 0, 0, 159, 0, 0, 0, 206, 0, 0, 0, 162, 0, 0, 0, 100, 0, 0, 0, 88, 0, 0, 0, 83, 0, 0, 0, 232, 0, 0, 0, 193, 0, 0, 0, 169, 0, 0, 0, 194, 0, 0, 0, 123, 0, 0, 0, 89, 0, 0, 0, 33, 0, 0, 0, 51, 0, 0, 0, 226, 0, 0, 0, 67, 0, 0, 0, 115, 0, 0, 0, 43, 0, 0, 0, 172, 0, 0, 0, 45, 0, 0, 0, 193, 0, 0, 0, 137, 0, 0, 0, 59, 0, 0, 0, 21, 0, 0, 0, 226, 0, 0, 0, 213, 0, 0, 0, 192, 0, 0, 0, 151, 0, 0, 0, 138, 0, 0, 0, 253, 0, 0, 0, 111, 0, 0, 0, 54, 0, 0, 0, 51, 0, 0, 0, 183, +0, 0, 0, 185, 0, 0, 0, 195, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 208, 0, 0, 0, 182, 0, 0, 0, 86, 0, 0, 0, 48, 0, 0, 0, 92, 0, 0, 0, 174, 0, 0, 0, 179, 0, 0, 0, 117, 0, 0, 0, 68, 0, 0, 0, 164, 0, 0, 0, 131, 0, 0, 0, 81, 0, 0, 0, 110, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 0, 239, 0, 0, 0, 69, 0, 0, 0, 118, 0, 0, 0, 230, 0, 0, 0, 245, 0, 0, 0, 162, 0, 0, 0, 13, 0, 0, 0, 212, 0, 0, 0, 22, 0, 0, 0, 59, 0, 0, 0, 88, 0, 0, 0, 47, 0, 0, 0, 242, 0, 0, 0, 47, 0, 0, 0, 54, 0, 0, 0, 24, 0, 0, 0, 63, 0, 0, 0, 253, 0, +0, 0, 47, 0, 0, 0, 224, 0, 0, 0, 155, 0, 0, 0, 30, 0, 0, 0, 140, 0, 0, 0, 197, 0, 0, 0, 24, 0, 0, 0, 169, 0, 0, 0, 202, 0, 0, 0, 212, 0, 0, 0, 43, 0, 0, 0, 53, 0, 0, 0, 182, 0, 0, 0, 149, 0, 0, 0, 10, 0, 0, 0, 159, 0, 0, 0, 126, 0, 0, 0, 251, 0, 0, 0, 196, 0, 0, 0, 239, 0, 0, 0, 136, 0, 0, 0, 123, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0, 236, 0, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 122, 0, 0, 0, 252, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 210, 0, 0, 0, 218, 0, 0, 0, 199, 0, 0, 0, 68, 0, 0, 0, 214, 0, 0, 0, 122, 0, 0, 0, 219, 0, 0, 0, 38, 0, 0, 0, 125, 0, 0, 0, 29, 0, 0, 0, 184, 0, 0, 0, 225, 0, 0, 0, 222, 0, 0, 0, 157, 0, 0, 0, 122, 0, 0, 0, 125, 0, 0, 0, 23, 0, 0, 0, 126, 0, 0, 0, 28, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0, 141, 0, 0, +0, 45, 0, 0, 0, 124, 0, 0, 0, 94, 0, 0, 0, 24, 0, 0, 0, 56, 0, 0, 0, 30, 0, 0, 0, 175, 0, 0, 0, 199, 0, 0, 0, 27, 0, 0, 0, 51, 0, 0, 0, 72, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 246, 0, 0, 0, 242, 0, 0, 0, 202, 0, 0, 0, 15, 0, 0, 0, 39, 0, 0, 0, 27, 0, 0, 0, 99, 0, 0, 0, 18, 0, 0, 0, 126, 0, 0, 0, 2, 0, 0, 0, 29, 0, 0, 0, 73, 0, 0, 0, 192, 0, 0, 0, 93, 0, 0, 0, 121, 0, 0, 0, 135, 0, 0, 0, 239, 0, 0, 0, 94, 0, 0, 0, 122, 0, 0, 0, 47, 0, 0, 0, 31, 0, 0, 0, 102, 0, 0, 0, 85, 0, 0, 0, 216, 0, +0, 0, 9, 0, 0, 0, 217, 0, 0, 0, 97, 0, 0, 0, 84, 0, 0, 0, 131, 0, 0, 0, 2, 0, 0, 0, 24, 0, 0, 0, 130, 0, 0, 0, 147, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 208, 0, 0, 0, 167, 0, 0, 0, 218, 0, 0, 0, 216, 0, 0, 0, 117, 0, 0, 0, 137, 0, 0, 0, 250, 0, 0, 0, 242, 0, 0, 0, 217, 0, 0, 0, 163, 0, 0, 0, 184, 0, 0, 0, 107, 0, 0, 0, 90, 0, 0, 0, 53, 0, 0, 0, 40, 0, 0, 0, 210, 0, 0, 0, 107, 0, 0, 0, 89, 0, 0, 0, 194, 0, 0, 0, 248, 0, 0, 0, 69, 0, 0, 0, 226, 0, 0, 0, 188, 0, 0, 0, 6, 0, 0, 0, 101, 0, 0, 0, 192, 0, +0, 0, 163, 0, 0, 0, 136, 0, 0, 0, 81, 0, 0, 0, 149, 0, 0, 0, 252, 0, 0, 0, 150, 0, 0, 0, 148, 0, 0, 0, 120, 0, 0, 0, 232, 0, 0, 0, 13, 0, 0, 0, 139, 0, 0, 0, 65, 0, 0, 0, 201, 0, 0, 0, 194, 0, 0, 0, 88, 0, 0, 0, 72, 0, 0, 0, 117, 0, 0, 0, 16, 0, 0, 0, 47, 0, 0, 0, 205, 0, 0, 0, 42, 0, 0, 0, 201, 0, 0, 0, 160, 0, 0, 0, 109, 0, 0, 0, 15, 0, 0, 0, 221, 0, 0, 0, 156, 0, 0, 0, 152, 0, 0, 0, 38, 0, 0, 0, 61, 0, 0, 0, 47, 0, 0, 0, 102, 0, 0, 0, 41, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 0, 137, 0, 0, 0, 189, 0, +0, 0, 126, 0, 0, 0, 238, 0, 0, 0, 110, 0, 0, 0, 221, 0, 0, 0, 183, 0, 0, 0, 14, 0, 0, 0, 239, 0, 0, 0, 176, 0, 0, 0, 12, 0, 0, 0, 180, 0, 0, 0, 252, 0, 0, 0, 127, 0, 0, 0, 194, 0, 0, 0, 201, 0, 0, 0, 58, 0, 0, 0, 60, 0, 0, 0, 100, 0, 0, 0, 239, 0, 0, 0, 69, 0, 0, 0, 68, 0, 0, 0, 175, 0, 0, 0, 138, 0, 0, 0, 144, 0, 0, 0, 101, 0, 0, 0, 118, 0, 0, 0, 161, 0, 0, 0, 76, 0, 0, 0, 112, 0, 0, 0, 75, 0, 0, 0, 14, 0, 0, 0, 160, 0, 0, 0, 131, 0, 0, 0, 112, 0, 0, 0, 19, 0, 0, 0, 164, 0, 0, 0, 175, 0, 0, 0, 184, +0, 0, 0, 56, 0, 0, 0, 25, 0, 0, 0, 34, 0, 0, 0, 101, 0, 0, 0, 9, 0, 0, 0, 180, 0, 0, 0, 2, 0, 0, 0, 79, 0, 0, 0, 6, 0, 0, 0, 248, 0, 0, 0, 23, 0, 0, 0, 206, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 218, 0, 0, 0, 80, 0, 0, 0, 124, 0, 0, 0, 138, 0, 0, 0, 209, 0, 0, 0, 78, 0, 0, 0, 247, 0, 0, 0, 212, 0, 0, 0, 22, 0, 0, 0, 108, 0, 0, 0, 78, 0, 0, 0, 149, 0, 0, 0, 157, 0, 0, 0, 93, 0, 0, 0, 15, 0, 0, 0, 145, 0, 0, 0, 43, 0, 0, 0, 82, 0, 0, 0, 254, 0, 0, 0, 92, 0, 0, 0, 52, 0, 0, 0, 229, 0, 0, 0, 48, 0, 0, 0, +230, 0, 0, 0, 164, 0, 0, 0, 59, 0, 0, 0, 243, 0, 0, 0, 243, 0, 0, 0, 52, 0, 0, 0, 8, 0, 0, 0, 169, 0, 0, 0, 74, 0, 0, 0, 160, 0, 0, 0, 181, 0, 0, 0, 110, 0, 0, 0, 179, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 38, 0, 0, 0, 217, 0, 0, 0, 94, 0, 0, 0, 163, 0, 0, 0, 15, 0, 0, 0, 235, 0, 0, 0, 162, 0, 0, 0, 243, 0, 0, 0, 32, 0, 0, 0, 59, 0, 0, 0, 55, 0, 0, 0, 212, 0, 0, 0, 228, 0, 0, 0, 158, 0, 0, 0, 206, 0, 0, 0, 6, 0, 0, 0, 61, 0, 0, 0, 83, 0, 0, 0, 237, 0, 0, 0, 174, 0, 0, 0, 43, 0, 0, 0, 235, 0, 0, 0, 182, +0, 0, 0, 36, 0, 0, 0, 10, 0, 0, 0, 17, 0, 0, 0, 163, 0, 0, 0, 15, 0, 0, 0, 214, 0, 0, 0, 127, 0, 0, 0, 164, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, 0, 159, 0, 0, 0, 44, 0, 0, 0, 252, 0, 0, 0, 214, 0, 0, 0, 178, 0, 0, 0, 30, 0, 0, 0, 46, 0, 0, +0, 82, 0, 0, 0, 122, 0, 0, 0, 6, 0, 0, 0, 135, 0, 0, 0, 45, 0, 0, 0, 134, 0, 0, 0, 114, 0, 0, 0, 43, 0, 0, 0, 109, 0, 0, 0, 144, 0, 0, 0, 119, 0, 0, 0, 70, 0, 0, 0, 67, 0, 0, 0, 181, 0, 0, 0, 122, 0, 0, 0, 248, 0, 0, 0, 96, 0, 0, 0, 125, 0, 0, 0, 145, 0, 0, 0, 96, 0, 0, 0, 91, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 7, 0, 0, 0, 151, 0, 0, 0, 135, 0, 0, 0, 199, 0, 0, 0, 4, 0, 0, 0, 28, 0, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 57, 0, 0, 0, 88, 0, 0, 0, 199, 0, 0, 0, 133, 0, 0, 0, 163, 0, 0, 0, 252, 0, 0, 0, +100, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 37, 0, 0, 0, 162, 0, 0, 0, 191, 0, 0, 0, 80, 0, 0, 0, 148, 0, 0, 0, 202, 0, 0, 0, 38, 0, 0, 0, 49, 0, 0, 0, 69, 0, 0, 0, 10, 0, 0, 0, 36, 0, 0, 0, 210, 0, 0, 0, 81, 0, 0, 0, 41, 0, 0, 0, 81, 0, 0, 0, 22, 0, 0, 0, 77, 0, 0, 0, 74, 0, 0, 0, 215, 0, 0, 0, 152, 0, 0, 0, 113, 0, 0, 0, 87, 0, 0, 0, 172, 0, 0, 0, 125, 0, 0, 0, 139, 0, 0, 0, 55, 0, 0, 0, 189, 0, 0, 0, 99, 0, 0, 0, 255, 0, 0, 0, 135, 0, 0, 0, 177, 0, 0, 0, 73, 0, 0, 0, 149, 0, 0, 0, 32, 0, 0, 0, 124, +0, 0, 0, 207, 0, 0, 0, 124, 0, 0, 0, 89, 0, 0, 0, 196, 0, 0, 0, 145, 0, 0, 0, 156, 0, 0, 0, 239, 0, 0, 0, 208, 0, 0, 0, 219, 0, 0, 0, 96, 0, 0, 0, 9, 0, 0, 0, 157, 0, 0, 0, 70, 0, 0, 0, 203, 0, 0, 0, 120, 0, 0, 0, 148, 0, 0, 0, 144, 0, 0, 0, 228, 0, 0, 0, 69, 0, 0, 0, 179, 0, 0, 0, 246, 0, 0, 0, 217, 0, 0, 0, 246, 0, 0, 0, 87, 0, 0, 0, 116, 0, 0, 0, 213, 0, 0, 0, 248, 0, 0, 0, 131, 0, 0, 0, 79, 0, 0, 0, 57, 0, 0, 0, 201, 0, 0, 0, 189, 0, 0, 0, 136, 0, 0, 0, 194, 0, 0, 0, 87, 0, 0, 0, 33, 0, 0, 0, +31, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 104, 0, 0, 0, 248, 0, 0, 0, 199, 0, 0, 0, 33, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 42, 0, 0, 0, 54, 0, 0, 0, 104, 0, 0, 0, 252, 0, 0, 0, 95, 0, 0, 0, 182, 0, 0, 0, 79, 0, 0, 0, 165, 0, 0, 0, 227, 0, 0, 0, 157, 0, 0, 0, 36, 0, 0, 0, 47, 0, 0, 0, 192, 0, 0, 0, 147, 0, 0, 0, 97, 0, 0, 0, 207, 0, 0, 0, 248, 0, 0, 0, 10, 0, 0, 0, 237, 0, 0, 0, 225, 0, 0, 0, 219, 0, 0, 0, 39, 0, 0, 0, 236, 0, 0, 0, 14, 0, 0, 0, 20, 0, 0, 0, 50, 0, 0, 0, 95, 0, 0, 0, 142, 0, 0, 0, 161, +0, 0, 0, 98, 0, 0, 0, 65, 0, 0, 0, 22, 0, 0, 0, 149, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 206, 0, 0, 0, 149, 0, 0, 0, 91, 0, 0, 0, 14, 0, 0, 0, 87, 0, 0, 0, 199, 0, 0, 0, 185, 0, 0, 0, 98, 0, 0, 0, 181, 0, 0, 0, 40, 0, 0, 0, 202, 0, 0, 0, 17, 0, 0, 0, 236, 0, 0, 0, 180, 0, 0, 0, 70, 0, 0, 0, 6, 0, 0, 0, 115, 0, 0, 0, 38, 0, 0, 0, 255, 0, 0, 0, 251, 0, 0, 0, 102, 0, 0, 0, 125, 0, 0, 0, 238, 0, 0, 0, 95, 0, 0, 0, 178, 0, 0, 0, 86, 0, 0, 0, 253, 0, 0, 0, 42, 0, 0, 0, 8, 0, 0, 0, 146, 0, 0, 0, 103, 0, 0, +0, 119, 0, 0, 0, 86, 0, 0, 0, 161, 0, 0, 0, 255, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 149, 0, 0, 0, 240, 0, 0, 0, 227, 0, 0, 0, 58, 0, 0, 0, 10, 0, 0, 0, 202, 0, 0, 0, 148, 0, 0, 0, 77, 0, 0, 0, 158, 0, 0, 0, 126, 0, 0, 0, 61, 0, 0, 0, 185, 0, 0, 0, 110, 0, 0, 0, 182, 0, 0, 0, 176, 0, 0, 0, 206, 0, 0, 0, 164, 0, 0, 0, 48, 0, 0, 0, 137, 0, 0, 0, 153, 0, 0, 0, 233, 0, 0, 0, 173, 0, 0, 0, 17, 0, 0, 0, 89, 0, 0, 0, 246, 0, 0, 0, 72, 0, 0, 0, 149, 0, 0, 0, 161, 0, 0, 0, 111, 0, 0, 0, 95, 0, 0, 0, 183, +0, 0, 0, 165, 0, 0, 0, 187, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 210, 0, 0, 0, 138, 0, 0, 0, 214, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 27, 0, 0, 0, 178, 0, 0, 0, 13, 0, 0, 0, 55, 0, 0, 0, 106, 0, 0, 0, 5, 0, 0, 0, 244, 0, 0, 0, 157, 0, 0, 0, 62, 0, 0, 0, 23, 0, 0, 0, 42, 0, 0, 0, 67, 0, 0, 0, 210, 0, 0, 0, 58, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 0, 153, 0, 0, 0, 147, 0, 0, 0, 209, 0, 0, 0, 154, 0, 0, 0, 114, 0, 0, 0, 243, 0, 0, 0, 169, 0, 0, 0, 22, 0, 0, 0, 189, 0, 0, 0, 180, 0, 0, 0, 76, 0, 0, 0, 221, 0, 0, 0, 249, 0, 0, 0, 212, 0, 0, 0, 178, 0, 0, 0, 100, 0, 0, 0, 154, 0, 0, 0, 211, 0, 0, 0, 5, 0, 0, 0, 228, 0, 0, 0, 163, 0, 0, 0, 115, 0, 0, 0, 28, 0, 0, 0, 203, 0, 0, 0, 126, 0, 0, 0, 87, 0, 0, 0, 103, 0, 0, 0, 255, 0, 0, +0, 4, 0, 0, 0, 179, 0, 0, 0, 16, 0, 0, 0, 185, 0, 0, 0, 75, 0, 0, 0, 164, 0, 0, 0, 173, 0, 0, 0, 208, 0, 0, 0, 109, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 0, 180, 0, 0, 0, 175, 0, 0, 0, 52, 0, 0, 0, 169, 0, 0, 0, 170, 0, 0, 0, 101, 0, 0, 0, 236, 0, 0, 0, 217, 0, 0, 0, 105, 0, 0, 0, 227, 0, 0, 0, 133, 0, 0, 0, 205, 0, 0, 0, 204, 0, 0, 0, 231, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 65, 0, 0, 0, 193, 0, 0, 0, 28, 0, 0, 0, 249, 0, 0, 0, 160, 0, 0, 0, 250, 0, 0, 0, 183, 0, 0, 0, 19, 0, 0, 0, 4, 0, 0, 0, 253, 0, +0, 0, 136, 0, 0, 0, 60, 0, 0, 0, 12, 0, 0, 0, 208, 0, 0, 0, 9, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 79, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 204, 0, 0, 0, 195, 0, 0, 0, 187, 0, 0, 0, 222, 0, 0, 0, 128, 0, 0, 0, 197, 0, 0, 0, 51, 0, 0, 0, 188, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 23, 0, 0, 0, 54, 0, 0, 0, 221, 0, 0, 0, 198, 0, 0, 0, 222, 0, 0, 0, 232, 0, 0, 0, 155, 0, 0, 0, 93, 0, 0, 0, 121, 0, 0, 0, 27, 0, 0, 0, 101, 0, 0, 0, 10, 0, 0, 0, 190, 0, 0, 0, 81, 0, 0, 0, 87, 0, 0, 0, 173, 0, 0, 0, 80, 0, 0, +0, 121, 0, 0, 0, 8, 0, 0, 0, 113, 0, 0, 0, 155, 0, 0, 0, 7, 0, 0, 0, 149, 0, 0, 0, 143, 0, 0, 0, 251, 0, 0, 0, 174, 0, 0, 0, 75, 0, 0, 0, 56, 0, 0, 0, 186, 0, 0, 0, 207, 0, 0, 0, 83, 0, 0, 0, 42, 0, 0, 0, 134, 0, 0, 0, 30, 0, 0, 0, 192, 0, 0, 0, 80, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 0, 27, 0, 0, 0, 246, 0, 0, 0, 135, 0, 0, 0, 108, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 102, 0, 0, 0, 85, 0, 0, 0, 237, 0, 0, 0, 74, 0, 0, 0, 237, 0, 0, 0, 141, 0, 0, 0, 225, 0, 0, 0, 102, 0, 0, 0, 24, 0, 0, 0, +178, 0, 0, 0, 20, 0, 0, 0, 116, 0, 0, 0, 141, 0, 0, 0, 253, 0, 0, 0, 26, 0, 0, 0, 54, 0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 92, 0, 0, 0, 139, 0, 0, 0, 137, 0, 0, 0, 243, 0, 0, 0, 171, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 36, 0, 0, 0, 103, 0, 0, 0, 253, 0, 0, 0, 112, 0, 0, 0, 253, 0, 0, 0, 78, 0, 0, 0, 42, 0, 0, 0, 193, 0, 0, 0, 58, 0, 0, 0, 202, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 236, 0, 0, 0, 116, 0, 0, 0, 103, 0, 0, 0, 239, 0, 0, 0, 97, 0, 0, 0, 224, 0, 0, 0, 40, 0, 0, 0, 208, 0, 0, +0, 150, 0, 0, 0, 244, 0, 0, 0, 72, 0, 0, 0, 222, 0, 0, 0, 129, 0, 0, 0, 227, 0, 0, 0, 239, 0, 0, 0, 220, 0, 0, 0, 170, 0, 0, 0, 125, 0, 0, 0, 243, 0, 0, 0, 182, 0, 0, 0, 85, 0, 0, 0, 166, 0, 0, 0, 101, 0, 0, 0, 235, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 112, 0, 0, 0, 145, 0, 0, 0, 49, 0, 0, 0, 16, 0, 0, 0, 147, 0, 0, 0, 13, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 239, 0, 0, 0, 98, 0, 0, 0, 232, 0, 0, 0, 111, 0, 0, 0, 130, 0, 0, 0, 227, 0, 0, 0, 105, 0, 0, 0, 61, 0, 0, 0, 145, 0, 0, 0, 127, 0, 0, 0, 49, +0, 0, 0, 225, 0, 0, 0, 38, 0, 0, 0, 53, 0, 0, 0, 60, 0, 0, 0, 74, 0, 0, 0, 47, 0, 0, 0, 171, 0, 0, 0, 196, 0, 0, 0, 154, 0, 0, 0, 94, 0, 0, 0, 171, 0, 0, 0, 27, 0, 0, 0, 181, 0, 0, 0, 229, 0, 0, 0, 43, 0, 0, 0, 195, 0, 0, 0, 14, 0, 0, 0, 41, 0, 0, 0, 176, 0, 0, 0, 208, 0, 0, 0, 115, 0, 0, 0, 230, 0, 0, 0, 79, 0, 0, 0, 100, 0, 0, 0, 242, 0, 0, 0, 188, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 154, 0, 0, 0, 82, 0, 0, 0, 51, 0, 0, 0, 47, 0, 0, 0, 189, 0, 0, 0, 204, 0, 0, 0, 3, 0, 0, 0, 238, +0, 0, 0, 138, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 219, 0, 0, 0, 13, 0, 0, 0, 34, 0, 0, 0, 61, 0, 0, 0, 181, 0, 0, 0, 20, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 240, 0, 0, 0, 129, 0, 0, 0, 226, 0, 0, +0, 185, 0, 0, 0, 55, 0, 0, 0, 162, 0, 0, 0, 169, 0, 0, 0, 132, 0, 0, 0, 17, 0, 0, 0, 154, 0, 0, 0, 7, 0, 0, 0, 181, 0, 0, 0, 83, 0, 0, 0, 137, 0, 0, 0, 120, 0, 0, 0, 169, 0, 0, 0, 48, 0, 0, 0, 39, 0, 0, 0, 161, 0, 0, 0, 241, 0, 0, 0, 78, 0, 0, 0, 92, 0, 0, 0, 46, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 251, 0, 0, 0, 77, 0, 0, 0, 220, 0, 0, 0, 203, 0, 0, 0, 23, 0, 0, 0, 53, 0, 0, 0, 64, 0, 0, 0, 255, 0, 0, 0, 183, 0, 0, 0, 140, 0, 0, 0, 254, 0, 0, 0, 74, 0, 0, 0, 228, 0, 0, 0, 78, 0, 0, 0, +153, 0, 0, 0, 78, 0, 0, 0, 168, 0, 0, 0, 116, 0, 0, 0, 84, 0, 0, 0, 93, 0, 0, 0, 92, 0, 0, 0, 150, 0, 0, 0, 163, 0, 0, 0, 18, 0, 0, 0, 85, 0, 0, 0, 54, 0, 0, 0, 49, 0, 0, 0, 23, 0, 0, 0, 92, 0, 0, 0, 206, 0, 0, 0, 36, 0, 0, 0, 239, 0, 0, 0, 123, 0, 0, 0, 134, 0, 0, 0, 242, 0, 0, 0, 15, 0, 0, 0, 119, 0, 0, 0, 232, 0, 0, 0, 92, 0, 0, 0, 125, 0, 0, 0, 135, 0, 0, 0, 56, 0, 0, 0, 45, 0, 0, 0, 239, 0, 0, 0, 175, 0, 0, 0, 242, 0, 0, 0, 140, 0, 0, 0, 114, 0, 0, 0, 46, 0, 0, 0, 235, 0, 0, 0, 182, 0, 0, 0, +85, 0, 0, 0, 75, 0, 0, 0, 110, 0, 0, 0, 241, 0, 0, 0, 78, 0, 0, 0, 138, 0, 0, 0, 14, 0, 0, 0, 154, 0, 0, 0, 108, 0, 0, 0, 76, 0, 0, 0, 37, 0, 0, 0, 234, 0, 0, 0, 134, 0, 0, 0, 194, 0, 0, 0, 209, 0, 0, 0, 79, 0, 0, 0, 183, 0, 0, 0, 62, 0, 0, 0, 168, 0, 0, 0, 92, 0, 0, 0, 141, 0, 0, 0, 102, 0, 0, 0, 129, 0, 0, 0, 37, 0, 0, 0, 237, 0, 0, 0, 197, 0, 0, 0, 76, 0, 0, 0, 5, 0, 0, 0, 185, 0, 0, 0, 216, 0, 0, 0, 214, 0, 0, 0, 112, 0, 0, 0, 190, 0, 0, 0, 115, 0, 0, 0, 130, 0, 0, 0, 232, 0, 0, 0, 161, 0, 0, +0, 229, 0, 0, 0, 30, 0, 0, 0, 113, 0, 0, 0, 213, 0, 0, 0, 38, 0, 0, 0, 78, 0, 0, 0, 109, 0, 0, 0, 195, 0, 0, 0, 167, 0, 0, 0, 79, 0, 0, 0, 34, 0, 0, 0, 69, 0, 0, 0, 38, 0, 0, 0, 162, 0, 0, 0, 126, 0, 0, 0, 22, 0, 0, 0, 247, 0, 0, 0, 247, 0, 0, 0, 99, 0, 0, 0, 220, 0, 0, 0, 134, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 113, 0, 0, 0, 56, 0, 0, 0, 92, 0, 0, 0, 51, 0, 0, 0, 195, 0, 0, 0, 206, 0, 0, 0, 48, 0, 0, 0, 255, 0, 0, 0, 249, 0, 0, 0, 44, 0, 0, 0, 145, 0, 0, 0, 113, 0, 0, 0, 138, 0, 0, 0, 114, 0, 0, +0, 140, 0, 0, 0, 68, 0, 0, 0, 9, 0, 0, 0, 40, 0, 0, 0, 213, 0, 0, 0, 35, 0, 0, 0, 201, 0, 0, 0, 143, 0, 0, 0, 243, 0, 0, 0, 132, 0, 0, 0, 69, 0, 0, 0, 198, 0, 0, 0, 154, 0, 0, 0, 94, 0, 0, 0, 255, 0, 0, 0, 210, 0, 0, 0, 199, 0, 0, 0, 87, 0, 0, 0, 147, 0, 0, 0, 163, 0, 0, 0, 193, 0, 0, 0, 105, 0, 0, 0, 221, 0, 0, 0, 98, 0, 0, 0, 15, 0, 0, 0, 218, 0, 0, 0, 92, 0, 0, 0, 48, 0, 0, 0, 89, 0, 0, 0, 93, 0, 0, 0, 233, 0, 0, 0, 76, 0, 0, 0, 146, 0, 0, 0, 126, 0, 0, 0, 80, 0, 0, 0, 39, 0, 0, 0, 114, 0, 0, +0, 215, 0, 0, 0, 12, 0, 0, 0, 214, 0, 0, 0, 105, 0, 0, 0, 150, 0, 0, 0, 129, 0, 0, 0, 53, 0, 0, 0, 132, 0, 0, 0, 148, 0, 0, 0, 53, 0, 0, 0, 139, 0, 0, 0, 108, 0, 0, 0, 170, 0, 0, 0, 98, 0, 0, 0, 134, 0, 0, 0, 110, 0, 0, 0, 28, 0, 0, 0, 21, 0, 0, 0, 243, 0, 0, 0, 108, 0, 0, 0, 179, 0, 0, 0, 255, 0, 0, 0, 101, 0, 0, 0, 27, 0, 0, 0, 162, 0, 0, 0, 155, 0, 0, 0, 89, 0, 0, 0, 226, 0, 0, 0, 169, 0, 0, 0, 101, 0, 0, 0, 136, 0, 0, 0, 196, 0, 0, 0, 80, 0, 0, 0, 250, 0, 0, 0, 187, 0, 0, 0, 59, 0, 0, 0, 110, +0, 0, 0, 95, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 202, 0, 0, 0, 151, 0, 0, 0, 212, 0, 0, 0, 221, 0, 0, 0, 246, 0, 0, 0, 205, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 229, 0, 0, 0, 151, 0, 0, 0, 103, 0, 0, 0, 43, 0, 0, 0, 140, 0, 0, 0, 102, 0, 0, 0, 15, 0, 0, 0, 53, 0, 0, 0, 155, 0, 0, 0, 245, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 89, 0, 0, 0, 39, 0, 0, 0, 216, 0, 0, 0, 219, 0, 0, 0, 90, 0, 0, 0, 17, 0, 0, 0, 94, 0, 0, 0, 130, 0, 0, 0, 243, 0, 0, 0, 56, 0, 0, 0, 255, 0, 0, 0, 28, 0, 0, 0, 237, 0, 0, 0, 254, 0, 0, 0, 63, 0, 0, 0, 100, 0, 0, 0, 84, 0, 0, 0, 63, 0, 0, 0, 127, 0, 0, 0, 209, 0, 0, 0, 129, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 101, 0, 0, 0, 197, 0, 0, 0, 203, 0, 0, 0, 253, 0, 0, 0, 225, 0, 0, 0, 128, 0, 0, 0, 205, 0, 0, 0, 17, 0, +0, 0, 224, 0, 0, 0, 219, 0, 0, 0, 34, 0, 0, 0, 40, 0, 0, 0, 230, 0, 0, 0, 255, 0, 0, 0, 97, 0, 0, 0, 157, 0, 0, 0, 65, 0, 0, 0, 20, 0, 0, 0, 45, 0, 0, 0, 59, 0, 0, 0, 38, 0, 0, 0, 34, 0, 0, 0, 223, 0, 0, 0, 241, 0, 0, 0, 52, 0, 0, 0, 129, 0, 0, 0, 233, 0, 0, 0, 69, 0, 0, 0, 238, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 139, 0, 0, 0, 166, 0, 0, 0, 63, 0, 0, 0, 239, 0, 0, 0, 247, 0, 0, 0, 67, 0, 0, 0, 25, 0, 0, 0, 241, 0, 0, 0, 67, 0, 0, 0, 238, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 0, 80, 0, 0, +0, 222, 0, 0, 0, 192, 0, 0, 0, 182, 0, 0, 0, 1, 0, 0, 0, 227, 0, 0, 0, 140, 0, 0, 0, 60, 0, 0, 0, 77, 0, 0, 0, 49, 0, 0, 0, 210, 0, 0, 0, 176, 0, 0, 0, 88, 0, 0, 0, 205, 0, 0, 0, 237, 0, 0, 0, 16, 0, 0, 0, 74, 0, 0, 0, 122, 0, 0, 0, 239, 0, 0, 0, 128, 0, 0, 0, 169, 0, 0, 0, 25, 0, 0, 0, 50, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 51, 0, 0, 0, 140, 0, 0, 0, 6, 0, 0, 0, 203, 0, 0, 0, 125, 0, 0, 0, 79, 0, 0, 0, 255, 0, 0, 0, 48, 0, 0, 0, 216, 0, 0, 0, 18, 0, 0, 0, 59, 0, 0, 0, 57, 0, 0, 0, 28, 0, 0, 0, +6, 0, 0, 0, 249, 0, 0, 0, 76, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 113, 0, 0, 0, 181, 0, 0, 0, 22, 0, 0, 0, 148, 0, 0, 0, 103, 0, 0, 0, 223, 0, 0, 0, 238, 0, 0, 0, 17, 0, 0, 0, 222, 0, 0, 0, 164, 0, 0, 0, 29, 0, 0, 0, 136, 0, 0, 0, 147, 0, 0, 0, 53, 0, 0, 0, 169, 0, 0, 0, 50, 0, 0, 0, 16, 0, 0, 0, 233, 0, 0, 0, 195, 0, 0, 0, 188, 0, 0, 0, 123, 0, 0, 0, 92, 0, 0, 0, 252, 0, 0, 0, 178, 0, 0, 0, 249, 0, 0, 0, 201, 0, 0, 0, 47, 0, 0, 0, 229, 0, 0, 0, 186, 0, 0, 0, 58, 0, 0, 0, 11, 0, 0, 0, 171, 0, 0, 0, +100, 0, 0, 0, 56, 0, 0, 0, 111, 0, 0, 0, 91, 0, 0, 0, 75, 0, 0, 0, 147, 0, 0, 0, 218, 0, 0, 0, 100, 0, 0, 0, 236, 0, 0, 0, 77, 0, 0, 0, 61, 0, 0, 0, 160, 0, 0, 0, 245, 0, 0, 0, 187, 0, 0, 0, 186, 0, 0, 0, 71, 0, 0, 0, 72, 0, 0, 0, 96, 0, 0, 0, 188, 0, 0, 0, 69, 0, 0, 0, 31, 0, 0, 0, 35, 0, 0, 0, 162, 0, 0, 0, 59, 0, 0, 0, 112, 0, 0, 0, 118, 0, 0, 0, 230, 0, 0, 0, 151, 0, 0, 0, 153, 0, 0, 0, 79, 0, 0, 0, 119, 0, 0, 0, 84, 0, 0, 0, 103, 0, 0, 0, 48, 0, 0, 0, 154, 0, 0, 0, 231, 0, 0, 0, 102, 0, 0, 0, +214, 0, 0, 0, 205, 0, 0, 0, 46, 0, 0, 0, 81, 0, 0, 0, 36, 0, 0, 0, 44, 0, 0, 0, 66, 0, 0, 0, 74, 0, 0, 0, 17, 0, 0, 0, 254, 0, 0, 0, 111, 0, 0, 0, 126, 0, 0, 0, 135, 0, 0, 0, 192, 0, 0, 0, 177, 0, 0, 0, 240, 0, 0, 0, 163, 0, 0, 0, 111, 0, 0, 0, 12, 0, 0, 0, 147, 0, 0, 0, 169, 0, 0, 0, 10, 0, 0, 0, 114, 0, 0, 0, 239, 0, 0, 0, 92, 0, 0, 0, 190, 0, 0, 0, 101, 0, 0, 0, 53, 0, 0, 0, 167, 0, 0, 0, 106, 0, 0, 0, 78, 0, 0, 0, 44, 0, 0, 0, 191, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 232, 0, 0, 0, 47, 0, 0, 0, +151, 0, 0, 0, 199, 0, 0, 0, 62, 0, 0, 0, 200, 0, 0, 0, 23, 0, 0, 0, 172, 0, 0, 0, 30, 0, 0, 0, 123, 0, 0, 0, 239, 0, 0, 0, 33, 0, 0, 0, 229, 0, 0, 0, 64, 0, 0, 0, 204, 0, 0, 0, 30, 0, 0, 0, 220, 0, 0, 0, 214, 0, 0, 0, 189, 0, 0, 0, 151, 0, 0, 0, 122, 0, 0, 0, 124, 0, 0, 0, 117, 0, 0, 0, 134, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 90, 0, 0, 0, 110, 0, 0, 0, 124, 0, 0, 0, 229, 0, 0, 0, 81, 0, 0, 0, 60, 0, 0, 0, 27, 0, 0, 0, 91, 0, 0, 0, 130, 0, 0, 0, 154, 0, 0, 0, 7, 0, 0, 0, 96, 0, 0, 0, 161, 0, 0, 0, +25, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 136, 0, 0, 0, 166, 0, 0, 0, 171, 0, 0, 0, 143, 0, 0, 0, 227, 0, 0, 0, 58, 0, 0, 0, 73, 0, 0, 0, 248, 0, 0, 0, 254, 0, 0, 0, 52, 0, 0, 0, 231, 0, 0, 0, 106, 0, 0, 0, 178, 0, 0, 0, 254, 0, 0, 0, 64, +0, 0, 0, 38, 0, 0, 0, 116, 0, 0, 0, 87, 0, 0, 0, 76, 0, 0, 0, 246, 0, 0, 0, 212, 0, 0, 0, 153, 0, 0, 0, 206, 0, 0, 0, 93, 0, 0, 0, 123, 0, 0, 0, 47, 0, 0, 0, 103, 0, 0, 0, 214, 0, 0, 0, 90, 0, 0, 0, 228, 0, 0, 0, 78, 0, 0, 0, 92, 0, 0, 0, 130, 0, 0, 0, 179, 0, 0, 0, 189, 0, 0, 0, 85, 0, 0, 0, 37, 0, 0, 0, 246, 0, 0, 0, 106, 0, 0, 0, 147, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 198, 0, 0, 0, 125, 0, 0, 0, 92, 0, 0, 0, 177, 0, 0, 0, 43, 0, 0, 0, 91, 0, 0, 0, 255, 0, 0, 0, 251, 0, 0, 0, 86, 0, 0, 0, 248, +0, 0, 0, 1, 0, 0, 0, 65, 0, 0, 0, 144, 0, 0, 0, 198, 0, 0, 0, 182, 0, 0, 0, 172, 0, 0, 0, 79, 0, 0, 0, 254, 0, 0, 0, 167, 0, 0, 0, 65, 0, 0, 0, 112, 0, 0, 0, 219, 0, 0, 0, 250, 0, 0, 0, 155, 0, 0, 0, 44, 0, 0, 0, 212, 0, 0, 0, 35, 0, 0, 0, 103, 0, 0, 0, 44, 0, 0, 0, 138, 0, 0, 0, 99, 0, 0, 0, 108, 0, 0, 0, 7, 0, 0, 0, 38, 0, 0, 0, 72, 0, 0, 0, 79, 0, 0, 0, 194, 0, 0, 0, 3, 0, 0, 0, 210, 0, 0, 0, 83, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 237, 0, 0, 0, 101, 0, 0, 0, 113, 0, 0, 0, 71, 0, 0, 0, 169, 0, +0, 0, 22, 0, 0, 0, 22, 0, 0, 0, 18, 0, 0, 0, 188, 0, 0, 0, 40, 0, 0, 0, 51, 0, 0, 0, 57, 0, 0, 0, 192, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 205, 0, 0, 0, 51, 0, 0, 0, 67, 0, 0, 0, 199, 0, 0, 0, 151, 0, 0, 0, 118, 0, 0, 0, 155, 0, 0, 0, 147, 0, 0, 0, 145, 0, 0, 0, 114, 0, 0, 0, 235, 0, 0, 0, 197, 0, 0, 0, 24, 0, 0, 0, 103, 0, 0, 0, 76, 0, 0, 0, 17, 0, 0, 0, 240, 0, 0, 0, 244, 0, 0, 0, 229, 0, 0, 0, 115, 0, 0, 0, 178, 0, 0, 0, 92, 0, 0, 0, 27, 0, 0, 0, 194, 0, 0, 0, 38, 0, 0, 0, 63, 0, 0, 0, 191, 0, +0, 0, 43, 0, 0, 0, 134, 0, 0, 0, 230, 0, 0, 0, 140, 0, 0, 0, 29, 0, 0, 0, 223, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 213, 0, 0, 0, 248, 0, 0, 0, 58, 0, 0, 0, 195, 0, 0, 0, 68, 0, 0, 0, 114, 0, 0, 0, 230, 0, 0, 0, 120, 0, 0, 0, 157, 0, 0, 0, 43, 0, 0, 0, 151, 0, 0, 0, 248, 0, 0, 0, 40, 0, 0, 0, 69, 0, 0, 0, 180, 0, 0, 0, 32, 0, 0, 0, 201, 0, 0, 0, 42, 0, 0, 0, 140, 0, 0, 0, 103, 0, 0, 0, 170, 0, 0, 0, 17, 0, 0, 0, 197, 0, 0, 0, 91, 0, 0, 0, 47, 0, 0, 0, 23, 0, 0, 0, 15, 0, 0, 0, 134, 0, 0, 0, 82, 0, +0, 0, 215, 0, 0, 0, 157, 0, 0, 0, 195, 0, 0, 0, 68, 0, 0, 0, 81, 0, 0, 0, 118, 0, 0, 0, 50, 0, 0, 0, 101, 0, 0, 0, 180, 0, 0, 0, 55, 0, 0, 0, 129, 0, 0, 0, 153, 0, 0, 0, 70, 0, 0, 0, 55, 0, 0, 0, 98, 0, 0, 0, 237, 0, 0, 0, 207, 0, 0, 0, 100, 0, 0, 0, 157, 0, 0, 0, 114, 0, 0, 0, 64, 0, 0, 0, 122, 0, 0, 0, 76, 0, 0, 0, 11, 0, 0, 0, 118, 0, 0, 0, 42, 0, 0, 0, 251, 0, 0, 0, 86, 0, 0, 0, 51, 0, 0, 0, 167, 0, 0, 0, 144, 0, 0, 0, 124, 0, 0, 0, 195, 0, 0, 0, 111, 0, 0, 0, 23, 0, 0, 0, 165, 0, 0, 0, 160, +0, 0, 0, 103, 0, 0, 0, 114, 0, 0, 0, 23, 0, 0, 0, 234, 0, 0, 0, 126, 0, 0, 0, 99, 0, 0, 0, 20, 0, 0, 0, 131, 0, 0, 0, 222, 0, 0, 0, 193, 0, 0, 0, 113, 0, 0, 0, 45, 0, 0, 0, 65, 0, 0, 0, 50, 0, 0, 0, 122, 0, 0, 0, 243, 0, 0, 0, 209, 0, 0, 0, 43, 0, 0, 0, 216, 0, 0, 0, 42, 0, 0, 0, 166, 0, 0, 0, 70, 0, 0, 0, 54, 0, 0, 0, 172, 0, 0, 0, 204, 0, 0, 0, 107, 0, 0, 0, 124, 0, 0, 0, 249, 0, 0, 0, 184, 0, 0, 0, 139, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 208, 0, 0, 0, 125, 0, 0, 0, 143, 0, 0, 0, 115, 0, 0, 0, 234, +0, 0, 0, 32, 0, 0, 0, 218, 0, 0, 0, 134, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 173, 0, 0, 0, 115, 0, 0, 0, 77, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 169, 0, 0, 0, 218, 0, 0, 0, 31, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 221, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 156, 0, 0, 0, 178, 0, 0, 0, 97, 0, 0, 0, 10, 0, 0, 0, 152, 0, 0, 0, 42, 0, 0, 0, 165, 0, 0, 0, 215, 0, 0, 0, 238, 0, 0, 0, 169, 0, 0, 0, 172, 0, 0, 0, 101, 0, 0, 0, 203, 0, 0, 0, 10, 0, 0, 0, 30, 0, 0, 0, 226, 0, 0, 0, 190, 0, 0, 0, 220, 0, 0, 0, 133, 0, 0, 0, 89, 0, 0, 0, 15, 0, 0, 0, 156, 0, 0, 0, 166, 0, 0, 0, 87, 0, 0, 0, 52, 0, 0, 0, 165, 0, 0, 0, 135, 0, 0, 0, 235, 0, 0, 0, 123, 0, 0, 0, 30, 0, 0, 0, 12, 0, 0, 0, 60, 0, 0, 0, 47, 0, 0, 0, 189, 0, 0, 0, 132, 0, 0, 0, 99, 0, 0, +0, 13, 0, 0, 0, 181, 0, 0, 0, 160, 0, 0, 0, 240, 0, 0, 0, 75, 0, 0, 0, 158, 0, 0, 0, 147, 0, 0, 0, 198, 0, 0, 0, 52, 0, 0, 0, 154, 0, 0, 0, 52, 0, 0, 0, 255, 0, 0, 0, 115, 0, 0, 0, 25, 0, 0, 0, 47, 0, 0, 0, 110, 0, 0, 0, 84, 0, 0, 0, 69, 0, 0, 0, 44, 0, 0, 0, 146, 0, 0, 0, 49, 0, 0, 0, 118, 0, 0, 0, 52, 0, 0, 0, 241, 0, 0, 0, 178, 0, 0, 0, 38, 0, 0, 0, 232, 0, 0, 0, 116, 0, 0, 0, 10, 0, 0, 0, 103, 0, 0, 0, 144, 0, 0, 0, 109, 0, 0, 0, 12, 0, 0, 0, 76, 0, 0, 0, 204, 0, 0, 0, 192, 0, 0, 0, 230, 0, 0, +0, 189, 0, 0, 0, 167, 0, 0, 0, 94, 0, 0, 0, 85, 0, 0, 0, 140, 0, 0, 0, 205, 0, 0, 0, 88, 0, 0, 0, 155, 0, 0, 0, 17, 0, 0, 0, 162, 0, 0, 0, 187, 0, 0, 0]).concat([75, 0, 0, 0, 177, 0, 0, 0, 67, 0, 0, 0, 4, 0, 0, 0, 60, 0, 0, 0, 85, 0, 0, 0, 237, 0, 0, 0, 35, 0, 0, 0, 254, 0, 0, 0, 205, 0, 0, 0, 177, 0, 0, 0, 83, 0, 0, 0, 5, 0, 0, 0, 251, 0, 0, 0, 117, 0, 0, 0, 245, 0, 0, 0, 1, 0, 0, 0, 175, 0, 0, 0, 56, 0, 0, 0, 114, 0, 0, 0, 88, 0, 0, 0, 252, 0, 0, 0, 4, 0, 0, 0, 41, 0, 0, 0, 52, 0, 0, 0, 122, 0, +0, 0, 103, 0, 0, 0, 162, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 110, 0, 0, 0, 208, 0, 0, 0, 43, 0, 0, 0, 115, 0, 0, 0, 213, 0, 0, 0, 184, 0, 0, 0, 228, 0, 0, 0, 48, 0, 0, 0, 150, 0, 0, 0, 173, 0, 0, 0, 69, 0, 0, 0, 223, 0, 0, 0, 166, 0, 0, 0, 92, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 26, 0, 0, 0, 144, 0, 0, 0, 126, 0, 0, 0, 220, 0, 0, 0, 216, 0, 0, 0, 254, 0, 0, 0, 193, 0, 0, 0, 47, 0, 0, 0, 93, 0, 0, 0, 103, 0, 0, 0, 238, 0, 0, 0, 103, 0, 0, 0, 47, 0, 0, 0, 237, 0, 0, 0, 111, 0, 0, 0, 85, 0, 0, 0, 67, +0, 0, 0, 95, 0, 0, 0, 135, 0, 0, 0, 20, 0, 0, 0, 53, 0, 0, 0, 66, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 174, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 133, 0, 0, 0, 26, 0, 0, 0, 118, 0, 0, 0, 135, 0, 0, 0, 200, 0, 0, 0, 160, 0, 0, 0, 110, 0, 0, 0, 225, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 106, 0, 0, 0, 74, 0, 0, 0, 52, 0, 0, 0, 113, 0, 0, 0, 237, 0, 0, 0, 124, 0, 0, 0, 214, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 101, 0, 0, 0, 74, 0, 0, 0, 92, 0, 0, 0, 92, 0, 0, 0, 4, 0, 0, 0, 245, 0, 0, 0, 36, 0, 0, 0, 63, +0, 0, 0, 176, 0, 0, 0, 22, 0, 0, 0, 94, 0, 0, 0, 140, 0, 0, 0, 178, 0, 0, 0, 210, 0, 0, 0, 197, 0, 0, 0, 32, 0, 0, 0, 152, 0, 0, 0, 131, 0, 0, 0, 194, 0, 0, 0, 55, 0, 0, 0, 160, 0, 0, 0, 65, 0, 0, 0, 168, 0, 0, 0, 72, 0, 0, 0, 92, 0, 0, 0, 95, 0, 0, 0, 191, 0, 0, 0, 200, 0, 0, 0, 250, 0, 0, 0, 36, 0, 0, 0, 224, 0, 0, 0, 89, 0, 0, 0, 44, 0, 0, 0, 189, 0, 0, 0, 246, 0, 0, 0, 129, 0, 0, 0, 126, 0, 0, 0, 136, 0, 0, 0, 230, 0, 0, 0, 202, 0, 0, 0, 4, 0, 0, 0, 216, 0, 0, 0, 93, 0, 0, 0, 96, 0, 0, 0, 187, +0, 0, 0, 116, 0, 0, 0, 167, 0, 0, 0, 11, 0, 0, 0, 33, 0, 0, 0, 19, 0, 0, 0, 145, 0, 0, 0, 191, 0, 0, 0, 119, 0, 0, 0, 122, 0, 0, 0, 51, 0, 0, 0, 188, 0, 0, 0, 233, 0, 0, 0, 7, 0, 0, 0, 57, 0, 0, 0, 10, 0, 0, 0, 221, 0, 0, 0, 125, 0, 0, 0, 6, 0, 0, 0, 16, 0, 0, 0, 154, 0, 0, 0, 238, 0, 0, 0, 71, 0, 0, 0, 115, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 90, 0, 0, 0, 251, 0, 0, 0, 205, 0, 0, 0, 77, 0, 0, 0, 208, 0, 0, 0, 210, 0, 0, 0, 58, 0, 0, 0, 1, 0, 0, 0, 186, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 213, 0, 0, 0, 57, 0, 0, 0, 74, 0, 0, 0, 11, 0, 0, 0, 32, 0, 0, 0, 106, 0, 0, 0, 67, 0, 0, 0, 160, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 94, 0, 0, 0, 73, 0, 0, 0, 124, 0, 0, 0, 201, 0, 0, 0, 71, 0, 0, 0, 241, 0, 0, 0, 124, 0, 0, 0, 55, 0, 0, 0, 185, +0, 0, 0, 35, 0, 0, 0, 239, 0, 0, 0, 107, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 140, 0, 0, 0, 69, 0, 0, 0, 118, 0, 0, 0, 223, 0, 0, 0, 20, 0, 0, 0, 107, 0, 0, 0, 110, 0, 0, 0, 66, 0, 0, 0, 201, 0, 0, 0, 202, 0, 0, 0, 41, 0, 0, 0, 76, 0, 0, 0, 118, 0, 0, 0, 55, 0, 0, 0, 218, 0, 0, 0, 138, 0, 0, 0, 45, 0, 0, 0, 124, 0, 0, 0, 58, 0, 0, 0, 88, 0, 0, 0, 242, 0, 0, 0, 3, 0, 0, 0, 180, 0, 0, 0, 181, 0, 0, 0, 185, 0, 0, 0, 26, 0, 0, 0, 19, 0, 0, 0, 45, 0, 0, 0, 222, 0, 0, 0, 95, 0, 0, 0, 107, 0, 0, 0, 157, 0, +0, 0, 186, 0, 0, 0, 82, 0, 0, 0, 201, 0, 0, 0, 93, 0, 0, 0, 179, 0, 0, 0, 243, 0, 0, 0, 48, 0, 0, 0, 76, 0, 0, 0, 111, 0, 0, 0, 254, 0, 0, 0, 107, 0, 0, 0, 12, 0, 0, 0, 98, 0, 0, 0, 215, 0, 0, 0, 72, 0, 0, 0, 113, 0, 0, 0, 239, 0, 0, 0, 177, 0, 0, 0, 133, 0, 0, 0, 121, 0, 0, 0, 192, 0, 0, 0, 237, 0, 0, 0, 36, 0, 0, 0, 177, 0, 0, 0, 8, 0, 0, 0, 147, 0, 0, 0, 118, 0, 0, 0, 142, 0, 0, 0, 247, 0, 0, 0, 56, 0, 0, 0, 142, 0, 0, 0, 235, 0, 0, 0, 254, 0, 0, 0, 128, 0, 0, 0, 64, 0, 0, 0, 175, 0, 0, 0, 144, +0, 0, 0, 100, 0, 0, 0, 73, 0, 0, 0, 74, 0, 0, 0, 136, 0, 0, 0, 218, 0, 0, 0, 193, 0, 0, 0, 152, 0, 0, 0, 68, 0, 0, 0, 60, 0, 0, 0, 83, 0, 0, 0, 78, 0, 0, 0, 219, 0, 0, 0, 75, 0, 0, 0, 185, 0, 0, 0, 18, 0, 0, 0, 95, 0, 0, 0, 205, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 239, 0, 0, 0, 117, 0, 0, 0, 231, 0, 0, 0, 177, 0, 0, 0, 58, 0, 0, 0, 229, 0, 0, 0, 7, 0, 0, 0, 250, 0, 0, 0, 202, 0, 0, 0, 101, 0, 0, 0, 123, 0, 0, 0, 114, 0, 0, 0, 16, 0, 0, 0, 100, 0, 0, 0, 127, 0, 0, 0, 61, 0, 0, 0, 129, 0, 0, 0, 240, 0, +0, 0, 235, 0, 0, 0, 22, 0, 0, 0, 253, 0, 0, 0, 88, 0, 0, 0, 51, 0, 0, 0, 141, 0, 0, 0, 124, 0, 0, 0, 26, 0, 0, 0, 251, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 138, 0, 0, 0, 238, 0, 0, 0, 144, 0, 0, 0, 187, 0, 0, 0, 51, 0, 0, 0, 109, 0, 0, 0, 69, 0, 0, 0, 233, 0, 0, 0, 142, 0, 0, 0, 153, 0, 0, 0, 133, 0, 0, 0, 225, 0, 0, 0, 8, 0, 0, 0, 31, 0, 0, 0, 197, 0, 0, 0, 241, 0, 0, 0, 181, 0, 0, 0, 70, 0, 0, 0, 228, 0, 0, 0, 231, 0, 0, 0, 67, 0, 0, 0, 75, 0, 0, 0, 160, 0, 0, 0, 63, 0, 0, 0, 43, 0, 0, 0, 6, 0, 0, +0, 186, 0, 0, 0, 23, 0, 0, 0, 174, 0, 0, 0, 61, 0, 0, 0, 230, 0, 0, 0, 206, 0, 0, 0, 189, 0, 0, 0, 184, 0, 0, 0, 237, 0, 0, 0, 116, 0, 0, 0, 17, 0, 0, 0, 53, 0, 0, 0, 236, 0, 0, 0, 150, 0, 0, 0, 254, 0, 0, 0, 49, 0, 0, 0, 227, 0, 0, 0, 14, 0, 0, 0, 122, 0, 0, 0, 78, 0, 0, 0, 201, 0, 0, 0, 29, 0, 0, 0, 203, 0, 0, 0, 32, 0, 0, 0, 224, 0, 0, 0, 103, 0, 0, 0, 233, 0, 0, 0, 123, 0, 0, 0, 219, 0, 0, 0, 150, 0, 0, 0, 92, 0, 0, 0, 176, 0, 0, 0, 50, 0, 0, 0, 208, 0, 0, 0, 89, 0, 0, 0, 49, 0, 0, 0, 144, 0, +0, 0, 220, 0, 0, 0, 146, 0, 0, 0, 151, 0, 0, 0, 172, 0, 0, 0, 9, 0, 0, 0, 56, 0, 0, 0, 49, 0, 0, 0, 15, 0, 0, 0, 126, 0, 0, 0, 214, 0, 0, 0, 93, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 182, 0, 0, 0, 31, 0, 0, 0, 234, 0, 0, 0, 240, 0, 0, 0, 91, 0, 0, 0, 7, 0, 0, 0, 129, 0, 0, 0, 159, 0, 0, 0, 199, 0, 0, 0, 222, 0, 0, 0, 107, 0, 0, 0, 65, 0, 0, 0, 34, 0, 0, 0, 53, 0, 0, 0, 20, 0, 0, 0, 103, 0, 0, 0, 119, 0, 0, 0, 62, 0, 0, 0, 144, 0, 0, 0, 129, 0, 0, 0, 176, 0, 0, 0, 217, 0, 0, 0, 133, 0, 0, 0, 76, 0, 0, +0, 202, 0, 0, 0, 155, 0, 0, 0, 63, 0, 0, 0, 4, 0, 0, 0, 89, 0, 0, 0, 214, 0, 0, 0, 170, 0, 0, 0, 23, 0, 0, 0, 195, 0, 0, 0, 136, 0, 0, 0, 52, 0, 0, 0, 55, 0, 0, 0, 186, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 182, 0, 0, 0, 105, 0, 0, 0, 200, +0, 0, 0, 129, 0, 0, 0, 149, 0, 0, 0, 148, 0, 0, 0, 51, 0, 0, 0, 146, 0, 0, 0, 52, 0, 0, 0, 233, 0, 0, 0, 60, 0, 0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 61, 0, 0, 0, 90, 0, 0, 0, 55, 0, 0, 0, 156, 0, 0, 0, 34, 0, 0, 0, 160, 0, 0, 0, 170, 0, 0, 0, 101, 0, 0, 0, 206, 0, 0, 0, 180, 0, 0, 0, 194, 0, 0, 0, 45, 0, 0, 0, 102, 0, 0, 0, 103, 0, 0, 0, 2, 0, 0, 0, 255, 0, 0, 0, 116, 0, 0, 0, 16, 0, 0, 0, 34, 0, 0, 0, 176, 0, 0, 0, 213, 0, 0, 0, 230, 0, 0, 0, 199, 0, 0, 0, 239, 0, 0, 0, 177, 0, 0, 0, 167, 0, 0, 0, 19, +0, 0, 0, 218, 0, 0, 0, 96, 0, 0, 0, 180, 0, 0, 0, 128, 0, 0, 0, 193, 0, 0, 0, 66, 0, 0, 0, 125, 0, 0, 0, 16, 0, 0, 0, 112, 0, 0, 0, 151, 0, 0, 0, 4, 0, 0, 0, 77, 0, 0, 0, 218, 0, 0, 0, 35, 0, 0, 0, 137, 0, 0, 0, 194, 0, 0, 0, 14, 0, 0, 0, 104, 0, 0, 0, 203, 0, 0, 0, 222, 0, 0, 0, 224, 0, 0, 0, 155, 0, 0, 0, 41, 0, 0, 0, 51, 0, 0, 0, 254, 0, 0, 0, 66, 0, 0, 0, 42, 0, 0, 0, 54, 0, 0, 0, 43, 0, 0, 0, 46, 0, 0, 0, 54, 0, 0, 0, 100, 0, 0, 0, 92, 0, 0, 0, 139, 0, 0, 0, 204, 0, 0, 0, 129, 0, 0, 0, 106, +0, 0, 0, 21, 0, 0, 0, 8, 0, 0, 0, 161, 0, 0, 0, 39, 0, 0, 0, 232, 0, 0, 0, 87, 0, 0, 0, 229, 0, 0, 0, 120, 0, 0, 0, 142, 0, 0, 0, 242, 0, 0, 0, 88, 0, 0, 0, 25, 0, 0, 0, 18, 0, 0, 0, 66, 0, 0, 0, 174, 0, 0, 0, 196, 0, 0, 0, 99, 0, 0, 0, 62, 0, 0, 0, 120, 0, 0, 0, 150, 0, 0, 0, 156, 0, 0, 0, 167, 0, 0, 0, 202, 0, 0, 0, 128, 0, 0, 0, 174, 0, 0, 0, 2, 0, 0, 0, 133, 0, 0, 0, 177, 0, 0, 0, 124, 0, 0, 0, 4, 0, 0, 0, 92, 0, 0, 0, 193, 0, 0, 0, 91, 0, 0, 0, 38, 0, 0, 0, 193, 0, 0, 0, 186, 0, 0, 0, 237, 0, +0, 0, 165, 0, 0, 0, 89, 0, 0, 0, 112, 0, 0, 0, 133, 0, 0, 0, 140, 0, 0, 0, 140, 0, 0, 0, 232, 0, 0, 0, 135, 0, 0, 0, 172, 0, 0, 0, 106, 0, 0, 0, 40, 0, 0, 0, 153, 0, 0, 0, 53, 0, 0, 0, 159, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 40, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 218, 0, 0, 0, 128, 0, 0, 0, 40, 0, 0, 0, 56, 0, 0, 0, 222, 0, 0, 0, 159, 0, 0, 0, 205, 0, 0, 0, 228, 0, 0, 0, 227, 0, 0, 0, 98, 0, 0, 0, 251, 0, 0, 0, 46, 0, 0, 0, 70, 0, 0, 0, 141, 0, 0, 0, 1, 0, 0, 0, 179, 0, 0, 0, 6, 0, 0, 0, 81, 0, 0, +0, 212, 0, 0, 0, 25, 0, 0, 0, 59, 0, 0, 0, 17, 0, 0, 0, 250, 0, 0, 0, 226, 0, 0, 0, 173, 0, 0, 0, 30, 0, 0, 0, 160, 0, 0, 0, 32, 0, 0, 0, 153, 0, 0, 0, 105, 0, 0, 0, 10, 0, 0, 0, 174, 0, 0, 0, 163, 0, 0, 0, 112, 0, 0, 0, 78, 0, 0, 0, 100, 0, 0, 0, 128, 0, 0, 0, 183, 0, 0, 0, 133, 0, 0, 0, 156, 0, 0, 0, 135, 0, 0, 0, 84, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 85, 0, 0, 0, 128, 0, 0, 0, 109, 0, 0, 0, 141, 0, 0, 0, 124, 0, 0, 0, 169, 0, 0, 0, 100, 0, 0, 0, 202, 0, 0, 0, 108, 0, 0, 0, 46, 0, 0, 0, 33, 0, +0, 0, 216, 0, 0, 0, 200, 0, 0, 0, 108, 0, 0, 0, 145, 0, 0, 0, 74, 0, 0, 0, 7, 0, 0, 0, 173, 0, 0, 0, 8, 0, 0, 0, 117, 0, 0, 0, 193, 0, 0, 0, 79, 0, 0, 0, 164, 0, 0, 0, 178, 0, 0, 0, 195, 0, 0, 0, 111, 0, 0, 0, 70, 0, 0, 0, 62, 0, 0, 0, 177, 0, 0, 0, 206, 0, 0, 0, 82, 0, 0, 0, 171, 0, 0, 0, 103, 0, 0, 0, 9, 0, 0, 0, 84, 0, 0, 0, 72, 0, 0, 0, 107, 0, 0, 0, 108, 0, 0, 0, 215, 0, 0, 0, 29, 0, 0, 0, 113, 0, 0, 0, 118, 0, 0, 0, 203, 0, 0, 0, 255, 0, 0, 0, 221, 0, 0, 0, 49, 0, 0, 0, 54, 0, 0, 0, 136, 0, +0, 0, 250, 0, 0, 0, 253, 0, 0, 0, 240, 0, 0, 0, 54, 0, 0, 0, 111, 0, 0, 0, 7, 0, 0, 0, 116, 0, 0, 0, 136, 0, 0, 0, 80, 0, 0, 0, 208, 0, 0, 0, 149, 0, 0, 0, 56, 0, 0, 0, 74, 0, 0, 0, 72, 0, 0, 0, 46, 0, 0, 0, 7, 0, 0, 0, 100, 0, 0, 0, 151, 0, 0, 0, 17, 0, 0, 0, 118, 0, 0, 0, 1, 0, 0, 0, 26, 0, 0, 0, 39, 0, 0, 0, 77, 0, 0, 0, 142, 0, 0, 0, 37, 0, 0, 0, 154, 0, 0, 0, 155, 0, 0, 0, 28, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 0, 0, 0, 87, 0, 0, 0, 189, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 172, 0, 0, 0, 94, 0, 0, 0, 118, 0, 0, 0, 163, 0, 0, 0, 113, 0, 0, 0, 173, 0, 0, 0, 43, 0, 0, 0, 16, 0, 0, 0, 69, 0, 0, 0, 2, 0, 0, 0, 236, 0, 0, 0, 89, 0, 0, 0, 213, 0, 0, 0, 93, 0, 0, 0, 169, 0, 0, 0, 68, 0, 0, 0, 204, 0, 0, 0, 37, 0, 0, 0, 76, 0, 0, 0, 179, 0, +0, 0, 60, 0, 0, 0, 91, 0, 0, 0, 105, 0, 0, 0, 7, 0, 0, 0, 85, 0, 0, 0, 38, 0, 0, 0, 107, 0, 0, 0, 48, 0, 0, 0, 107, 0, 0, 0, 212, 0, 0, 0, 167, 0, 0, 0, 81, 0, 0, 0, 41, 0, 0, 0, 227, 0, 0, 0, 249, 0, 0, 0, 122, 0, 0, 0, 117, 0, 0, 0, 42, 0, 0, 0, 130, 0, 0, 0, 47, 0, 0, 0, 214, 0, 0, 0, 29, 0, 0, 0, 153, 0, 0, 0, 43, 0, 0, 0, 128, 0, 0, 0, 213, 0, 0, 0, 103, 0, 0, 0, 30, 0, 0, 0, 21, 0, 0, 0, 157, 0, 0, 0, 202, 0, 0, 0, 253, 0, 0, 0, 235, 0, 0, 0, 172, 0, 0, 0, 151, 0, 0, 0, 53, 0, 0, 0, 9, 0, 0, +0, 127, 0, 0, 0, 63, 0, 0, 0, 53, 0, 0, 0, 13, 0, 0, 0, 52, 0, 0, 0, 10, 0, 0, 0, 184, 0, 0, 0, 103, 0, 0, 0, 86, 0, 0, 0, 41, 0, 0, 0, 32, 0, 0, 0, 243, 0, 0, 0, 25, 0, 0, 0, 95, 0, 0, 0, 226, 0, 0, 0, 131, 0, 0, 0, 66, 0, 0, 0, 115, 0, 0, 0, 83, 0, 0, 0, 168, 0, 0, 0, 197, 0, 0, 0, 2, 0, 0, 0, 25, 0, 0, 0, 51, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 189, 0, 0, 0, 195, 0, 0, 0, 135, 0, 0, 0, 140, 0, 0, 0, 215, 0, 0, 0, 118, 0, 0, 0, 237, 0, 0, 0, 37, 0, 0, 0, 71, 0, 0, 0, 57, 0, 0, 0, 55, 0, 0, 0, +118, 0, 0, 0, 13, 0, 0, 0, 29, 0, 0, 0, 12, 0, 0, 0, 245, 0, 0, 0, 90, 0, 0, 0, 109, 0, 0, 0, 67, 0, 0, 0, 136, 0, 0, 0, 153, 0, 0, 0, 21, 0, 0, 0, 180, 0, 0, 0, 82, 0, 0, 0, 15, 0, 0, 0, 42, 0, 0, 0, 179, 0, 0, 0, 176, 0, 0, 0, 63, 0, 0, 0, 166, 0, 0, 0, 179, 0, 0, 0, 38, 0, 0, 0, 179, 0, 0, 0, 199, 0, 0, 0, 69, 0, 0, 0, 245, 0, 0, 0, 146, 0, 0, 0, 95, 0, 0, 0, 155, 0, 0, 0, 23, 0, 0, 0, 157, 0, 0, 0, 35, 0, 0, 0, 189, 0, 0, 0, 21, 0, 0, 0, 254, 0, 0, 0, 82, 0, 0, 0, 82, 0, 0, 0, 21, 0, 0, 0, 38, +0, 0, 0, 121, 0, 0, 0, 134, 0, 0, 0, 186, 0, 0, 0, 6, 0, 0, 0, 86, 0, 0, 0, 102, 0, 0, 0, 187, 0, 0, 0, 140, 0, 0, 0, 46, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 213, 0, 0, 0, 74, 0, 0, 0, 24, 0, 0, 0, 82, 0, 0, 0, 218, 0, 0, 0, 132, 0, 0, 0, 68, 0, 0, 0, 240, 0, 0, 0, 62, 0, 0, 0, 233, 0, 0, 0, 140, 0, 0, 0, 53, 0, 0, 0, 173, 0, 0, 0, 160, 0, 0, 0, 65, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 77, 0, 0, 0, 185, 0, 0, 0, 210, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 78, 0, 0, 0, 91, 0, 0, 0, 197, 0, 0, 0, 194, +0, 0, 0, 160, 0, 0, 0, 27, 0, 0, 0, 207, 0, 0, 0, 12, 0, 0, 0, 191, 0, 0, 0, 23, 0, 0, 0, 102, 0, 0, 0, 87, 0, 0, 0, 193, 0, 0, 0, 23, 0, 0, 0, 144, 0, 0, 0, 69, 0, 0, 0, 113, 0, 0, 0, 194, 0, 0, 0, 225, 0, 0, 0, 36, 0, 0, 0, 235, 0, 0, 0, 39, 0, 0, 0, 44, 0, 0, 0, 185, 0, 0, 0, 66, 0, 0, 0, 164, 0, 0, 0, 175, 0, 0, 0, 59, 0, 0, 0, 66, 0, 0, 0, 14, 0, 0, 0, 194, 0, 0, 0, 15, 0, 0, 0, 242, 0, 0, 0, 234, 0, 0, 0, 131, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 19, 0, 0, 0, 23, 0, 0, 0, 176, 0, 0, 0, 189, +0, 0, 0, 137, 0, 0, 0, 23, 0, 0, 0, 227, 0, 0, 0, 114, 0, 0, 0, 203, 0, 0, 0, 14, 0, 0, 0, 118, 0, 0, 0, 126, 0, 0, 0, 65, 0, 0, 0, 99, 0, 0, 0, 4, 0, 0, 0, 136, 0, 0, 0, 113, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 56, 0, 0, 0, 134, 0, 0, 0, 87, 0, 0, 0, 221, 0, 0, 0, 159, 0, 0, 0, 238, 0, 0, 0, 84, 0, 0, 0, 112, 0, 0, 0, 101, 0, 0, 0, 191, 0, 0, 0, 241, 0, 0, 0, 44, 0, 0, 0, 224, 0, 0, 0, 57, 0, 0, 0, 13, 0, 0, 0, 227, 0, 0, 0, 137, 0, 0, 0, 253, 0, 0, 0, 142, 0, 0, 0, 147, 0, 0, 0, 79, 0, 0, 0, 67, +0, 0, 0, 220, 0, 0, 0, 213, 0, 0, 0, 91, 0, 0, 0, 222, 0, 0, 0, 249, 0, 0, 0, 152, 0, 0, 0, 229, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 59, 0, 0, 0, 101, 0, 0, 0, 17, 0, 0, 0, 223, 0, 0, 0, 178, 0, 0, 0, 242, 0, 0, 0, 99, 0, 0, 0, 148, +0, 0, 0, 18, 0, 0, 0, 111, 0, 0, 0, 92, 0, 0, 0, 158, 0, 0, 0, 119, 0, 0, 0, 193, 0, 0, 0, 182, 0, 0, 0, 216, 0, 0, 0, 171, 0, 0, 0, 88, 0, 0, 0, 122, 0, 0, 0, 29, 0, 0, 0, 149, 0, 0, 0, 115, 0, 0, 0, 221, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, 0, 111, 0, 0, 0, 242, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 219, 0, 0, 0, 118, 0, 0, 0, 174, 0, 0, 0, 6, 0, 0, 0, 78, 0, 0, 0, 44, 0, 0, 0, 82, 0, 0, 0, 27, 0, 0, 0, 188, 0, 0, 0, 90, 0, 0, 0, 90, 0, 0, 0, 165, 0, 0, 0, 190, 0, 0, 0, 39, 0, 0, 0, 189, 0, 0, 0, 235, +0, 0, 0, 225, 0, 0, 0, 20, 0, 0, 0, 23, 0, 0, 0, 104, 0, 0, 0, 38, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 209, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 223, 0, 0, 0, 241, 0, 0, 0, 6, 0, 0, 0, 92, 0, 0, 0, 166, 0, 0, 0, 27, 0, 0, 0, 185, 0, 0, 0, 36, 0, 0, 0, 197, 0, 0, 0, 102, 0, 0, 0, 128, 0, 0, 0, 19, 0, 0, 0, 14, 0, 0, 0, 72, 0, 0, 0, 140, 0, 0, 0, 135, 0, 0, 0, 49, 0, 0, 0, 132, 0, 0, 0, 180, 0, 0, 0, 96, 0, 0, 0, 237, 0, 0, 0, 197, 0, 0, 0, 236, 0, 0, 0, 182, 0, 0, 0, 197, 0, 0, 0, 5, 0, 0, 0, 51, 0, 0, +0, 95, 0, 0, 0, 47, 0, 0, 0, 125, 0, 0, 0, 64, 0, 0, 0, 182, 0, 0, 0, 50, 0, 0, 0, 29, 0, 0, 0, 56, 0, 0, 0, 116, 0, 0, 0, 27, 0, 0, 0, 241, 0, 0, 0, 9, 0, 0, 0, 61, 0, 0, 0, 212, 0, 0, 0, 105, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 141, 0, 0, 0, 248, 0, 0, 0, 52, 0, 0, 0, 54, 0, 0, 0, 117, 0, 0, 0, 85, 0, 0, 0, 24, 0, 0, 0, 85, 0, 0, 0, 88, 0, 0, 0, 60, 0, 0, 0, 121, 0, 0, 0, 175, 0, 0, 0, 38, 0, 0, 0, 128, 0, 0, 0, 171, 0, 0, 0, 155, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 203, 0, 0, 0, +218, 0, 0, 0, 193, 0, 0, 0, 159, 0, 0, 0, 246, 0, 0, 0, 47, 0, 0, 0, 162, 0, 0, 0, 244, 0, 0, 0, 69, 0, 0, 0, 23, 0, 0, 0, 190, 0, 0, 0, 235, 0, 0, 0, 133, 0, 0, 0, 237, 0, 0, 0, 158, 0, 0, 0, 205, 0, 0, 0, 86, 0, 0, 0, 245, 0, 0, 0, 23, 0, 0, 0, 69, 0, 0, 0, 66, 0, 0, 0, 180, 0, 0, 0, 31, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 5, 0, 0, 0, 116, 0, 0, 0, 21, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 106, 0, 0, 0, 61, 0, 0, 0, 36, 0, 0, 0, 9, 0, 0, 0, 13, 0, 0, 0, 88, 0, 0, 0, 177, 0, 0, 0, 66, 0, +0, 0, 215, 0, 0, 0, 4, 0, 0, 0, 141, 0, 0, 0, 189, 0, 0, 0, 163, 0, 0, 0, 196, 0, 0, 0, 6, 0, 0, 0, 155, 0, 0, 0, 31, 0, 0, 0, 144, 0, 0, 0, 88, 0, 0, 0, 96, 0, 0, 0, 116, 0, 0, 0, 178, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 60, 0, 0, 0, 210, 0, 0, 0, 218, 0, 0, 0, 130, 0, 0, 0, 187, 0, 0, 0, 16, 0, 0, 0, 144, 0, 0, 0, 105, 0, 0, 0, 146, 0, 0, 0, 169, 0, 0, 0, 180, 0, 0, 0, 48, 0, 0, 0, 129, 0, 0, 0, 227, 0, 0, 0, 124, 0, 0, 0, 168, 0, 0, 0, 137, 0, 0, 0, 69, 0, 0, 0, 63, 0, 0, 0, 220, 0, 0, 0, 5, 0, +0, 0, 203, 0, 0, 0, 65, 0, 0, 0, 60, 0, 0, 0, 200, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 44, 0, 0, 0, 56, 0, 0, 0, 153, 0, 0, 0, 227, 0, 0, 0, 104, 0, 0, 0, 85, 0, 0, 0, 249, 0, 0, 0, 211, 0, 0, 0, 50, 0, 0, 0, 199, 0, 0, 0, 191, 0, 0, 0, 250, 0, 0, 0, 212, 0, 0, 0, 27, 0, 0, 0, 93, 0, 0, 0, 222, 0, 0, 0, 220, 0, 0, 0, 16, 0, 0, 0, 66, 0, 0, 0, 192, 0, 0, 0, 66, 0, 0, 0, 217, 0, 0, 0, 117, 0, 0, 0, 45, 0, 0, 0, 171, 0, 0, 0, 53, 0, 0, 0, 78, 0, 0, 0, 135, 0, 0, 0, 196, 0, 0, 0, 101, 0, 0, 0, 151, 0, +0, 0, 103, 0, 0, 0, 36, 0, 0, 0, 164, 0, 0, 0, 71, 0, 0, 0, 173, 0, 0, 0, 63, 0, 0, 0, 142, 0, 0, 0, 243, 0, 0, 0, 203, 0, 0, 0, 49, 0, 0, 0, 23, 0, 0, 0, 119, 0, 0, 0, 197, 0, 0, 0, 226, 0, 0, 0, 215, 0, 0, 0, 143, 0, 0, 0, 60, 0, 0, 0, 193, 0, 0, 0, 205, 0, 0, 0, 86, 0, 0, 0, 72, 0, 0, 0, 193, 0, 0, 0, 108, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 174, 0, 0, 0, 95, 0, 0, 0, 136, 0, 0, 0, 123, 0, 0, 0, 165, 0, 0, 0, 144, 0, 0, 0, 223, 0, 0, 0, 16, 0, 0, 0, 178, 0, 0, 0, 139, 0, 0, 0, 94, 0, 0, 0, 36, 0, 0, 0, 23, 0, 0, 0, 195, 0, 0, 0, 163, 0, 0, 0, 212, 0, 0, 0, 15, 0, 0, 0, 146, 0, 0, 0, 97, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 90, 0, 0, 0, 173, 0, 0, 0, 118, 0, 0, 0, 189, 0, 0, 0, 216, 0, 0, 0, 28, 0, 0, 0, 221, 0, 0, 0, 224, 0, +0, 0, 18, 0, 0, 0, 109, 0, 0, 0, 142, 0, 0, 0, 189, 0, 0, 0, 112, 0, 0, 0, 143, 0, 0, 0, 2, 0, 0, 0, 163, 0, 0, 0, 36, 0, 0, 0, 77, 0, 0, 0, 90, 0, 0, 0, 103, 0, 0, 0, 196, 0, 0, 0, 218, 0, 0, 0, 247, 0, 0, 0, 32, 0, 0, 0, 15, 0, 0, 0, 129, 0, 0, 0, 91, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 36, 0, 0, 0, 103, 0, 0, 0, 131, 0, 0, 0, 11, 0, 0, 0, 42, 0, 0, 0, 128, 0, 0, 0, 231, 0, 0, 0, 253, 0, 0, 0, 116, 0, 0, 0, 75, 0, 0, 0, 158, 0, 0, 0, 92, 0, 0, 0, 13, 0, 0, 0, 148, 0, 0, 0, 213, 0, 0, 0, 95, 0, 0, +0, 31, 0, 0, 0, 162, 0, 0, 0, 251, 0, 0, 0, 235, 0, 0, 0, 225, 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 0, 248, 0, 0, 0, 32, 0, 0, 0, 173, 0, 0, 0, 129, 0, 0, 0, 48, 0, 0, 0, 6, 0, 0, 0, 45, 0, 0, 0, 161, 0, 0, 0, 129, 0, 0, 0, 149, 0, 0, 0, 54, 0, 0, 0, 207, 0, 0, 0, 17, 0, 0, 0, 11, 0, 0, 0, 175, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 154, 0, 0, 0, 108, 0, 0, 0, 85, 0, 0, 0, 193, 0, 0, 0, 22, 0, 0, 0, 54, 0, 0, 0, 79, 0, 0, 0, 241, 0, 0, 0, 94, 0, 0, 0, 116, 0, 0, 0, 53, 0, 0, 0, 19, 0, 0, 0, 40, 0, 0, 0, 215, +0, 0, 0, 17, 0, 0, 0, 207, 0, 0, 0, 184, 0, 0, 0, 222, 0, 0, 0, 147, 0, 0, 0, 179, 0, 0, 0, 5, 0, 0, 0, 184, 0, 0, 0, 181, 0, 0, 0, 115, 0, 0, 0, 233, 0, 0, 0, 235, 0, 0, 0, 173, 0, 0, 0, 25, 0, 0, 0, 30, 0, 0, 0, 137, 0, 0, 0, 15, 0, 0, 0, 139, 0, 0, 0, 21, 0, 0, 0, 213, 0, 0, 0, 140, 0, 0, 0, 227, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 0, 121, 0, 0, 0, 231, 0, 0, 0, 24, 0, 0, 0, 230, 0, 0, 0, 15, 0, 0, 0, 87, 0, 0, 0, 147, 0, 0, 0, 21, 0, 0, 0, 160, 0, 0, 0, 167, 0, 0, 0, 170, 0, 0, 0, 196, 0, 0, 0, 191, +0, 0, 0, 79, 0, 0, 0, 48, 0, 0, 0, 116, 0, 0, 0, 149, 0, 0, 0, 94, 0, 0, 0, 105, 0, 0, 0, 74, 0, 0, 0, 91, 0, 0, 0, 69, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, 35, 0, 0, 0, 116, 0, 0, 0, 76, 0, 0, 0, 223, 0, 0, 0, 107, 0, 0, 0, 69, 0, 0, 0, 151, 0, 0, 0, 41, 0, 0, 0, 108, 0, 0, 0, 196, 0, 0, 0, 66, 0, 0, 0, 11, 0, 0, 0, 221, 0, 0, 0, 192, 0, 0, 0, 41, 0, 0, 0, 92, 0, 0, 0, 155, 0, 0, 0, 52, 0, 0, 0, 151, 0, 0, 0, 208, 0, 0, 0, 199, 0, 0, 0, 121, 0, 0, 0, 128, 0, 0, 0, 99, 0, 0, 0, 116, 0, +0, 0, 228, 0, 0, 0, 142, 0, 0, 0, 55, 0, 0, 0, 176, 0, 0, 0, 43, 0, 0, 0, 124, 0, 0, 0, 232, 0, 0, 0, 104, 0, 0, 0, 108, 0, 0, 0, 195, 0, 0, 0, 130, 0, 0, 0, 151, 0, 0, 0, 87, 0, 0, 0, 34, 0, 0, 0, 190, 0, 0, 0, 131, 0, 0, 0, 182, 0, 0, 0, 75, 0, 0, 0, 128, 0, 0, 0, 107, 0, 0, 0, 67, 0, 0, 0, 36, 0, 0, 0, 94, 0, 0, 0, 239, 0, 0, 0, 153, 0, 0, 0, 155, 0, 0, 0, 168, 0, 0, 0, 252, 0, 0, 0, 37, 0, 0, 0, 141, 0, 0, 0, 59, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 43, 0, 0, 0, 62, 0, 0, 0, 231, 0, 0, 0, 149, +0, 0, 0, 118, 0, 0, 0, 155, 0, 0, 0, 204, 0, 0, 0, 21, 0, 0, 0, 219, 0, 0, 0, 50, 0, 0, 0, 230, 0, 0, 0, 102, 0, 0, 0, 132, 0, 0, 0, 240, 0, 0, 0, 74, 0, 0, 0, 19, 0, 0, 0, 166, 0, 0, 0, 214, 0, 0, 0, 250, 0, 0, 0, 147, 0, 0, 0, 70, 0, 0, 0, 7, 0, 0, 0, 246, 0, 0, 0, 126, 0, 0, 0, 92, 0, 0, 0, 109, 0, 0, 0, 94, 0, 0, 0, 246, 0, 0, 0, 166, 0, 0, 0, 231, 0, 0, 0, 72, 0, 0, 0, 240, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 255, 0, 0, 0, 144, 0, 0, 0, 193, 0, 0, 0, 204, 0, 0, 0, 76, 0, 0, 0, 25, 0, 0, 0, 156, +0, 0, 0, 60, 0, 0, 0, 78, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 80, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, 21, 0, 0, 0, 89, 0, 0, 0, 242, 0, 0, 0, 139, 0, 0, 0, 129, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 211, 0, 0, 0, 108, 0, 0, 0, 153, 0, 0, +0, 140, 0, 0, 0, 112, 0, 0, 0, 103, 0, 0, 0, 236, 0, 0, 0, 204, 0, 0, 0, 238, 0, 0, 0, 158, 0, 0, 0, 89, 0, 0, 0, 69, 0, 0, 0, 89, 0, 0, 0, 125, 0, 0, 0, 71, 0, 0, 0, 117, 0, 0, 0, 105, 0, 0, 0, 245, 0, 0, 0, 36, 0, 0, 0, 147, 0, 0, 0, 93, 0, 0, 0, 106, 0, 0, 0, 79, 0, 0, 0, 27, 0, 0, 0, 190, 0, 0, 0, 107, 0, 0, 0, 48, 0, 0, 0, 207, 0, 0, 0, 117, 0, 0, 0, 70, 0, 0, 0, 227, 0, 0, 0, 123, 0, 0, 0, 157, 0, 0, 0, 252, 0, 0, 0, 205, 0, 0, 0, 216, 0, 0, 0, 92, 0, 0, 0, 31, 0, 0, 0, 180, 0, 0, 0, 200, 0, +0, 0, 226, 0, 0, 0, 36, 0, 0, 0, 236, 0, 0, 0, 26, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 50, 0, 0, 0, 87, 0, 0, 0, 253, 0, 0, 0, 60, 0, 0, 0, 90, 0, 0, 0, 152, 0, 0, 0, 16, 0, 0, 0, 163, 0, 0, 0, 219, 0, 0, 0, 247, 0, 0, 0, 48, 0, 0, 0, 216, 0, 0, 0, 194, 0, 0, 0, 154, 0, 0, 0, 225, 0, 0, 0, 211, 0, 0, 0, 206, 0, 0, 0, 34, 0, 0, 0, 229, 0, 0, 0, 128, 0, 0, 0, 30, 0, 0, 0, 217, 0, 0, 0, 228, 0, 0, 0, 31, 0, 0, 0, 171, 0, 0, 0, 192, 0, 0, 0, 113, 0, 0, 0, 26, 0, 0, 0, 134, 0, 0, 0, 14, 0, 0, 0, 39, 0, +0, 0, 153, 0, 0, 0, 91, 0, 0, 0, 250, 0, 0, 0, 118, 0, 0, 0, 153, 0, 0, 0, 176, 0, 0, 0, 8, 0, 0, 0, 60, 0, 0, 0, 42, 0, 0, 0, 147, 0, 0, 0, 210, 0, 0, 0, 133, 0, 0, 0, 27, 0, 0, 0, 106, 0, 0, 0, 93, 0, 0, 0, 166, 0, 0, 0, 238, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 51, 0, 0, 0, 189, 0, 0, 0, 106, 0, 0, 0, 54, 0, 0, 0, 115, 0, 0, 0, 55, 0, 0, 0, 58, 0, 0, 0, 68, 0, 0, 0, 180, 0, 0, 0, 236, 0, 0, 0, 169, 0, 0, 0, 122, 0, 0, 0, 222, 0, 0, 0, 131, 0, 0, 0, 64, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 40, +0, 0, 0, 186, 0, 0, 0, 162, 0, 0, 0, 48, 0, 0, 0, 211, 0, 0, 0, 181, 0, 0, 0, 109, 0, 0, 0, 5, 0, 0, 0, 63, 0, 0, 0, 159, 0, 0, 0, 243, 0, 0, 0, 21, 0, 0, 0, 141, 0, 0, 0, 124, 0, 0, 0, 202, 0, 0, 0, 201, 0, 0, 0, 252, 0, 0, 0, 138, 0, 0, 0, 124, 0, 0, 0, 148, 0, 0, 0, 176, 0, 0, 0, 99, 0, 0, 0, 54, 0, 0, 0, 155, 0, 0, 0, 120, 0, 0, 0, 209, 0, 0, 0, 145, 0, 0, 0, 31, 0, 0, 0, 147, 0, 0, 0, 216, 0, 0, 0, 87, 0, 0, 0, 67, 0, 0, 0, 222, 0, 0, 0, 118, 0, 0, 0, 163, 0, 0, 0, 67, 0, 0, 0, 155, 0, 0, 0, +53, 0, 0, 0, 226, 0, 0, 0, 169, 0, 0, 0, 61, 0, 0, 0, 50, 0, 0, 0, 30, 0, 0, 0, 187, 0, 0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 112, 0, 0, 0, 233, 0, 0, 0, 69, 0, 0, 0, 47, 0, 0, 0, 143, 0, 0, 0, 112, 0, 0, 0, 127, 0, 0, 0, 8, 0, 0, 0, 126, 0, 0, 0, 83, 0, 0, 0, 196, 0, 0, 0, 122, 0, 0, 0, 191, 0, 0, 0, 247, 0, 0, 0, 225, 0, 0, 0, 164, 0, 0, 0, 106, 0, 0, 0, 216, 0, 0, 0, 172, 0, 0, 0, 100, 0, 0, 0, 27, 0, 0, 0, 17, 0, 0, 0, 178, 0, 0, 0, 235, 0, 0, 0, 71, 0, 0, 0, 70, 0, 0, 0, 24, 0, 0, 0, 62, 0, 0, 0, +31, 0, 0, 0, 153, 0, 0, 0, 12, 0, 0, 0, 204, 0, 0, 0, 241, 0, 0, 0, 44, 0, 0, 0, 224, 0, 0, 0, 231, 0, 0, 0, 143, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 126, 0, 0, 0, 101, 0, 0, 0, 184, 0, 0, 0, 12, 0, 0, 0, 208, 0, 0, 0, 251, 0, 0, 0, 200, 0, 0, 0, 185, 0, 0, 0, 144, 0, 0, 0, 152, 0, 0, 0, 51, 0, 0, 0, 97, 0, 0, 0, 59, 0, 0, 0, 216, 0, 0, 0, 39, 0, 0, 0, 160, 0, 0, 0, 190, 0, 0, 0, 114, 0, 0, 0, 58, 0, 0, 0, 80, 0, 0, 0, 75, 0, 0, 0, 116, 0, 0, 0, 171, 0, 0, 0, 1, 0, 0, 0, 200, 0, 0, 0, 147, 0, 0, 0, +197, 0, 0, 0, 228, 0, 0, 0, 199, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 180, 0, 0, 0, 202, 0, 0, 0, 238, 0, 0, 0, 235, 0, 0, 0, 142, 0, 0, 0, 215, 0, 0, 0, 78, 0, 0, 0, 38, 0, 0, 0, 198, 0, 0, 0, 29, 0, 0, 0, 226, 0, 0, 0, 113, 0, 0, 0, 175, 0, 0, 0, 137, 0, 0, 0, 160, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 11, 0, 0, 0, 228, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 168, 0, 0, 0, 250, 0, 0, 0, 130, 0, 0, 0, 116, 0, 0, 0, 6, 0, 0, 0, 82, 0, 0, 0, 109, 0, 0, 0, 8, 0, 0, 0, 82, 0, 0, 0, 138, 0, 0, 0, 255, 0, 0, 0, 98, 0, 0, 0, 197, 0, 0, 0, 106, 0, 0, 0, 68, 0, 0, 0, 15, 0, 0, 0, 81, 0, 0, 0, 140, 0, 0, 0, 31, 0, 0, 0, 110, 0, 0, 0, 182, 0, 0, 0, 198, 0, 0, 0, 44, 0, 0, 0, 129, 0, 0, 0, 211, 0, 0, 0, 118, 0, 0, 0, 70, 0, 0, 0, 244, 0, 0, 0, +41, 0, 0, 0, 116, 0, 0, 0, 46, 0, 0, 0, 128, 0, 0, 0, 167, 0, 0, 0, 26, 0, 0, 0, 143, 0, 0, 0, 246, 0, 0, 0, 189, 0, 0, 0, 214, 0, 0, 0, 142, 0, 0, 0, 191, 0, 0, 0, 193, 0, 0, 0, 149, 0, 0, 0, 42, 0, 0, 0, 235, 0, 0, 0, 160, 0, 0, 0, 127, 0, 0, 0, 69, 0, 0, 0, 160, 0, 0, 0, 80, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 177, 0, 0, 0, 87, 0, 0, 0, 76, 0, 0, 0, 116, 0, 0, 0, 183, 0, 0, 0, 226, 0, 0, 0, 137, 0, 0, 0, 125, 0, 0, 0, 7, 0, 0, 0, 238, 0, 0, 0, 167, 0, 0, 0, 173, 0, 0, 0, 183, 0, 0, 0, 9, 0, 0, 0, +11, 0, 0, 0, 73, 0, 0, 0, 78, 0, 0, 0, 191, 0, 0, 0, 202, 0, 0, 0, 229, 0, 0, 0, 33, 0, 0, 0, 230, 0, 0, 0, 230, 0, 0, 0, 175, 0, 0, 0, 213, 0, 0, 0, 103, 0, 0, 0, 243, 0, 0, 0, 206, 0, 0, 0, 126, 0, 0, 0, 124, 0, 0, 0, 147, 0, 0, 0, 123, 0, 0, 0, 90, 0, 0, 0, 16, 0, 0, 0, 18, 0, 0, 0, 14, 0, 0, 0, 108, 0, 0, 0, 6, 0, 0, 0, 17, 0, 0, 0, 117, 0, 0, 0, 213, 0, 0, 0, 252, 0, 0, 0, 134, 0, 0, 0, 163, 0, 0, 0, 59, 0, 0, 0, 163, 0, 0, 0, 62, 0, 0, 0, 10, 0, 0, 0, 251, 0, 0, 0, 11, 0, 0, 0, 247, 0, 0, 0, +54, 0, 0, 0, 177, 0, 0, 0, 91, 0, 0, 0, 218, 0, 0, 0, 112, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 218, 0, 0, 0, 136, 0, 0, 0, 143, 0, 0, 0, 132, 0, 0, 0, 168, 0, 0, 0, 188, 0, 0, 0, 28, 0, 0, 0, 57, 0, 0, 0, 184, 0, 0, 0, 101, 0, 0, 0, 243, 0, 0, 0, 77, 0, 0, 0, 96, 0, 0, 0, 150, 0, 0, 0, 157, 0, 0, 0, 49, 0, 0, 0, 244, 0, 0, 0, 162, 0, 0, 0, 190, 0, 0, 0, 129, 0, 0, 0, 185, 0, 0, 0, 165, 0, 0, 0, 89, 0, 0, 0, 158, 0, 0, 0, 186, 0, 0, 0, 7, 0, 0, 0, 190, 0, 0, 0, 116, 0, 0, 0, 88, 0, 0, +0, 216, 0, 0, 0, 235, 0, 0, 0, 197, 0, 0, 0, 159, 0, 0, 0, 61, 0, 0, 0, 209, 0, 0, 0, 244, 0, 0, 0, 174, 0, 0, 0, 206, 0, 0, 0, 83, 0, 0, 0, 223, 0, 0, 0, 79, 0, 0, 0, 199, 0, 0, 0, 42, 0, 0, 0, 137, 0, 0, 0, 77, 0, 0, 0, 41, 0, 0, 0, 216, 0, 0, 0, 242, 0, 0, 0, 170, 0, 0, 0, 233, 0, 0, 0, 14, 0, 0, 0, 247, 0, 0, 0, 46, 0, 0, 0, 95, 0, 0, 0, 157, 0, 0, 0, 138, 0, 0, 0, 91, 0, 0, 0, 9, 0, 0, 0, 237, 0, 0, 0, 201, 0, 0, 0, 36, 0, 0, 0, 34, 0, 0, 0, 244, 0, 0, 0, 15, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, +0, 28, 0, 0, 0, 132, 0, 0, 0, 110, 0, 0, 0, 52, 0, 0, 0, 20, 0, 0, 0, 108, 0, 0, 0, 234, 0, 0, 0, 179, 0, 0, 0, 134, 0, 0, 0, 93, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 152, 0, 0, 0, 97, 0, 0, 0, 232, 0, 0, 0, 106, 0, 0, 0, 210, 0, 0, 0, 129, 0, 0, 0, 73, 0, 0, 0, 37, 0, 0, 0, 213, 0, 0, 0, 91, 0, 0, 0, 24, 0, 0, 0, 199, 0, 0, 0, 53, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 164, 0, 0, 0, 70, 0, 0, 0, 173, 0, 0, 0, 24, 0, 0, 0, 13, 0, 0, 0, 201, 0, 0, 0, 95, 0, 0, 0, 24, 0, 0, 0, 145, 0, 0, 0, 59, 0, 0, 0, 180, +0, 0, 0, 192, 0, 0, 0, 96, 0, 0, 0, 89, 0, 0, 0, 141, 0, 0, 0, 102, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 121, 0, 0, 0, 83, 0, 0, 0, 110, 0, 0, 0, 36, 0, 0, 0, 174, 0, 0, 0, 87, 0, 0, 0, 217, 0, 0, 0, 88, 0, 0, 0, 9, 0, 0, 0, 133, 0, 0, 0, 72, 0, 0, 0, 162, 0, 0, 0, 211, 0, 0, 0, 181, 0, 0, 0, 226, 0, 0, 0, 77, 0, 0, 0, 17, 0, 0, 0, 130, 0, 0, 0, 230, 0, 0, 0, 134, 0, 0, 0, 60, 0, 0, 0, 233, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 194, 0, 0, 0, 87, 0, 0, 0, 247, 0, 0, 0, 102, 0, 0, 0, 122, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 227, 0, 0, 0, 137, 0, 0, 0, 3, 0, 0, 0, 215, 0, 0, 0, 34, 0, 0, 0, 149, 0, 0, 0, 159, 0, 0, 0, 202, 0, 0, 0, 180, 0, 0, 0, 141, 0, 0, 0, 158, 0, 0, 0, 109, 0, 0, 0, 151, 0, 0, 0, 255, 0, 0, 0, 141, 0, 0, 0, 33, 0, 0, +0, 89, 0, 0, 0, 7, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0, 94, 0, 0, 0, 248, 0, 0, 0, 68, 0, 0, 0, 70, 0, 0, 0, 231, 0, 0, 0, 133, 0, 0, 0, 128, 0, 0, 0, 197, 0, 0, 0, 137, 0, 0, 0, 80, 0, 0, 0, 139, 0, 0, 0, 216, 0, 0, 0, 83, 0, 0, 0, 134, 0, 0, 0, 36, 0, 0, 0, 134, 0, 0, 0, 41, 0, 0, 0, 82, 0, 0, 0, 1, 0, 0, 0, 250, 0, 0, 0, 32, 0, 0, 0, 195, 0, 0, 0, 78, 0, 0, 0, 149, 0, 0, 0, 203, 0, 0, 0, 173, 0, 0, 0, 123, 0, 0, 0, 52, 0, 0, 0, 148, 0, 0, 0, 48, 0, 0, 0, 183, 0, 0, 0, 122, 0, 0, 0, +250, 0, 0, 0, 150, 0, 0, 0, 65, 0, 0, 0, 96, 0, 0, 0, 43, 0, 0, 0, 203, 0, 0, 0, 89, 0, 0, 0, 185, 0, 0, 0, 202, 0, 0, 0, 80, 0, 0, 0, 194, 0, 0, 0, 91, 0, 0, 0, 155, 0, 0, 0, 120, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 0, 58, 0, 0, 0, 136, 0, 0, 0, 148, 0, 0, 0, 95, 0, 0, 0, 10, 0, 0, 0, 155, 0, 0, 0, 152, 0, 0, 0, 43, 0, 0, 0, 110, 0, 0, 0, 83, 0, 0, 0, 17, 0, 0, 0, 246, 0, 0, 0, 255, 0, 0, 0, 198, 0, 0, 0]).concat([125, 0, 0, 0, 66, 0, 0, 0, 204, 0, 0, 0, 2, 0, 0, 0, 128, 0, 0, 0, 64, 0, 0, 0, 13, 0, +0, 0, 30, 0, 0, 0, 251, 0, 0, 0, 175, 0, 0, 0, 97, 0, 0, 0, 7, 0, 0, 0, 176, 0, 0, 0, 230, 0, 0, 0, 47, 0, 0, 0, 129, 0, 0, 0, 112, 0, 0, 0, 161, 0, 0, 0, 46, 0, 0, 0, 57, 0, 0, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 0, 0, 0, 44, 0, 0, 0, 135, 0, 0, 0, 69, 0, 0, 0, 74, 0, 0, 0, 91, 0, 0, 0, 105, 0, 0, 0, 151, 0, 0, 0, 172, 0, 0, 0, 109, 0, 0, 0, 44, 0, 0, 0, 16, 0, 0, 0, 66, 0, 0, 0, 124, 0, 0, 0, 59, 0, 0, 0, 21, 0, 0, 0, 112, 0, 0, 0, 96, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 109, 0, 0, 0, 58, 0, 0, 0, +155, 0, 0, 0, 24, 0, 0, 0, 128, 0, 0, 0, 94, 0, 0, 0, 219, 0, 0, 0, 5, 0, 0, 0, 189, 0, 0, 0, 198, 0, 0, 0, 183, 0, 0, 0, 60, 0, 0, 0, 194, 0, 0, 0, 64, 0, 0, 0, 77, 0, 0, 0, 93, 0, 0, 0, 206, 0, 0, 0, 151, 0, 0, 0, 138, 0, 0, 0, 52, 0, 0, 0, 21, 0, 0, 0, 171, 0, 0, 0, 40, 0, 0, 0, 93, 0, 0, 0, 16, 0, 0, 0, 240, 0, 0, 0, 55, 0, 0, 0, 12, 0, 0, 0, 204, 0, 0, 0, 22, 0, 0, 0, 250, 0, 0, 0, 31, 0, 0, 0, 51, 0, 0, 0, 13, 0, 0, 0, 25, 0, 0, 0, 249, 0, 0, 0, 53, 0, 0, 0, 170, 0, 0, 0, 89, 0, 0, 0, 26, 0, +0, 0, 12, 0, 0, 0, 92, 0, 0, 0, 6, 0, 0, 0, 252, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 151, 0, 0, 0, 83, 0, 0, 0, 54, 0, 0, 0, 252, 0, 0, 0, 42, 0, 0, 0, 165, 0, 0, 0, 90, 0, 0, 0, 155, 0, 0, 0, 48, 0, 0, 0, 239, 0, 0, 0, 35, 0, 0, 0, 175, 0, 0, 0, 57, 0, 0, 0, 93, 0, 0, 0, 154, 0, 0, 0, 107, 0, 0, 0, 117, 0, 0, 0, 87, 0, 0, 0, 72, 0, 0, 0, 11, 0, 0, 0, 38, 0, 0, 0, 220, 0, 0, 0, 118, 0, 0, 0, 59, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, 0, 156, 0, 0, 0, 63, 0, 0, 0, 137, 0, 0, 0, 11, 0, 0, 0, 98, 0, 0, 0, +83, 0, 0, 0, 175, 0, 0, 0, 131, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 188, 0, 0, 0, 106, 0, 0, 0, 198, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 117, 0, 0, 0, 42, 0, 0, 0, 13, 0, 0, 0, 230, 0, 0, 0, 148, 0, 0, 0, 84, 0, 0, 0, 207, 0, 0, 0, 179, 0, 0, 0, 229, 0, 0, 0, 150, 0, 0, 0, 37, 0, 0, 0, 254, 0, 0, 0, 130, 0, 0, 0, 177, 0, 0, 0, 116, 0, 0, 0, 49, 0, 0, 0, 138, 0, 0, 0, 167, 0, 0, 0, 111, 0, 0, 0, 86, 0, 0, 0, 189, 0, 0, 0, 141, 0, 0, 0, 244, 0, 0, 0, 224, 0, 0, 0, 148, 0, 0, 0, 81, 0, 0, 0, 89, 0, 0, 0, +222, 0, 0, 0, 44, 0, 0, 0, 90, 0, 0, 0, 244, 0, 0, 0, 132, 0, 0, 0, 107, 0, 0, 0, 74, 0, 0, 0, 136, 0, 0, 0, 147, 0, 0, 0, 192, 0, 0, 0, 12, 0, 0, 0, 154, 0, 0, 0, 172, 0, 0, 0, 167, 0, 0, 0, 160, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 13, +0, 0, 0, 214, 0, 0, 0, 199, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 0, 16, 0, 0, 0, 173, 0, 0, 0, 199, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 135, 0, 0, 0, 135, 0, 0, 0, 147, 0, 0, 0, 152, 0, 0, 0, 24, 0, 0, 0, 184, 0, 0, 0, 211, 0, 0, 0, 156, 0, 0, 0, 172, 0, 0, 0, 90, 0, 0, 0, 61, 0, 0, 0, 197, 0, 0, 0, 117, 0, 0, 0, 248, 0, 0, 0, 73, 0, 0, 0, 50, 0, 0, 0, 20, 0, 0, 0, 204, 0, 0, 0, 81, 0, 0, 0, 150, 0, 0, 0, 36, 0, 0, 0, 101, 0, 0, 0, 156, 0, 0, 0, 93, 0, 0, 0, 240, 0, 0, 0, 55, 0, 0, 0, 4, 0, 0, 0, 240, 0, +0, 0, 52, 0, 0, 0, 105, 0, 0, 0, 42, 0, 0, 0, 240, 0, 0, 0, 165, 0, 0, 0, 100, 0, 0, 0, 202, 0, 0, 0, 222, 0, 0, 0, 43, 0, 0, 0, 91, 0, 0, 0, 21, 0, 0, 0, 16, 0, 0, 0, 210, 0, 0, 0, 171, 0, 0, 0, 6, 0, 0, 0, 221, 0, 0, 0, 196, 0, 0, 0, 176, 0, 0, 0, 182, 0, 0, 0, 91, 0, 0, 0, 193, 0, 0, 0, 23, 0, 0, 0, 223, 0, 0, 0, 143, 0, 0, 0, 2, 0, 0, 0, 189, 0, 0, 0, 89, 0, 0, 0, 61, 0, 0, 0, 191, 0, 0, 0, 92, 0, 0, 0, 49, 0, 0, 0, 68, 0, 0, 0, 44, 0, 0, 0, 50, 0, 0, 0, 148, 0, 0, 0, 4, 0, 0, 0, 96, 0, 0, 0, +132, 0, 0, 0, 15, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 143, 0, 0, 0, 201, 0, 0, 0, 29, 0, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 162, 0, 0, 0, 73, 0, 0, 0, 14, 0, 0, 0, 80, 0, 0, 0, 145, 0, 0, 0, 8, 0, 0, 0, 154, 0, 0, 0, 67, 0, 0, 0, 85, 0, 0, 0, 5, 0, 0, 0, 93, 0, 0, 0, 147, 0, 0, 0, 85, 0, 0, 0, 223, 0, 0, 0, 155, 0, 0, 0, 18, 0, 0, 0, 25, 0, 0, 0, 236, 0, 0, 0, 147, 0, 0, 0, 133, 0, 0, 0, 66, 0, 0, 0, 158, 0, 0, 0, 102, 0, 0, 0, 15, 0, 0, 0, 157, 0, 0, 0, 175, 0, 0, 0, 153, 0, 0, 0, 175, +0, 0, 0, 38, 0, 0, 0, 137, 0, 0, 0, 188, 0, 0, 0, 97, 0, 0, 0, 253, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 75, 0, 0, 0, 244, 0, 0, 0, 51, 0, 0, 0, 149, 0, 0, 0, 201, 0, 0, 0, 53, 0, 0, 0, 88, 0, 0, 0, 18, 0, 0, 0, 85, 0, 0, 0, 249, 0, 0, 0, 218, 0, 0, 0, 203, 0, 0, 0, 68, 0, 0, 0, 167, 0, 0, 0, 220, 0, 0, 0, 87, 0, 0, 0, 226, 0, 0, 0, 249, 0, 0, 0, 154, 0, 0, 0, 230, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 0, 84, 0, 0, 0, 167, 0, 0, 0, 57, 0, 0, 0, 165, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 86, +0, 0, 0, 110, 0, 0, 0, 170, 0, 0, 0, 139, 0, 0, 0, 143, 0, 0, 0, 176, 0, 0, 0, 44, 0, 0, 0, 135, 0, 0, 0, 175, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0, 76, 0, 0, 0, 178, 0, 0, 0, 18, 0, 0, 0, 248, 0, 0, 0, 50, 0, 0, 0, 168, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 73, 0, 0, 0, 50, 0, 0, 0, 186, 0, 0, 0, 31, 0, 0, 0, 93, 0, 0, 0, 68, 0, 0, 0, 142, 0, 0, 0, 68, 0, 0, 0, 122, 0, 0, 0, 220, 0, 0, 0, 17, 0, 0, 0, 251, 0, 0, 0, 57, 0, 0, 0, 8, 0, 0, 0, 87, 0, 0, 0, 135, 0, 0, 0, 165, 0, +0, 0, 18, 0, 0, 0, 66, 0, 0, 0, 147, 0, 0, 0, 14, 0, 0, 0, 23, 0, 0, 0, 180, 0, 0, 0, 174, 0, 0, 0, 114, 0, 0, 0, 89, 0, 0, 0, 208, 0, 0, 0, 170, 0, 0, 0, 168, 0, 0, 0, 22, 0, 0, 0, 139, 0, 0, 0, 99, 0, 0, 0, 17, 0, 0, 0, 179, 0, 0, 0, 67, 0, 0, 0, 4, 0, 0, 0, 218, 0, 0, 0, 12, 0, 0, 0, 168, 0, 0, 0, 183, 0, 0, 0, 104, 0, 0, 0, 221, 0, 0, 0, 78, 0, 0, 0, 84, 0, 0, 0, 231, 0, 0, 0, 175, 0, 0, 0, 93, 0, 0, 0, 93, 0, 0, 0, 5, 0, 0, 0, 118, 0, 0, 0, 54, 0, 0, 0, 236, 0, 0, 0, 13, 0, 0, 0, 109, 0, 0, +0, 124, 0, 0, 0, 130, 0, 0, 0, 50, 0, 0, 0, 56, 0, 0, 0, 85, 0, 0, 0, 87, 0, 0, 0, 116, 0, 0, 0, 91, 0, 0, 0, 125, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 251, 0, 0, 0, 6, 0, 0, 0, 41, 0, 0, 0, 240, 0, 0, 0, 19, 0, 0, 0, 85, 0, 0, 0, 84, 0, 0, 0, 198, 0, 0, 0, 167, 0, 0, 0, 220, 0, 0, 0, 76, 0, 0, 0, 159, 0, 0, 0, 152, 0, 0, 0, 73, 0, 0, 0, 32, 0, 0, 0, 168, 0, 0, 0, 195, 0, 0, 0, 141, 0, 0, 0, 250, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 71, 0, 0, 0, 157, 0, 0, 0, 233, 0, 0, 0, 37, 0, 0, 0, 213, 0, 0, 0, 227, 0, 0, 0, 71, 0, 0, 0, 120, 0, 0, 0, 223, 0, 0, 0, 133, 0, 0, 0, 167, 0, 0, 0, 133, 0, 0, 0, 94, 0, 0, 0, 122, 0, 0, 0, 76, 0, 0, 0, 95, 0, 0, 0, 121, 0, 0, 0, 26, 0, 0, 0, 243, 0, 0, 0, 162, 0, 0, 0, 178, 0, 0, 0, 40, 0, 0, 0, 160, +0, 0, 0, 156, 0, 0, 0, 221, 0, 0, 0, 48, 0, 0, 0, 64, 0, 0, 0, 212, 0, 0, 0, 56, 0, 0, 0, 189, 0, 0, 0, 40, 0, 0, 0, 252, 0, 0, 0, 187, 0, 0, 0, 213, 0, 0, 0, 120, 0, 0, 0, 109, 0, 0, 0, 29, 0, 0, 0, 212, 0, 0, 0, 153, 0, 0, 0, 180, 0, 0, 0, 170, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 122, 0, 0, 0, 27, 0, 0, 0, 216, 0, 0, 0, 254, 0, 0, 0, 180, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, 0, 204, 0, 0, 0, 231, 0, 0, 0, 196, 0, 0, 0, 211, 0, 0, 0, 58, 0, 0, 0, 115, 0, 0, 0, 131, 0, 0, 0, 65, 0, 0, 0, 92, 0, 0, 0, +64, 0, 0, 0, 215, 0, 0, 0, 45, 0, 0, 0, 85, 0, 0, 0, 38, 0, 0, 0, 225, 0, 0, 0, 123, 0, 0, 0, 95, 0, 0, 0, 229, 0, 0, 0, 220, 0, 0, 0, 63, 0, 0, 0, 125, 0, 0, 0, 161, 0, 0, 0, 167, 0, 0, 0, 38, 0, 0, 0, 68, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 192, 0, 0, 0, 143, 0, 0, 0, 125, 0, 0, 0, 241, 0, 0, 0, 181, 0, 0, 0, 17, 0, 0, 0, 71, 0, 0, 0, 123, 0, 0, 0, 25, 0, 0, 0, 212, 0, 0, 0, 117, 0, 0, 0, 111, 0, 0, 0, 30, 0, 0, 0, 165, 0, 0, 0, 39, 0, 0, 0, 254, 0, 0, 0, 200, 0, 0, 0, 14, 0, 0, 0, 211, 0, 0, 0, +17, 0, 0, 0, 61, 0, 0, 0, 171, 0, 0, 0, 239, 0, 0, 0, 44, 0, 0, 0, 237, 0, 0, 0, 177, 0, 0, 0, 61, 0, 0, 0, 124, 0, 0, 0, 50, 0, 0, 0, 129, 0, 0, 0, 107, 0, 0, 0, 254, 0, 0, 0, 248, 0, 0, 0, 28, 0, 0, 0, 60, 0, 0, 0, 123, 0, 0, 0, 192, 0, 0, 0, 97, 0, 0, 0, 223, 0, 0, 0, 184, 0, 0, 0, 117, 0, 0, 0, 118, 0, 0, 0, 127, 0, 0, 0, 170, 0, 0, 0, 216, 0, 0, 0, 147, 0, 0, 0, 175, 0, 0, 0, 61, 0, 0, 0, 232, 0, 0, 0, 61, 0, 0, 0, 253, 0, 0, 0, 91, 0, 0, 0, 78, 0, 0, 0, 141, 0, 0, 0, 182, 0, 0, 0, 126, 0, 0, +0, 130, 0, 0, 0, 155, 0, 0, 0, 239, 0, 0, 0, 206, 0, 0, 0, 4, 0, 0, 0, 105, 0, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 255, 0, 0, 0, 239, 0, 0, 0, 160, 0, 0, 0, 82, 0, 0, 0, 181, 0, 0, 0, 121, 0, 0, 0, 23, 0, 0, 0, 94, 0, 0, 0, 47, 0, 0, 0, 222, 0, 0, 0, 214, 0, 0, 0, 60, 0, 0, 0, 45, 0, 0, 0, 160, 0, 0, 0, 67, 0, 0, 0, 180, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 192, 0, 0, 0, 97, 0, 0, 0, 72, 0, 0, 0, 72, 0, 0, 0, 23, 0, 0, 0, 244, 0, 0, 0, 158, 0, 0, 0, 24, 0, 0, 0, 81, 0, 0, 0, 45, 0, 0, 0, 234, 0, 0, 0, +47, 0, 0, 0, 242, 0, 0, 0, 242, 0, 0, 0, 224, 0, 0, 0, 163, 0, 0, 0, 20, 0, 0, 0, 183, 0, 0, 0, 139, 0, 0, 0, 58, 0, 0, 0, 48, 0, 0, 0, 245, 0, 0, 0, 129, 0, 0, 0, 193, 0, 0, 0, 93, 0, 0, 0, 113, 0, 0, 0, 57, 0, 0, 0, 98, 0, 0, 0, 85, 0, 0, 0, 31, 0, 0, 0, 96, 0, 0, 0, 90, 0, 0, 0, 229, 0, 0, 0, 137, 0, 0, 0, 138, 0, 0, 0, 118, 0, 0, 0, 108, 0, 0, 0, 219, 0, 0, 0, 77, 0, 0, 0, 10, 0, 0, 0, 91, 0, 0, 0, 114, 0, 0, 0, 157, 0, 0, 0, 89, 0, 0, 0, 110, 0, 0, 0, 99, 0, 0, 0, 99, 0, 0, 0, 24, 0, 0, 0, 124, +0, 0, 0, 227, 0, 0, 0, 250, 0, 0, 0, 226, 0, 0, 0, 219, 0, 0, 0, 161, 0, 0, 0, 141, 0, 0, 0, 244, 0, 0, 0, 165, 0, 0, 0, 215, 0, 0, 0, 22, 0, 0, 0, 178, 0, 0, 0, 208, 0, 0, 0, 179, 0, 0, 0, 63, 0, 0, 0, 57, 0, 0, 0, 206, 0, 0, 0, 96, 0, 0, 0, 9, 0, 0, 0, 108, 0, 0, 0, 245, 0, 0, 0, 118, 0, 0, 0, 23, 0, 0, 0, 36, 0, 0, 0, 128, 0, 0, 0, 58, 0, 0, 0, 150, 0, 0, 0, 199, 0, 0, 0, 148, 0, 0, 0, 46, 0, 0, 0, 247, 0, 0, 0, 107, 0, 0, 0, 239, 0, 0, 0, 181, 0, 0, 0, 5, 0, 0, 0, 150, 0, 0, 0, 239, 0, 0, 0, +211, 0, 0, 0, 123, 0, 0, 0, 81, 0, 0, 0, 218, 0, 0, 0, 5, 0, 0, 0, 68, 0, 0, 0, 103, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 33, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0, 0, 115, 0, 0, 0, 111, 0, 0, 0, 33, 0, 0, 0, 185, 0, 0, 0, 222, 0, 0, 0, 34, 0, +0, 0, 125, 0, 0, 0, 235, 0, 0, 0, 151, 0, 0, 0, 49, 0, 0, 0, 16, 0, 0, 0, 163, 0, 0, 0, 234, 0, 0, 0, 225, 0, 0, 0, 198, 0, 0, 0, 55, 0, 0, 0, 235, 0, 0, 0, 143, 0, 0, 0, 67, 0, 0, 0, 88, 0, 0, 0, 222, 0, 0, 0, 65, 0, 0, 0, 100, 0, 0, 0, 14, 0, 0, 0, 62, 0, 0, 0, 7, 0, 0, 0, 153, 0, 0, 0, 61, 0, 0, 0, 241, 0, 0, 0, 223, 0, 0, 0, 30, 0, 0, 0, 248, 0, 0, 0, 173, 0, 0, 0, 67, 0, 0, 0, 194, 0, 0, 0, 23, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 169, 0, 0, 0, 134, 0, 0, 0, 205, 0, 0, 0, 24, 0, +0, 0, 215, 0, 0, 0, 120, 0, 0, 0, 200, 0, 0, 0, 116, 0, 0, 0, 102, 0, 0, 0, 210, 0, 0, 0, 9, 0, 0, 0, 24, 0, 0, 0, 165, 0, 0, 0, 241, 0, 0, 0, 202, 0, 0, 0, 166, 0, 0, 0, 98, 0, 0, 0, 146, 0, 0, 0, 193, 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 235, 0, 0, 0, 66, 0, 0, 0, 46, 0, 0, 0, 123, 0, 0, 0, 52, 0, 0, 0, 36, 0, 0, 0, 76, 0, 0, 0, 207, 0, 0, 0, 56, 0, 0, 0, 229, 0, 0, 0, 108, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 44, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 36, 0, 0, 0, 56, 0, 0, 0, 173, 0, 0, 0, 36, 0, 0, 0, +126, 0, 0, 0, 25, 0, 0, 0, 240, 0, 0, 0, 108, 0, 0, 0, 249, 0, 0, 0, 49, 0, 0, 0, 244, 0, 0, 0, 53, 0, 0, 0, 17, 0, 0, 0, 246, 0, 0, 0, 70, 0, 0, 0, 51, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 0, 89, 0, 0, 0, 32, 0, 0, 0, 11, 0, 0, 0, 161, 0, 0, 0, 8, 0, 0, 0, 25, 0, 0, 0, 173, 0, 0, 0, 57, 0, 0, 0, 84, 0, 0, 0, 234, 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 182, 0, 0, 0, 226, 0, 0, 0, 210, 0, 0, 0, 188, 0, 0, 0, 77, 0, 0, 0, 252, 0, 0, 0, 156, 0, 0, 0, 240, 0, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 34, 0, +0, 0, 63, 0, 0, 0, 185, 0, 0, 0, 210, 0, 0, 0, 17, 0, 0, 0, 134, 0, 0, 0, 144, 0, 0, 0, 85, 0, 0, 0, 206, 0, 0, 0, 60, 0, 0, 0, 196, 0, 0, 0, 11, 0, 0, 0, 75, 0, 0, 0, 98, 0, 0, 0, 153, 0, 0, 0, 55, 0, 0, 0, 132, 0, 0, 0, 63, 0, 0, 0, 116, 0, 0, 0, 162, 0, 0, 0, 249, 0, 0, 0, 206, 0, 0, 0, 226, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 42, 0, 0, 0, 61, 0, 0, 0, 163, 0, 0, 0, 227, 0, 0, 0, 219, 0, 0, 0, 90, 0, 0, 0, 157, 0, 0, 0, 147, 0, 0, 0, 204, 0, 0, 0, 165, 0, 0, 0, 239, 0, 0, 0, 130, 0, 0, 0, 145, +0, 0, 0, 29, 0, 0, 0, 230, 0, 0, 0, 108, 0, 0, 0, 104, 0, 0, 0, 163, 0, 0, 0, 100, 0, 0, 0, 23, 0, 0, 0, 155, 0, 0, 0, 139, 0, 0, 0, 200, 0, 0, 0, 58, 0, 0, 0, 97, 0, 0, 0, 230, 0, 0, 0, 157, 0, 0, 0, 198, 0, 0, 0, 237, 0, 0, 0, 123, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0, 38, 0, 0, 0, 157, 0, 0, 0, 58, 0, 0, 0, 179, 0, 0, 0, 19, 0, 0, 0, 204, 0, 0, 0, 138, 0, 0, 0, 253, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 29, 0, 0, 0, 237, 0, 0, 0, 19, 0, 0, 0, 208, 0, 0, 0, 85, 0, 0, 0, 87, 0, 0, 0, 14, 0, 0, 0, 26, 0, +0, 0, 234, 0, 0, 0, 191, 0, 0, 0, 253, 0, 0, 0, 74, 0, 0, 0, 60, 0, 0, 0, 142, 0, 0, 0, 236, 0, 0, 0, 41, 0, 0, 0, 126, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 18, 0, 0, 0, 153, 0, 0, 0, 215, 0, 0, 0, 132, 0, 0, 0, 249, 0, 0, 0, 85, 0, 0, 0, 127, 0, 0, 0, 241, 0, 0, 0, 139, 0, 0, 0, 180, 0, 0, 0, 210, 0, 0, 0, 149, 0, 0, 0, 163, 0, 0, 0, 141, 0, 0, 0, 240, 0, 0, 0, 138, 0, 0, 0, 167, 0, 0, 0, 235, 0, 0, 0, 130, 0, 0, 0, 75, 0, 0, 0, 44, 0, 0, 0, 40, 0, 0, 0, 244, 0, 0, 0, 58, 0, 0, 0, 246, 0, 0, 0, +222, 0, 0, 0, 10, 0, 0, 0, 224, 0, 0, 0, 65, 0, 0, 0, 68, 0, 0, 0, 35, 0, 0, 0, 248, 0, 0, 0, 63, 0, 0, 0, 3, 0, 0, 0, 100, 0, 0, 0, 159, 0, 0, 0, 195, 0, 0, 0, 85, 0, 0, 0, 76, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, 148, 0, 0, 0, 28, 0, 0, 0, 36, 0, 0, 0, 93, 0, 0, 0, 95, 0, 0, 0, 146, 0, 0, 0, 69, 0, 0, 0, 150, 0, 0, 0, 87, 0, 0, 0, 55, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 205, 0, 0, 0, 144, 0, 0, 0, 102, 0, 0, 0, 185, 0, 0, 0, 118, 0, 0, 0, 160, 0, 0, 0, 91, 0, 0, 0, 165, 0, 0, 0, 133, 0, 0, 0, 117, 0, 0, 0, 35, 0, 0, 0, 249, 0, 0, 0, 137, 0, 0, 0, 165, 0, 0, 0, 130, 0, 0, 0, 178, 0, 0, 0, 111, 0, 0, 0, 177, 0, 0, 0, 235, 0, 0, 0, 196, 0, 0, 0, 105, 0, 0, 0, 111, 0, 0, 0, 24, 0, 0, 0, 90, 0, 0, 0, 237, 0, 0, 0, 148, 0, 0, 0, 61, +0, 0, 0, 157, 0, 0, 0, 217, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 53, 0, 0, 0, 176, 0, 0, 0, 230, 0, 0, 0, 115, 0, 0, 0, 6, 0, 0, 0, 183, 0, 0, 0, 55, 0, 0, 0, 224, 0, 0, 0, 248, 0, 0, 0, 176, 0, 0, 0, 34, 0, 0, 0, 232, 0, 0, 0, 210, 0, 0, 0, 237, 0, 0, 0, 11, 0, 0, 0, 239, 0, 0, 0, 230, 0, 0, 0, 198, 0, 0, 0, 90, 0, 0, 0, 153, 0, 0, 0, 158, 0, 0, 0, 26, 0, 0, 0, 159, 0, 0, 0, 4, 0, 0, 0, 151, 0, 0, 0, 228, 0, 0, 0, 77, 0, 0, 0, 11, 0, 0, 0, 190, 0, 0, 0, 186, 0, 0, 0, 68, 0, 0, 0, 64, 0, 0, 0, 193, +0, 0, 0, 86, 0, 0, 0, 150, 0, 0, 0, 145, 0, 0, 0, 95, 0, 0, 0, 31, 0, 0, 0, 187, 0, 0, 0, 84, 0, 0, 0, 111, 0, 0, 0, 136, 0, 0, 0, 137, 0, 0, 0, 10, 0, 0, 0, 178, 0, 0, 0, 214, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 106, 0, 0, 0, 130, 0, 0, 0, 238, 0, 0, 0, 20, 0, 0, 0, 170, 0, 0, 0, 118, 0, 0, 0, 48, 0, 0, 0, 101, 0, 0, 0, 15, 0, 0, 0, 103, 0, 0, 0, 57, 0, 0, 0, 166, 0, 0, 0, 81, 0, 0, 0, 124, 0, 0, 0, 73, 0, 0, 0, 36, 0, 0, 0, 53, 0, 0, 0, 163, 0, 0, 0, 120, 0, 0, 0, 209, 0, 0, 0, 17, 0, 0, 0, 15, +0, 0, 0, 117, 0, 0, 0, 211, 0, 0, 0, 112, 0, 0, 0, 70, 0, 0, 0, 219, 0, 0, 0, 32, 0, 0, 0, 81, 0, 0, 0, 203, 0, 0, 0, 146, 0, 0, 0, 128, 0, 0, 0, 84, 0, 0, 0, 16, 0, 0, 0, 116, 0, 0, 0, 54, 0, 0, 0, 134, 0, 0, 0, 169, 0, 0, 0, 215, 0, 0, 0, 163, 0, 0, 0, 8, 0, 0, 0, 120, 0, 0, 0, 241, 0, 0, 0, 1, 0, 0, 0, 41, 0, 0, 0, 248, 0, 0, 0, 128, 0, 0, 0, 59, 0, 0, 0, 219, 0, 0, 0, 167, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 191, 0, 0, 0, 160, 0, 0, 0, 204, 0, 0, 0, 237, 0, 0, 0, 83, 0, 0, 0, 162, 0, 0, 0, 162, +0, 0, 0, 25, 0, 0, 0, 57, 0, 0, 0, 72, 0, 0, 0, 131, 0, 0, 0, 25, 0, 0, 0, 55, 0, 0, 0, 88, 0, 0, 0, 209, 0, 0, 0, 4, 0, 0, 0, 40, 0, 0, 0, 64, 0, 0, 0, 247, 0, 0, 0, 138, 0, 0, 0, 194, 0, 0, 0, 8, 0, 0, 0, 183, 0, 0, 0, 165, 0, 0, 0, 66, 0, 0, 0, 207, 0, 0, 0, 83, 0, 0, 0, 76, 0, 0, 0, 167, 0, 0, 0, 187, 0, 0, 0, 246, 0, 0, 0, 142, 0, 0, 0, 173, 0, 0, 0, 221, 0, 0, 0, 247, 0, 0, 0, 144, 0, 0, 0, 221, 0, 0, 0, 95, 0, 0, 0, 147, 0, 0, 0, 137, 0, 0, 0, 174, 0, 0, 0, 4, 0, 0, 0, 55, 0, 0, 0, 230, 0, +0, 0, 154, 0, 0, 0, 183, 0, 0, 0, 232, 0, 0, 0, 192, 0, 0, 0, 223, 0, 0, 0, 22, 0, 0, 0, 42, 0, 0, 0, 191, 0, 0, 0, 196, 0, 0, 0, 58, 0, 0, 0, 60, 0, 0, 0, 65, 0, 0, 0, 213, 0, 0, 0, 137, 0, 0, 0, 114, 0, 0, 0, 90, 0, 0, 0, 31, 0, 0, 0, 150, 0, 0, 0, 255, 0, 0, 0, 52, 0, 0, 0, 44, 0, 0, 0, 19, 0, 0, 0, 33, 0, 0, 0, 203, 0, 0, 0, 10, 0, 0, 0, 137, 0, 0, 0, 133, 0, 0, 0, 190, 0, 0, 0, 179, 0, 0, 0, 112, 0, 0, 0, 158, 0, 0, 0, 30, 0, 0, 0, 222, 0, 0, 0, 151, 0, 0, 0, 175, 0, 0, 0, 150, 0, 0, 0, 48, +0, 0, 0, 247, 0, 0, 0, 72, 0, 0, 0, 137, 0, 0, 0, 64, 0, 0, 0, 141, 0, 0, 0, 7, 0, 0, 0, 241, 0, 0, 0, 37, 0, 0, 0, 240, 0, 0, 0, 48, 0, 0, 0, 88, 0, 0, 0, 30, 0, 0, 0, 212, 0, 0, 0, 147, 0, 0, 0, 87, 0, 0, 0, 226, 0, 0, 0, 23, 0, 0, 0, 231, 0, 0, 0, 157, 0, 0, 0, 171, 0, 0, 0, 60, 0, 0, 0, 85, 0, 0, 0, 3, 0, 0, 0, 130, 0, 0, 0, 47, 0, 0, 0, 43, 0, 0, 0, 219, 0, 0, 0, 86, 0, 0, 0, 30, 0, 0, 0, 48, 0, 0, 0, 46, 0, 0, 0, 36, 0, 0, 0, 71, 0, 0, 0, 110, 0, 0, 0, 230, 0, 0, 0, 255, 0, 0, 0, 51, 0, 0, +0, 36, 0, 0, 0, 44, 0, 0, 0, 117, 0, 0, 0, 81, 0, 0, 0, 212, 0, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 6, 0, 0, 0, 217, 0, 0, 0, 161, 0, 0, 0, 93, 0, 0, 0, 225, 0, 0, 0, 244, 0, 0, 0, 209, 0, 0, 0, 30, 0, 0, 0, 60, 0, 0, 0, 154, 0, 0, 0, 198, +0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 19, 0, 0, 0, 19, 0, 0, 0, 120, 0, 0, 0, 192, 0, 0, 0, 216, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 45, 0, 0, 0, 158, 0, 0, 0, 169, 0, 0, 0, 201, 0, 0, 0, 121, 0, 0, 0, 87, 0, 0, 0, 171, 0, 0, 0, 36, 0, 0, 0, 145, 0, 0, 0, 146, 0, 0, 0, 25, 0, 0, 0, 105, 0, 0, 0, 251, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 166, 0, 0, 0, 117, 0, 0, 0, 73, 0, 0, 0, 125, 0, 0, 0, 96, 0, 0, 0, 115, 0, 0, 0, 64, 0, 0, 0, 66, 0, 0, 0, 196, 0, 0, 0, 19, 0, 0, 0, 10, 0, 0, 0, 149, 0, 0, 0, 121, +0, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 148, 0, 0, 0, 153, 0, 0, 0, 155, 0, 0, 0, 30, 0, 0, 0, 12, 0, 0, 0, 232, 0, 0, 0, 31, 0, 0, 0, 84, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 192, 0, 0, 0, 82, 0, 0, 0, 20, 0, 0, 0, 137, 0, 0, 0, 115, 0, 0, 0, 161, 0, 0, 0, 55, 0, 0, 0, 135, 0, 0, 0, 106, 0, 0, 0, 122, 0, 0, 0, 207, 0, 0, 0, 29, 0, 0, 0, 217, 0, 0, 0, 46, 0, 0, 0, 26, 0, 0, 0, 103, 0, 0, 0, 237, 0, 0, 0, 116, 0, 0, 0, 192, 0, 0, 0, 240, 0, 0, 0, 156, 0, 0, 0, 51, 0, 0, 0, 221, 0, 0, 0, 223, +0, 0, 0, 8, 0, 0, 0, 191, 0, 0, 0, 123, 0, 0, 0, 209, 0, 0, 0, 102, 0, 0, 0, 218, 0, 0, 0, 230, 0, 0, 0, 201, 0, 0, 0, 73, 0, 0, 0, 8, 0, 0, 0, 233, 0, 0, 0, 221, 0, 0, 0, 94, 0, 0, 0, 85, 0, 0, 0, 176, 0, 0, 0, 10, 0, 0, 0, 222, 0, 0, 0, 33, 0, 0, 0, 76, 0, 0, 0, 90, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 128, 0, 0, 0, 58, 0, 0, 0, 87, 0, 0, 0, 146, 0, 0, 0, 122, 0, 0, 0, 241, 0, 0, 0, 196, 0, 0, 0, 44, 0, 0, 0, 64, 0, 0, 0, 175, 0, 0, 0, 47, 0, 0, 0, 201, 0, 0, 0, 146, 0, 0, 0, 3, 0, 0, 0, 229, 0, +0, 0, 90, 0, 0, 0, 188, 0, 0, 0, 220, 0, 0, 0, 244, 0, 0, 0, 9, 0, 0, 0, 243, 0, 0, 0, 225, 0, 0, 0, 43, 0, 0, 0, 124, 0, 0, 0, 5, 0, 0, 0, 134, 0, 0, 0, 128, 0, 0, 0, 147, 0, 0, 0, 74, 0, 0, 0, 173, 0, 0, 0, 180, 0, 0, 0, 143, 0, 0, 0, 126, 0, 0, 0, 153, 0, 0, 0, 12, 0, 0, 0, 253, 0, 0, 0, 205, 0, 0, 0, 239, 0, 0, 0, 209, 0, 0, 0, 255, 0, 0, 0, 44, 0, 0, 0, 105, 0, 0, 0, 52, 0, 0, 0, 19, 0, 0, 0, 65, 0, 0, 0, 100, 0, 0, 0, 207, 0, 0, 0, 59, 0, 0, 0, 208, 0, 0, 0, 144, 0, 0, 0, 9, 0, 0, 0, 30, 0, +0, 0, 157, 0, 0, 0, 69, 0, 0, 0, 214, 0, 0, 0, 128, 0, 0, 0, 230, 0, 0, 0, 69, 0, 0, 0, 170, 0, 0, 0, 244, 0, 0, 0, 21, 0, 0, 0, 170, 0, 0, 0, 92, 0, 0, 0, 52, 0, 0, 0, 135, 0, 0, 0, 153, 0, 0, 0, 162, 0, 0, 0, 140, 0, 0, 0, 38, 0, 0, 0, 132, 0, 0, 0, 98, 0, 0, 0, 125, 0, 0, 0, 182, 0, 0, 0, 41, 0, 0, 0, 192, 0, 0, 0, 82, 0, 0, 0, 234, 0, 0, 0, 245, 0, 0, 0, 129, 0, 0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 53, 0, 0, 0, 169, 0, 0, 0, 14, 0, 0, 0, 231, 0, 0, 0, 32, 0, 0, 0, 114, 0, 0, 0, 124, 0, 0, 0, 109, +0, 0, 0, 148, 0, 0, 0, 95, 0, 0, 0, 82, 0, 0, 0, 68, 0, 0, 0, 84, 0, 0, 0, 227, 0, 0, 0, 241, 0, 0, 0, 178, 0, 0, 0, 176, 0, 0, 0, 54, 0, 0, 0, 70, 0, 0, 0, 15, 0, 0, 0, 174, 0, 0, 0, 146, 0, 0, 0, 232, 0, 0, 0, 112, 0, 0, 0, 157, 0, 0, 0, 110, 0, 0, 0, 121, 0, 0, 0, 177, 0, 0, 0, 173, 0, 0, 0, 55, 0, 0, 0, 169, 0, 0, 0, 95, 0, 0, 0, 192, 0, 0, 0, 222, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0, 85, 0, 0, 0, 55, 0, 0, 0, 198, 0, 0, 0, 28, 0, 0, 0, 39, 0, 0, 0, 28, 0, 0, 0, 109, 0, 0, 0, 20, 0, 0, 0, 79, 0, +0, 0, 202, 0, 0, 0, 164, 0, 0, 0, 196, 0, 0, 0, 136, 0, 0, 0, 37, 0, 0, 0, 70, 0, 0, 0, 57, 0, 0, 0, 252, 0, 0, 0, 90, 0, 0, 0, 229, 0, 0, 0, 254, 0, 0, 0, 41, 0, 0, 0, 17, 0, 0, 0, 105, 0, 0, 0, 245, 0, 0, 0, 114, 0, 0, 0, 132, 0, 0, 0, 77, 0, 0, 0, 120, 0, 0, 0, 159, 0, 0, 0, 148, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 211, 0, 0, 0, 255, 0, 0, 0, 87, 0, 0, 0, 11, 0, 0, 0, 176, 0, 0, 0, 178, 0, 0, 0, 220, 0, 0, 0, 248, 0, 0, 0, 79, 0, 0, 0, 226, 0, 0, 0, 18, 0, 0, 0, 213, 0, 0, 0, 54, 0, 0, 0, 190, 0, 0, 0, 107, 0, 0, 0, 9, 0, 0, 0, 67, 0, 0, 0, 109, 0, 0, 0, 163, 0, 0, 0, 77, 0, 0, 0, 144, 0, 0, 0, 45, 0, 0, 0, 184, 0, 0, 0, 116, 0, 0, 0, 232, 0, 0, 0, 113, 0, 0, 0, 69, 0, 0, 0, 25, 0, 0, 0, 139, 0, 0, 0, 12, 0, 0, 0, 106, 0, +0, 0, 184, 0, 0, 0, 66, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 173, 0, 0, 0, 44, 0, 0, 0, 3, 0, 0, 0, 142, 0, 0, 0, 172, 0, 0, 0, 215, 0, 0, 0, 152, 0, 0, 0, 41, 0, 0, 0, 19, 0, 0, 0, 198, 0, 0, 0, 2, 0, 0, 0, 41, 0, 0, 0, 181, 0, 0, 0, 212, 0, 0, 0, 231, 0, 0, 0, 207, 0, 0, 0, 204, 0, 0, 0, 139, 0, 0, 0, 131, 0, 0, 0, 236, 0, 0, 0, 53, 0, 0, 0, 199, 0, 0, 0, 156, 0, 0, 0, 116, 0, 0, 0, 183, 0, 0, 0, 173, 0, 0, 0, 133, 0, 0, 0, 95, 0, 0, 0, 120, 0, 0, 0, 132, 0, 0, 0, 225, 0, 0, 0, 86, 0, 0, 0, 69, 0, +0, 0, 105, 0, 0, 0, 104, 0, 0, 0, 90, 0, 0, 0, 79, 0, 0, 0, 184, 0, 0, 0, 177, 0, 0, 0, 41, 0, 0, 0, 255, 0, 0, 0, 51, 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 0, 183, 0, 0, 0, 203, 0, 0, 0, 150, 0, 0, 0, 37, 0, 0, 0, 230, 0, 0, 0, 230, 0, 0, 0, 65, 0, 0, 0, 152, 0, 0, 0, 26, 0, 0, 0, 187, 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 0, 242, 0, 0, 0, 178, 0, 0, 0, 145, 0, 0, 0, 52, 0, 0, 0, 44, 0, 0, 0, 108, 0, 0, 0, 247, 0, 0, 0, 102, 0, 0, 0, 164, 0, 0, 0, 98, 0, 0, 0, 107, 0, 0, 0, 57, 0, 0, 0, 179, 0, 0, 0, 186, 0, +0, 0, 101, 0, 0, 0, 211, 0, 0, 0, 28, 0, 0, 0, 248, 0, 0, 0, 17, 0, 0, 0, 170, 0, 0, 0, 190, 0, 0, 0, 220, 0, 0, 0, 128, 0, 0, 0, 89, 0, 0, 0, 135, 0, 0, 0, 245, 0, 0, 0, 123, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 179, 0, 0, 0, 62, 0, 0, 0, 57, 0, 0, 0, 218, 0, 0, 0, 190, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 139, 0, 0, 0, 241, 0, 0, 0, 160, 0, 0, 0, 245, 0, 0, 0, 220, 0, 0, 0, 41, 0, 0, 0, 180, 0, 0, 0, 226, 0, 0, 0, 7, 0, 0, 0, 198, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 137, 0, 0, 0, 23, +0, 0, 0, 81, 0, 0, 0, 212, 0, 0, 0, 187, 0, 0, 0, 212, 0, 0, 0, 34, 0, 0, 0, 234, 0, 0, 0, 126, 0, 0, 0, 125, 0, 0, 0, 124, 0, 0, 0, 36, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 232, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 149, 0, 0, 0, 6, 0, 0, 0, 218, 0, 0, 0, 124, 0, 0, 0, 164, 0, 0, 0, 12, 0, 0, 0, 244, 0, 0, 0, 186, 0, 0, 0, 110, 0, 0, 0, 225, 0, 0, 0, 137, 0, 0, 0, 181, 0, 0, 0, 89, 0, 0, 0, 202, 0, 0, 0, 241, 0, 0, 0, 192, 0, 0, 0, 41, 0, 0, 0, 54, 0, 0, 0, 9, 0, 0, 0, 68, 0, 0, 0, 226, 0, 0, 0, 127, +0, 0, 0, 209, 0, 0, 0, 99, 0, 0, 0, 21, 0, 0, 0, 153, 0, 0, 0, 234, 0, 0, 0, 37, 0, 0, 0, 207, 0, 0, 0, 12, 0, 0, 0, 157, 0, 0, 0, 192, 0, 0, 0, 68, 0, 0, 0, 111, 0, 0, 0, 29, 0, 0, 0, 134, 0, 0, 0, 78, 0, 0, 0, 207, 0, 0, 0, 247, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, 0, 18, 0, 0, 0, 251, 0, 0, 0, 25, 0, 0, 0, 251, 0, 0, 0, 224, 0, 0, 0, 237, 0, 0, 0, 16, 0, 0, 0, 200, 0, 0, 0, 226, 0, 0, 0, 245, 0, 0, 0, 117, 0, 0, 0, 177, 0, 0, 0, 51, 0, 0, 0, 192, 0, 0, 0, 150, 0, 0, 0, 13, +0, 0, 0, 251, 0, 0, 0, 21, 0, 0, 0, 108, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 95, 0, 0, 0, 5, 0, 0, 0, 105, 0, 0, 0, 62, 0, 0, 0, 71, 0, 0, 0, 151, 0, 0, 0, 44, 0, 0, 0, 175, 0, 0, 0, 82, 0, 0, 0, 124, 0, 0, 0, 120, 0, 0, 0, 131, 0, 0, 0, 173, 0, 0, 0, 27, 0, 0, 0, 57, 0, 0, 0, 130, 0, 0, 0, 47, 0, 0, 0, 2, 0, 0, 0, 111, 0, 0, 0, 71, 0, 0, 0, 219, 0, 0, 0, 42, 0, 0, 0, 176, 0, 0, 0, 225, 0, 0, 0, 145, 0, 0, 0, 153, 0, 0, 0, 85, 0, 0, 0, 184, 0, 0, 0, 153, 0, 0, 0, 58, 0, 0, 0, 160, 0, 0, 0, 68, 0, 0, +0, 17, 0, 0, 0, 81, 0, 0, 0, 163, 120, 89, 19, 202, 77, 235, 117, 171, 216, 65, 65, 77, 10, 112, 0, 152, 232, 121, 119, 121, 64, 199, 140, 115, 254, 111, 43, 238, 108, 3, 82, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 15, 10, 5, 0, 14, 9, 4, 3, 13, 8, 7, 2, 12, 11, 6, 1, 1, 2, 3, 0, 6, 7, 4, 5, 11, 8, 9, 10, 12, 13, 14, 15, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3, 15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0, 3, 3, 3, +3, 7, 7, 7, 7, 11, 11, 11, 11, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 15, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31, 26, 0, 0, 0, 213, 0, 0, 0, 37, 0, 0, 0, 143, 0, 0, 0, 96, 0, 0, 0, 45, 0, 0, 0, 86, 0, 0, 0, 201, 0, 0, 0, 178, 0, 0, 0, 167, 0, 0, 0, 37, 0, 0, 0, 149, 0, 0, 0, 96, 0, 0, 0, 199, 0, 0, 0, 44, 0, 0, 0, 105, 0, 0, 0, 92, 0, 0, 0, 220, 0, 0, 0, 214, 0, 0, 0, 253, 0, 0, 0, 49, 0, 0, 0, 226, +0, 0, 0, 164, 0, 0, 0, 192, 0, 0, 0, 254, 0, 0, 0, 83, 0, 0, 0, 110, 0, 0, 0, 205, 0, 0, 0, 211, 0, 0, 0, 54, 0, 0, 0, 105, 0, 0, 0, 33, 0, 0, 0, 88, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, +0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 102, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 221, 0, 0, 0, +183, 0, 0, 0, 165, 0, 0, 0, 179, 0, 0, 0, 138, 0, 0, 0, 222, 0, 0, 0, 109, 0, 0, 0, 245, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 119, 0, 0, 0, 128, 0, 0, 0, 159, 0, 0, 0, 240, 0, 0, 0, 32, 0, 0, 0, 125, 0, 0, 0, 227, 0, 0, 0, 171, 0, 0, 0, 100, 0, 0, 0, 142, 0, 0, 0, 78, 0, 0, 0, 234, 0, 0, 0, 102, 0, 0, 0, 101, 0, 0, 0, 118, 0, 0, 0, 139, 0, 0, 0, 215, 0, 0, 0, 15, 0, 0, 0, 95, 0, 0, 0, 135, 0, 0, 0, 103, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 97, 109, 98, 105, 103, 117, 111, 117, 115, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 46, 42, 115, 0, 0, 0, 0, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 80, 79, 83, 73, 88, 76, 89, 95, 67, 79, 82, 82, 69, 67, 84, 0, 115, 116, 100, 58, 58, 98, 97, 100, 95, 97, 108, 108, 111, 99, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 37, 115, 10, 0, 0, 0, 0, 0, 37, 115, 10, 0, 0, 0, 0, 0, 105, 110, 32, 117, 115, 101, 32, 98, 121, 116, 101, 115, 32, 32, 32, 32, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, +0, 0, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 98, 97, 100, 95, 97, 114, 114, 97, 121, 95, 110, 101, 119, 95, 108, 101, 110, 103, 116, 104, 0, 0, 0, 0, 58, 32, 0, 0, 0, 0, 0, 0, 58, 32, 0, 0, 0, 0, 0, 0, 115, 121, 115, 116, 101, 109, 32, 98, 121, 116, 101, 115, 32, 32, 32, 32, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, 0, 0, 0, 0, 0, 0, 109, 97, 120, 32, 115, 121, 115, 116, 101, 109, 32, 98, 121, 116, 101, 115, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 120, 181, 1, 0, 6, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 181, 1, 0, 6, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 116, 57, 101, 120, 99, 101, 112, 116, 105, 111, 110, 0, 0, 0, 0, 83, 116, 57, 98, 97, 100, 95, 97, 108, 108, 111, 99, 0, 0, 0, 0, 83, 116, 50, 48, 98, 97, 100, 95, 97, 114, 114, 97, 121, 95, 110, 101, 119, 95, 108, 101, 110, 103, 116, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 181, 1, 0, 0, 0, +0, 0, 64, 181, 1, 0, 112, 181, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 181, 1, 0, 120, 181, 1, 0, 0, 0, 0, 0]), "i8", Na, 8); +var qb = xa(F(12, "i8", E), 8); +v(0 == qb % 8); +r._memset = rb; +r._memcpy = sb; +var tb = {crypto:m}; +function ub(a, b, c) { + c && e({message:"_randombytes count overflow"}); + G.set(tb.crypto.randomBytes(b), a); + return 0 +} +r._randombytes = ub; +var vb = 0; +function M(a) { + return B[vb >> 2] = a +} +var N = {L:1, ca:2, Bd:3, sc:4, I:5, za:6, Jb:7, Sc:8, $:9, Zb:10, ua:11, Ld:11, $a:12, Ya:13, kc:14, ed:15, Wb:16, va:17, Md:18, wa:19, gd:20, aa:21, A:22, Mc:23, Za:24, ld:25, Id:26, lc:27, ad:28, da:29, yd:30, Fc:31, rd:32, hc:33, ab:34, Wc:35, pc:36, $b:37, vc:38, wc:39, xc:40, Ec:41, Jd:42, Qc:43, uc:44, ec:45, Tc:46, Pb:50, Sb:51, Nd:52, Oc:53, Tb:54, Ub:55, fc:56, Vb:57, cd:60, Rc:61, Fd:62, bd:63, Xc:64, Yc:65, xd:66, Uc:67, Mb:68, Cd:69, ac:70, td:71, Hc:74, yc:75, ic:76, Rb:77, mc:79, md:80, +Qb:81, wd:82, zc:83, Ac:84, Dc:85, Cc:86, Bc:87, dd:88, Nc:89, ya:90, Ic:91, ba:92, nd:95, qd:96, dc:104, Pc:105, Nb:106, vd:107, jd:108, Zc:109, zd:110, cc:111, Kb:112, bc:113, Lc:114, Jc:115, Gd:116, nc:117, oc:118, rc:119, Ob:120, gc:121, Gc:122, ud:123, Ad:124, Lb:125, Kc:126, tc:127, fd:128, Hd:129, sd:130, Kd:131, jc:132, Dd:133, kd:134, Vc:135, $c:136, Yb:137, qc:138, od:139, Xb:140, hd:141, pd:142, Ed:143}, wb = {"0":"Success", 1:"Not super-user", 2:"No such file or directory", 3:"No such process", +4:"Interrupted system call", 5:"I/O error", 6:"No such device or address", 7:"Arg list too long", 8:"Exec format error", 9:"Bad file number", 10:"No children", 11:"No more processes", 12:"Not enough core", 13:"Permission denied", 14:"Bad address", 15:"Block device required", 16:"Mount device busy", 17:"File exists", 18:"Cross-device link", 19:"No such device", 20:"Not a directory", 21:"Is a directory", 22:"Invalid argument", 23:"Too many open files in system", 24:"Too many open files", 25:"Not a typewriter", +26:"Text file busy", 27:"File too large", 28:"No space left on device", 29:"Illegal seek", 30:"Read only file system", 31:"Too many links", 32:"Broken pipe", 33:"Math arg out of domain of func", 34:"Math result not representable", 35:"No message of desired type", 36:"Identifier removed", 37:"Channel number out of range", 38:"Level 2 not synchronized", 39:"Level 3 halted", 40:"Level 3 reset", 41:"Link number out of range", 42:"Protocol driver not attached", 43:"No CSI structure available", 44:"Level 2 halted", +45:"Deadlock condition", 46:"No record locks available", 50:"Invalid exchange", 51:"Invalid request descriptor", 52:"Exchange full", 53:"No anode", 54:"Invalid request code", 55:"Invalid slot", 56:"File locking deadlock error", 57:"Bad font file fmt", 60:"Device not a stream", 61:"No data (for no delay io)", 62:"Timer expired", 63:"Out of streams resources", 64:"Machine is not on the network", 65:"Package not installed", 66:"The object is remote", 67:"The link has been severed", 68:"Advertise error", +69:"Srmount error", 70:"Communication error on send", 71:"Protocol error", 74:"Multihop attempted", 75:"Inode is remote (not really error)", 76:"Cross mount point (not really error)", 77:"Trying to read unreadable message", 79:"Inappropriate file type or format", 80:"Given log. name not unique", 81:"f.d. invalid for this operation", 82:"Remote address changed", 83:"Can\t access a needed shared lib", 84:"Accessing a corrupted shared lib", 85:".lib section in a.out corrupted", 86:"Attempting to link in too many libs", +87:"Attempting to exec a shared library", 88:"Function not implemented", 89:"No more files", 90:"Directory not empty", 91:"File or path name too long", 92:"Too many symbolic links", 95:"Operation not supported on transport endpoint", 96:"Protocol family not supported", 104:"Connection reset by peer", 105:"No buffer space available", 106:"Address family not supported by protocol family", 107:"Protocol wrong type for socket", 108:"Socket operation on non-socket", 109:"Protocol not available", 110:"Can't send after socket shutdown", +111:"Connection refused", 112:"Address already in use", 113:"Connection aborted", 114:"Network is unreachable", 115:"Network interface is not configured", 116:"Connection timed out", 117:"Host is down", 118:"Host is unreachable", 119:"Connection already in progress", 120:"Socket already connected", 121:"Destination address required", 122:"Message too long", 123:"Unknown protocol", 124:"Socket type not supported", 125:"Address not available", 126:"ENETRESET", 127:"Socket is already connected", 128:"Socket is not connected", +129:"TOOMANYREFS", 130:"EPROCLIM", 131:"EUSERS", 132:"EDQUOT", 133:"ESTALE", 134:"Not supported", 135:"No medium (in tape drive)", 136:"No such host or network path", 137:"Filename exists with different case", 138:"EILSEQ", 139:"Value too large for defined data type", 140:"Operation canceled", 141:"State not recoverable", 142:"Previous owner died", 143:"Streams pipe error"}; +function xb(a, b, c) { + var d = O(a, {parent:l}).d, a = "/" === a ? "/" : yb(a)[2], f = zb(d, a); + f && e(new Q(f)); + d.l.Ta || e(new Q(N.L)); + return d.l.Ta(d, a, b, c) +} +function Ab(a, b) { + b = b & 4095 | 32768; + return xb(a, b, 0) +} +function Bb(a, b) { + b = b & 1023 | 16384; + return xb(a, b, 0) +} +function Cb(a, b, c) { + return xb(a, b | 8192, c) +} +function Db(a, b) { + var c = O(b, {parent:l}).d, d = "/" === b ? "/" : yb(b)[2], f = zb(c, d); + f && e(new Q(f)); + c.l.Wa || e(new Q(N.L)); + return c.l.Wa(c, d, a) +} +function Eb(a, b) { + var c; + c = "string" === typeof a ? O(a, {N:l}).d : a; + c.l.Y || e(new Q(N.L)); + c.l.Y(c, {mode:b & 4095 | c.mode & -4096, timestamp:Date.now()}) +} +function Fb(a, b) { + var c, a = Gb(a), d; + "string" === typeof b ? (d = Hb[b], "undefined" === typeof d && e(Error("Unknown file open mode: " + b))) : d = b; + b = d; + c = b & 512 ? c & 4095 | 32768 : 0; + var f; + try { + var g = O(a, {N:!(b & 65536)}); + f = g.d; + a = g.path + }catch(h) { + } + b & 512 && (f ? b & 2048 && e(new Q(N.va)) : f = xb(a, c, 0)); + f || e(new Q(N.ca)); + 8192 === (f.mode & 61440) && (b &= -1025); + f ? 40960 === (f.mode & 61440) ? c = N.ba : 16384 === (f.mode & 61440) && (0 !== (b & 3) || b & 1024) ? c = N.aa : (c = ["r", "w", "rw"][b & 3], b & 1024 && (c += "w"), c = Ib(f, c)) : c = N.ca; + c && e(new Q(c)); + b & 1024 && (c = f, c = "string" === typeof c ? O(c, {N:l}).d : c, c.l.Y || e(new Q(N.L)), 16384 === (c.mode & 61440) && e(new Q(N.aa)), 32768 !== (c.mode & 61440) && e(new Q(N.A)), (g = Ib(c, "w")) && e(new Q(g)), c.l.Y(c, {size:0, timestamp:Date.now()})); + var i = {path:a, d:f, M:b, seekable:l, position:0, e:f.e, Gb:[], error:n}, j; + a: { + f = k || 4096; + for(c = k || 1;c <= f;c++) { + if(!R[c]) { + j = c; + break a + } + } + e(new Q(N.Za)) + } + i.s = j; + Object.defineProperty(i, "object", {get:function() { + return i.d + }, set:function(a) { + i.d = a + }}); + Object.defineProperty(i, "isRead", {get:function() { + return 1 !== (i.M & 3) + }}); + Object.defineProperty(i, "isWrite", {get:function() { + return 0 !== (i.M & 3) + }}); + Object.defineProperty(i, "isAppend", {get:function() { + return i.M & 8 + }}); + R[j] = i; + i.e.open && i.e.open(i); + return i +} +function Jb(a) { + try { + a.e.close && a.e.close(a) + }catch(b) { + e(b) + }finally { + R[a.s] = m + } +} +function Kb(a, b, c, d, f) { + (0 > d || 0 > f) && e(new Q(N.A)); + 0 === (a.M & 3) && e(new Q(N.$)); + 16384 === (a.d.mode & 61440) && e(new Q(N.aa)); + a.e.write || e(new Q(N.A)); + var g = l; + "undefined" === typeof f ? (f = a.position, g = n) : a.seekable || e(new Q(N.da)); + a.M & 8 && ((!a.seekable || !a.e.na) && e(new Q(N.da)), a.e.na(a, 0, 2)); + b = a.e.write(a, b, c, d, f); + g || (a.position += b); + return b +} +function yb(a) { + return/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1) +} +function Lb(a, b) { + for(var c = 0, d = a.length - 1;0 <= d;d--) { + var f = a[d]; + "." === f ? a.splice(d, 1) : ".." === f ? (a.splice(d, 1), c++) : c && (a.splice(d, 1), c--) + } + if(b) { + for(;c--;c) { + a.unshift("..") + } + } + return a +} +function Gb(a) { + var b = "/" === a.charAt(0), c = "/" === a.substr(-1), a = Lb(a.split("/").filter(function(a) { + return!!a + }), !b).join("/"); + !a && !b && (a = "."); + a && c && (a += "/"); + return(b ? "/" : "") + a +} +function S() { + var a = Array.prototype.slice.call(arguments, 0); + return Gb(a.filter(function(a) { + "string" !== typeof a && e(new TypeError("Arguments to path.join must be strings")); + return a + }).join("/")) +} +function Mb() { + for(var a = "", b = n, c = arguments.length - 1;-1 <= c && !b;c--) { + var d = 0 <= c ? arguments[c] : "/"; + "string" !== typeof d && e(new TypeError("Arguments to path.resolve must be strings")); + d && (a = d + "/" + a, b = "/" === d.charAt(0)) + } + a = Lb(a.split("/").filter(function(a) { + return!!a + }), !b).join("/"); + return(b ? "/" : "") + a || "." +} +var Nb = []; +function Ob(a, b) { + Nb[a] = {input:[], H:[], O:b}; + Pb[a] = {e:Qb} +} +var Qb = {open:function(a) { + Rb || (Rb = new pa); + var b = Nb[a.d.X]; + b || e(new Q(N.wa)); + a.q = b; + a.seekable = n +}, close:function(a) { + a.q.H.length && a.q.O.W(a.q, 10) +}, Q:function(a, b, c, d) { + (!a.q || !a.q.O.Na) && e(new Q(N.za)); + for(var f = 0, g = 0;g < d;g++) { + var h; + try { + h = a.q.O.Na(a.q) + }catch(i) { + e(new Q(N.I)) + } + h === k && 0 === f && e(new Q(N.ua)); + if(h === m || h === k) { + break + } + f++; + b[c + g] = h + } + f && (a.d.timestamp = Date.now()); + return f +}, write:function(a, b, c, d) { + (!a.q || !a.q.O.W) && e(new Q(N.za)); + for(var f = 0;f < d;f++) { + try { + a.q.O.W(a.q, b[c + f]) + }catch(g) { + e(new Q(N.I)) + } + } + d && (a.d.timestamp = Date.now()); + return f +}}, Rb, T = {z:function() { + return T.ka(m, "/", 16895, 0) +}, ka:function(a, b, c, d) { + (24576 === (c & 61440) || 4096 === (c & 61440)) && e(new Q(N.L)); + c = Sb(a, b, c, d); + c.l = T.l; + 16384 === (c.mode & 61440) ? (c.e = T.e, c.g = {}) : 32768 === (c.mode & 61440) ? (c.e = T.e, c.g = []) : 40960 === (c.mode & 61440) ? c.e = T.e : 8192 === (c.mode & 61440) && (c.e = Tb); + c.timestamp = Date.now(); + a && (a.g[b] = c); + return c +}, l:{ge:function(a) { + var b = {}; + b.ce = 8192 === (a.mode & 61440) ? a.id : 1; + b.je = a.id; + b.mode = a.mode; + b.pe = 1; + b.uid = 0; + b.he = 0; + b.X = a.X; + b.size = 16384 === (a.mode & 61440) ? 4096 : 32768 === (a.mode & 61440) ? a.g.length : 40960 === (a.mode & 61440) ? a.link.length : 0; + b.Yd = new Date(a.timestamp); + b.oe = new Date(a.timestamp); + b.ae = new Date(a.timestamp); + b.ib = 4096; + b.Zd = Math.ceil(b.size / b.ib); + return b +}, Y:function(a, b) { + b.mode !== k && (a.mode = b.mode); + b.timestamp !== k && (a.timestamp = b.timestamp); + if(b.size !== k) { + var c = a.g; + if(b.size < c.length) { + c.length = b.size + }else { + for(;b.size > c.length;) { + c.push(0) + } + } + } +}, tb:function() { + e(new Q(N.ca)) +}, Ta:function(a, b, c, d) { + return T.ka(a, b, c, d) +}, rename:function(a, b, c) { + if(16384 === (a.mode & 61440)) { + var d; + try { + d = Ub(b, c) + }catch(f) { + } + if(d) { + for(var g in d.g) { + e(new Q(N.ya)) + } + } + } + delete a.parent.g[a.name]; + a.name = c; + b.g[c] = a +}, ze:function(a, b) { + delete a.g[b] +}, ve:function(a, b) { + var c = Ub(a, b), d; + for(d in c.g) { + e(new Q(N.ya)) + } + delete a.g[b] +}, Wa:function(a, b, c) { + a = T.ka(a, b, 41471, 0); + a.link = c; + return a +}, Va:function(a) { + 40960 !== (a.mode & 61440) && e(new Q(N.A)); + return a.link +}}, e:{open:function(a) { + if(16384 === (a.d.mode & 61440)) { + var b = [".", ".."], c; + for(c in a.d.g) { + a.d.g.hasOwnProperty(c) && b.push(c) + } + a.lb = b + } +}, Q:function(a, b, c, d, f) { + a = a.d.g; + d = Math.min(a.length - f, d); + if(a.subarray) { + b.set(a.subarray(f, f + d), c) + }else { + for(var g = 0;g < d;g++) { + b[c + g] = a[f + g] + } + } + return d +}, write:function(a, b, c, d, f) { + for(var g = a.d.g;g.length < f;) { + g.push(0) + } + for(var h = 0;h < d;h++) { + g[f + h] = b[c + h] + } + a.d.timestamp = Date.now(); + return d +}, na:function(a, b, c) { + 1 === c ? b += a.position : 2 === c && 32768 === (a.d.mode & 61440) && (b += a.d.g.length); + 0 > b && e(new Q(N.A)); + a.Gb = []; + return a.position = b +}, ue:function(a) { + return a.lb +}, Wd:function(a, b, c) { + a = a.d.g; + for(b += c;b > a.length;) { + a.push(0) + } +}, ne:function(a, b, c, d, f, g, h) { + 32768 !== (a.d.mode & 61440) && e(new Q(N.wa)); + a = a.d.g; + if(h & 2) { + if(0 < f || f + d < a.length) { + a = a.subarray ? a.subarray(f, f + d) : Array.prototype.slice.call(a, f, f + d) + } + f = l; + (d = Oa(d)) || e(new Q(N.$a)); + b.set(a, d) + }else { + v(a.buffer === b || a.buffer === b.buffer), f = n, d = a.byteOffset + } + return{te:d, Xd:f} +}}}, Vb = F(1, "i32*", E), Wb = F(1, "i32*", E); +nb = F(1, "i32*", E); +var Xb = m, Pb = [m], R = [m], Yb = 1, Zb = [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ], $b = l; +function Q(a) { + this.mb = a; + for(var b in N) { + if(N[b] === a) { + this.code = b; + break + } + } + this.message = wb[a] +} +function ac(a) { + a instanceof Q || e(a + " : " + Error().stack); + M(a.mb) +} +function bc(a, b) { + for(var c = 0, d = 0;d < b.length;d++) { + c = (c << 5) - c + b.charCodeAt(d) | 0 + } + return(a + c) % Zb.length +} +function Ub(a, b) { + var c = Ib(a, "x"); + c && e(new Q(c)); + for(c = Zb[bc(a.id, b)];c;c = c.wb) { + if(c.parent.id === a.id && c.name === b) { + return c + } + } + return a.l.tb(a, b) +} +function Sb(a, b, c, d) { + var f = {id:Yb++, name:b, mode:c, l:{}, e:{}, X:d, parent:m, z:m}; + a || (a = f); + f.parent = a; + f.z = a.z; + Object.defineProperty(f, "read", {get:function() { + return 365 === (f.mode & 365) + }, set:function(a) { + a ? f.mode |= 365 : f.mode &= -366 + }}); + Object.defineProperty(f, "write", {get:function() { + return 146 === (f.mode & 146) + }, set:function(a) { + a ? f.mode |= 146 : f.mode &= -147 + }}); + a = bc(f.parent.id, f.name); + f.wb = Zb[a]; + return Zb[a] = f +} +function O(a, b) { + a = Mb("/", a); + b = b || {pa:0}; + 8 < b.pa && e(new Q(N.ba)); + for(var c = Lb(a.split("/").filter(function(a) { + return!!a + }), n), d = Xb, f = "/", g = 0;g < c.length;g++) { + var h = g === c.length - 1; + if(h && b.parent) { + break + } + d = Ub(d, c[g]); + f = S(f, c[g]); + d.ub && (d = d.z.root); + if(!h || b.N) { + for(h = 0;40960 === (d.mode & 61440);) { + d = O(f, {N:n}).d; + d.l.Va || e(new Q(N.A)); + var d = d.l.Va(d), i = Mb; + var j = yb(f), f = j[0], j = j[1]; + !f && !j ? f = "." : (j && (j = j.substr(0, j.length - 1)), f += j); + f = i(f, d); + d = O(f, {pa:b.pa}).d; + 40 < h++ && e(new Q(N.ba)) + } + } + } + return{path:f, d:d} +} +function cc(a) { + for(var b;;) { + if(a === a.parent) { + return b ? S(a.z.Ua, b) : a.z.Ua + } + b = b ? S(a.name, b) : a.name; + a = a.parent + } +} +var Hb = {r:0, rs:8192, "r+":2, w:1537, wx:3585, xw:3585, "w+":1538, "wx+":3586, "xw+":3586, a:521, ax:2569, xa:2569, "a+":522, "ax+":2570, "xa+":2570}; +function Ib(a, b) { + return $b ? 0 : -1 !== b.indexOf("r") && !(a.mode & 292) || -1 !== b.indexOf("w") && !(a.mode & 146) || -1 !== b.indexOf("x") && !(a.mode & 73) ? N.Ya : 0 +} +function zb(a, b) { + try { + return Ub(a, b), N.va + }catch(c) { + } + return Ib(a, "wx") +} +var Tb = {open:function(a) { + a.e = Pb[a.d.X].e; + a.e.open && a.e.open(a) +}, na:function() { + e(new Q(N.da)) +}}, dc; +function ec(a, b) { + var c = 0; + a && (c |= 365); + b && (c |= 146); + return c +} +function fc(a, b, c, d, f) { + a = S("string" === typeof a ? a : cc(a), b); + d = ec(d, f); + f = Ab(a, d); + if(c) { + if("string" === typeof c) { + for(var b = Array(c.length), g = 0, h = c.length;g < h;++g) { + b[g] = c.charCodeAt(g) + } + c = b + } + Eb(a, d | 146); + b = Fb(a, "w"); + Kb(b, c, 0, c.length, 0); + Jb(b); + Eb(a, d) + } + return f +} +function gc(a, b, c, d) { + a = S("string" === typeof a ? a : cc(a), b); + gc.Sa || (gc.Sa = 64); + b = gc.Sa++ << 8 | 0; + Pb[b] = {e:{open:function(a) { + a.seekable = n + }, close:function() { + d && (d.buffer && d.buffer.length) && d(10) + }, Q:function(a, b, d, i) { + for(var j = 0, p = 0;p < i;p++) { + var z; + try { + z = c() + }catch(w) { + e(new Q(N.I)) + } + z === k && 0 === j && e(new Q(N.ua)); + if(z === m || z === k) { + break + } + j++; + b[d + p] = z + } + j && (a.d.timestamp = Date.now()); + return j + }, write:function(a, b, c, i) { + for(var j = 0;j < i;j++) { + try { + d(b[c + j]) + }catch(p) { + e(new Q(N.I)) + } + } + i && (a.d.timestamp = Date.now()); + return j + }}}; + return Cb(a, c && d ? 511 : c ? 219 : 365, b) +} +function hc(a, b, c) { + a = R[a]; + if(!a) { + return-1 + } + a.sender(G.subarray(b, b + c)); + return c +} +function ic(a, b, c) { + var d = R[a]; + if(!d) { + return M(N.$), -1 + } + if(d && "socket" in d) { + return hc(a, b, c) + } + try { + return Kb(d, A, b, c) + }catch(f) { + return ac(f), -1 + } +} +function jc(a, b, c, d) { + c *= b; + if(0 == c) { + return 0 + } + a = ic(d, a, c); + if(-1 == a) { + if(b = R[d]) { + b.error = l + } + return 0 + } + return Math.floor(a / b) +} +r._strlen = kc; +function lc(a) { + return 0 > a || 0 === a && -Infinity === 1 / a +} +function mc(a, b) { + function c(a) { + var c; + "double" === a ? c = Ja[b + f >> 3] : "i64" == a ? (c = [B[b + f >> 2], B[b + (f + 8) >> 2]], f += 8) : (a = "i32", c = B[b + f >> 2]); + f += Math.max(Math.max(la(a), ma), 8); + return c + } + for(var d = a, f = 0, g = [], h, i;;) { + var j = d; + h = A[d]; + if(0 === h) { + break + } + i = A[d + 1 | 0]; + if(37 == h) { + var p = n, z = n, w = n, C = n; + a:for(;;) { + switch(i) { + case 43: + p = l; + break; + case 45: + z = l; + break; + case 35: + w = l; + break; + case 48: + if(C) { + break a + }else { + C = l; + break + } + ; + default: + break a + } + d++; + i = A[d + 1 | 0] + } + var D = 0; + if(42 == i) { + D = c("i32"), d++, i = A[d + 1 | 0] + }else { + for(;48 <= i && 57 >= i;) { + D = 10 * D + (i - 48), d++, i = A[d + 1 | 0] + } + } + var L = n; + if(46 == i) { + var H = 0, L = l; + d++; + i = A[d + 1 | 0]; + if(42 == i) { + H = c("i32"), d++ + }else { + for(;;) { + i = A[d + 1 | 0]; + if(48 > i || 57 < i) { + break + } + H = 10 * H + (i - 48); + d++ + } + } + i = A[d + 1 | 0] + }else { + H = 6 + } + var y; + switch(String.fromCharCode(i)) { + case "h": + i = A[d + 2 | 0]; + 104 == i ? (d++, y = 1) : y = 2; + break; + case "l": + i = A[d + 2 | 0]; + 108 == i ? (d++, y = 8) : y = 4; + break; + case "L": + ; + case "q": + ; + case "j": + y = 8; + break; + case "z": + ; + case "t": + ; + case "I": + y = 4; + break; + default: + y = m + } + y && d++; + i = A[d + 1 | 0]; + switch(String.fromCharCode(i)) { + case "d": + ; + case "i": + ; + case "u": + ; + case "o": + ; + case "x": + ; + case "X": + ; + case "p": + j = 100 == i || 105 == i; + y = y || 4; + var P = h = c("i" + 8 * y), s; + 8 == y && (h = 117 == i ? +(h[0] >>> 0) + 4294967296 * +(h[1] >>> 0) : +(h[0] >>> 0) + 4294967296 * +(h[1] | 0)); + 4 >= y && (h = (j ? eb : db)(h & Math.pow(256, y) - 1, 8 * y)); + var ta = Math.abs(h), j = ""; + if(100 == i || 105 == i) { + s = 8 == y && nc ? nc.stringify(P[0], P[1], m) : eb(h, 8 * y).toString(10) + }else { + if(117 == i) { + s = 8 == y && nc ? nc.stringify(P[0], P[1], l) : db(h, 8 * y).toString(10), h = Math.abs(h) + }else { + if(111 == i) { + s = (w ? "0" : "") + ta.toString(8) + }else { + if(120 == i || 88 == i) { + j = w && 0 != h ? "0x" : ""; + if(8 == y && nc) { + if(P[1]) { + s = (P[1] >>> 0).toString(16); + for(w = (P[0] >>> 0).toString(16);8 > w.length;) { + w = "0" + w + } + s += w + }else { + s = (P[0] >>> 0).toString(16) + } + }else { + if(0 > h) { + h = -h; + s = (ta - 1).toString(16); + P = []; + for(w = 0;w < s.length;w++) { + P.push((15 - parseInt(s[w], 16)).toString(16)) + } + for(s = P.join("");s.length < 2 * y;) { + s = "f" + s + } + }else { + s = ta.toString(16) + } + } + 88 == i && (j = j.toUpperCase(), s = s.toUpperCase()) + }else { + 112 == i && (0 === ta ? s = "(nil)" : (j = "0x", s = ta.toString(16))) + } + } + } + } + if(L) { + for(;s.length < H;) { + s = "0" + s + } + } + for(p && (j = 0 > h ? "-" + j : "+" + j);j.length + s.length < D;) { + z ? s += " " : C ? s = "0" + s : j = " " + j + } + s = j + s; + s.split("").forEach(function(a) { + g.push(a.charCodeAt(0)) + }); + break; + case "f": + ; + case "F": + ; + case "e": + ; + case "E": + ; + case "g": + ; + case "G": + h = c("double"); + if(isNaN(h)) { + s = "nan", C = n + }else { + if(isFinite(h)) { + L = n; + y = Math.min(H, 20); + if(103 == i || 71 == i) { + L = l, H = H || 1, y = parseInt(h.toExponential(y).split("e")[1], 10), H > y && -4 <= y ? (i = (103 == i ? "f" : "F").charCodeAt(0), H -= y + 1) : (i = (103 == i ? "e" : "E").charCodeAt(0), H--), y = Math.min(H, 20) + } + if(101 == i || 69 == i) { + s = h.toExponential(y), /[eE][-+]\d$/.test(s) && (s = s.slice(0, -1) + "0" + s.slice(-1)) + }else { + if(102 == i || 70 == i) { + s = h.toFixed(y), 0 === h && lc(h) && (s = "-" + s) + } + } + j = s.split("e"); + if(L && !w) { + for(;1 < j[0].length && -1 != j[0].indexOf(".") && ("0" == j[0].slice(-1) || "." == j[0].slice(-1));) { + j[0] = j[0].slice(0, -1) + } + }else { + for(w && -1 == s.indexOf(".") && (j[0] += ".");H > y++;) { + j[0] += "0" + } + } + s = j[0] + (1 < j.length ? "e" + j[1] : ""); + 69 == i && (s = s.toUpperCase()); + p && 0 <= h && (s = "+" + s) + }else { + s = (0 > h ? "-" : "") + "inf", C = n + } + } + for(;s.length < D;) { + s = z ? s + " " : C && ("-" == s[0] || "+" == s[0]) ? s[0] + "0" + s.slice(1) : (C ? "0" : " ") + s + } + 97 > i && (s = s.toUpperCase()); + s.split("").forEach(function(a) { + g.push(a.charCodeAt(0)) + }); + break; + case "s": + C = (p = c("i8*")) ? kc(p) : 6; + L && (C = Math.min(C, H)); + if(!z) { + for(;C < D--;) { + g.push(32) + } + } + if(p) { + for(w = 0;w < C;w++) { + g.push(G[p++ | 0]) + } + }else { + g = g.concat(J("(null)".substr(0, C), l)) + } + if(z) { + for(;C < D--;) { + g.push(32) + } + } + break; + case "c": + for(z && g.push(c("i8"));0 < --D;) { + g.push(32) + } + z || g.push(c("i8")); + break; + case "n": + z = c("i32*"); + B[z >> 2] = g.length; + break; + case "%": + g.push(h); + break; + default: + for(w = j;w < d + 2;w++) { + g.push(A[w]) + } + } + d += 2 + }else { + g.push(h), d += 1 + } + } + return g +} +function oc(a, b, c) { + c = mc(b, c); + b = ja(); + a = jc(F(c, "i8", La), 1, c.length, a); + ka(b); + return a +} +function pc(a) { + pc.ia || (x = x + 4095 >> 12 << 12, pc.ia = l, v(ua), pc.hb = ua, ua = function() { + wa("cannot dynamically allocate, sbrk now has control") + }); + var b = x; + 0 != a && pc.hb(a); + return b +} +function U() { + return B[U.m >> 2] +} +function qc() { + return!!qc.ta +} +function rc(a) { + var b = n; + try { + a == __ZTIi && (b = l) + }catch(c) { + } + try { + a == __ZTIj && (b = l) + }catch(d) { + } + try { + a == __ZTIl && (b = l) + }catch(f) { + } + try { + a == __ZTIm && (b = l) + }catch(g) { + } + try { + a == __ZTIx && (b = l) + }catch(h) { + } + try { + a == __ZTIy && (b = l) + }catch(i) { + } + try { + a == __ZTIf && (b = l) + }catch(j) { + } + try { + a == __ZTId && (b = l) + }catch(p) { + } + try { + a == __ZTIe && (b = l) + }catch(z) { + } + try { + a == __ZTIc && (b = l) + }catch(w) { + } + try { + a == __ZTIa && (b = l) + }catch(C) { + } + try { + a == __ZTIh && (b = l) + }catch(D) { + } + try { + a == __ZTIs && (b = l) + }catch(L) { + } + try { + a == __ZTIt && (b = l) + }catch(H) { + } + return b +} +function sc(a, b, c) { + if(0 == c) { + return n + } + if(0 == b || b == a) { + return l + } + switch(rc(b) ? b : B[B[b >> 2] - 8 >> 2]) { + case 0: + return 0 == B[B[a >> 2] - 8 >> 2] ? sc(B[a + 8 >> 2], B[b + 8 >> 2], c) : n; + case 1: + return n; + case 2: + return sc(a, B[b + 8 >> 2], c); + default: + return n + } +} +function tc(a, b, c) { + if(!tc.sb) { + try { + B[__ZTVN10__cxxabiv119__pointer_type_infoE >> 2] = 0 + }catch(d) { + } + try { + B[pb >> 2] = 1 + }catch(f) { + } + try { + B[ob >> 2] = 2 + }catch(g) { + } + tc.sb = l + } + B[U.m >> 2] = a; + B[U.m + 4 >> 2] = b; + B[U.m + 8 >> 2] = c; + "uncaught_exception" in qc ? qc.ta++ : qc.ta = 1; + e(a + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.") +} +function uc(a) { + try { + return vc(a) + }catch(b) { + } +} +function wc() { + if(wc.Bb) { + wc.Bb = n + }else { + V.setThrew(0); + B[U.m + 4 >> 2] = 0; + var a = B[U.m >> 2], b = B[U.m + 8 >> 2]; + b && (na("vi", b, [a]), B[U.m + 8 >> 2] = 0); + a && (uc(a), B[U.m >> 2] = 0) + } +} +var xc = F(1, "i32*", E); +function yc(a) { + var b, c; + yc.ia ? (c = B[xc >> 2], b = B[c >> 2]) : (yc.ia = l, W.USER = "root", W.PATH = "/", W.PWD = "/", W.HOME = "/home/emscripten", W.LANG = "en_US.UTF-8", W._ = "./this.program", b = F(1024, "i8", E), c = F(256, "i8*", E), B[c >> 2] = b, B[xc >> 2] = c); + var d = [], f = 0, g; + for(g in a) { + if("string" === typeof a[g]) { + var h = g + "=" + a[g]; + d.push(h); + f += h.length + } + } + 1024 < f && e(Error("Environment size exceeded TOTAL_ENV_SIZE!")); + for(a = 0;a < d.length;a++) { + h = d[a]; + for(f = 0;f < h.length;f++) { + A[b + f | 0] = h.charCodeAt(f) + } + A[b + f | 0] = 0; + B[c + 4 * a >> 2] = b; + b += h.length + 1 + } + B[c + 4 * d.length >> 2] = 0 +} +var W = {}; +function zc(a) { + if(0 === a) { + return 0 + } + a = Fa(a); + if(!W.hasOwnProperty(a)) { + return 0 + } + zc.J && vc(zc.J); + zc.J = F(J(W[a]), "i8", Ka); + return zc.J +} +function Ac(a, b, c) { + if(a in wb) { + if(wb[a].length > c - 1) { + return M(N.ab) + } + a = wb[a]; + for(c = 0;c < a.length;c++) { + A[b + c | 0] = a.charCodeAt(c) + } + return A[b + c | 0] = 0 + } + return M(N.A) +} +function Bc(a) { + Bc.buffer || (Bc.buffer = Oa(256)); + Ac(a, Bc.buffer, 256); + return Bc.buffer +} +function Cc(a) { + r.exit(a) +} +function Dc(a, b) { + var c = db(a & 255); + A[Dc.J | 0] = c; + if(-1 == ic(b, Dc.J, 1)) { + if(c = R[b]) { + c.error = l + } + return-1 + } + return c +} +var Ec = n, Fc = n, Gc = n, Hc = n, Ic = k, Jc = k; +function Kc(a) { + return{jpg:"image/jpeg", jpeg:"image/jpeg", png:"image/png", bmp:"image/bmp", ogg:"audio/ogg", wav:"audio/wav", mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".") + 1)] +} +var Lc = []; +function Mc() { + var a = r.canvas; + Lc.forEach(function(b) { + b(a.width, a.height) + }) +} +function Nc() { + var a = r.canvas; + this.Ib = a.width; + this.Hb = a.height; + a.width = screen.width; + a.height = screen.height; + "undefined" != typeof SDL && (a = Qa[SDL.screen + 0 * ma >> 2], B[SDL.screen + 0 * ma >> 2] = a | 8388608); + Mc() +} +function Oc() { + var a = r.canvas; + a.width = this.Ib; + a.height = this.Hb; + "undefined" != typeof SDL && (a = Qa[SDL.screen + 0 * ma >> 2], B[SDL.screen + 0 * ma >> 2] = a & -8388609); + Mc() +} +var Pc, Qc, Rc, Sc; +r.RandomBytes = tb; +vb = ra(4); +B[vb >> 2] = 0; +var Xb = Sb(m, "/", 16895, 0), Tc = T, Uc = {type:Tc, se:{}, Ua:"/", root:m}, Vc; +Vc = O("/", {N:n}); +var Wc = Tc.z(Uc); +Wc.z = Uc; +Uc.root = Wc; +Vc && (Vc.d.z = Uc, Vc.d.ub = l, Xb = Uc.root); +Bb("/tmp", 511); +Bb("/dev", 511); +Pb[259] = {e:{Q:function() { + return 0 +}, write:function() { + return 0 +}}}; +Cb("/dev/null", 438, 259); +Ob(1280, {Na:function(a) { + if(!a.input.length) { + var b = m; + if(ca) { + if(process.Eb.be) { + return + } + b = process.Eb.Q() + }else { + "undefined" != typeof window && "function" == typeof window.prompt ? (b = window.prompt("Input: "), b !== m && (b += "\n")) : "function" == typeof readline && (b = readline(), b !== m && (b += "\n")) + } + if(!b) { + return m + } + a.input = J(b, l) + } + return a.input.shift() +}, W:function(a, b) { + b === m || 10 === b ? (r.print(a.H.join("")), a.H = []) : a.H.push(Rb.oa(b)) +}}); +Ob(1536, {W:function(a, b) { + b === m || 10 === b ? (r.printErr(a.H.join("")), a.H = []) : a.H.push(Rb.oa(b)) +}}); +Cb("/dev/tty", 438, 1280); +Cb("/dev/tty1", 438, 1536); +Bb("/dev/shm", 511); +Bb("/dev/shm/tmp", 511); +Xa.unshift({V:function() { + if(!r.noFSInit && !dc) { + v(!dc, "FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)"); + dc = l; + r.stdin = r.stdin; + r.stdout = r.stdout; + r.stderr = r.stderr; + r.stdin ? gc("/dev", "stdin", r.stdin) : Db("/dev/tty", "/dev/stdin"); + r.stdout ? gc("/dev", "stdout", m, r.stdout) : Db("/dev/tty", "/dev/stdout"); + r.stderr ? gc("/dev", "stderr", m, r.stderr) : Db("/dev/tty1", "/dev/stderr"); + var a = Fb("/dev/stdin", "r"); + B[Vb >> 2] = a.s; + v(1 === a.s, "invalid handle for stdin (" + a.s + ")"); + a = Fb("/dev/stdout", "w"); + B[Wb >> 2] = a.s; + v(2 === a.s, "invalid handle for stdout (" + a.s + ")"); + a = Fb("/dev/stderr", "w"); + B[nb >> 2] = a.s; + v(3 === a.s, "invalid handle for stderr (" + a.s + ")") + } +}}); +Ya.push({V:function() { + $b = n +}}); +Za.push({V:function() { + dc = n; + for(var a = 0;a < R.length;a++) { + var b = R[a]; + b && Jb(b) + } +}}); +r.FS_createFolder = function(a, b, c, d) { + a = S("string" === typeof a ? a : cc(a), b); + return Bb(a, ec(c, d)) +}; +r.FS_createPath = function(a, b) { + for(var a = "string" === typeof a ? a : cc(a), c = b.split("/").reverse();c.length;) { + var d = c.pop(); + if(d) { + var f = S(a, d); + try { + Bb(f, 511) + }catch(g) { + } + a = f + } + } + return f +}; +r.FS_createDataFile = fc; +r.FS_createPreloadedFile = function(a, b, c, d, f, g, h, i) { + function j() { + Gc = document.pointerLockElement === w || document.mozPointerLockElement === w || document.webkitPointerLockElement === w + } + function p(c) { + function j(c) { + i || fc(a, b, c, d, f); + g && g(); + jb("cp " + C) + } + var p = n; + r.preloadPlugins.forEach(function(a) { + !p && a.canHandle(C) && (a.handle(c, C, j, function() { + h && h(); + jb("cp " + C) + }), p = l) + }); + p || j(c) + } + r.preloadPlugins || (r.preloadPlugins = []); + if(!Pc && !ea) { + Pc = l; + try { + new Blob, Qc = l + }catch(z) { + Qc = n, console.log("warning: no blob constructor, cannot create blobs with mimetypes") + } + Rc = "undefined" != typeof MozBlobBuilder ? MozBlobBuilder : "undefined" != typeof WebKitBlobBuilder ? WebKitBlobBuilder : !Qc ? console.log("warning: no BlobBuilder") : m; + Sc = "undefined" != typeof window ? window.URL ? window.URL : window.webkitURL : console.log("warning: cannot create object URLs"); + r.preloadPlugins.push({canHandle:function(a) { + return!r.re && /\.(jpg|jpeg|png|bmp)$/i.test(a) + }, handle:function(a, b, c, d) { + var f = m; + if(Qc) { + try { + f = new Blob([a], {type:Kc(b)}), f.size !== a.length && (f = new Blob([(new Uint8Array(a)).buffer], {type:Kc(b)})) + }catch(g) { + var h = "Blob constructor present but fails: " + g + "; falling back to blob builder"; + oa || (oa = {}); + oa[h] || (oa[h] = 1, r.P(h)) + } + } + f || (f = new Rc, f.append((new Uint8Array(a)).buffer), f = f.getBlob()); + var i = Sc.createObjectURL(f), j = new Image; + j.onload = function() { + v(j.complete, "Image " + b + " could not be decoded"); + var d = document.createElement("canvas"); + d.width = j.width; + d.height = j.height; + d.getContext("2d").drawImage(j, 0, 0); + r.preloadedImages[b] = d; + Sc.revokeObjectURL(i); + c && c(a) + }; + j.onerror = function() { + console.log("Image " + i + " could not be decoded"); + d && d() + }; + j.src = i + }}); + r.preloadPlugins.push({canHandle:function(a) { + return!r.qe && a.substr(-4) in {".ogg":1, ".wav":1, ".mp3":1} + }, handle:function(a, b, c, d) { + function f(d) { + h || (h = l, r.preloadedAudios[b] = d, c && c(a)) + } + function g() { + h || (h = l, r.preloadedAudios[b] = new Audio, d && d()) + } + var h = n; + if(Qc) { + try { + var i = new Blob([a], {type:Kc(b)}) + }catch(j) { + return g() + } + var i = Sc.createObjectURL(i), p = new Audio; + p.addEventListener("canplaythrough", function() { + f(p) + }, n); + p.onerror = function() { + if(!h) { + console.log("warning: browser could not fully decode audio " + b + ", trying slower base64 approach"); + for(var c = "", d = 0, g = 0, i = 0;i < a.length;i++) { + d = d << 8 | a[i]; + for(g += 8;6 <= g;) { + var j = d >> g - 6 & 63, g = g - 6, c = c + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[j] + } + } + 2 == g ? (c += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(d & 3) << 4], c += "==") : 4 == g && (c += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(d & 15) << 2], c += "="); + p.src = "data:audio/x-" + b.substr(-3) + ";base64," + c; + f(p) + } + }; + p.src = i; + setTimeout(function() { + za || f(p) + }, 1E4) + }else { + return g() + } + }}); + var w = r.canvas; + w.qa = w.requestPointerLock || w.mozRequestPointerLock || w.webkitRequestPointerLock; + w.La = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock || aa(); + w.La = w.La.bind(document); + document.addEventListener("pointerlockchange", j, n); + document.addEventListener("mozpointerlockchange", j, n); + document.addEventListener("webkitpointerlockchange", j, n); + r.elementPointerLock && w.addEventListener("click", function(a) { + !Gc && w.qa && (w.qa(), a.preventDefault()) + }, n) + } + var C, D = S.apply(m, [a, b]); + "/" == D[0] && (D = D.substr(1)); + C = D; + ib("cp " + C); + if("string" == typeof c) { + var L = h, H = function() { + L ? L() : e('Loading data file "' + c + '" failed.') + }, y = new XMLHttpRequest; + y.open("GET", c, l); + y.responseType = "arraybuffer"; + y.onload = function() { + if(200 == y.status || 0 == y.status && y.response) { + var a = y.response; + v(a, 'Loading data file "' + c + '" failed (no arrayBuffer).'); + a = new Uint8Array(a); + p(a); + jb("al " + c) + }else { + H() + } + }; + y.onerror = H; + y.send(m); + ib("al " + c) + }else { + p(c) + } +}; +r.FS_createLazyFile = function(a, b, c, d, f) { + var g, h; + "undefined" !== typeof XMLHttpRequest ? (ea || e("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"), g = function() { + this.ma = n; + this.T = [] + }, g.prototype.get = function(a) { + if(!(a > this.length - 1 || 0 > a)) { + var b = a % this.S; + return this.pb(Math.floor(a / this.S))[b] + } + }, g.prototype.Cb = function(a) { + this.pb = a + }, g.prototype.Fa = function() { + var a = new XMLHttpRequest; + a.open("HEAD", c, n); + a.send(m); + 200 <= a.status && 300 > a.status || 304 === a.status || e(Error("Couldn't load " + c + ". Status: " + a.status)); + var b = Number(a.getResponseHeader("Content-length")), d, f = 1048576; + if(!((d = a.getResponseHeader("Accept-Ranges")) && "bytes" === d)) { + f = b + } + var g = this; + g.Cb(function(a) { + var d = a * f, h = (a + 1) * f - 1, h = Math.min(h, b - 1); + if("undefined" === typeof g.T[a]) { + var i = g.T; + d > h && e(Error("invalid range (" + d + ", " + h + ") or no bytes requested!")); + h > b - 1 && e(Error("only " + b + " bytes available! programmer error!")); + var j = new XMLHttpRequest; + j.open("GET", c, n); + b !== f && j.setRequestHeader("Range", "bytes=" + d + "-" + h); + "undefined" != typeof Uint8Array && (j.responseType = "arraybuffer"); + j.overrideMimeType && j.overrideMimeType("text/plain; charset=x-user-defined"); + j.send(m); + 200 <= j.status && 300 > j.status || 304 === j.status || e(Error("Couldn't load " + c + ". Status: " + j.status)); + d = j.response !== k ? new Uint8Array(j.response || []) : J(j.responseText || "", l); + i[a] = d + } + "undefined" === typeof g.T[a] && e(Error("doXHR failed!")); + return g.T[a] + }); + this.gb = b; + this.fb = f; + this.ma = l + }, g = new g, Object.defineProperty(g, "length", {get:function() { + this.ma || this.Fa(); + return this.gb + }}), Object.defineProperty(g, "chunkSize", {get:function() { + this.ma || this.Fa(); + return this.fb + }}), h = k) : (h = c, g = k); + var i, a = S("string" === typeof a ? a : cc(a), b); + i = Ab(a, ec(d, f)); + g ? i.g = g : h && (i.g = m, i.url = h); + var j = {}; + Object.keys(i.e).forEach(function(a) { + var b = i.e[a]; + j[a] = function() { + var a; + if(i.ke || i.le || i.link || i.g) { + a = l + }else { + a = l; + "undefined" !== typeof XMLHttpRequest && e(Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")); + if(r.read) { + try { + i.g = J(r.read(i.url), l) + }catch(c) { + a = n + } + }else { + e(Error("Cannot load without read() or XMLHttpRequest.")) + } + a || M(N.I) + } + a || e(new Q(N.I)); + return b.apply(m, arguments) + } + }); + j.Q = function(a, b, c, d, f) { + a = a.d.g; + d = Math.min(a.length - f, d); + if(a.slice) { + for(var g = 0;g < d;g++) { + b[c + g] = a[f + g] + } + }else { + for(g = 0;g < d;g++) { + b[c + g] = a.get(f + g) + } + } + return d + }; + i.e = j; + return i +}; +r.FS_createLink = function(a, b, c) { + a = S("string" === typeof a ? a : cc(a), b); + return Db(c, a) +}; +r.FS_createDevice = gc; +U.m = F(12, "void*", E); +yc(W); +Dc.J = F([0], "i8", E); +r.requestFullScreen = function(a, b) { + function c() { + Fc = n; + (document.webkitFullScreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.mozFullscreenElement || document.fullScreenElement || document.fullscreenElement) === d ? (d.Ga = document.cancelFullScreen || document.mozCancelFullScreen || document.webkitCancelFullScreen, d.Ga = d.Ga.bind(document), Ic && d.qa(), Fc = l, Jc && Nc()) : Jc && Oc(); + if(r.onFullScreen) { + r.onFullScreen(Fc) + } + } + Ic = a; + Jc = b; + "undefined" === typeof Ic && (Ic = l); + "undefined" === typeof Jc && (Jc = n); + var d = r.canvas; + Hc || (Hc = l, document.addEventListener("fullscreenchange", c, n), document.addEventListener("mozfullscreenchange", c, n), document.addEventListener("webkitfullscreenchange", c, n)); + d.Ab = d.requestFullScreen || d.mozRequestFullScreen || (d.webkitRequestFullScreen ? function() { + d.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) + } : m); + d.Ab() +}; +r.requestAnimationFrame = function(a) { + window.requestAnimationFrame || (window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || window.setTimeout); + window.requestAnimationFrame(a) +}; +r.pauseMainLoop = aa(); +r.resumeMainLoop = function() { + Ec && (Ec = n, m()) +}; +r.getUserMedia = function() { + window.Ma || (window.Ma = navigator.getUserMedia || navigator.mozGetUserMedia); + window.Ma(k) +}; +Sa = u = xa(sa); +Ta = Sa + 5242880; +Ua = x = xa(Ta); +v(Ua < va); +var Xc = F([8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", 3), Yc = F([8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, +2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, +0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0], "i8", 3), Zc = Math.min; +var V = (function(global,env,buffer) { +// EMSCRIPTEN_START_ASM + "use asm"; + var a = new global.Int8Array(buffer); + var b = new global.Int16Array(buffer); + var c = new global.Int32Array(buffer); + var d = new global.Uint8Array(buffer); + var e = new global.Uint16Array(buffer); + var f = new global.Uint32Array(buffer); + var g = new global.Float32Array(buffer); + var h = new global.Float64Array(buffer); + var i = env.STACKTOP | 0; + var j = env.STACK_MAX | 0; + var k = env.tempDoublePtr | 0; + var l = env.ABORT | 0; + var m = env.cttz_i8 | 0; + var n = env.ctlz_i8 | 0; + var o = env.__ZTVN10__cxxabiv120__si_class_type_infoE | 0; + var p = env._stderr | 0; + var q = env.__ZTVN10__cxxabiv117__class_type_infoE | 0; + var r = env.___progname | 0; + var s = +env.NaN; + var t = +env.Infinity; + var u = 0; + var v = 0; + var w = 0; + var x = 0; + var y = 0, z = 0, A = 0, B = 0, C = 0.0, D = 0, E = 0, F = 0, G = 0.0; + var H = 0; + var I = 0; + var J = 0; + var K = 0; + var L = 0; + var M = 0; + var N = 0; + var O = 0; + var P = 0; + var Q = 0; + var R = global.Math.floor; + var S = global.Math.abs; + var T = global.Math.sqrt; + var U = global.Math.pow; + var V = global.Math.cos; + var W = global.Math.sin; + var X = global.Math.tan; + var Y = global.Math.acos; + var Z = global.Math.asin; + var _ = global.Math.atan; + var $ = global.Math.atan2; + var aa = global.Math.exp; + var ab = global.Math.log; + var ac = global.Math.ceil; + var ad = global.Math.imul; + var ae = env.abort; + var af = env.assert; + var ag = env.asmPrintInt; + var ah = env.asmPrintFloat; + var ai = env.min; + var aj = env.invoke_vi; + var ak = env.invoke_vii; + var al = env.invoke_ii; + var am = env.invoke_viii; + var an = env.invoke_v; + var ao = env.invoke_iii; + var ap = env._strncmp; + var aq = env._llvm_va_end; + var ar = env._sysconf; + var as = env.___cxa_throw; + var at = env._randombytes; + var au = env._strerror; + var av = env._abort; + var aw = env._fprintf; + var ax = env._llvm_eh_exception; + var ay = env.___cxa_free_exception; + var az = env._fflush; + var aA = env.___buildEnvironment; + var aB = env.__reallyNegative; + var aC = env._strchr; + var aD = env._fputc; + var aE = env.___setErrNo; + var aF = env._fwrite; + var aG = env._send; + var aH = env._write; + var aI = env._exit; + var aJ = env.___cxa_find_matching_catch; + var aK = env.___cxa_allocate_exception; + var aL = env._isspace; + var aM = env.___cxa_is_number_type; + var aN = env.___resumeException; + var aO = env.__formatString; + var aP = env.___cxa_does_inherit; + var aQ = env._getenv; + var aR = env._vfprintf; + var aS = env.___cxa_begin_catch; + var aT = env.__ZSt18uncaught_exceptionv; + var aU = env._pwrite; + var aV = env.___cxa_call_unexpected; + var aW = env._sbrk; + var aX = env._strerror_r; + var aY = env.___errno_location; + var aZ = env.___gxx_personality_v0; + var a_ = env._time; + var a$ = env.__exit; + var a0 = env.___cxa_end_catch; +// EMSCRIPTEN_START_FUNCS +function a7(a) { + a = a | 0; + var b = 0; + b = i; + i = i + a | 0; + i = i + 7 >> 3 << 3; + return b | 0; +} +function a8() { + return i | 0; +} +function a9(a) { + a = a | 0; + i = a; +} +function ba(a, b) { + a = a | 0; + b = b | 0; + if ((u | 0) == 0) { + u = a; + v = b; + } +} +function bb(b) { + b = b | 0; + a[k] = a[b]; + a[k + 1 | 0] = a[b + 1 | 0]; + a[k + 2 | 0] = a[b + 2 | 0]; + a[k + 3 | 0] = a[b + 3 | 0]; +} +function bc(b) { + b = b | 0; + a[k] = a[b]; + a[k + 1 | 0] = a[b + 1 | 0]; + a[k + 2 | 0] = a[b + 2 | 0]; + a[k + 3 | 0] = a[b + 3 | 0]; + a[k + 4 | 0] = a[b + 4 | 0]; + a[k + 5 | 0] = a[b + 5 | 0]; + a[k + 6 | 0] = a[b + 6 | 0]; + a[k + 7 | 0] = a[b + 7 | 0]; +} +function bd(a) { + a = a | 0; + H = a; +} +function be(a) { + a = a | 0; + I = a; +} +function bf(a) { + a = a | 0; + J = a; +} +function bg(a) { + a = a | 0; + K = a; +} +function bh(a) { + a = a | 0; + L = a; +} +function bi(a) { + a = a | 0; + M = a; +} +function bj(a) { + a = a | 0; + N = a; +} +function bk(a) { + a = a | 0; + O = a; +} +function bl(a) { + a = a | 0; + P = a; +} +function bm(a) { + a = a | 0; + Q = a; +} +function bn() { + c[27996] = q + 8; + c[27998] = o + 8; + c[28002] = o + 8; +} +function bo(a, b) { + a = a | 0; + b = b | 0; + return a >>> ((32 - b | 0) >>> 0) | a << b | 0; +} +function bp(a, b) { + a = a | 0; + b = b | 0; + return a >>> ((32 - b | 0) >>> 0) | a << b | 0; +} +function bq(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function br(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function bs(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function bt(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function bu(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0; + e = i; + i = i + 640 | 0; + f = e | 0; + g = e + 128 | 0; + bR(c, d, 32, 0) | 0; + a[c] = a[c] & -8; + h = c + 31 | 0; + a[h] = a[h] & 63 | 64; + cV(f, c); + cR(g, f); + cJ(b, g); + g = 0; + while (1) { + a[c + g | 0] = a[d + g | 0] | 0; + f = g + 1 | 0; + if ((f | 0) < 32) { + g = f; + } else { + j = 0; + break; + } + } + do { + a[c + (j + 32) | 0] = a[b + j | 0] | 0; + j = j + 1 | 0; + } while ((j | 0) < 32); + i = e; + return 0; +} +function bv() { + return en(10) | 0; +} +function bw(b, c, d, e, f) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0; + g = i; + i = i + 32 | 0; + h = g | 0; + j = h | 0; + k = i; + i = i + 128 | 0; + fn(j | 0, 1280, 32) | 0; + l = k | 0; + m = fp(d << 3 | 0 >>> 29, e << 3 | d >>> 29, 512, 0) | 0; + n = H; + o = 0; + do { + a[k + o | 0] = a[f + o | 0] ^ 54; + o = o + 1 | 0; + } while ((o | 0) < 32); + fm(k + 32 | 0, 54, 32); + o = h | 0; + h = k | 0; + bS(o, h, 64, 0) | 0; + bS(o, c, d, e) | 0; + p = d & 63; + q = e & 0; + e = p; + do { + if ((p | 0) == 0 & (q | 0) == 0) { + a[k + e | 0] = -128; + r = fp(p, q, 1, 0) | 0; + s = r; + t = 18; + } else { + r = d & 63; + u = c + (d - r) | 0; + fn(l | 0, u | 0, r) | 0; + a[k + e | 0] = -128; + r = 0; + u = fp(p, q, 1, 0) | 0; + v = u; + if (q >>> 0 < r >>> 0 | q >>> 0 == r >>> 0 & p >>> 0 < 56 >>> 0) { + s = v; + t = 18; + break; + } + if (v >>> 0 < 120) { + v = d & 63; + fm(k + (v + 1) | 0, 0, 119 - v | 0); + } + a[k + 120 | 0] = (n >>> 24 | 0 << 8) & 255; + a[k + 121 | 0] = (n >>> 16 | 0 << 16) & 255; + a[k + 122 | 0] = (n >>> 8 | 0 << 24) & 255; + a[k + 123 | 0] = n & 255; + a[k + 124 | 0] = (m >>> 24 | n << 8) & 255; + a[k + 125 | 0] = (m >>> 16 | n << 16) & 255; + a[k + 126 | 0] = (m >>> 8 | n << 24) & 255; + a[k + 127 | 0] = m & 255; + v = 128; + r = 0; + bS(o, h, v, r) | 0; + w = 0; + } + } while (0); + if ((t | 0) == 18) { + if (s >>> 0 < 56) { + s = d & 63; + fm(k + (s + 1) | 0, 0, ((s + 2 | 0) >>> 0 > 56 ? s + 1 | 0 : 55) - s | 0); + } + a[k + 56 | 0] = (n >>> 24 | 0 << 8) & 255; + a[k + 57 | 0] = (n >>> 16 | 0 << 16) & 255; + a[k + 58 | 0] = (n >>> 8 | 0 << 24) & 255; + a[k + 59 | 0] = n & 255; + a[k + 60 | 0] = (m >>> 24 | n << 8) & 255; + a[k + 61 | 0] = (m >>> 16 | n << 16) & 255; + a[k + 62 | 0] = (m >>> 8 | n << 24) & 255; + a[k + 63 | 0] = m & 255; + m = 64; + n = 0; + bS(o, h, m, n) | 0; + w = 0; + } + do { + a[k + w | 0] = a[f + w | 0] ^ 92; + w = w + 1 | 0; + } while ((w | 0) < 32); + fm(k + 32 | 0, 92, 32); + w = k + 64 | 0; + fn(w | 0, j | 0, 32) | 0; + j = 0; + do { + a[b + j | 0] = a[1280 + j | 0] | 0; + j = j + 1 | 0; + } while ((j | 0) < 32); + fm(k + 96 | 0, 0, 32); + a[k + 96 | 0] = -128; + a[k + 126 | 0] = 3; + bS(b, h, 128, 0) | 0; + i = g; + return 0; +} +function bx(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 32 | 0; + g = f | 0; + bw(g, b, c, d, e) | 0; + e = em(a, g) | 0; + i = f; + return e | 0; +} +function by(b, c, d, e, f) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0; + g = i; + i = i + 64 | 0; + h = g | 0; + j = h | 0; + k = i; + i = i + 256 | 0; + l = k | 0; + fn(j | 0, 1216, 64) | 0; + m = fp(d, e, 128, 0) | 0; + n = H; + o = 0; + do { + a[k + o | 0] = a[f + o | 0] ^ 54; + o = o + 1 | 0; + } while ((o | 0) < 32); + fm(k + 32 | 0, 54, 96); + o = h | 0; + h = k | 0; + bV(o, h, 128, 0) | 0; + bV(o, c, d, e) | 0; + p = d & 127; + q = e & 0; + e = p; + do { + if ((p | 0) == 0 & (q | 0) == 0) { + a[k + e | 0] = -128; + r = fp(p, q, 1, 0) | 0; + s = r; + t = 34; + } else { + r = d & 127; + u = c + (d - r) | 0; + fn(l | 0, u | 0, r) | 0; + a[k + e | 0] = -128; + r = 0; + u = fp(p, q, 1, 0) | 0; + v = u; + if (q >>> 0 < r >>> 0 | q >>> 0 == r >>> 0 & p >>> 0 < 112 >>> 0) { + s = v; + t = 34; + break; + } + if (v >>> 0 < 247) { + v = d & 127; + fm(k + (v + 1) | 0, 0, 246 - v | 0); + } + a[k + 247 | 0] = (n >>> 29 | 0 << 3) & 255; + a[k + 248 | 0] = (n >>> 21 | 0 << 11) & 255; + a[k + 249 | 0] = (n >>> 13 | 0 << 19) & 255; + a[k + 250 | 0] = (n >>> 5 | 0 << 27) & 255; + a[k + 251 | 0] = (m >>> 29 | n << 3) & 255; + a[k + 252 | 0] = (m >>> 21 | n << 11) & 255; + a[k + 253 | 0] = (m >>> 13 | n << 19) & 255; + a[k + 254 | 0] = (m >>> 5 | n << 27) & 255; + a[k + 255 | 0] = (m << 3 | 0 >>> 29) & 255; + v = 256; + r = 0; + bV(o, h, v, r) | 0; + w = 0; + } + } while (0); + if ((t | 0) == 34) { + if (s >>> 0 < 119) { + s = d & 127; + fm(k + (s + 1) | 0, 0, ((s + 2 | 0) >>> 0 > 119 ? s + 1 | 0 : 118) - s | 0); + } + a[k + 119 | 0] = (n >>> 29 | 0 << 3) & 255; + a[k + 120 | 0] = (n >>> 21 | 0 << 11) & 255; + a[k + 121 | 0] = (n >>> 13 | 0 << 19) & 255; + a[k + 122 | 0] = (n >>> 5 | 0 << 27) & 255; + a[k + 123 | 0] = (m >>> 29 | n << 3) & 255; + a[k + 124 | 0] = (m >>> 21 | n << 11) & 255; + a[k + 125 | 0] = (m >>> 13 | n << 19) & 255; + a[k + 126 | 0] = (m >>> 5 | n << 27) & 255; + a[k + 127 | 0] = (m << 3 | 0 >>> 29) & 255; + m = 128; + n = 0; + bV(o, h, m, n) | 0; + w = 0; + } + do { + a[k + w | 0] = a[f + w | 0] ^ 92; + w = w + 1 | 0; + } while ((w | 0) < 32); + fm(k + 32 | 0, 92, 96); + w = k + 128 | 0; + fn(w | 0, j | 0, 64) | 0; + fn(j | 0, 1216, 64) | 0; + fm(k + 192 | 0, 0, 64); + a[k + 192 | 0] = -128; + a[k + 254 | 0] = 6; + bV(o, h, 256, 0) | 0; + fn(b | 0, j | 0, 32) | 0; + i = g; + return 0; +} +function bz(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 32 | 0; + g = f | 0; + by(g, b, c, d, e) | 0; + e = em(a, g) | 0; + i = f; + return e | 0; +} +function bA(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + return ci(a, b, c, d, e, f) | 0; +} +function bB(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + return cj(a, b, c, d, e, f) | 0; +} +function bC(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0; + d = i; + i = i + 32 | 0; + e = d | 0; + b3(e, c, b) | 0; + b = bG(a, 112040, e, 136) | 0; + i = d; + return b | 0; +} +function bD(a, b, c, d, e, f, g) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0; + h = i; + i = i + 32 | 0; + j = h | 0; + bC(j, f, g) | 0; + g = bA(a, b, c, d, e, j) | 0; + i = h; + return g | 0; +} +function bE(a, b, c, d, e, f, g) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0; + h = i; + i = i + 32 | 0; + j = h | 0; + bC(j, f, g) | 0; + g = bB(a, b, c, d, e, j) | 0; + i = h; + return g | 0; +} +function bF(a, b) { + a = a | 0; + b = b | 0; + at(b | 0, 32, 0); + return b2(a, b) | 0; +} +function bG(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0; + e = bq(d) | 0; + f = bq(c) | 0; + g = bq(c + 4 | 0) | 0; + h = bq(c + 8 | 0) | 0; + i = bq(c + 12 | 0) | 0; + j = d + 4 | 0; + k = bq(j) | 0; + l = bq(b) | 0; + m = b + 4 | 0; + n = bq(m) | 0; + o = b + 8 | 0; + p = bq(o) | 0; + q = b + 12 | 0; + r = bq(q) | 0; + s = d + 8 | 0; + t = bq(s) | 0; + u = bq(c + 16 | 0) | 0; + v = bq(c + 20 | 0) | 0; + w = bq(c + 24 | 0) | 0; + x = bq(c + 28 | 0) | 0; + c = d + 12 | 0; + y = bq(c) | 0; + z = y; + A = x; + x = w; + w = v; + v = u; + u = t; + B = r; + C = p; + D = n; + E = l; + F = k; + G = i; + i = h; + h = g; + g = f; + f = e; + H = 20; + do { + I = (bo(f + w | 0, 7) | 0) ^ G; + J = (bo(I + f | 0, 9) | 0) ^ C; + K = (bo(J + I | 0, 13) | 0) ^ w; + L = (bo(K + J | 0, 18) | 0) ^ f; + M = (bo(g + F | 0, 7) | 0) ^ B; + N = (bo(M + F | 0, 9) | 0) ^ x; + O = (bo(N + M | 0, 13) | 0) ^ g; + P = (bo(O + N | 0, 18) | 0) ^ F; + Q = (bo(E + u | 0, 7) | 0) ^ A; + R = (bo(Q + u | 0, 9) | 0) ^ h; + S = (bo(R + Q | 0, 13) | 0) ^ E; + T = (bo(S + R | 0, 18) | 0) ^ u; + U = (bo(v + z | 0, 7) | 0) ^ i; + V = (bo(U + z | 0, 9) | 0) ^ D; + W = (bo(V + U | 0, 13) | 0) ^ v; + X = (bo(W + V | 0, 18) | 0) ^ z; + g = (bo(U + L | 0, 7) | 0) ^ O; + h = (bo(g + L | 0, 9) | 0) ^ R; + i = (bo(h + g | 0, 13) | 0) ^ U; + f = (bo(i + h | 0, 18) | 0) ^ L; + E = (bo(P + I | 0, 7) | 0) ^ S; + D = (bo(E + P | 0, 9) | 0) ^ V; + G = (bo(D + E | 0, 13) | 0) ^ I; + F = (bo(G + D | 0, 18) | 0) ^ P; + v = (bo(T + M | 0, 7) | 0) ^ W; + C = (bo(v + T | 0, 9) | 0) ^ J; + B = (bo(C + v | 0, 13) | 0) ^ M; + u = (bo(B + C | 0, 18) | 0) ^ T; + w = (bo(X + Q | 0, 7) | 0) ^ K; + x = (bo(w + X | 0, 9) | 0) ^ N; + A = (bo(x + w | 0, 13) | 0) ^ Q; + z = (bo(A + x | 0, 18) | 0) ^ X; + H = H - 2 | 0; + } while ((H | 0) > 0); + H = f + e - (bq(d) | 0) | 0; + d = F + k - (bq(j) | 0) | 0; + j = u + t - (bq(s) | 0) | 0; + s = z + y - (bq(c) | 0) | 0; + c = E + l - (bq(b) | 0) | 0; + b = D + n - (bq(m) | 0) | 0; + m = C + p - (bq(o) | 0) | 0; + o = B + r - (bq(q) | 0) | 0; + br(a, H); + br(a + 4 | 0, d); + br(a + 8 | 0, j); + br(a + 12 | 0, s); + br(a + 16 | 0, c); + br(a + 20 | 0, b); + br(a + 24 | 0, m); + br(a + 28 | 0, o); + return 0; +} +function bH(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0; + e = bs(d) | 0; + f = bs(c) | 0; + g = bs(c + 4 | 0) | 0; + h = bs(c + 8 | 0) | 0; + i = bs(c + 12 | 0) | 0; + j = bs(d + 4 | 0) | 0; + k = bs(b) | 0; + l = bs(b + 4 | 0) | 0; + m = bs(b + 8 | 0) | 0; + n = bs(b + 12 | 0) | 0; + b = bs(d + 8 | 0) | 0; + o = bs(c + 16 | 0) | 0; + p = bs(c + 20 | 0) | 0; + q = bs(c + 24 | 0) | 0; + r = bs(c + 28 | 0) | 0; + c = bs(d + 12 | 0) | 0; + d = c; + s = r; + t = q; + u = p; + v = o; + w = b; + x = n; + y = m; + z = l; + A = k; + B = j; + C = i; + D = h; + E = g; + F = f; + G = e; + H = 20; + do { + I = (bp(G + u | 0, 7) | 0) ^ C; + J = (bp(I + G | 0, 9) | 0) ^ y; + K = (bp(J + I | 0, 13) | 0) ^ u; + L = (bp(K + J | 0, 18) | 0) ^ G; + M = (bp(F + B | 0, 7) | 0) ^ x; + N = (bp(M + B | 0, 9) | 0) ^ t; + O = (bp(N + M | 0, 13) | 0) ^ F; + P = (bp(O + N | 0, 18) | 0) ^ B; + Q = (bp(A + w | 0, 7) | 0) ^ s; + R = (bp(Q + w | 0, 9) | 0) ^ E; + S = (bp(R + Q | 0, 13) | 0) ^ A; + T = (bp(S + R | 0, 18) | 0) ^ w; + U = (bp(v + d | 0, 7) | 0) ^ D; + V = (bp(U + d | 0, 9) | 0) ^ z; + W = (bp(V + U | 0, 13) | 0) ^ v; + X = (bp(W + V | 0, 18) | 0) ^ d; + F = (bp(U + L | 0, 7) | 0) ^ O; + E = (bp(F + L | 0, 9) | 0) ^ R; + D = (bp(E + F | 0, 13) | 0) ^ U; + G = (bp(D + E | 0, 18) | 0) ^ L; + A = (bp(P + I | 0, 7) | 0) ^ S; + z = (bp(A + P | 0, 9) | 0) ^ V; + C = (bp(z + A | 0, 13) | 0) ^ I; + B = (bp(C + z | 0, 18) | 0) ^ P; + v = (bp(T + M | 0, 7) | 0) ^ W; + y = (bp(v + T | 0, 9) | 0) ^ J; + x = (bp(y + v | 0, 13) | 0) ^ M; + w = (bp(x + y | 0, 18) | 0) ^ T; + u = (bp(X + Q | 0, 7) | 0) ^ K; + t = (bp(u + X | 0, 9) | 0) ^ N; + s = (bp(t + u | 0, 13) | 0) ^ Q; + d = (bp(s + t | 0, 18) | 0) ^ X; + H = H - 2 | 0; + } while ((H | 0) > 0); + bt(a, G + e | 0); + bt(a + 4 | 0, F + f | 0); + bt(a + 8 | 0, E + g | 0); + bt(a + 12 | 0, D + h | 0); + bt(a + 16 | 0, C + i | 0); + bt(a + 20 | 0, B + j | 0); + bt(a + 24 | 0, A + k | 0); + bt(a + 28 | 0, z + l | 0); + bt(a + 32 | 0, y + m | 0); + bt(a + 36 | 0, x + n | 0); + bt(a + 40 | 0, w + b | 0); + bt(a + 44 | 0, v + o | 0); + bt(a + 48 | 0, u + p | 0); + bt(a + 52 | 0, t + q | 0); + bt(a + 56 | 0, s + r | 0); + bt(a + 60 | 0, d + c | 0); + return 0; +} +function bI(a, b) { + a = a | 0; + b = b | 0; + return a >>> ((32 - b | 0) >>> 0) | a << b | 0; +} +function bJ(a, b) { + a = a | 0; + b = b | 0; + return a >>> ((32 - b | 0) >>> 0) | a << b | 0; +} +function bK(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function bL(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function bM(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function bN(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function bO(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0; + e = bK(d) | 0; + f = bK(c) | 0; + g = bK(c + 4 | 0) | 0; + h = bK(c + 8 | 0) | 0; + i = bK(c + 12 | 0) | 0; + j = bK(d + 4 | 0) | 0; + k = bK(b) | 0; + l = bK(b + 4 | 0) | 0; + m = bK(b + 8 | 0) | 0; + n = bK(b + 12 | 0) | 0; + b = bK(d + 8 | 0) | 0; + o = bK(c + 16 | 0) | 0; + p = bK(c + 20 | 0) | 0; + q = bK(c + 24 | 0) | 0; + r = bK(c + 28 | 0) | 0; + c = bK(d + 12 | 0) | 0; + d = c; + s = r; + t = q; + u = p; + v = o; + w = b; + x = n; + y = m; + z = l; + A = k; + B = j; + C = i; + D = h; + E = g; + F = f; + G = e; + H = 12; + do { + I = (bI(G + u | 0, 7) | 0) ^ C; + J = (bI(I + G | 0, 9) | 0) ^ y; + K = (bI(J + I | 0, 13) | 0) ^ u; + L = (bI(K + J | 0, 18) | 0) ^ G; + M = (bI(F + B | 0, 7) | 0) ^ x; + N = (bI(M + B | 0, 9) | 0) ^ t; + O = (bI(N + M | 0, 13) | 0) ^ F; + P = (bI(O + N | 0, 18) | 0) ^ B; + Q = (bI(A + w | 0, 7) | 0) ^ s; + R = (bI(Q + w | 0, 9) | 0) ^ E; + S = (bI(R + Q | 0, 13) | 0) ^ A; + T = (bI(S + R | 0, 18) | 0) ^ w; + U = (bI(v + d | 0, 7) | 0) ^ D; + V = (bI(U + d | 0, 9) | 0) ^ z; + W = (bI(V + U | 0, 13) | 0) ^ v; + X = (bI(W + V | 0, 18) | 0) ^ d; + F = (bI(U + L | 0, 7) | 0) ^ O; + E = (bI(F + L | 0, 9) | 0) ^ R; + D = (bI(E + F | 0, 13) | 0) ^ U; + G = (bI(D + E | 0, 18) | 0) ^ L; + A = (bI(P + I | 0, 7) | 0) ^ S; + z = (bI(A + P | 0, 9) | 0) ^ V; + C = (bI(z + A | 0, 13) | 0) ^ I; + B = (bI(C + z | 0, 18) | 0) ^ P; + v = (bI(T + M | 0, 7) | 0) ^ W; + y = (bI(v + T | 0, 9) | 0) ^ J; + x = (bI(y + v | 0, 13) | 0) ^ M; + w = (bI(x + y | 0, 18) | 0) ^ T; + u = (bI(X + Q | 0, 7) | 0) ^ K; + t = (bI(u + X | 0, 9) | 0) ^ N; + s = (bI(t + u | 0, 13) | 0) ^ Q; + d = (bI(s + t | 0, 18) | 0) ^ X; + H = H - 2 | 0; + } while ((H | 0) > 0); + bL(a, G + e | 0); + bL(a + 4 | 0, F + f | 0); + bL(a + 8 | 0, E + g | 0); + bL(a + 12 | 0, D + h | 0); + bL(a + 16 | 0, C + i | 0); + bL(a + 20 | 0, B + j | 0); + bL(a + 24 | 0, A + k | 0); + bL(a + 28 | 0, z + l | 0); + bL(a + 32 | 0, y + m | 0); + bL(a + 36 | 0, x + n | 0); + bL(a + 40 | 0, w + b | 0); + bL(a + 44 | 0, v + o | 0); + bL(a + 48 | 0, u + p | 0); + bL(a + 52 | 0, t + q | 0); + bL(a + 56 | 0, s + r | 0); + bL(a + 60 | 0, d + c | 0); + return 0; +} +function bP(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0; + e = bM(d) | 0; + f = bM(c) | 0; + g = bM(c + 4 | 0) | 0; + h = bM(c + 8 | 0) | 0; + i = bM(c + 12 | 0) | 0; + j = bM(d + 4 | 0) | 0; + k = bM(b) | 0; + l = bM(b + 4 | 0) | 0; + m = bM(b + 8 | 0) | 0; + n = bM(b + 12 | 0) | 0; + b = bM(d + 8 | 0) | 0; + o = bM(c + 16 | 0) | 0; + p = bM(c + 20 | 0) | 0; + q = bM(c + 24 | 0) | 0; + r = bM(c + 28 | 0) | 0; + c = bM(d + 12 | 0) | 0; + d = c; + s = r; + t = q; + u = p; + v = o; + w = b; + x = n; + y = m; + z = l; + A = k; + B = j; + C = i; + D = h; + E = g; + F = f; + G = e; + H = 8; + do { + I = (bJ(G + u | 0, 7) | 0) ^ C; + J = (bJ(I + G | 0, 9) | 0) ^ y; + K = (bJ(J + I | 0, 13) | 0) ^ u; + L = (bJ(K + J | 0, 18) | 0) ^ G; + M = (bJ(F + B | 0, 7) | 0) ^ x; + N = (bJ(M + B | 0, 9) | 0) ^ t; + O = (bJ(N + M | 0, 13) | 0) ^ F; + P = (bJ(O + N | 0, 18) | 0) ^ B; + Q = (bJ(A + w | 0, 7) | 0) ^ s; + R = (bJ(Q + w | 0, 9) | 0) ^ E; + S = (bJ(R + Q | 0, 13) | 0) ^ A; + T = (bJ(S + R | 0, 18) | 0) ^ w; + U = (bJ(v + d | 0, 7) | 0) ^ D; + V = (bJ(U + d | 0, 9) | 0) ^ z; + W = (bJ(V + U | 0, 13) | 0) ^ v; + X = (bJ(W + V | 0, 18) | 0) ^ d; + F = (bJ(U + L | 0, 7) | 0) ^ O; + E = (bJ(F + L | 0, 9) | 0) ^ R; + D = (bJ(E + F | 0, 13) | 0) ^ U; + G = (bJ(D + E | 0, 18) | 0) ^ L; + A = (bJ(P + I | 0, 7) | 0) ^ S; + z = (bJ(A + P | 0, 9) | 0) ^ V; + C = (bJ(z + A | 0, 13) | 0) ^ I; + B = (bJ(C + z | 0, 18) | 0) ^ P; + v = (bJ(T + M | 0, 7) | 0) ^ W; + y = (bJ(v + T | 0, 9) | 0) ^ J; + x = (bJ(y + v | 0, 13) | 0) ^ M; + w = (bJ(x + y | 0, 18) | 0) ^ T; + u = (bJ(X + Q | 0, 7) | 0) ^ K; + t = (bJ(u + X | 0, 9) | 0) ^ N; + s = (bJ(t + u | 0, 13) | 0) ^ Q; + d = (bJ(s + t | 0, 18) | 0) ^ X; + H = H - 2 | 0; + } while ((H | 0) > 0); + bN(a, G + e | 0); + bN(a + 4 | 0, F + f | 0); + bN(a + 8 | 0, E + g | 0); + bN(a + 12 | 0, D + h | 0); + bN(a + 16 | 0, C + i | 0); + bN(a + 20 | 0, B + j | 0); + bN(a + 24 | 0, A + k | 0); + bN(a + 28 | 0, z + l | 0); + bN(a + 32 | 0, y + m | 0); + bN(a + 36 | 0, x + n | 0); + bN(a + 40 | 0, w + b | 0); + bN(a + 44 | 0, v + o | 0); + bN(a + 48 | 0, u + p | 0); + bN(a + 52 | 0, t + q | 0); + bN(a + 56 | 0, s + r | 0); + bN(a + 60 | 0, d + c | 0); + return 0; +} +function bQ(b, c, d, e) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0; + f = i; + i = i + 32 | 0; + g = f | 0; + h = g | 0; + j = i; + i = i + 128 | 0; + fn(h | 0, 1184, 32) | 0; + k = d << 3 | 0 >>> 29; + l = g | 0; + bS(l, c, d, e) | 0; + g = d & 63; + m = e & 0; + n = g; + do { + if ((g | 0) == 0 & (m | 0) == 0) { + a[j + n | 0] = -128; + o = fp(g, m, 1, 0) | 0; + p = o; + } else { + o = j | 0; + q = d & 63; + r = c + (d - q) | 0; + fn(o | 0, r | 0, q) | 0; + a[j + n | 0] = -128; + q = 0; + r = fp(g, m, 1, 0) | 0; + o = r; + if (m >>> 0 < q >>> 0 | m >>> 0 == q >>> 0 & g >>> 0 < 56 >>> 0) { + p = o; + break; + } + if (o >>> 0 < 120) { + o = d & 63; + fm(j + (o + 1) | 0, 0, 119 - o | 0); + } + a[j + 120 | 0] = (e >>> 21 | 0 << 11) & 255; + a[j + 121 | 0] = (e >>> 13 | 0 << 19) & 255; + a[j + 122 | 0] = (e >>> 5 | 0 << 27) & 255; + a[j + 123 | 0] = (d >>> 29 | e << 3) & 255; + a[j + 124 | 0] = (d >>> 21 | e << 11) & 255; + a[j + 125 | 0] = (d >>> 13 | e << 19) & 255; + a[j + 126 | 0] = (d >>> 5 | e << 27) & 255; + a[j + 127 | 0] = k & 255; + o = j | 0; + q = 128; + r = 0; + bS(l, o, q, r) | 0; + fn(b | 0, h | 0, 32) | 0; + i = f; + return 0; + } + } while (0); + if (p >>> 0 < 56) { + p = d & 63; + fm(j + (p + 1) | 0, 0, ((p + 2 | 0) >>> 0 > 56 ? p + 1 | 0 : 55) - p | 0); + } + a[j + 56 | 0] = (e >>> 21 | 0 << 11) & 255; + a[j + 57 | 0] = (e >>> 13 | 0 << 19) & 255; + a[j + 58 | 0] = (e >>> 5 | 0 << 27) & 255; + a[j + 59 | 0] = (d >>> 29 | e << 3) & 255; + a[j + 60 | 0] = (d >>> 21 | e << 11) & 255; + a[j + 61 | 0] = (d >>> 13 | e << 19) & 255; + a[j + 62 | 0] = (d >>> 5 | e << 27) & 255; + a[j + 63 | 0] = k & 255; + bS(l, j | 0, 64, 0) | 0; + fn(b | 0, h | 0, 32) | 0; + i = f; + return 0; +} +function bR(b, c, d, e) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0; + f = i; + i = i + 64 | 0; + g = f | 0; + h = g | 0; + j = i; + i = i + 256 | 0; + fn(h | 0, 1120, 64) | 0; + k = g | 0; + bV(k, c, d, e) | 0; + g = d & 127; + l = e & 0; + m = g; + do { + if ((g | 0) == 0 & (l | 0) == 0) { + a[j + m | 0] = -128; + n = fp(g, l, 1, 0) | 0; + o = n; + } else { + n = j | 0; + p = d & 127; + q = c + (d - p) | 0; + fn(n | 0, q | 0, p) | 0; + a[j + m | 0] = -128; + p = 0; + q = fp(g, l, 1, 0) | 0; + n = q; + if (l >>> 0 < p >>> 0 | l >>> 0 == p >>> 0 & g >>> 0 < 112 >>> 0) { + o = n; + break; + } + if (n >>> 0 < 247) { + n = d & 127; + fm(j + (n + 1) | 0, 0, 246 - n | 0); + } + a[j + 247 | 0] = (e >>> 29 | 0 << 3) & 255; + a[j + 248 | 0] = (e >>> 21 | 0 << 11) & 255; + a[j + 249 | 0] = (e >>> 13 | 0 << 19) & 255; + a[j + 250 | 0] = (e >>> 5 | 0 << 27) & 255; + a[j + 251 | 0] = (d >>> 29 | e << 3) & 255; + a[j + 252 | 0] = (d >>> 21 | e << 11) & 255; + a[j + 253 | 0] = (d >>> 13 | e << 19) & 255; + a[j + 254 | 0] = (d >>> 5 | e << 27) & 255; + a[j + 255 | 0] = (d << 3 | 0 >>> 29) & 255; + n = j | 0; + p = 256; + q = 0; + bV(k, n, p, q) | 0; + fn(b | 0, h | 0, 64) | 0; + i = f; + return 0; + } + } while (0); + if (o >>> 0 < 119) { + o = d & 127; + fm(j + (o + 1) | 0, 0, ((o + 2 | 0) >>> 0 > 119 ? o + 1 | 0 : 118) - o | 0); + } + a[j + 119 | 0] = (e >>> 29 | 0 << 3) & 255; + a[j + 120 | 0] = (e >>> 21 | 0 << 11) & 255; + a[j + 121 | 0] = (e >>> 13 | 0 << 19) & 255; + a[j + 122 | 0] = (e >>> 5 | 0 << 27) & 255; + a[j + 123 | 0] = (d >>> 29 | e << 3) & 255; + a[j + 124 | 0] = (d >>> 21 | e << 11) & 255; + a[j + 125 | 0] = (d >>> 13 | e << 19) & 255; + a[j + 126 | 0] = (d >>> 5 | e << 27) & 255; + a[j + 127 | 0] = (d << 3 | 0 >>> 29) & 255; + bV(k, j | 0, 128, 0) | 0; + fn(b | 0, h | 0, 64) | 0; + i = f; + return 0; +} +function bS(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0; + e = bT(a) | 0; + f = a + 4 | 0; + g = bT(f) | 0; + h = a + 8 | 0; + i = bT(h) | 0; + j = a + 12 | 0; + k = bT(j) | 0; + l = a + 16 | 0; + m = bT(l) | 0; + n = a + 20 | 0; + o = bT(n) | 0; + p = a + 24 | 0; + q = bT(p) | 0; + r = a + 28 | 0; + s = bT(r) | 0; + t = 0; + if (d >>> 0 > t >>> 0 | d >>> 0 == t >>> 0 & c >>> 0 > 63 >>> 0) { + u = s; + v = q; + w = o; + x = m; + y = k; + z = i; + A = g; + B = e; + C = d; + D = c; + E = b; + } else { + F = s; + G = q; + I = o; + J = m; + K = k; + L = i; + M = g; + N = e; + bU(a, N); + bU(f, M); + bU(h, L); + bU(j, K); + bU(l, J); + bU(n, I); + bU(p, G); + bU(r, F); + return 0; + } + while (1) { + e = bT(E) | 0; + g = bT(E + 4 | 0) | 0; + i = bT(E + 8 | 0) | 0; + k = bT(E + 12 | 0) | 0; + m = bT(E + 16 | 0) | 0; + o = bT(E + 20 | 0) | 0; + q = bT(E + 24 | 0) | 0; + s = bT(E + 28 | 0) | 0; + b = bT(E + 32 | 0) | 0; + c = bT(E + 36 | 0) | 0; + d = bT(E + 40 | 0) | 0; + t = bT(E + 44 | 0) | 0; + O = bT(E + 48 | 0) | 0; + P = bT(E + 52 | 0) | 0; + Q = bT(E + 56 | 0) | 0; + R = bT(E + 60 | 0) | 0; + S = u + 1116352408 + (x & w ^ v & ~x) + ((x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)) + e | 0; + T = B & A; + U = S + y | 0; + V = ((B >>> 2 | B << 30) ^ (B >>> 13 | B << 19) ^ (B >>> 22 | B << 10)) + ((B ^ A) & z ^ T) + S | 0; + S = v + 1899447441 + g + (U & x ^ w & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + W = V & B; + X = S + z | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & A ^ T ^ W) + S | 0; + S = w - 1245643825 + i + (X & U ^ x & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = Y & V; + Z = S + A | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & B ^ W ^ T) + S | 0; + S = x - 373957723 + k + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = _ & Y; + $ = S + B | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ T ^ W) + S | 0; + S = U + 961987163 + m + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = aa & _; + T = S + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ W ^ U) + S | 0; + S = o + 1508970993 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = V & aa; + W = S + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ U ^ X) + S | 0; + S = q - 1841331548 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = Y & V; + U = S + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ X ^ Z) + S | 0; + S = s - 1424204075 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = _ & Y; + X = S + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ Z ^ $) + S | 0; + S = b - 670586216 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = aa & _; + Z = S + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ $ ^ T) + S | 0; + S = c + 310598401 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = V & aa; + $ = S + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ T ^ W) + S | 0; + S = d + 607225278 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = Y & V; + T = S + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ W ^ U) + S | 0; + S = t + 1426881987 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = _ & Y; + W = S + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ U ^ X) + S | 0; + S = O + 1925078388 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = aa & _; + U = S + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ X ^ Z) + S | 0; + S = P - 2132889090 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = V & aa; + X = S + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ Z ^ $) + S | 0; + S = Q - 1680079193 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = Y & V; + Z = S + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ $ ^ T) + S | 0; + S = R - 1046744716 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = _ & Y; + $ = S + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ T ^ W) + S | 0; + S = ((g >>> 18 | g << 14) ^ g >>> 3 ^ (g >>> 7 | g << 25)) + e + c + ((Q >>> 19 | Q << 13) ^ Q >>> 10 ^ (Q >>> 17 | Q << 15)) | 0; + e = ((i >>> 18 | i << 14) ^ i >>> 3 ^ (i >>> 7 | i << 25)) + g + d + ((R >>> 19 | R << 13) ^ R >>> 10 ^ (R >>> 17 | R << 15)) | 0; + g = ((k >>> 18 | k << 14) ^ k >>> 3 ^ (k >>> 7 | k << 25)) + i + t + ((S >>> 19 | S << 13) ^ S >>> 10 ^ (S >>> 17 | S << 15)) | 0; + i = ((m >>> 18 | m << 14) ^ m >>> 3 ^ (m >>> 7 | m << 25)) + k + O + ((e >>> 19 | e << 13) ^ e >>> 10 ^ (e >>> 17 | e << 15)) | 0; + k = ((o >>> 18 | o << 14) ^ o >>> 3 ^ (o >>> 7 | o << 25)) + m + P + ((g >>> 19 | g << 13) ^ g >>> 10 ^ (g >>> 17 | g << 15)) | 0; + m = ((q >>> 18 | q << 14) ^ q >>> 3 ^ (q >>> 7 | q << 25)) + o + Q + ((i >>> 19 | i << 13) ^ i >>> 10 ^ (i >>> 17 | i << 15)) | 0; + o = ((s >>> 18 | s << 14) ^ s >>> 3 ^ (s >>> 7 | s << 25)) + q + R + ((k >>> 19 | k << 13) ^ k >>> 10 ^ (k >>> 17 | k << 15)) | 0; + q = ((b >>> 18 | b << 14) ^ b >>> 3 ^ (b >>> 7 | b << 25)) + s + S + ((m >>> 19 | m << 13) ^ m >>> 10 ^ (m >>> 17 | m << 15)) | 0; + s = ((c >>> 18 | c << 14) ^ c >>> 3 ^ (c >>> 7 | c << 25)) + b + e + ((o >>> 19 | o << 13) ^ o >>> 10 ^ (o >>> 17 | o << 15)) | 0; + b = ((d >>> 18 | d << 14) ^ d >>> 3 ^ (d >>> 7 | d << 25)) + c + g + ((q >>> 19 | q << 13) ^ q >>> 10 ^ (q >>> 17 | q << 15)) | 0; + c = ((t >>> 18 | t << 14) ^ t >>> 3 ^ (t >>> 7 | t << 25)) + d + i + ((s >>> 19 | s << 13) ^ s >>> 10 ^ (s >>> 17 | s << 15)) | 0; + d = ((O >>> 18 | O << 14) ^ O >>> 3 ^ (O >>> 7 | O << 25)) + t + k + ((b >>> 19 | b << 13) ^ b >>> 10 ^ (b >>> 17 | b << 15)) | 0; + t = ((P >>> 18 | P << 14) ^ P >>> 3 ^ (P >>> 7 | P << 25)) + O + m + ((c >>> 19 | c << 13) ^ c >>> 10 ^ (c >>> 17 | c << 15)) | 0; + O = ((Q >>> 18 | Q << 14) ^ Q >>> 3 ^ (Q >>> 7 | Q << 25)) + P + o + ((d >>> 19 | d << 13) ^ d >>> 10 ^ (d >>> 17 | d << 15)) | 0; + P = ((R >>> 18 | R << 14) ^ R >>> 3 ^ (R >>> 7 | R << 25)) + Q + q + ((t >>> 19 | t << 13) ^ t >>> 10 ^ (t >>> 17 | t << 15)) | 0; + Q = ((S >>> 18 | S << 14) ^ S >>> 3 ^ (S >>> 7 | S << 25)) + R + s + ((O >>> 19 | O << 13) ^ O >>> 10 ^ (O >>> 17 | O << 15)) | 0; + R = S - 459576895 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = aa & _; + T = R + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ W ^ U) + R | 0; + R = e - 272742522 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = V & aa; + W = R + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ U ^ X) + R | 0; + R = g + 264347078 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = Y & V; + U = R + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ X ^ Z) + R | 0; + R = i + 604807628 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = _ & Y; + X = R + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ Z ^ $) + R | 0; + R = k + 770255983 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = aa & _; + Z = R + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ $ ^ T) + R | 0; + R = m + 1249150122 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = V & aa; + $ = R + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ T ^ W) + R | 0; + R = o + 1555081692 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = Y & V; + T = R + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ W ^ U) + R | 0; + R = q + 1996064986 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = _ & Y; + W = R + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ U ^ X) + R | 0; + R = s - 1740746414 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = aa & _; + U = R + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ X ^ Z) + R | 0; + R = b - 1473132947 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = V & aa; + X = R + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ Z ^ $) + R | 0; + R = c - 1341970488 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = Y & V; + Z = R + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ $ ^ T) + R | 0; + R = d - 1084653625 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = _ & Y; + $ = R + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ T ^ W) + R | 0; + R = t - 958395405 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = aa & _; + T = R + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ W ^ U) + R | 0; + R = O - 710438585 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = V & aa; + W = R + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ U ^ X) + R | 0; + R = P + 113926993 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = Y & V; + U = R + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ X ^ Z) + R | 0; + R = Q + 338241895 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = _ & Y; + X = R + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ Z ^ $) + R | 0; + R = ((e >>> 18 | e << 14) ^ e >>> 3 ^ (e >>> 7 | e << 25)) + S + b + ((P >>> 19 | P << 13) ^ P >>> 10 ^ (P >>> 17 | P << 15)) | 0; + S = ((g >>> 18 | g << 14) ^ g >>> 3 ^ (g >>> 7 | g << 25)) + e + c + ((Q >>> 19 | Q << 13) ^ Q >>> 10 ^ (Q >>> 17 | Q << 15)) | 0; + e = ((i >>> 18 | i << 14) ^ i >>> 3 ^ (i >>> 7 | i << 25)) + g + d + ((R >>> 19 | R << 13) ^ R >>> 10 ^ (R >>> 17 | R << 15)) | 0; + g = ((k >>> 18 | k << 14) ^ k >>> 3 ^ (k >>> 7 | k << 25)) + i + t + ((S >>> 19 | S << 13) ^ S >>> 10 ^ (S >>> 17 | S << 15)) | 0; + i = ((m >>> 18 | m << 14) ^ m >>> 3 ^ (m >>> 7 | m << 25)) + k + O + ((e >>> 19 | e << 13) ^ e >>> 10 ^ (e >>> 17 | e << 15)) | 0; + k = ((o >>> 18 | o << 14) ^ o >>> 3 ^ (o >>> 7 | o << 25)) + m + P + ((g >>> 19 | g << 13) ^ g >>> 10 ^ (g >>> 17 | g << 15)) | 0; + m = ((q >>> 18 | q << 14) ^ q >>> 3 ^ (q >>> 7 | q << 25)) + o + Q + ((i >>> 19 | i << 13) ^ i >>> 10 ^ (i >>> 17 | i << 15)) | 0; + o = ((s >>> 18 | s << 14) ^ s >>> 3 ^ (s >>> 7 | s << 25)) + q + R + ((k >>> 19 | k << 13) ^ k >>> 10 ^ (k >>> 17 | k << 15)) | 0; + q = ((b >>> 18 | b << 14) ^ b >>> 3 ^ (b >>> 7 | b << 25)) + s + S + ((m >>> 19 | m << 13) ^ m >>> 10 ^ (m >>> 17 | m << 15)) | 0; + s = ((c >>> 18 | c << 14) ^ c >>> 3 ^ (c >>> 7 | c << 25)) + b + e + ((o >>> 19 | o << 13) ^ o >>> 10 ^ (o >>> 17 | o << 15)) | 0; + b = ((d >>> 18 | d << 14) ^ d >>> 3 ^ (d >>> 7 | d << 25)) + c + g + ((q >>> 19 | q << 13) ^ q >>> 10 ^ (q >>> 17 | q << 15)) | 0; + c = ((t >>> 18 | t << 14) ^ t >>> 3 ^ (t >>> 7 | t << 25)) + d + i + ((s >>> 19 | s << 13) ^ s >>> 10 ^ (s >>> 17 | s << 15)) | 0; + d = ((O >>> 18 | O << 14) ^ O >>> 3 ^ (O >>> 7 | O << 25)) + t + k + ((b >>> 19 | b << 13) ^ b >>> 10 ^ (b >>> 17 | b << 15)) | 0; + t = ((P >>> 18 | P << 14) ^ P >>> 3 ^ (P >>> 7 | P << 25)) + O + m + ((c >>> 19 | c << 13) ^ c >>> 10 ^ (c >>> 17 | c << 15)) | 0; + O = ((Q >>> 18 | Q << 14) ^ Q >>> 3 ^ (Q >>> 7 | Q << 25)) + P + o + ((d >>> 19 | d << 13) ^ d >>> 10 ^ (d >>> 17 | d << 15)) | 0; + P = ((R >>> 18 | R << 14) ^ R >>> 3 ^ (R >>> 7 | R << 25)) + Q + q + ((t >>> 19 | t << 13) ^ t >>> 10 ^ (t >>> 17 | t << 15)) | 0; + Q = R + 666307205 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = aa & _; + Z = Q + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ $ ^ T) + Q | 0; + Q = S + 773529912 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = V & aa; + $ = Q + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ T ^ W) + Q | 0; + Q = e + 1294757372 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = Y & V; + T = Q + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ W ^ U) + Q | 0; + Q = g + 1396182291 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = _ & Y; + W = Q + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ U ^ X) + Q | 0; + Q = i + 1695183700 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = aa & _; + U = Q + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ X ^ Z) + Q | 0; + Q = k + 1986661051 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = V & aa; + X = Q + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ Z ^ $) + Q | 0; + Q = m - 2117940946 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = Y & V; + Z = Q + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ $ ^ T) + Q | 0; + Q = o - 1838011259 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = _ & Y; + $ = Q + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ T ^ W) + Q | 0; + Q = q - 1564481375 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = aa & _; + T = Q + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ W ^ U) + Q | 0; + Q = s - 1474664885 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = V & aa; + W = Q + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ U ^ X) + Q | 0; + Q = b - 1035236496 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = Y & V; + U = Q + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ X ^ Z) + Q | 0; + Q = c - 949202525 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = _ & Y; + X = Q + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ Z ^ $) + Q | 0; + Q = d - 778901479 + T + (X & U ^ W & ~X) + ((X >>> 6 | X << 26) ^ (X >>> 11 | X << 21) ^ (X >>> 25 | X << 7)) | 0; + T = aa & _; + Z = Q + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ $ ^ T) + Q | 0; + Q = t - 694614492 + W + (Z & X ^ U & ~Z) + ((Z >>> 6 | Z << 26) ^ (Z >>> 11 | Z << 21) ^ (Z >>> 25 | Z << 7)) | 0; + W = V & aa; + $ = Q + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ T ^ W) + Q | 0; + Q = O - 200395387 + U + ($ & Z ^ X & ~$) + (($ >>> 6 | $ << 26) ^ ($ >>> 11 | $ << 21) ^ ($ >>> 25 | $ << 7)) | 0; + U = Y & V; + T = Q + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ W ^ U) + Q | 0; + Q = P + 275423344 + X + (T & $ ^ Z & ~T) + ((T >>> 6 | T << 26) ^ (T >>> 11 | T << 21) ^ (T >>> 25 | T << 7)) | 0; + X = _ & Y; + W = Q + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ U ^ X) + Q | 0; + Q = ((S >>> 18 | S << 14) ^ S >>> 3 ^ (S >>> 7 | S << 25)) + R + s + ((O >>> 19 | O << 13) ^ O >>> 10 ^ (O >>> 17 | O << 15)) | 0; + R = ((e >>> 18 | e << 14) ^ e >>> 3 ^ (e >>> 7 | e << 25)) + S + b + ((P >>> 19 | P << 13) ^ P >>> 10 ^ (P >>> 17 | P << 15)) | 0; + S = ((g >>> 18 | g << 14) ^ g >>> 3 ^ (g >>> 7 | g << 25)) + e + c + ((Q >>> 19 | Q << 13) ^ Q >>> 10 ^ (Q >>> 17 | Q << 15)) | 0; + e = ((i >>> 18 | i << 14) ^ i >>> 3 ^ (i >>> 7 | i << 25)) + g + d + ((R >>> 19 | R << 13) ^ R >>> 10 ^ (R >>> 17 | R << 15)) | 0; + g = ((k >>> 18 | k << 14) ^ k >>> 3 ^ (k >>> 7 | k << 25)) + i + t + ((S >>> 19 | S << 13) ^ S >>> 10 ^ (S >>> 17 | S << 15)) | 0; + i = ((m >>> 18 | m << 14) ^ m >>> 3 ^ (m >>> 7 | m << 25)) + k + O + ((e >>> 19 | e << 13) ^ e >>> 10 ^ (e >>> 17 | e << 15)) | 0; + k = ((o >>> 18 | o << 14) ^ o >>> 3 ^ (o >>> 7 | o << 25)) + m + P + ((g >>> 19 | g << 13) ^ g >>> 10 ^ (g >>> 17 | g << 15)) | 0; + m = ((q >>> 18 | q << 14) ^ q >>> 3 ^ (q >>> 7 | q << 25)) + o + Q + ((i >>> 19 | i << 13) ^ i >>> 10 ^ (i >>> 17 | i << 15)) | 0; + o = ((s >>> 18 | s << 14) ^ s >>> 3 ^ (s >>> 7 | s << 25)) + q + R + ((k >>> 19 | k << 13) ^ k >>> 10 ^ (k >>> 17 | k << 15)) | 0; + q = ((b >>> 18 | b << 14) ^ b >>> 3 ^ (b >>> 7 | b << 25)) + s + S + ((m >>> 19 | m << 13) ^ m >>> 10 ^ (m >>> 17 | m << 15)) | 0; + s = ((c >>> 18 | c << 14) ^ c >>> 3 ^ (c >>> 7 | c << 25)) + b + e + ((o >>> 19 | o << 13) ^ o >>> 10 ^ (o >>> 17 | o << 15)) | 0; + b = ((d >>> 18 | d << 14) ^ d >>> 3 ^ (d >>> 7 | d << 25)) + c + g + ((q >>> 19 | q << 13) ^ q >>> 10 ^ (q >>> 17 | q << 15)) | 0; + c = ((t >>> 18 | t << 14) ^ t >>> 3 ^ (t >>> 7 | t << 25)) + d + i + ((s >>> 19 | s << 13) ^ s >>> 10 ^ (s >>> 17 | s << 15)) | 0; + d = ((O >>> 18 | O << 14) ^ O >>> 3 ^ (O >>> 7 | O << 25)) + t + k + ((b >>> 19 | b << 13) ^ b >>> 10 ^ (b >>> 17 | b << 15)) | 0; + t = Q + 430227734 + Z + (W & T ^ $ & ~W) + ((W >>> 6 | W << 26) ^ (W >>> 11 | W << 21) ^ (W >>> 25 | W << 7)) | 0; + Z = aa & _; + U = t + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ X ^ Z) + t | 0; + t = R + 506948616 + $ + (U & W ^ T & ~U) + ((U >>> 6 | U << 26) ^ (U >>> 11 | U << 21) ^ (U >>> 25 | U << 7)) | 0; + $ = V & aa; + R = t + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ Z ^ $) + t | 0; + t = S + 659060556 + T + (R & U ^ W & ~R) + ((R >>> 6 | R << 26) ^ (R >>> 11 | R << 21) ^ (R >>> 25 | R << 7)) | 0; + T = Y & V; + S = t + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ $ ^ T) + t | 0; + t = e + 883997877 + W + (S & R ^ U & ~S) + ((S >>> 6 | S << 26) ^ (S >>> 11 | S << 21) ^ (S >>> 25 | S << 7)) | 0; + W = _ & Y; + e = t + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ T ^ W) + t | 0; + t = g + 958139571 + U + (e & S ^ R & ~e) + ((e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7)) | 0; + U = aa & _; + g = t + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ W ^ U) + t | 0; + t = i + 1322822218 + R + (g & e ^ S & ~g) + ((g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7)) | 0; + R = V & aa; + i = t + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ U ^ R) + t | 0; + t = k + 1537002063 + S + (i & g ^ e & ~i) + ((i >>> 6 | i << 26) ^ (i >>> 11 | i << 21) ^ (i >>> 25 | i << 7)) | 0; + S = Y & V; + k = t + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ R ^ S) + t | 0; + t = m + 1747873779 + e + (k & i ^ g & ~k) + ((k >>> 6 | k << 26) ^ (k >>> 11 | k << 21) ^ (k >>> 25 | k << 7)) | 0; + e = _ & Y; + R = t + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ S ^ e) + t | 0; + t = o + 1955562222 + g + (R & k ^ i & ~R) + ((R >>> 6 | R << 26) ^ (R >>> 11 | R << 21) ^ (R >>> 25 | R << 7)) | 0; + g = aa & _; + S = t + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ e ^ g) + t | 0; + t = q + 2024104815 + i + (S & R ^ k & ~S) + ((S >>> 6 | S << 26) ^ (S >>> 11 | S << 21) ^ (S >>> 25 | S << 7)) | 0; + i = V & aa; + q = t + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ g ^ i) + t | 0; + t = s - 2067236844 + k + (q & S ^ R & ~q) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) | 0; + k = Y & V; + s = t + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ i ^ k) + t | 0; + t = b - 1933114872 + R + (s & q ^ S & ~s) + ((s >>> 6 | s << 26) ^ (s >>> 11 | s << 21) ^ (s >>> 25 | s << 7)) | 0; + R = _ & Y; + b = t + aa | 0; + aa = ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + (_ & V ^ k ^ R) + t | 0; + t = c - 1866530822 + S + (b & s ^ q & ~b) + ((b >>> 6 | b << 26) ^ (b >>> 11 | b << 21) ^ (b >>> 25 | b << 7)) | 0; + S = aa & _; + k = t + V | 0; + V = ((aa >>> 2 | aa << 30) ^ (aa >>> 13 | aa << 19) ^ (aa >>> 22 | aa << 10)) + (aa & Y ^ R ^ S) + t | 0; + t = d - 1538233109 + q + (k & b ^ s & ~k) + ((k >>> 6 | k << 26) ^ (k >>> 11 | k << 21) ^ (k >>> 25 | k << 7)) | 0; + q = V & aa; + R = t + Y | 0; + Y = ((V >>> 2 | V << 30) ^ (V >>> 13 | V << 19) ^ (V >>> 22 | V << 10)) + (V & _ ^ S ^ q) + t | 0; + t = O - 1090935817 + ((P >>> 18 | P << 14) ^ P >>> 3 ^ (P >>> 7 | P << 25)) + m + ((c >>> 19 | c << 13) ^ c >>> 10 ^ (c >>> 17 | c << 15)) + s + (R & k ^ b & ~R) + ((R >>> 6 | R << 26) ^ (R >>> 11 | R << 21) ^ (R >>> 25 | R << 7)) | 0; + s = Y & V; + c = t + _ | 0; + _ = ((Y >>> 2 | Y << 30) ^ (Y >>> 13 | Y << 19) ^ (Y >>> 22 | Y << 10)) + (Y & aa ^ q ^ s) + t | 0; + t = P - 965641998 + ((Q >>> 18 | Q << 14) ^ Q >>> 3 ^ (Q >>> 7 | Q << 25)) + o + ((d >>> 19 | d << 13) ^ d >>> 10 ^ (d >>> 17 | d << 15)) + b + (c & R ^ k & ~c) + ((c >>> 6 | c << 26) ^ (c >>> 11 | c << 21) ^ (c >>> 25 | c << 7)) | 0; + b = (_ & (Y ^ V) ^ s) + B + ((_ >>> 2 | _ << 30) ^ (_ >>> 13 | _ << 19) ^ (_ >>> 22 | _ << 10)) + t | 0; + s = _ + A | 0; + _ = Y + z | 0; + Y = V + y | 0; + V = aa + x + t | 0; + t = c + w | 0; + c = R + v | 0; + R = k + u | 0; + k = fp(D, C, -64, -1) | 0; + aa = H; + d = 0; + if (aa >>> 0 > d >>> 0 | aa >>> 0 == d >>> 0 & k >>> 0 > 63 >>> 0) { + u = R; + v = c; + w = t; + x = V; + y = Y; + z = _; + A = s; + B = b; + C = aa; + D = k; + E = E + 64 | 0; + } else { + F = R; + G = c; + I = t; + J = V; + K = Y; + L = _; + M = s; + N = b; + break; + } + } + bU(a, N); + bU(f, M); + bU(h, L); + bU(j, K); + bU(l, J); + bU(n, I); + bU(p, G); + bU(r, F); + return 0; +} +function bT(a) { + a = a | 0; + return (d[a + 2 | 0] | 0) << 8 | (d[a + 3 | 0] | 0) | (d[a + 1 | 0] | 0) << 16 | (d[a] | 0) << 24 | 0; +} +function bU(b, c) { + b = b | 0; + c = c | 0; + a[b + 3 | 0] = c & 255; + a[b + 2 | 0] = c >>> 8 & 255; + a[b + 1 | 0] = c >>> 16 & 255; + a[b] = c >>> 24 & 255; + return; +} +function bV(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0, ae = 0, af = 0, ag = 0, ah = 0, ai = 0, aj = 0, ak = 0, al = 0, am = 0, an = 0, ao = 0, ap = 0, aq = 0, ar = 0, as = 0, at = 0, au = 0, av = 0, aw = 0, ax = 0, ay = 0, az = 0, aA = 0, aB = 0, aC = 0, aD = 0, aE = 0, aF = 0, aG = 0, aH = 0, aI = 0, aJ = 0, aK = 0, aL = 0, aM = 0, aN = 0, aO = 0, aP = 0, aQ = 0; + e = bW(a) | 0; + f = H; + g = a + 8 | 0; + h = bW(g) | 0; + i = H; + j = a + 16 | 0; + k = bW(j) | 0; + l = H; + m = a + 24 | 0; + n = bW(m) | 0; + o = H; + p = a + 32 | 0; + q = bW(p) | 0; + r = H; + s = a + 40 | 0; + t = bW(s) | 0; + u = H; + v = a + 48 | 0; + w = bW(v) | 0; + x = H; + y = a + 56 | 0; + z = bW(y) | 0; + A = H; + B = 0; + if (d >>> 0 > B >>> 0 | d >>> 0 == B >>> 0 & c >>> 0 > 127 >>> 0) { + C = A; + D = z; + E = x; + F = w; + G = u; + I = t; + J = r; + K = q; + L = o; + M = n; + N = l; + O = k; + P = i; + Q = h; + R = f; + S = e; + T = d; + U = c; + V = b; + } else { + W = A; + X = z; + Y = x; + Z = w; + _ = u; + $ = t; + aa = r; + ab = q; + ac = o; + ad = n; + ae = l; + af = k; + ag = i; + ah = h; + ai = f; + aj = e; + bX(a, aj, ai); + bX(g, ah, ag); + bX(j, af, ae); + bX(m, ad, ac); + bX(p, ab, aa); + bX(s, $, _); + bX(v, Z, Y); + bX(y, X, W); + return 0; + } + while (1) { + e = bW(V) | 0; + f = H; + h = bW(V + 8 | 0) | 0; + i = H; + k = bW(V + 16 | 0) | 0; + l = H; + n = bW(V + 24 | 0) | 0; + o = H; + q = bW(V + 32 | 0) | 0; + r = H; + t = bW(V + 40 | 0) | 0; + u = H; + w = bW(V + 48 | 0) | 0; + x = H; + z = bW(V + 56 | 0) | 0; + A = H; + b = bW(V + 64 | 0) | 0; + c = H; + d = bW(V + 72 | 0) | 0; + B = H; + ak = bW(V + 80 | 0) | 0; + al = H; + am = bW(V + 88 | 0) | 0; + an = H; + ao = bW(V + 96 | 0) | 0; + ap = H; + aq = bW(V + 104 | 0) | 0; + ar = H; + as = bW(V + 112 | 0) | 0; + at = H; + au = bW(V + 120 | 0) | 0; + av = H; + aw = fp(D, C, -685199838, 1116352408) | 0; + ax = fp(aw, H, K & I ^ F & ~K, J & G ^ E & ~J) | 0; + aw = fp(ax, H, (K >>> 14 | J << 18 | (0 << 18 | 0 >>> 14)) ^ (K >>> 18 | J << 14 | (0 << 14 | 0 >>> 18)) ^ (J >>> 9 | 0 << 23 | (K << 23 | 0 >>> 9)), (J >>> 14 | 0 << 18 | (K << 18 | 0 >>> 14)) ^ (J >>> 18 | 0 << 14 | (K << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (J << 23 | K >>> 9))) | 0; + ax = fp(aw, H, e, f) | 0; + aw = H; + ay = S & Q; + az = R & P; + aA = fp((S >>> 28 | R << 4 | (0 << 4 | 0 >>> 28)) ^ (R >>> 2 | 0 << 30 | (S << 30 | 0 >>> 2)) ^ (R >>> 7 | 0 << 25 | (S << 25 | 0 >>> 7)), (R >>> 28 | 0 << 4 | (S << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (R << 30 | S >>> 2)) ^ (0 >>> 7 | 0 << 25 | (R << 25 | S >>> 7)), (S ^ Q) & O ^ ay, (R ^ P) & N ^ az) | 0; + aB = H; + aC = fp(ax, aw, M, L) | 0; + aD = H; + aE = fp(aA, aB, ax, aw) | 0; + aw = H; + ax = fp(F, E, 602891725, 1899447441) | 0; + aB = fp(ax, H, h, i) | 0; + ax = fp(aB, H, aC & K ^ I & ~aC, aD & J ^ G & ~aD) | 0; + aB = fp(ax, H, (aC >>> 14 | aD << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aD << 14 | (0 << 14 | 0 >>> 18)) ^ (aD >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aD >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aD >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aD << 23 | aC >>> 9))) | 0; + ax = H; + aA = aE & S; + aF = aw & R; + aG = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & Q ^ ay ^ aA, aw & P ^ az ^ aF) | 0; + az = H; + ay = fp(aB, ax, O, N) | 0; + aH = H; + aI = fp(aG, az, aB, ax) | 0; + ax = H; + aB = fp(I, G, -330482897, -1245643825) | 0; + az = fp(aB, H, k, l) | 0; + aB = fp(az, H, ay & aC ^ K & ~ay, aH & aD ^ J & ~aH) | 0; + az = fp(aB, H, (ay >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | ay >>> 9))) | 0; + aB = H; + aG = aI & aE; + aJ = ax & aw; + aK = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & S ^ aA ^ aG, ax & R ^ aF ^ aJ) | 0; + aF = H; + aA = fp(az, aB, Q, P) | 0; + aL = H; + aM = fp(aK, aF, az, aB) | 0; + aB = H; + az = fp(K, J, -2121671748, -373957723) | 0; + aF = fp(az, H, n, o) | 0; + az = fp(aF, H, aA & ay ^ aC & ~aA, aL & aH ^ aD & ~aL) | 0; + aF = fp(az, H, (aA >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aA >>> 9))) | 0; + az = H; + aK = aM & aI; + aN = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aG ^ aK, aB & aw ^ aJ ^ aN) | 0; + aJ = H; + aG = fp(aF, az, S, R) | 0; + aP = H; + aQ = fp(aO, aJ, aF, az) | 0; + az = H; + aF = fp(aC, aD, -213338824, 961987163) | 0; + aD = fp(aF, H, q, r) | 0; + aF = fp(aD, H, aG & aA ^ ay & ~aG, aP & aL ^ aH & ~aP) | 0; + aD = fp(aF, H, (aG >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aG >>> 9))) | 0; + aF = H; + aC = aQ & aM; + aJ = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aK ^ aC, az & ax ^ aN ^ aJ) | 0; + aN = H; + aK = fp(aD, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, aN, aD, aF) | 0; + aF = H; + aD = fp(t, u, -1241133031, 1508970993) | 0; + aN = fp(aD, H, ay, aH) | 0; + aH = fp(aN, H, aK & aG ^ aA & ~aK, aw & aP ^ aL & ~aw) | 0; + aN = fp(aH, H, (aK >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aK >>> 9))) | 0; + aH = H; + ay = aE & aQ; + aD = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aC ^ ay, aF & aB ^ aJ ^ aD) | 0; + aJ = H; + aC = fp(aN, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, aJ, aN, aH) | 0; + aH = H; + aN = fp(w, x, -1357295717, -1841331548) | 0; + aJ = fp(aN, H, aA, aL) | 0; + aL = fp(aJ, H, aC & aK ^ aG & ~aC, ax & aw ^ aP & ~ax) | 0; + aJ = fp(aL, H, (aC >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aC >>> 9))) | 0; + aL = H; + aA = aI & aE; + aN = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ ay ^ aA, aH & az ^ aD ^ aN) | 0; + aD = H; + ay = fp(aJ, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, aD, aJ, aL) | 0; + aL = H; + aJ = fp(z, A, -630357736, -1424204075) | 0; + aD = fp(aJ, H, aG, aP) | 0; + aP = fp(aD, H, ay & aC ^ aK & ~ay, aB & ax ^ aw & ~aB) | 0; + aD = fp(aP, H, (ay >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | ay >>> 9))) | 0; + aP = H; + aG = aM & aI; + aJ = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aA ^ aG, aL & aF ^ aN ^ aJ) | 0; + aN = H; + aA = fp(aD, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, aN, aD, aP) | 0; + aP = H; + aD = fp(b, c, -1560083902, -670586216) | 0; + aN = fp(aD, H, aK, aw) | 0; + aw = fp(aN, H, aA & ay ^ aC & ~aA, az & aB ^ ax & ~az) | 0; + aN = fp(aw, H, (aA >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aA >>> 9))) | 0; + aw = H; + aK = aQ & aM; + aD = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aG ^ aK, aP & aH ^ aJ ^ aD) | 0; + aJ = H; + aG = fp(aN, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, aJ, aN, aw) | 0; + aw = H; + aN = fp(d, B, 1164996542, 310598401) | 0; + aJ = fp(aN, H, aC, ax) | 0; + ax = fp(aJ, H, aG & aA ^ ay & ~aG, aF & az ^ aB & ~aF) | 0; + aJ = fp(ax, H, (aG >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aG >>> 9))) | 0; + ax = H; + aC = aE & aQ; + aN = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aK ^ aC, aw & aL ^ aD ^ aN) | 0; + aD = H; + aK = fp(aJ, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, aD, aJ, ax) | 0; + ax = H; + aJ = fp(ak, al, 1323610764, 607225278) | 0; + aD = fp(aJ, H, ay, aB) | 0; + aB = fp(aD, H, aK & aG ^ aA & ~aK, aH & aF ^ az & ~aH) | 0; + aD = fp(aB, H, (aK >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aK >>> 9))) | 0; + aB = H; + ay = aI & aE; + aJ = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aC ^ ay, ax & aP ^ aN ^ aJ) | 0; + aN = H; + aC = fp(aD, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, aN, aD, aB) | 0; + aB = H; + aD = fp(am, an, -704662302, 1426881987) | 0; + aN = fp(aD, H, aA, az) | 0; + az = fp(aN, H, aC & aK ^ aG & ~aC, aL & aH ^ aF & ~aL) | 0; + aN = fp(az, H, (aC >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aC >>> 9))) | 0; + az = H; + aA = aM & aI; + aD = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ ay ^ aA, aB & aw ^ aJ ^ aD) | 0; + aJ = H; + ay = fp(aN, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, aJ, aN, az) | 0; + az = H; + aN = fp(ao, ap, -226784913, 1925078388) | 0; + aJ = fp(aN, H, aG, aF) | 0; + aF = fp(aJ, H, ay & aC ^ aK & ~ay, aP & aL ^ aH & ~aP) | 0; + aJ = fp(aF, H, (ay >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | ay >>> 9))) | 0; + aF = H; + aG = aQ & aM; + aN = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aA ^ aG, az & ax ^ aD ^ aN) | 0; + aD = H; + aA = fp(aJ, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, aD, aJ, aF) | 0; + aF = H; + aJ = fp(aq, ar, 991336113, -2132889090) | 0; + aD = fp(aJ, H, aK, aH) | 0; + aH = fp(aD, H, aA & ay ^ aC & ~aA, aw & aP ^ aL & ~aw) | 0; + aD = fp(aH, H, (aA >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aA >>> 9))) | 0; + aH = H; + aK = aE & aQ; + aJ = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aG ^ aK, aF & aB ^ aN ^ aJ) | 0; + aN = H; + aG = fp(aD, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, aN, aD, aH) | 0; + aH = H; + aD = fp(as, at, 633803317, -1680079193) | 0; + aN = fp(aD, H, aC, aL) | 0; + aL = fp(aN, H, aG & aA ^ ay & ~aG, ax & aw ^ aP & ~ax) | 0; + aN = fp(aL, H, (aG >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aG >>> 9))) | 0; + aL = H; + aC = aI & aE; + aD = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aK ^ aC, aH & az ^ aJ ^ aD) | 0; + aJ = H; + aK = fp(aN, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, aJ, aN, aL) | 0; + aL = H; + aN = fp(au, av, -815192428, -1046744716) | 0; + aJ = fp(aN, H, ay, aP) | 0; + aP = fp(aJ, H, aK & aG ^ aA & ~aK, aB & ax ^ aw & ~aB) | 0; + aJ = fp(aP, H, (aK >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aK >>> 9))) | 0; + aP = H; + ay = aM & aI; + aN = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aC ^ ay, aL & aF ^ aD ^ aN) | 0; + aD = H; + aC = fp(aJ, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, aD, aJ, aP) | 0; + aP = H; + aJ = fp((h >>> 8 | i << 24 | (0 << 24 | 0 >>> 8)) ^ (h >>> 7 | i << 25) ^ (h >>> 1 | i << 31 | (0 << 31 | 0 >>> 1)), (i >>> 8 | 0 << 24 | (h << 24 | 0 >>> 8)) ^ (i >>> 7 | 0 << 25) ^ (i >>> 1 | 0 << 31 | (h << 31 | 0 >>> 1)), e, f) | 0; + f = fp(aJ, H, d, B) | 0; + aJ = fp(f, H, (at >>> 29 | 0 << 3 | (as << 3 | 0 >>> 29)) ^ (as >>> 6 | at << 26) ^ (as >>> 19 | at << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (at << 3 | as >>> 29)) ^ (at >>> 6 | 0 << 26) ^ (at >>> 19 | 0 << 13 | (as << 13 | 0 >>> 19))) | 0; + f = H; + e = fp((k >>> 8 | l << 24 | (0 << 24 | 0 >>> 8)) ^ (k >>> 7 | l << 25) ^ (k >>> 1 | l << 31 | (0 << 31 | 0 >>> 1)), (l >>> 8 | 0 << 24 | (k << 24 | 0 >>> 8)) ^ (l >>> 7 | 0 << 25) ^ (l >>> 1 | 0 << 31 | (k << 31 | 0 >>> 1)), h, i) | 0; + i = fp(e, H, ak, al) | 0; + e = fp(i, H, (av >>> 29 | 0 << 3 | (au << 3 | 0 >>> 29)) ^ (au >>> 6 | av << 26) ^ (au >>> 19 | av << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (av << 3 | au >>> 29)) ^ (av >>> 6 | 0 << 26) ^ (av >>> 19 | 0 << 13 | (au << 13 | 0 >>> 19))) | 0; + i = H; + h = fp((n >>> 8 | o << 24 | (0 << 24 | 0 >>> 8)) ^ (n >>> 7 | o << 25) ^ (n >>> 1 | o << 31 | (0 << 31 | 0 >>> 1)), (o >>> 8 | 0 << 24 | (n << 24 | 0 >>> 8)) ^ (o >>> 7 | 0 << 25) ^ (o >>> 1 | 0 << 31 | (n << 31 | 0 >>> 1)), k, l) | 0; + l = fp(h, H, am, an) | 0; + h = fp(l, H, (f >>> 29 | 0 << 3 | (aJ << 3 | 0 >>> 29)) ^ (aJ >>> 6 | f << 26) ^ (aJ >>> 19 | f << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (f << 3 | aJ >>> 29)) ^ (f >>> 6 | 0 << 26) ^ (f >>> 19 | 0 << 13 | (aJ << 13 | 0 >>> 19))) | 0; + l = H; + k = fp((q >>> 8 | r << 24 | (0 << 24 | 0 >>> 8)) ^ (q >>> 7 | r << 25) ^ (q >>> 1 | r << 31 | (0 << 31 | 0 >>> 1)), (r >>> 8 | 0 << 24 | (q << 24 | 0 >>> 8)) ^ (r >>> 7 | 0 << 25) ^ (r >>> 1 | 0 << 31 | (q << 31 | 0 >>> 1)), n, o) | 0; + o = fp(k, H, ao, ap) | 0; + k = fp(o, H, (i >>> 29 | 0 << 3 | (e << 3 | 0 >>> 29)) ^ (e >>> 6 | i << 26) ^ (e >>> 19 | i << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (i << 3 | e >>> 29)) ^ (i >>> 6 | 0 << 26) ^ (i >>> 19 | 0 << 13 | (e << 13 | 0 >>> 19))) | 0; + o = H; + n = fp((t >>> 8 | u << 24 | (0 << 24 | 0 >>> 8)) ^ (t >>> 7 | u << 25) ^ (t >>> 1 | u << 31 | (0 << 31 | 0 >>> 1)), (u >>> 8 | 0 << 24 | (t << 24 | 0 >>> 8)) ^ (u >>> 7 | 0 << 25) ^ (u >>> 1 | 0 << 31 | (t << 31 | 0 >>> 1)), q, r) | 0; + r = fp(n, H, aq, ar) | 0; + n = fp(r, H, (l >>> 29 | 0 << 3 | (h << 3 | 0 >>> 29)) ^ (h >>> 6 | l << 26) ^ (h >>> 19 | l << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (l << 3 | h >>> 29)) ^ (l >>> 6 | 0 << 26) ^ (l >>> 19 | 0 << 13 | (h << 13 | 0 >>> 19))) | 0; + r = H; + q = fp((w >>> 8 | x << 24 | (0 << 24 | 0 >>> 8)) ^ (w >>> 7 | x << 25) ^ (w >>> 1 | x << 31 | (0 << 31 | 0 >>> 1)), (x >>> 8 | 0 << 24 | (w << 24 | 0 >>> 8)) ^ (x >>> 7 | 0 << 25) ^ (x >>> 1 | 0 << 31 | (w << 31 | 0 >>> 1)), t, u) | 0; + u = fp(q, H, as, at) | 0; + q = fp(u, H, (o >>> 29 | 0 << 3 | (k << 3 | 0 >>> 29)) ^ (k >>> 6 | o << 26) ^ (k >>> 19 | o << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (o << 3 | k >>> 29)) ^ (o >>> 6 | 0 << 26) ^ (o >>> 19 | 0 << 13 | (k << 13 | 0 >>> 19))) | 0; + u = H; + t = fp((z >>> 8 | A << 24 | (0 << 24 | 0 >>> 8)) ^ (z >>> 7 | A << 25) ^ (z >>> 1 | A << 31 | (0 << 31 | 0 >>> 1)), (A >>> 8 | 0 << 24 | (z << 24 | 0 >>> 8)) ^ (A >>> 7 | 0 << 25) ^ (A >>> 1 | 0 << 31 | (z << 31 | 0 >>> 1)), w, x) | 0; + x = fp(t, H, au, av) | 0; + t = fp(x, H, (r >>> 29 | 0 << 3 | (n << 3 | 0 >>> 29)) ^ (n >>> 6 | r << 26) ^ (n >>> 19 | r << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (r << 3 | n >>> 29)) ^ (r >>> 6 | 0 << 26) ^ (r >>> 19 | 0 << 13 | (n << 13 | 0 >>> 19))) | 0; + x = H; + w = fp((b >>> 8 | c << 24 | (0 << 24 | 0 >>> 8)) ^ (b >>> 7 | c << 25) ^ (b >>> 1 | c << 31 | (0 << 31 | 0 >>> 1)), (c >>> 8 | 0 << 24 | (b << 24 | 0 >>> 8)) ^ (c >>> 7 | 0 << 25) ^ (c >>> 1 | 0 << 31 | (b << 31 | 0 >>> 1)), z, A) | 0; + A = fp(w, H, aJ, f) | 0; + w = fp(A, H, (u >>> 29 | 0 << 3 | (q << 3 | 0 >>> 29)) ^ (q >>> 6 | u << 26) ^ (q >>> 19 | u << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (u << 3 | q >>> 29)) ^ (u >>> 6 | 0 << 26) ^ (u >>> 19 | 0 << 13 | (q << 13 | 0 >>> 19))) | 0; + A = H; + z = fp((d >>> 8 | B << 24 | (0 << 24 | 0 >>> 8)) ^ (d >>> 7 | B << 25) ^ (d >>> 1 | B << 31 | (0 << 31 | 0 >>> 1)), (B >>> 8 | 0 << 24 | (d << 24 | 0 >>> 8)) ^ (B >>> 7 | 0 << 25) ^ (B >>> 1 | 0 << 31 | (d << 31 | 0 >>> 1)), b, c) | 0; + c = fp(z, H, e, i) | 0; + z = fp(c, H, (x >>> 29 | 0 << 3 | (t << 3 | 0 >>> 29)) ^ (t >>> 6 | x << 26) ^ (t >>> 19 | x << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (x << 3 | t >>> 29)) ^ (x >>> 6 | 0 << 26) ^ (x >>> 19 | 0 << 13 | (t << 13 | 0 >>> 19))) | 0; + c = H; + b = fp((ak >>> 8 | al << 24 | (0 << 24 | 0 >>> 8)) ^ (ak >>> 7 | al << 25) ^ (ak >>> 1 | al << 31 | (0 << 31 | 0 >>> 1)), (al >>> 8 | 0 << 24 | (ak << 24 | 0 >>> 8)) ^ (al >>> 7 | 0 << 25) ^ (al >>> 1 | 0 << 31 | (ak << 31 | 0 >>> 1)), d, B) | 0; + B = fp(b, H, h, l) | 0; + b = fp(B, H, (A >>> 29 | 0 << 3 | (w << 3 | 0 >>> 29)) ^ (w >>> 6 | A << 26) ^ (w >>> 19 | A << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (A << 3 | w >>> 29)) ^ (A >>> 6 | 0 << 26) ^ (A >>> 19 | 0 << 13 | (w << 13 | 0 >>> 19))) | 0; + B = H; + d = fp((am >>> 8 | an << 24 | (0 << 24 | 0 >>> 8)) ^ (am >>> 7 | an << 25) ^ (am >>> 1 | an << 31 | (0 << 31 | 0 >>> 1)), (an >>> 8 | 0 << 24 | (am << 24 | 0 >>> 8)) ^ (an >>> 7 | 0 << 25) ^ (an >>> 1 | 0 << 31 | (am << 31 | 0 >>> 1)), ak, al) | 0; + al = fp(d, H, k, o) | 0; + d = fp(al, H, (c >>> 29 | 0 << 3 | (z << 3 | 0 >>> 29)) ^ (z >>> 6 | c << 26) ^ (z >>> 19 | c << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (c << 3 | z >>> 29)) ^ (c >>> 6 | 0 << 26) ^ (c >>> 19 | 0 << 13 | (z << 13 | 0 >>> 19))) | 0; + al = H; + ak = fp((ao >>> 8 | ap << 24 | (0 << 24 | 0 >>> 8)) ^ (ao >>> 7 | ap << 25) ^ (ao >>> 1 | ap << 31 | (0 << 31 | 0 >>> 1)), (ap >>> 8 | 0 << 24 | (ao << 24 | 0 >>> 8)) ^ (ap >>> 7 | 0 << 25) ^ (ap >>> 1 | 0 << 31 | (ao << 31 | 0 >>> 1)), am, an) | 0; + an = fp(ak, H, n, r) | 0; + ak = fp(an, H, (B >>> 29 | 0 << 3 | (b << 3 | 0 >>> 29)) ^ (b >>> 6 | B << 26) ^ (b >>> 19 | B << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (B << 3 | b >>> 29)) ^ (B >>> 6 | 0 << 26) ^ (B >>> 19 | 0 << 13 | (b << 13 | 0 >>> 19))) | 0; + an = H; + am = fp((aq >>> 8 | ar << 24 | (0 << 24 | 0 >>> 8)) ^ (aq >>> 7 | ar << 25) ^ (aq >>> 1 | ar << 31 | (0 << 31 | 0 >>> 1)), (ar >>> 8 | 0 << 24 | (aq << 24 | 0 >>> 8)) ^ (ar >>> 7 | 0 << 25) ^ (ar >>> 1 | 0 << 31 | (aq << 31 | 0 >>> 1)), ao, ap) | 0; + ap = fp(am, H, q, u) | 0; + am = fp(ap, H, (al >>> 29 | 0 << 3 | (d << 3 | 0 >>> 29)) ^ (d >>> 6 | al << 26) ^ (d >>> 19 | al << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (al << 3 | d >>> 29)) ^ (al >>> 6 | 0 << 26) ^ (al >>> 19 | 0 << 13 | (d << 13 | 0 >>> 19))) | 0; + ap = H; + ao = fp((as >>> 8 | at << 24 | (0 << 24 | 0 >>> 8)) ^ (as >>> 7 | at << 25) ^ (as >>> 1 | at << 31 | (0 << 31 | 0 >>> 1)), (at >>> 8 | 0 << 24 | (as << 24 | 0 >>> 8)) ^ (at >>> 7 | 0 << 25) ^ (at >>> 1 | 0 << 31 | (as << 31 | 0 >>> 1)), aq, ar) | 0; + ar = fp(ao, H, t, x) | 0; + ao = fp(ar, H, (an >>> 29 | 0 << 3 | (ak << 3 | 0 >>> 29)) ^ (ak >>> 6 | an << 26) ^ (ak >>> 19 | an << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (an << 3 | ak >>> 29)) ^ (an >>> 6 | 0 << 26) ^ (an >>> 19 | 0 << 13 | (ak << 13 | 0 >>> 19))) | 0; + ar = H; + aq = fp((au >>> 8 | av << 24 | (0 << 24 | 0 >>> 8)) ^ (au >>> 7 | av << 25) ^ (au >>> 1 | av << 31 | (0 << 31 | 0 >>> 1)), (av >>> 8 | 0 << 24 | (au << 24 | 0 >>> 8)) ^ (av >>> 7 | 0 << 25) ^ (av >>> 1 | 0 << 31 | (au << 31 | 0 >>> 1)), as, at) | 0; + at = fp(aq, H, w, A) | 0; + aq = fp(at, H, (ap >>> 29 | 0 << 3 | (am << 3 | 0 >>> 29)) ^ (am >>> 6 | ap << 26) ^ (am >>> 19 | ap << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ap << 3 | am >>> 29)) ^ (ap >>> 6 | 0 << 26) ^ (ap >>> 19 | 0 << 13 | (am << 13 | 0 >>> 19))) | 0; + at = H; + as = fp((aJ >>> 8 | f << 24 | (0 << 24 | 0 >>> 8)) ^ (aJ >>> 7 | f << 25) ^ (aJ >>> 1 | f << 31 | (0 << 31 | 0 >>> 1)), (f >>> 8 | 0 << 24 | (aJ << 24 | 0 >>> 8)) ^ (f >>> 7 | 0 << 25) ^ (f >>> 1 | 0 << 31 | (aJ << 31 | 0 >>> 1)), au, av) | 0; + av = fp(as, H, z, c) | 0; + as = fp(av, H, (ar >>> 29 | 0 << 3 | (ao << 3 | 0 >>> 29)) ^ (ao >>> 6 | ar << 26) ^ (ao >>> 19 | ar << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ar << 3 | ao >>> 29)) ^ (ar >>> 6 | 0 << 26) ^ (ar >>> 19 | 0 << 13 | (ao << 13 | 0 >>> 19))) | 0; + av = H; + au = fp(aJ, f, -1628353838, -459576895) | 0; + aD = fp(au, H, aA, aw) | 0; + aw = fp(aD, H, aC & aK ^ aG & ~aC, az & aB ^ ax & ~az) | 0; + aD = fp(aw, H, (aC >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aC >>> 9))) | 0; + aw = H; + aA = aQ & aM; + au = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ ay ^ aA, aP & aH ^ aN ^ au) | 0; + aN = H; + ay = fp(aD, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, aN, aD, aw) | 0; + aw = H; + aD = fp(e, i, 944711139, -272742522) | 0; + aN = fp(aD, H, aG, ax) | 0; + ax = fp(aN, H, ay & aC ^ aK & ~ay, aF & az ^ aB & ~aF) | 0; + aN = fp(ax, H, (ay >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | ay >>> 9))) | 0; + ax = H; + aG = aE & aQ; + aD = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aA ^ aG, aw & aL ^ au ^ aD) | 0; + au = H; + aA = fp(aN, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, au, aN, ax) | 0; + ax = H; + aN = fp(h, l, -1953704523, 264347078) | 0; + au = fp(aN, H, aK, aB) | 0; + aB = fp(au, H, aA & ay ^ aC & ~aA, aH & aF ^ az & ~aH) | 0; + au = fp(aB, H, (aA >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aA >>> 9))) | 0; + aB = H; + aK = aI & aE; + aN = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aG ^ aK, ax & aP ^ aD ^ aN) | 0; + aD = H; + aG = fp(au, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, aD, au, aB) | 0; + aB = H; + au = fp(k, o, 2007800933, 604807628) | 0; + aD = fp(au, H, aC, az) | 0; + az = fp(aD, H, aG & aA ^ ay & ~aG, aL & aH ^ aF & ~aL) | 0; + aD = fp(az, H, (aG >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aG >>> 9))) | 0; + az = H; + aC = aM & aI; + au = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aK ^ aC, aB & aw ^ aN ^ au) | 0; + aN = H; + aK = fp(aD, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, aN, aD, az) | 0; + az = H; + aD = fp(n, r, 1495990901, 770255983) | 0; + aN = fp(aD, H, ay, aF) | 0; + aF = fp(aN, H, aK & aG ^ aA & ~aK, aP & aL ^ aH & ~aP) | 0; + aN = fp(aF, H, (aK >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aK >>> 9))) | 0; + aF = H; + ay = aQ & aM; + aD = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aC ^ ay, az & ax ^ au ^ aD) | 0; + au = H; + aC = fp(aN, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, au, aN, aF) | 0; + aF = H; + aN = fp(q, u, 1856431235, 1249150122) | 0; + au = fp(aN, H, aA, aH) | 0; + aH = fp(au, H, aC & aK ^ aG & ~aC, aw & aP ^ aL & ~aw) | 0; + au = fp(aH, H, (aC >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aC >>> 9))) | 0; + aH = H; + aA = aE & aQ; + aN = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ ay ^ aA, aF & aB ^ aD ^ aN) | 0; + aD = H; + ay = fp(au, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, aD, au, aH) | 0; + aH = H; + au = fp(t, x, -1119749164, 1555081692) | 0; + aD = fp(au, H, aG, aL) | 0; + aL = fp(aD, H, ay & aC ^ aK & ~ay, ax & aw ^ aP & ~ax) | 0; + aD = fp(aL, H, (ay >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | ay >>> 9))) | 0; + aL = H; + aG = aI & aE; + au = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aA ^ aG, aH & az ^ aN ^ au) | 0; + aN = H; + aA = fp(aD, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, aN, aD, aL) | 0; + aL = H; + aD = fp(w, A, -2096016459, 1996064986) | 0; + aN = fp(aD, H, aK, aP) | 0; + aP = fp(aN, H, aA & ay ^ aC & ~aA, aB & ax ^ aw & ~aB) | 0; + aN = fp(aP, H, (aA >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aA >>> 9))) | 0; + aP = H; + aK = aM & aI; + aD = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aG ^ aK, aL & aF ^ au ^ aD) | 0; + au = H; + aG = fp(aN, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, au, aN, aP) | 0; + aP = H; + aN = fp(z, c, -295247957, -1740746414) | 0; + au = fp(aN, H, aC, aw) | 0; + aw = fp(au, H, aG & aA ^ ay & ~aG, az & aB ^ ax & ~az) | 0; + au = fp(aw, H, (aG >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aG >>> 9))) | 0; + aw = H; + aC = aQ & aM; + aN = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aK ^ aC, aP & aH ^ aD ^ aN) | 0; + aD = H; + aK = fp(au, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, aD, au, aw) | 0; + aw = H; + au = fp(b, B, 766784016, -1473132947) | 0; + aD = fp(au, H, ay, ax) | 0; + ax = fp(aD, H, aK & aG ^ aA & ~aK, aF & az ^ aB & ~aF) | 0; + aD = fp(ax, H, (aK >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aK >>> 9))) | 0; + ax = H; + ay = aE & aQ; + au = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aC ^ ay, aw & aL ^ aN ^ au) | 0; + aN = H; + aC = fp(aD, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, aN, aD, ax) | 0; + ax = H; + aD = fp(d, al, -1728372417, -1341970488) | 0; + aN = fp(aD, H, aA, aB) | 0; + aB = fp(aN, H, aC & aK ^ aG & ~aC, aH & aF ^ az & ~aH) | 0; + aN = fp(aB, H, (aC >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aC >>> 9))) | 0; + aB = H; + aA = aI & aE; + aD = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ ay ^ aA, ax & aP ^ au ^ aD) | 0; + au = H; + ay = fp(aN, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, au, aN, aB) | 0; + aB = H; + aN = fp(ak, an, -1091629340, -1084653625) | 0; + au = fp(aN, H, aG, az) | 0; + az = fp(au, H, ay & aC ^ aK & ~ay, aL & aH ^ aF & ~aL) | 0; + au = fp(az, H, (ay >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | ay >>> 9))) | 0; + az = H; + aG = aM & aI; + aN = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aA ^ aG, aB & aw ^ aD ^ aN) | 0; + aD = H; + aA = fp(au, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, aD, au, az) | 0; + az = H; + au = fp(am, ap, 1034457026, -958395405) | 0; + aD = fp(au, H, aK, aF) | 0; + aF = fp(aD, H, aA & ay ^ aC & ~aA, aP & aL ^ aH & ~aP) | 0; + aD = fp(aF, H, (aA >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aA >>> 9))) | 0; + aF = H; + aK = aQ & aM; + au = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aG ^ aK, az & ax ^ aN ^ au) | 0; + aN = H; + aG = fp(aD, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, aN, aD, aF) | 0; + aF = H; + aD = fp(ao, ar, -1828018395, -710438585) | 0; + aN = fp(aD, H, aC, aH) | 0; + aH = fp(aN, H, aG & aA ^ ay & ~aG, aw & aP ^ aL & ~aw) | 0; + aN = fp(aH, H, (aG >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aG >>> 9))) | 0; + aH = H; + aC = aE & aQ; + aD = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aK ^ aC, aF & aB ^ au ^ aD) | 0; + au = H; + aK = fp(aN, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, au, aN, aH) | 0; + aH = H; + aN = fp(aq, at, -536640913, 113926993) | 0; + au = fp(aN, H, ay, aL) | 0; + aL = fp(au, H, aK & aG ^ aA & ~aK, ax & aw ^ aP & ~ax) | 0; + au = fp(aL, H, (aK >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aK >>> 9))) | 0; + aL = H; + ay = aI & aE; + aN = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aC ^ ay, aH & az ^ aD ^ aN) | 0; + aD = H; + aC = fp(au, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, aD, au, aL) | 0; + aL = H; + au = fp(as, av, 168717936, 338241895) | 0; + aD = fp(au, H, aA, aP) | 0; + aP = fp(aD, H, aC & aK ^ aG & ~aC, aB & ax ^ aw & ~aB) | 0; + aD = fp(aP, H, (aC >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aC >>> 9))) | 0; + aP = H; + aA = aM & aI; + au = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ ay ^ aA, aL & aF ^ aN ^ au) | 0; + aN = H; + ay = fp(aD, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, aN, aD, aP) | 0; + aP = H; + aD = fp((e >>> 8 | i << 24 | (0 << 24 | 0 >>> 8)) ^ (e >>> 7 | i << 25) ^ (e >>> 1 | i << 31 | (0 << 31 | 0 >>> 1)), (i >>> 8 | 0 << 24 | (e << 24 | 0 >>> 8)) ^ (i >>> 7 | 0 << 25) ^ (i >>> 1 | 0 << 31 | (e << 31 | 0 >>> 1)), aJ, f) | 0; + f = fp(aD, H, b, B) | 0; + aD = fp(f, H, (at >>> 29 | 0 << 3 | (aq << 3 | 0 >>> 29)) ^ (aq >>> 6 | at << 26) ^ (aq >>> 19 | at << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (at << 3 | aq >>> 29)) ^ (at >>> 6 | 0 << 26) ^ (at >>> 19 | 0 << 13 | (aq << 13 | 0 >>> 19))) | 0; + f = H; + aJ = fp((h >>> 8 | l << 24 | (0 << 24 | 0 >>> 8)) ^ (h >>> 7 | l << 25) ^ (h >>> 1 | l << 31 | (0 << 31 | 0 >>> 1)), (l >>> 8 | 0 << 24 | (h << 24 | 0 >>> 8)) ^ (l >>> 7 | 0 << 25) ^ (l >>> 1 | 0 << 31 | (h << 31 | 0 >>> 1)), e, i) | 0; + i = fp(aJ, H, d, al) | 0; + aJ = fp(i, H, (av >>> 29 | 0 << 3 | (as << 3 | 0 >>> 29)) ^ (as >>> 6 | av << 26) ^ (as >>> 19 | av << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (av << 3 | as >>> 29)) ^ (av >>> 6 | 0 << 26) ^ (av >>> 19 | 0 << 13 | (as << 13 | 0 >>> 19))) | 0; + i = H; + e = fp((k >>> 8 | o << 24 | (0 << 24 | 0 >>> 8)) ^ (k >>> 7 | o << 25) ^ (k >>> 1 | o << 31 | (0 << 31 | 0 >>> 1)), (o >>> 8 | 0 << 24 | (k << 24 | 0 >>> 8)) ^ (o >>> 7 | 0 << 25) ^ (o >>> 1 | 0 << 31 | (k << 31 | 0 >>> 1)), h, l) | 0; + l = fp(e, H, ak, an) | 0; + e = fp(l, H, (f >>> 29 | 0 << 3 | (aD << 3 | 0 >>> 29)) ^ (aD >>> 6 | f << 26) ^ (aD >>> 19 | f << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (f << 3 | aD >>> 29)) ^ (f >>> 6 | 0 << 26) ^ (f >>> 19 | 0 << 13 | (aD << 13 | 0 >>> 19))) | 0; + l = H; + h = fp((n >>> 8 | r << 24 | (0 << 24 | 0 >>> 8)) ^ (n >>> 7 | r << 25) ^ (n >>> 1 | r << 31 | (0 << 31 | 0 >>> 1)), (r >>> 8 | 0 << 24 | (n << 24 | 0 >>> 8)) ^ (r >>> 7 | 0 << 25) ^ (r >>> 1 | 0 << 31 | (n << 31 | 0 >>> 1)), k, o) | 0; + o = fp(h, H, am, ap) | 0; + h = fp(o, H, (i >>> 29 | 0 << 3 | (aJ << 3 | 0 >>> 29)) ^ (aJ >>> 6 | i << 26) ^ (aJ >>> 19 | i << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (i << 3 | aJ >>> 29)) ^ (i >>> 6 | 0 << 26) ^ (i >>> 19 | 0 << 13 | (aJ << 13 | 0 >>> 19))) | 0; + o = H; + k = fp((q >>> 8 | u << 24 | (0 << 24 | 0 >>> 8)) ^ (q >>> 7 | u << 25) ^ (q >>> 1 | u << 31 | (0 << 31 | 0 >>> 1)), (u >>> 8 | 0 << 24 | (q << 24 | 0 >>> 8)) ^ (u >>> 7 | 0 << 25) ^ (u >>> 1 | 0 << 31 | (q << 31 | 0 >>> 1)), n, r) | 0; + r = fp(k, H, ao, ar) | 0; + k = fp(r, H, (l >>> 29 | 0 << 3 | (e << 3 | 0 >>> 29)) ^ (e >>> 6 | l << 26) ^ (e >>> 19 | l << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (l << 3 | e >>> 29)) ^ (l >>> 6 | 0 << 26) ^ (l >>> 19 | 0 << 13 | (e << 13 | 0 >>> 19))) | 0; + r = H; + n = fp((t >>> 8 | x << 24 | (0 << 24 | 0 >>> 8)) ^ (t >>> 7 | x << 25) ^ (t >>> 1 | x << 31 | (0 << 31 | 0 >>> 1)), (x >>> 8 | 0 << 24 | (t << 24 | 0 >>> 8)) ^ (x >>> 7 | 0 << 25) ^ (x >>> 1 | 0 << 31 | (t << 31 | 0 >>> 1)), q, u) | 0; + u = fp(n, H, aq, at) | 0; + n = fp(u, H, (o >>> 29 | 0 << 3 | (h << 3 | 0 >>> 29)) ^ (h >>> 6 | o << 26) ^ (h >>> 19 | o << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (o << 3 | h >>> 29)) ^ (o >>> 6 | 0 << 26) ^ (o >>> 19 | 0 << 13 | (h << 13 | 0 >>> 19))) | 0; + u = H; + q = fp((w >>> 8 | A << 24 | (0 << 24 | 0 >>> 8)) ^ (w >>> 7 | A << 25) ^ (w >>> 1 | A << 31 | (0 << 31 | 0 >>> 1)), (A >>> 8 | 0 << 24 | (w << 24 | 0 >>> 8)) ^ (A >>> 7 | 0 << 25) ^ (A >>> 1 | 0 << 31 | (w << 31 | 0 >>> 1)), t, x) | 0; + x = fp(q, H, as, av) | 0; + q = fp(x, H, (r >>> 29 | 0 << 3 | (k << 3 | 0 >>> 29)) ^ (k >>> 6 | r << 26) ^ (k >>> 19 | r << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (r << 3 | k >>> 29)) ^ (r >>> 6 | 0 << 26) ^ (r >>> 19 | 0 << 13 | (k << 13 | 0 >>> 19))) | 0; + x = H; + t = fp((z >>> 8 | c << 24 | (0 << 24 | 0 >>> 8)) ^ (z >>> 7 | c << 25) ^ (z >>> 1 | c << 31 | (0 << 31 | 0 >>> 1)), (c >>> 8 | 0 << 24 | (z << 24 | 0 >>> 8)) ^ (c >>> 7 | 0 << 25) ^ (c >>> 1 | 0 << 31 | (z << 31 | 0 >>> 1)), w, A) | 0; + A = fp(t, H, aD, f) | 0; + t = fp(A, H, (u >>> 29 | 0 << 3 | (n << 3 | 0 >>> 29)) ^ (n >>> 6 | u << 26) ^ (n >>> 19 | u << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (u << 3 | n >>> 29)) ^ (u >>> 6 | 0 << 26) ^ (u >>> 19 | 0 << 13 | (n << 13 | 0 >>> 19))) | 0; + A = H; + w = fp((b >>> 8 | B << 24 | (0 << 24 | 0 >>> 8)) ^ (b >>> 7 | B << 25) ^ (b >>> 1 | B << 31 | (0 << 31 | 0 >>> 1)), (B >>> 8 | 0 << 24 | (b << 24 | 0 >>> 8)) ^ (B >>> 7 | 0 << 25) ^ (B >>> 1 | 0 << 31 | (b << 31 | 0 >>> 1)), z, c) | 0; + c = fp(w, H, aJ, i) | 0; + w = fp(c, H, (x >>> 29 | 0 << 3 | (q << 3 | 0 >>> 29)) ^ (q >>> 6 | x << 26) ^ (q >>> 19 | x << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (x << 3 | q >>> 29)) ^ (x >>> 6 | 0 << 26) ^ (x >>> 19 | 0 << 13 | (q << 13 | 0 >>> 19))) | 0; + c = H; + z = fp((d >>> 8 | al << 24 | (0 << 24 | 0 >>> 8)) ^ (d >>> 7 | al << 25) ^ (d >>> 1 | al << 31 | (0 << 31 | 0 >>> 1)), (al >>> 8 | 0 << 24 | (d << 24 | 0 >>> 8)) ^ (al >>> 7 | 0 << 25) ^ (al >>> 1 | 0 << 31 | (d << 31 | 0 >>> 1)), b, B) | 0; + B = fp(z, H, e, l) | 0; + z = fp(B, H, (A >>> 29 | 0 << 3 | (t << 3 | 0 >>> 29)) ^ (t >>> 6 | A << 26) ^ (t >>> 19 | A << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (A << 3 | t >>> 29)) ^ (A >>> 6 | 0 << 26) ^ (A >>> 19 | 0 << 13 | (t << 13 | 0 >>> 19))) | 0; + B = H; + b = fp((ak >>> 8 | an << 24 | (0 << 24 | 0 >>> 8)) ^ (ak >>> 7 | an << 25) ^ (ak >>> 1 | an << 31 | (0 << 31 | 0 >>> 1)), (an >>> 8 | 0 << 24 | (ak << 24 | 0 >>> 8)) ^ (an >>> 7 | 0 << 25) ^ (an >>> 1 | 0 << 31 | (ak << 31 | 0 >>> 1)), d, al) | 0; + al = fp(b, H, h, o) | 0; + b = fp(al, H, (c >>> 29 | 0 << 3 | (w << 3 | 0 >>> 29)) ^ (w >>> 6 | c << 26) ^ (w >>> 19 | c << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (c << 3 | w >>> 29)) ^ (c >>> 6 | 0 << 26) ^ (c >>> 19 | 0 << 13 | (w << 13 | 0 >>> 19))) | 0; + al = H; + d = fp((am >>> 8 | ap << 24 | (0 << 24 | 0 >>> 8)) ^ (am >>> 7 | ap << 25) ^ (am >>> 1 | ap << 31 | (0 << 31 | 0 >>> 1)), (ap >>> 8 | 0 << 24 | (am << 24 | 0 >>> 8)) ^ (ap >>> 7 | 0 << 25) ^ (ap >>> 1 | 0 << 31 | (am << 31 | 0 >>> 1)), ak, an) | 0; + an = fp(d, H, k, r) | 0; + d = fp(an, H, (B >>> 29 | 0 << 3 | (z << 3 | 0 >>> 29)) ^ (z >>> 6 | B << 26) ^ (z >>> 19 | B << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (B << 3 | z >>> 29)) ^ (B >>> 6 | 0 << 26) ^ (B >>> 19 | 0 << 13 | (z << 13 | 0 >>> 19))) | 0; + an = H; + ak = fp((ao >>> 8 | ar << 24 | (0 << 24 | 0 >>> 8)) ^ (ao >>> 7 | ar << 25) ^ (ao >>> 1 | ar << 31 | (0 << 31 | 0 >>> 1)), (ar >>> 8 | 0 << 24 | (ao << 24 | 0 >>> 8)) ^ (ar >>> 7 | 0 << 25) ^ (ar >>> 1 | 0 << 31 | (ao << 31 | 0 >>> 1)), am, ap) | 0; + ap = fp(ak, H, n, u) | 0; + ak = fp(ap, H, (al >>> 29 | 0 << 3 | (b << 3 | 0 >>> 29)) ^ (b >>> 6 | al << 26) ^ (b >>> 19 | al << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (al << 3 | b >>> 29)) ^ (al >>> 6 | 0 << 26) ^ (al >>> 19 | 0 << 13 | (b << 13 | 0 >>> 19))) | 0; + ap = H; + am = fp((aq >>> 8 | at << 24 | (0 << 24 | 0 >>> 8)) ^ (aq >>> 7 | at << 25) ^ (aq >>> 1 | at << 31 | (0 << 31 | 0 >>> 1)), (at >>> 8 | 0 << 24 | (aq << 24 | 0 >>> 8)) ^ (at >>> 7 | 0 << 25) ^ (at >>> 1 | 0 << 31 | (aq << 31 | 0 >>> 1)), ao, ar) | 0; + ar = fp(am, H, q, x) | 0; + am = fp(ar, H, (an >>> 29 | 0 << 3 | (d << 3 | 0 >>> 29)) ^ (d >>> 6 | an << 26) ^ (d >>> 19 | an << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (an << 3 | d >>> 29)) ^ (an >>> 6 | 0 << 26) ^ (an >>> 19 | 0 << 13 | (d << 13 | 0 >>> 19))) | 0; + ar = H; + ao = fp((as >>> 8 | av << 24 | (0 << 24 | 0 >>> 8)) ^ (as >>> 7 | av << 25) ^ (as >>> 1 | av << 31 | (0 << 31 | 0 >>> 1)), (av >>> 8 | 0 << 24 | (as << 24 | 0 >>> 8)) ^ (av >>> 7 | 0 << 25) ^ (av >>> 1 | 0 << 31 | (as << 31 | 0 >>> 1)), aq, at) | 0; + at = fp(ao, H, t, A) | 0; + ao = fp(at, H, (ap >>> 29 | 0 << 3 | (ak << 3 | 0 >>> 29)) ^ (ak >>> 6 | ap << 26) ^ (ak >>> 19 | ap << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ap << 3 | ak >>> 29)) ^ (ap >>> 6 | 0 << 26) ^ (ap >>> 19 | 0 << 13 | (ak << 13 | 0 >>> 19))) | 0; + at = H; + aq = fp((aD >>> 8 | f << 24 | (0 << 24 | 0 >>> 8)) ^ (aD >>> 7 | f << 25) ^ (aD >>> 1 | f << 31 | (0 << 31 | 0 >>> 1)), (f >>> 8 | 0 << 24 | (aD << 24 | 0 >>> 8)) ^ (f >>> 7 | 0 << 25) ^ (f >>> 1 | 0 << 31 | (aD << 31 | 0 >>> 1)), as, av) | 0; + av = fp(aq, H, w, c) | 0; + aq = fp(av, H, (ar >>> 29 | 0 << 3 | (am << 3 | 0 >>> 29)) ^ (am >>> 6 | ar << 26) ^ (am >>> 19 | ar << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ar << 3 | am >>> 29)) ^ (ar >>> 6 | 0 << 26) ^ (ar >>> 19 | 0 << 13 | (am << 13 | 0 >>> 19))) | 0; + av = H; + as = fp(aD, f, 1188179964, 666307205) | 0; + aN = fp(as, H, aG, aw) | 0; + aw = fp(aN, H, ay & aC ^ aK & ~ay, az & aB ^ ax & ~az) | 0; + aN = fp(aw, H, (ay >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | ay >>> 9))) | 0; + aw = H; + aG = aQ & aM; + as = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aA ^ aG, aP & aH ^ au ^ as) | 0; + au = H; + aA = fp(aN, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, au, aN, aw) | 0; + aw = H; + aN = fp(aJ, i, 1546045734, 773529912) | 0; + au = fp(aN, H, aK, ax) | 0; + ax = fp(au, H, aA & ay ^ aC & ~aA, aF & az ^ aB & ~aF) | 0; + au = fp(ax, H, (aA >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aA >>> 9))) | 0; + ax = H; + aK = aE & aQ; + aN = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aG ^ aK, aw & aL ^ as ^ aN) | 0; + as = H; + aG = fp(au, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, as, au, ax) | 0; + ax = H; + au = fp(e, l, 1522805485, 1294757372) | 0; + as = fp(au, H, aC, aB) | 0; + aB = fp(as, H, aG & aA ^ ay & ~aG, aH & aF ^ az & ~aH) | 0; + as = fp(aB, H, (aG >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aG >>> 9))) | 0; + aB = H; + aC = aI & aE; + au = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aK ^ aC, ax & aP ^ aN ^ au) | 0; + aN = H; + aK = fp(as, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, aN, as, aB) | 0; + aB = H; + as = fp(h, o, -1651133473, 1396182291) | 0; + aN = fp(as, H, ay, az) | 0; + az = fp(aN, H, aK & aG ^ aA & ~aK, aL & aH ^ aF & ~aL) | 0; + aN = fp(az, H, (aK >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aK >>> 9))) | 0; + az = H; + ay = aM & aI; + as = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aC ^ ay, aB & aw ^ au ^ as) | 0; + au = H; + aC = fp(aN, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, au, aN, az) | 0; + az = H; + aN = fp(k, r, -1951439906, 1695183700) | 0; + au = fp(aN, H, aA, aF) | 0; + aF = fp(au, H, aC & aK ^ aG & ~aC, aP & aL ^ aH & ~aP) | 0; + au = fp(aF, H, (aC >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aC >>> 9))) | 0; + aF = H; + aA = aQ & aM; + aN = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ ay ^ aA, az & ax ^ as ^ aN) | 0; + as = H; + ay = fp(au, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, as, au, aF) | 0; + aF = H; + au = fp(n, u, 1014477480, 1986661051) | 0; + as = fp(au, H, aG, aH) | 0; + aH = fp(as, H, ay & aC ^ aK & ~ay, aw & aP ^ aL & ~aw) | 0; + as = fp(aH, H, (ay >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | ay >>> 9))) | 0; + aH = H; + aG = aE & aQ; + au = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aA ^ aG, aF & aB ^ aN ^ au) | 0; + aN = H; + aA = fp(as, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, aN, as, aH) | 0; + aH = H; + as = fp(q, x, 1206759142, -2117940946) | 0; + aN = fp(as, H, aK, aL) | 0; + aL = fp(aN, H, aA & ay ^ aC & ~aA, ax & aw ^ aP & ~ax) | 0; + aN = fp(aL, H, (aA >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aA >>> 9))) | 0; + aL = H; + aK = aI & aE; + as = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aG ^ aK, aH & az ^ au ^ as) | 0; + au = H; + aG = fp(aN, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, au, aN, aL) | 0; + aL = H; + aN = fp(t, A, 344077627, -1838011259) | 0; + au = fp(aN, H, aC, aP) | 0; + aP = fp(au, H, aG & aA ^ ay & ~aG, aB & ax ^ aw & ~aB) | 0; + au = fp(aP, H, (aG >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aG >>> 9))) | 0; + aP = H; + aC = aM & aI; + aN = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aK ^ aC, aL & aF ^ as ^ aN) | 0; + as = H; + aK = fp(au, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, as, au, aP) | 0; + aP = H; + au = fp(w, c, 1290863460, -1564481375) | 0; + as = fp(au, H, ay, aw) | 0; + aw = fp(as, H, aK & aG ^ aA & ~aK, az & aB ^ ax & ~az) | 0; + as = fp(aw, H, (aK >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aK >>> 9))) | 0; + aw = H; + ay = aQ & aM; + au = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aC ^ ay, aP & aH ^ aN ^ au) | 0; + aN = H; + aC = fp(as, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, aN, as, aw) | 0; + aw = H; + as = fp(z, B, -1136513023, -1474664885) | 0; + aN = fp(as, H, aA, ax) | 0; + ax = fp(aN, H, aC & aK ^ aG & ~aC, aF & az ^ aB & ~aF) | 0; + aN = fp(ax, H, (aC >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aC >>> 9))) | 0; + ax = H; + aA = aE & aQ; + as = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ ay ^ aA, aw & aL ^ au ^ as) | 0; + au = H; + ay = fp(aN, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, au, aN, ax) | 0; + ax = H; + aN = fp(b, al, -789014639, -1035236496) | 0; + au = fp(aN, H, aG, aB) | 0; + aB = fp(au, H, ay & aC ^ aK & ~ay, aH & aF ^ az & ~aH) | 0; + au = fp(aB, H, (ay >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | ay >>> 9))) | 0; + aB = H; + aG = aI & aE; + aN = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aA ^ aG, ax & aP ^ as ^ aN) | 0; + as = H; + aA = fp(au, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, as, au, aB) | 0; + aB = H; + au = fp(d, an, 106217008, -949202525) | 0; + as = fp(au, H, aK, az) | 0; + az = fp(as, H, aA & ay ^ aC & ~aA, aL & aH ^ aF & ~aL) | 0; + as = fp(az, H, (aA >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aA >>> 9))) | 0; + az = H; + aK = aM & aI; + au = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aG ^ aK, aB & aw ^ aN ^ au) | 0; + aN = H; + aG = fp(as, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, aN, as, az) | 0; + az = H; + as = fp(ak, ap, -688958952, -778901479) | 0; + aN = fp(as, H, aC, aF) | 0; + aF = fp(aN, H, aG & aA ^ ay & ~aG, aP & aL ^ aH & ~aP) | 0; + aN = fp(aF, H, (aG >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aG >>> 9))) | 0; + aF = H; + aC = aQ & aM; + as = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aK ^ aC, az & ax ^ au ^ as) | 0; + au = H; + aK = fp(aN, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, au, aN, aF) | 0; + aF = H; + aN = fp(am, ar, 1432725776, -694614492) | 0; + au = fp(aN, H, ay, aH) | 0; + aH = fp(au, H, aK & aG ^ aA & ~aK, aw & aP ^ aL & ~aw) | 0; + au = fp(aH, H, (aK >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aK >>> 9))) | 0; + aH = H; + ay = aE & aQ; + aN = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aC ^ ay, aF & aB ^ as ^ aN) | 0; + as = H; + aC = fp(au, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, as, au, aH) | 0; + aH = H; + au = fp(ao, at, 1467031594, -200395387) | 0; + as = fp(au, H, aA, aL) | 0; + aL = fp(as, H, aC & aK ^ aG & ~aC, ax & aw ^ aP & ~ax) | 0; + as = fp(aL, H, (aC >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aC >>> 9))) | 0; + aL = H; + aA = aI & aE; + au = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ ay ^ aA, aH & az ^ aN ^ au) | 0; + aN = H; + ay = fp(as, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, aN, as, aL) | 0; + aL = H; + as = fp(aq, av, 851169720, 275423344) | 0; + aN = fp(as, H, aG, aP) | 0; + aP = fp(aN, H, ay & aC ^ aK & ~ay, aB & ax ^ aw & ~aB) | 0; + aN = fp(aP, H, (ay >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | ay >>> 9))) | 0; + aP = H; + aG = aM & aI; + as = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aA ^ aG, aL & aF ^ au ^ as) | 0; + au = H; + aA = fp(aN, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, au, aN, aP) | 0; + aP = H; + aN = fp((aJ >>> 8 | i << 24 | (0 << 24 | 0 >>> 8)) ^ (aJ >>> 7 | i << 25) ^ (aJ >>> 1 | i << 31 | (0 << 31 | 0 >>> 1)), (i >>> 8 | 0 << 24 | (aJ << 24 | 0 >>> 8)) ^ (i >>> 7 | 0 << 25) ^ (i >>> 1 | 0 << 31 | (aJ << 31 | 0 >>> 1)), aD, f) | 0; + f = fp(aN, H, z, B) | 0; + aN = fp(f, H, (at >>> 29 | 0 << 3 | (ao << 3 | 0 >>> 29)) ^ (ao >>> 6 | at << 26) ^ (ao >>> 19 | at << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (at << 3 | ao >>> 29)) ^ (at >>> 6 | 0 << 26) ^ (at >>> 19 | 0 << 13 | (ao << 13 | 0 >>> 19))) | 0; + f = H; + aD = fp((e >>> 8 | l << 24 | (0 << 24 | 0 >>> 8)) ^ (e >>> 7 | l << 25) ^ (e >>> 1 | l << 31 | (0 << 31 | 0 >>> 1)), (l >>> 8 | 0 << 24 | (e << 24 | 0 >>> 8)) ^ (l >>> 7 | 0 << 25) ^ (l >>> 1 | 0 << 31 | (e << 31 | 0 >>> 1)), aJ, i) | 0; + i = fp(aD, H, b, al) | 0; + aD = fp(i, H, (av >>> 29 | 0 << 3 | (aq << 3 | 0 >>> 29)) ^ (aq >>> 6 | av << 26) ^ (aq >>> 19 | av << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (av << 3 | aq >>> 29)) ^ (av >>> 6 | 0 << 26) ^ (av >>> 19 | 0 << 13 | (aq << 13 | 0 >>> 19))) | 0; + i = H; + aJ = fp((h >>> 8 | o << 24 | (0 << 24 | 0 >>> 8)) ^ (h >>> 7 | o << 25) ^ (h >>> 1 | o << 31 | (0 << 31 | 0 >>> 1)), (o >>> 8 | 0 << 24 | (h << 24 | 0 >>> 8)) ^ (o >>> 7 | 0 << 25) ^ (o >>> 1 | 0 << 31 | (h << 31 | 0 >>> 1)), e, l) | 0; + l = fp(aJ, H, d, an) | 0; + aJ = fp(l, H, (f >>> 29 | 0 << 3 | (aN << 3 | 0 >>> 29)) ^ (aN >>> 6 | f << 26) ^ (aN >>> 19 | f << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (f << 3 | aN >>> 29)) ^ (f >>> 6 | 0 << 26) ^ (f >>> 19 | 0 << 13 | (aN << 13 | 0 >>> 19))) | 0; + l = H; + e = fp((k >>> 8 | r << 24 | (0 << 24 | 0 >>> 8)) ^ (k >>> 7 | r << 25) ^ (k >>> 1 | r << 31 | (0 << 31 | 0 >>> 1)), (r >>> 8 | 0 << 24 | (k << 24 | 0 >>> 8)) ^ (r >>> 7 | 0 << 25) ^ (r >>> 1 | 0 << 31 | (k << 31 | 0 >>> 1)), h, o) | 0; + o = fp(e, H, ak, ap) | 0; + e = fp(o, H, (i >>> 29 | 0 << 3 | (aD << 3 | 0 >>> 29)) ^ (aD >>> 6 | i << 26) ^ (aD >>> 19 | i << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (i << 3 | aD >>> 29)) ^ (i >>> 6 | 0 << 26) ^ (i >>> 19 | 0 << 13 | (aD << 13 | 0 >>> 19))) | 0; + o = H; + h = fp((n >>> 8 | u << 24 | (0 << 24 | 0 >>> 8)) ^ (n >>> 7 | u << 25) ^ (n >>> 1 | u << 31 | (0 << 31 | 0 >>> 1)), (u >>> 8 | 0 << 24 | (n << 24 | 0 >>> 8)) ^ (u >>> 7 | 0 << 25) ^ (u >>> 1 | 0 << 31 | (n << 31 | 0 >>> 1)), k, r) | 0; + r = fp(h, H, am, ar) | 0; + h = fp(r, H, (l >>> 29 | 0 << 3 | (aJ << 3 | 0 >>> 29)) ^ (aJ >>> 6 | l << 26) ^ (aJ >>> 19 | l << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (l << 3 | aJ >>> 29)) ^ (l >>> 6 | 0 << 26) ^ (l >>> 19 | 0 << 13 | (aJ << 13 | 0 >>> 19))) | 0; + r = H; + k = fp((q >>> 8 | x << 24 | (0 << 24 | 0 >>> 8)) ^ (q >>> 7 | x << 25) ^ (q >>> 1 | x << 31 | (0 << 31 | 0 >>> 1)), (x >>> 8 | 0 << 24 | (q << 24 | 0 >>> 8)) ^ (x >>> 7 | 0 << 25) ^ (x >>> 1 | 0 << 31 | (q << 31 | 0 >>> 1)), n, u) | 0; + u = fp(k, H, ao, at) | 0; + k = fp(u, H, (o >>> 29 | 0 << 3 | (e << 3 | 0 >>> 29)) ^ (e >>> 6 | o << 26) ^ (e >>> 19 | o << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (o << 3 | e >>> 29)) ^ (o >>> 6 | 0 << 26) ^ (o >>> 19 | 0 << 13 | (e << 13 | 0 >>> 19))) | 0; + u = H; + n = fp((t >>> 8 | A << 24 | (0 << 24 | 0 >>> 8)) ^ (t >>> 7 | A << 25) ^ (t >>> 1 | A << 31 | (0 << 31 | 0 >>> 1)), (A >>> 8 | 0 << 24 | (t << 24 | 0 >>> 8)) ^ (A >>> 7 | 0 << 25) ^ (A >>> 1 | 0 << 31 | (t << 31 | 0 >>> 1)), q, x) | 0; + x = fp(n, H, aq, av) | 0; + n = fp(x, H, (r >>> 29 | 0 << 3 | (h << 3 | 0 >>> 29)) ^ (h >>> 6 | r << 26) ^ (h >>> 19 | r << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (r << 3 | h >>> 29)) ^ (r >>> 6 | 0 << 26) ^ (r >>> 19 | 0 << 13 | (h << 13 | 0 >>> 19))) | 0; + x = H; + q = fp((w >>> 8 | c << 24 | (0 << 24 | 0 >>> 8)) ^ (w >>> 7 | c << 25) ^ (w >>> 1 | c << 31 | (0 << 31 | 0 >>> 1)), (c >>> 8 | 0 << 24 | (w << 24 | 0 >>> 8)) ^ (c >>> 7 | 0 << 25) ^ (c >>> 1 | 0 << 31 | (w << 31 | 0 >>> 1)), t, A) | 0; + A = fp(q, H, aN, f) | 0; + q = fp(A, H, (u >>> 29 | 0 << 3 | (k << 3 | 0 >>> 29)) ^ (k >>> 6 | u << 26) ^ (k >>> 19 | u << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (u << 3 | k >>> 29)) ^ (u >>> 6 | 0 << 26) ^ (u >>> 19 | 0 << 13 | (k << 13 | 0 >>> 19))) | 0; + A = H; + t = fp((z >>> 8 | B << 24 | (0 << 24 | 0 >>> 8)) ^ (z >>> 7 | B << 25) ^ (z >>> 1 | B << 31 | (0 << 31 | 0 >>> 1)), (B >>> 8 | 0 << 24 | (z << 24 | 0 >>> 8)) ^ (B >>> 7 | 0 << 25) ^ (B >>> 1 | 0 << 31 | (z << 31 | 0 >>> 1)), w, c) | 0; + c = fp(t, H, aD, i) | 0; + t = fp(c, H, (x >>> 29 | 0 << 3 | (n << 3 | 0 >>> 29)) ^ (n >>> 6 | x << 26) ^ (n >>> 19 | x << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (x << 3 | n >>> 29)) ^ (x >>> 6 | 0 << 26) ^ (x >>> 19 | 0 << 13 | (n << 13 | 0 >>> 19))) | 0; + c = H; + w = fp((b >>> 8 | al << 24 | (0 << 24 | 0 >>> 8)) ^ (b >>> 7 | al << 25) ^ (b >>> 1 | al << 31 | (0 << 31 | 0 >>> 1)), (al >>> 8 | 0 << 24 | (b << 24 | 0 >>> 8)) ^ (al >>> 7 | 0 << 25) ^ (al >>> 1 | 0 << 31 | (b << 31 | 0 >>> 1)), z, B) | 0; + B = fp(w, H, aJ, l) | 0; + w = fp(B, H, (A >>> 29 | 0 << 3 | (q << 3 | 0 >>> 29)) ^ (q >>> 6 | A << 26) ^ (q >>> 19 | A << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (A << 3 | q >>> 29)) ^ (A >>> 6 | 0 << 26) ^ (A >>> 19 | 0 << 13 | (q << 13 | 0 >>> 19))) | 0; + B = H; + z = fp((d >>> 8 | an << 24 | (0 << 24 | 0 >>> 8)) ^ (d >>> 7 | an << 25) ^ (d >>> 1 | an << 31 | (0 << 31 | 0 >>> 1)), (an >>> 8 | 0 << 24 | (d << 24 | 0 >>> 8)) ^ (an >>> 7 | 0 << 25) ^ (an >>> 1 | 0 << 31 | (d << 31 | 0 >>> 1)), b, al) | 0; + al = fp(z, H, e, o) | 0; + z = fp(al, H, (c >>> 29 | 0 << 3 | (t << 3 | 0 >>> 29)) ^ (t >>> 6 | c << 26) ^ (t >>> 19 | c << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (c << 3 | t >>> 29)) ^ (c >>> 6 | 0 << 26) ^ (c >>> 19 | 0 << 13 | (t << 13 | 0 >>> 19))) | 0; + al = H; + b = fp((ak >>> 8 | ap << 24 | (0 << 24 | 0 >>> 8)) ^ (ak >>> 7 | ap << 25) ^ (ak >>> 1 | ap << 31 | (0 << 31 | 0 >>> 1)), (ap >>> 8 | 0 << 24 | (ak << 24 | 0 >>> 8)) ^ (ap >>> 7 | 0 << 25) ^ (ap >>> 1 | 0 << 31 | (ak << 31 | 0 >>> 1)), d, an) | 0; + an = fp(b, H, h, r) | 0; + b = fp(an, H, (B >>> 29 | 0 << 3 | (w << 3 | 0 >>> 29)) ^ (w >>> 6 | B << 26) ^ (w >>> 19 | B << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (B << 3 | w >>> 29)) ^ (B >>> 6 | 0 << 26) ^ (B >>> 19 | 0 << 13 | (w << 13 | 0 >>> 19))) | 0; + an = H; + d = fp((am >>> 8 | ar << 24 | (0 << 24 | 0 >>> 8)) ^ (am >>> 7 | ar << 25) ^ (am >>> 1 | ar << 31 | (0 << 31 | 0 >>> 1)), (ar >>> 8 | 0 << 24 | (am << 24 | 0 >>> 8)) ^ (ar >>> 7 | 0 << 25) ^ (ar >>> 1 | 0 << 31 | (am << 31 | 0 >>> 1)), ak, ap) | 0; + ap = fp(d, H, k, u) | 0; + d = fp(ap, H, (al >>> 29 | 0 << 3 | (z << 3 | 0 >>> 29)) ^ (z >>> 6 | al << 26) ^ (z >>> 19 | al << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (al << 3 | z >>> 29)) ^ (al >>> 6 | 0 << 26) ^ (al >>> 19 | 0 << 13 | (z << 13 | 0 >>> 19))) | 0; + ap = H; + ak = fp((ao >>> 8 | at << 24 | (0 << 24 | 0 >>> 8)) ^ (ao >>> 7 | at << 25) ^ (ao >>> 1 | at << 31 | (0 << 31 | 0 >>> 1)), (at >>> 8 | 0 << 24 | (ao << 24 | 0 >>> 8)) ^ (at >>> 7 | 0 << 25) ^ (at >>> 1 | 0 << 31 | (ao << 31 | 0 >>> 1)), am, ar) | 0; + ar = fp(ak, H, n, x) | 0; + ak = fp(ar, H, (an >>> 29 | 0 << 3 | (b << 3 | 0 >>> 29)) ^ (b >>> 6 | an << 26) ^ (b >>> 19 | an << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (an << 3 | b >>> 29)) ^ (an >>> 6 | 0 << 26) ^ (an >>> 19 | 0 << 13 | (b << 13 | 0 >>> 19))) | 0; + ar = H; + am = fp((aq >>> 8 | av << 24 | (0 << 24 | 0 >>> 8)) ^ (aq >>> 7 | av << 25) ^ (aq >>> 1 | av << 31 | (0 << 31 | 0 >>> 1)), (av >>> 8 | 0 << 24 | (aq << 24 | 0 >>> 8)) ^ (av >>> 7 | 0 << 25) ^ (av >>> 1 | 0 << 31 | (aq << 31 | 0 >>> 1)), ao, at) | 0; + at = fp(am, H, q, A) | 0; + am = fp(at, H, (ap >>> 29 | 0 << 3 | (d << 3 | 0 >>> 29)) ^ (d >>> 6 | ap << 26) ^ (d >>> 19 | ap << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ap << 3 | d >>> 29)) ^ (ap >>> 6 | 0 << 26) ^ (ap >>> 19 | 0 << 13 | (d << 13 | 0 >>> 19))) | 0; + at = H; + ao = fp((aN >>> 8 | f << 24 | (0 << 24 | 0 >>> 8)) ^ (aN >>> 7 | f << 25) ^ (aN >>> 1 | f << 31 | (0 << 31 | 0 >>> 1)), (f >>> 8 | 0 << 24 | (aN << 24 | 0 >>> 8)) ^ (f >>> 7 | 0 << 25) ^ (f >>> 1 | 0 << 31 | (aN << 31 | 0 >>> 1)), aq, av) | 0; + av = fp(ao, H, t, c) | 0; + ao = fp(av, H, (ar >>> 29 | 0 << 3 | (ak << 3 | 0 >>> 29)) ^ (ak >>> 6 | ar << 26) ^ (ak >>> 19 | ar << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ar << 3 | ak >>> 29)) ^ (ar >>> 6 | 0 << 26) ^ (ar >>> 19 | 0 << 13 | (ak << 13 | 0 >>> 19))) | 0; + av = H; + aq = fp(aN, f, -1194143544, 430227734) | 0; + au = fp(aq, H, aK, aw) | 0; + aw = fp(au, H, aA & ay ^ aC & ~aA, az & aB ^ ax & ~az) | 0; + au = fp(aw, H, (aA >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aA >>> 9))) | 0; + aw = H; + aK = aQ & aM; + aq = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aG ^ aK, aP & aH ^ as ^ aq) | 0; + as = H; + aG = fp(au, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, as, au, aw) | 0; + aw = H; + au = fp(aD, i, 1363258195, 506948616) | 0; + as = fp(au, H, aC, ax) | 0; + ax = fp(as, H, aG & aA ^ ay & ~aG, aF & az ^ aB & ~aF) | 0; + as = fp(ax, H, (aG >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aG >>> 9))) | 0; + ax = H; + aC = aE & aQ; + au = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aK ^ aC, aw & aL ^ aq ^ au) | 0; + aq = H; + aK = fp(as, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, aq, as, ax) | 0; + ax = H; + as = fp(aJ, l, -544281703, 659060556) | 0; + aq = fp(as, H, ay, aB) | 0; + aB = fp(aq, H, aK & aG ^ aA & ~aK, aH & aF ^ az & ~aH) | 0; + aq = fp(aB, H, (aK >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aK >>> 9))) | 0; + aB = H; + ay = aI & aE; + as = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aC ^ ay, ax & aP ^ au ^ as) | 0; + au = H; + aC = fp(aq, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, au, aq, aB) | 0; + aB = H; + aq = fp(e, o, -509917016, 883997877) | 0; + au = fp(aq, H, aA, az) | 0; + az = fp(au, H, aC & aK ^ aG & ~aC, aL & aH ^ aF & ~aL) | 0; + au = fp(az, H, (aC >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aC >>> 9))) | 0; + az = H; + aA = aM & aI; + aq = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ ay ^ aA, aB & aw ^ as ^ aq) | 0; + as = H; + ay = fp(au, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, as, au, az) | 0; + az = H; + au = fp(h, r, -976659869, 958139571) | 0; + as = fp(au, H, aG, aF) | 0; + aF = fp(as, H, ay & aC ^ aK & ~ay, aP & aL ^ aH & ~aP) | 0; + as = fp(aF, H, (ay >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | ay >>> 9))) | 0; + aF = H; + aG = aQ & aM; + au = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aA ^ aG, az & ax ^ aq ^ au) | 0; + aq = H; + aA = fp(as, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, aq, as, aF) | 0; + aF = H; + as = fp(k, u, -482243893, 1322822218) | 0; + aq = fp(as, H, aK, aH) | 0; + aH = fp(aq, H, aA & ay ^ aC & ~aA, aw & aP ^ aL & ~aw) | 0; + aq = fp(aH, H, (aA >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aA >>> 9))) | 0; + aH = H; + aK = aE & aQ; + as = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aG ^ aK, aF & aB ^ au ^ as) | 0; + au = H; + aG = fp(aq, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, au, aq, aH) | 0; + aH = H; + aq = fp(n, x, 2003034995, 1537002063) | 0; + au = fp(aq, H, aC, aL) | 0; + aL = fp(au, H, aG & aA ^ ay & ~aG, ax & aw ^ aP & ~ax) | 0; + au = fp(aL, H, (aG >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aG >>> 9))) | 0; + aL = H; + aC = aI & aE; + aq = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aK ^ aC, aH & az ^ as ^ aq) | 0; + as = H; + aK = fp(au, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, as, au, aL) | 0; + aL = H; + au = fp(q, A, -692930397, 1747873779) | 0; + as = fp(au, H, ay, aP) | 0; + aP = fp(as, H, aK & aG ^ aA & ~aK, aB & ax ^ aw & ~aB) | 0; + as = fp(aP, H, (aK >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aK >>> 9))) | 0; + aP = H; + ay = aM & aI; + au = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aC ^ ay, aL & aF ^ aq ^ au) | 0; + aq = H; + aC = fp(as, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, aq, as, aP) | 0; + aP = H; + as = fp(t, c, 1575990012, 1955562222) | 0; + aq = fp(as, H, aA, aw) | 0; + aw = fp(aq, H, aC & aK ^ aG & ~aC, az & aB ^ ax & ~az) | 0; + aq = fp(aw, H, (aC >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aC >>> 9))) | 0; + aw = H; + aA = aQ & aM; + as = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ ay ^ aA, aP & aH ^ au ^ as) | 0; + au = H; + ay = fp(aq, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, au, aq, aw) | 0; + aw = H; + aq = fp(w, B, 1125592928, 2024104815) | 0; + au = fp(aq, H, aG, ax) | 0; + ax = fp(au, H, ay & aC ^ aK & ~ay, aF & az ^ aB & ~aF) | 0; + au = fp(ax, H, (ay >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | ay >>> 9))) | 0; + ax = H; + aG = aE & aQ; + aq = aw & aP; + aO = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aA ^ aG, aw & aL ^ as ^ aq) | 0; + as = H; + aA = fp(au, ax, aI, aH) | 0; + aH = H; + aI = fp(aO, as, au, ax) | 0; + ax = H; + au = fp(z, al, -1578062990, -2067236844) | 0; + as = fp(au, H, aK, aB) | 0; + aB = fp(as, H, aA & ay ^ aC & ~aA, aH & aF ^ az & ~aH) | 0; + as = fp(aB, H, (aA >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aA >>> 9))) | 0; + aB = H; + aK = aI & aE; + au = ax & aw; + aO = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aG ^ aK, ax & aP ^ aq ^ au) | 0; + aq = H; + aG = fp(as, aB, aM, aL) | 0; + aL = H; + aM = fp(aO, aq, as, aB) | 0; + aB = H; + as = fp(b, an, 442776044, -1933114872) | 0; + aq = fp(as, H, aC, az) | 0; + az = fp(aq, H, aG & aA ^ ay & ~aG, aL & aH ^ aF & ~aL) | 0; + aq = fp(az, H, (aG >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aG >>> 9))) | 0; + az = H; + aC = aM & aI; + as = aB & ax; + aO = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aK ^ aC, aB & aw ^ au ^ as) | 0; + au = H; + aK = fp(aq, az, aQ, aP) | 0; + aP = H; + aQ = fp(aO, au, aq, az) | 0; + az = H; + aq = fp(d, ap, 593698344, -1866530822) | 0; + au = fp(aq, H, ay, aF) | 0; + aF = fp(au, H, aK & aG ^ aA & ~aK, aP & aL ^ aH & ~aP) | 0; + au = fp(aF, H, (aK >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aK >>> 9))) | 0; + aF = H; + ay = aQ & aM; + aq = az & aB; + aO = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aC ^ ay, az & ax ^ as ^ aq) | 0; + as = H; + aC = fp(au, aF, aE, aw) | 0; + aw = H; + aE = fp(aO, as, au, aF) | 0; + aF = H; + au = fp(ak, ar, -561857047, -1538233109) | 0; + as = fp(au, H, aA, aH) | 0; + aH = fp(as, H, aC & aK ^ aG & ~aC, aw & aP ^ aL & ~aw) | 0; + as = fp(aH, H, (aC >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aC >>> 9))) | 0; + aH = H; + aA = aE & aQ; + au = aF & az; + aO = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ ay ^ aA, aF & aB ^ aq ^ au) | 0; + aq = H; + ay = fp(as, aH, aI, ax) | 0; + ax = H; + aI = fp(aO, aq, as, aH) | 0; + aH = H; + as = fp(am, at, -1295615723, -1090935817) | 0; + aq = fp(as, H, aG, aL) | 0; + aL = fp(aq, H, ay & aC ^ aK & ~ay, ax & aw ^ aP & ~ax) | 0; + aq = fp(aL, H, (ay >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | ay >>> 9))) | 0; + aL = H; + aG = aI & aE; + as = aH & aF; + aO = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aA ^ aG, aH & az ^ au ^ as) | 0; + au = H; + aA = fp(aq, aL, aM, aB) | 0; + aB = H; + aM = fp(aO, au, aq, aL) | 0; + aL = H; + aq = fp(ao, av, -479046869, -965641998) | 0; + au = fp(aq, H, aK, aP) | 0; + aP = fp(au, H, aA & ay ^ aC & ~aA, aB & ax ^ aw & ~aB) | 0; + au = fp(aP, H, (aA >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aA >>> 9))) | 0; + aP = H; + aK = aM & aI; + aq = aL & aH; + aO = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ aG ^ aK, aL & aF ^ as ^ aq) | 0; + as = H; + aG = fp(au, aP, aQ, az) | 0; + az = H; + aQ = fp(aO, as, au, aP) | 0; + aP = H; + au = fp((aD >>> 8 | i << 24 | (0 << 24 | 0 >>> 8)) ^ (aD >>> 7 | i << 25) ^ (aD >>> 1 | i << 31 | (0 << 31 | 0 >>> 1)), (i >>> 8 | 0 << 24 | (aD << 24 | 0 >>> 8)) ^ (i >>> 7 | 0 << 25) ^ (i >>> 1 | 0 << 31 | (aD << 31 | 0 >>> 1)), aN, f) | 0; + f = fp(au, H, w, B) | 0; + au = fp(f, H, (at >>> 29 | 0 << 3 | (am << 3 | 0 >>> 29)) ^ (am >>> 6 | at << 26) ^ (am >>> 19 | at << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (at << 3 | am >>> 29)) ^ (at >>> 6 | 0 << 26) ^ (at >>> 19 | 0 << 13 | (am << 13 | 0 >>> 19))) | 0; + f = H; + aN = fp((aJ >>> 8 | l << 24 | (0 << 24 | 0 >>> 8)) ^ (aJ >>> 7 | l << 25) ^ (aJ >>> 1 | l << 31 | (0 << 31 | 0 >>> 1)), (l >>> 8 | 0 << 24 | (aJ << 24 | 0 >>> 8)) ^ (l >>> 7 | 0 << 25) ^ (l >>> 1 | 0 << 31 | (aJ << 31 | 0 >>> 1)), aD, i) | 0; + i = fp(aN, H, z, al) | 0; + aN = fp(i, H, (av >>> 29 | 0 << 3 | (ao << 3 | 0 >>> 29)) ^ (ao >>> 6 | av << 26) ^ (ao >>> 19 | av << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (av << 3 | ao >>> 29)) ^ (av >>> 6 | 0 << 26) ^ (av >>> 19 | 0 << 13 | (ao << 13 | 0 >>> 19))) | 0; + i = H; + aD = fp((e >>> 8 | o << 24 | (0 << 24 | 0 >>> 8)) ^ (e >>> 7 | o << 25) ^ (e >>> 1 | o << 31 | (0 << 31 | 0 >>> 1)), (o >>> 8 | 0 << 24 | (e << 24 | 0 >>> 8)) ^ (o >>> 7 | 0 << 25) ^ (o >>> 1 | 0 << 31 | (e << 31 | 0 >>> 1)), aJ, l) | 0; + l = fp(aD, H, b, an) | 0; + aD = fp(l, H, (f >>> 29 | 0 << 3 | (au << 3 | 0 >>> 29)) ^ (au >>> 6 | f << 26) ^ (au >>> 19 | f << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (f << 3 | au >>> 29)) ^ (f >>> 6 | 0 << 26) ^ (f >>> 19 | 0 << 13 | (au << 13 | 0 >>> 19))) | 0; + l = H; + aJ = fp((h >>> 8 | r << 24 | (0 << 24 | 0 >>> 8)) ^ (h >>> 7 | r << 25) ^ (h >>> 1 | r << 31 | (0 << 31 | 0 >>> 1)), (r >>> 8 | 0 << 24 | (h << 24 | 0 >>> 8)) ^ (r >>> 7 | 0 << 25) ^ (r >>> 1 | 0 << 31 | (h << 31 | 0 >>> 1)), e, o) | 0; + o = fp(aJ, H, d, ap) | 0; + aJ = fp(o, H, (i >>> 29 | 0 << 3 | (aN << 3 | 0 >>> 29)) ^ (aN >>> 6 | i << 26) ^ (aN >>> 19 | i << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (i << 3 | aN >>> 29)) ^ (i >>> 6 | 0 << 26) ^ (i >>> 19 | 0 << 13 | (aN << 13 | 0 >>> 19))) | 0; + o = H; + e = fp((k >>> 8 | u << 24 | (0 << 24 | 0 >>> 8)) ^ (k >>> 7 | u << 25) ^ (k >>> 1 | u << 31 | (0 << 31 | 0 >>> 1)), (u >>> 8 | 0 << 24 | (k << 24 | 0 >>> 8)) ^ (u >>> 7 | 0 << 25) ^ (u >>> 1 | 0 << 31 | (k << 31 | 0 >>> 1)), h, r) | 0; + r = fp(e, H, ak, ar) | 0; + e = fp(r, H, (l >>> 29 | 0 << 3 | (aD << 3 | 0 >>> 29)) ^ (aD >>> 6 | l << 26) ^ (aD >>> 19 | l << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (l << 3 | aD >>> 29)) ^ (l >>> 6 | 0 << 26) ^ (l >>> 19 | 0 << 13 | (aD << 13 | 0 >>> 19))) | 0; + r = H; + h = fp((n >>> 8 | x << 24 | (0 << 24 | 0 >>> 8)) ^ (n >>> 7 | x << 25) ^ (n >>> 1 | x << 31 | (0 << 31 | 0 >>> 1)), (x >>> 8 | 0 << 24 | (n << 24 | 0 >>> 8)) ^ (x >>> 7 | 0 << 25) ^ (x >>> 1 | 0 << 31 | (n << 31 | 0 >>> 1)), k, u) | 0; + u = fp(h, H, am, at) | 0; + h = fp(u, H, (o >>> 29 | 0 << 3 | (aJ << 3 | 0 >>> 29)) ^ (aJ >>> 6 | o << 26) ^ (aJ >>> 19 | o << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (o << 3 | aJ >>> 29)) ^ (o >>> 6 | 0 << 26) ^ (o >>> 19 | 0 << 13 | (aJ << 13 | 0 >>> 19))) | 0; + u = H; + k = fp((q >>> 8 | A << 24 | (0 << 24 | 0 >>> 8)) ^ (q >>> 7 | A << 25) ^ (q >>> 1 | A << 31 | (0 << 31 | 0 >>> 1)), (A >>> 8 | 0 << 24 | (q << 24 | 0 >>> 8)) ^ (A >>> 7 | 0 << 25) ^ (A >>> 1 | 0 << 31 | (q << 31 | 0 >>> 1)), n, x) | 0; + x = fp(k, H, ao, av) | 0; + k = fp(x, H, (r >>> 29 | 0 << 3 | (e << 3 | 0 >>> 29)) ^ (e >>> 6 | r << 26) ^ (e >>> 19 | r << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (r << 3 | e >>> 29)) ^ (r >>> 6 | 0 << 26) ^ (r >>> 19 | 0 << 13 | (e << 13 | 0 >>> 19))) | 0; + x = H; + n = fp((t >>> 8 | c << 24 | (0 << 24 | 0 >>> 8)) ^ (t >>> 7 | c << 25) ^ (t >>> 1 | c << 31 | (0 << 31 | 0 >>> 1)), (c >>> 8 | 0 << 24 | (t << 24 | 0 >>> 8)) ^ (c >>> 7 | 0 << 25) ^ (c >>> 1 | 0 << 31 | (t << 31 | 0 >>> 1)), q, A) | 0; + A = fp(n, H, au, f) | 0; + n = fp(A, H, (u >>> 29 | 0 << 3 | (h << 3 | 0 >>> 29)) ^ (h >>> 6 | u << 26) ^ (h >>> 19 | u << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (u << 3 | h >>> 29)) ^ (u >>> 6 | 0 << 26) ^ (u >>> 19 | 0 << 13 | (h << 13 | 0 >>> 19))) | 0; + A = H; + q = fp((w >>> 8 | B << 24 | (0 << 24 | 0 >>> 8)) ^ (w >>> 7 | B << 25) ^ (w >>> 1 | B << 31 | (0 << 31 | 0 >>> 1)), (B >>> 8 | 0 << 24 | (w << 24 | 0 >>> 8)) ^ (B >>> 7 | 0 << 25) ^ (B >>> 1 | 0 << 31 | (w << 31 | 0 >>> 1)), t, c) | 0; + c = fp(q, H, aN, i) | 0; + q = fp(c, H, (x >>> 29 | 0 << 3 | (k << 3 | 0 >>> 29)) ^ (k >>> 6 | x << 26) ^ (k >>> 19 | x << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (x << 3 | k >>> 29)) ^ (x >>> 6 | 0 << 26) ^ (x >>> 19 | 0 << 13 | (k << 13 | 0 >>> 19))) | 0; + c = H; + t = fp((z >>> 8 | al << 24 | (0 << 24 | 0 >>> 8)) ^ (z >>> 7 | al << 25) ^ (z >>> 1 | al << 31 | (0 << 31 | 0 >>> 1)), (al >>> 8 | 0 << 24 | (z << 24 | 0 >>> 8)) ^ (al >>> 7 | 0 << 25) ^ (al >>> 1 | 0 << 31 | (z << 31 | 0 >>> 1)), w, B) | 0; + B = fp(t, H, aD, l) | 0; + t = fp(B, H, (A >>> 29 | 0 << 3 | (n << 3 | 0 >>> 29)) ^ (n >>> 6 | A << 26) ^ (n >>> 19 | A << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (A << 3 | n >>> 29)) ^ (A >>> 6 | 0 << 26) ^ (A >>> 19 | 0 << 13 | (n << 13 | 0 >>> 19))) | 0; + B = H; + w = fp((b >>> 8 | an << 24 | (0 << 24 | 0 >>> 8)) ^ (b >>> 7 | an << 25) ^ (b >>> 1 | an << 31 | (0 << 31 | 0 >>> 1)), (an >>> 8 | 0 << 24 | (b << 24 | 0 >>> 8)) ^ (an >>> 7 | 0 << 25) ^ (an >>> 1 | 0 << 31 | (b << 31 | 0 >>> 1)), z, al) | 0; + al = fp(w, H, aJ, o) | 0; + w = fp(al, H, (c >>> 29 | 0 << 3 | (q << 3 | 0 >>> 29)) ^ (q >>> 6 | c << 26) ^ (q >>> 19 | c << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (c << 3 | q >>> 29)) ^ (c >>> 6 | 0 << 26) ^ (c >>> 19 | 0 << 13 | (q << 13 | 0 >>> 19))) | 0; + al = H; + z = fp((d >>> 8 | ap << 24 | (0 << 24 | 0 >>> 8)) ^ (d >>> 7 | ap << 25) ^ (d >>> 1 | ap << 31 | (0 << 31 | 0 >>> 1)), (ap >>> 8 | 0 << 24 | (d << 24 | 0 >>> 8)) ^ (ap >>> 7 | 0 << 25) ^ (ap >>> 1 | 0 << 31 | (d << 31 | 0 >>> 1)), b, an) | 0; + an = fp(z, H, e, r) | 0; + z = fp(an, H, (B >>> 29 | 0 << 3 | (t << 3 | 0 >>> 29)) ^ (t >>> 6 | B << 26) ^ (t >>> 19 | B << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (B << 3 | t >>> 29)) ^ (B >>> 6 | 0 << 26) ^ (B >>> 19 | 0 << 13 | (t << 13 | 0 >>> 19))) | 0; + an = H; + b = fp((ak >>> 8 | ar << 24 | (0 << 24 | 0 >>> 8)) ^ (ak >>> 7 | ar << 25) ^ (ak >>> 1 | ar << 31 | (0 << 31 | 0 >>> 1)), (ar >>> 8 | 0 << 24 | (ak << 24 | 0 >>> 8)) ^ (ar >>> 7 | 0 << 25) ^ (ar >>> 1 | 0 << 31 | (ak << 31 | 0 >>> 1)), d, ap) | 0; + ap = fp(b, H, h, u) | 0; + b = fp(ap, H, (al >>> 29 | 0 << 3 | (w << 3 | 0 >>> 29)) ^ (w >>> 6 | al << 26) ^ (w >>> 19 | al << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (al << 3 | w >>> 29)) ^ (al >>> 6 | 0 << 26) ^ (al >>> 19 | 0 << 13 | (w << 13 | 0 >>> 19))) | 0; + ap = H; + d = fp((am >>> 8 | at << 24 | (0 << 24 | 0 >>> 8)) ^ (am >>> 7 | at << 25) ^ (am >>> 1 | at << 31 | (0 << 31 | 0 >>> 1)), (at >>> 8 | 0 << 24 | (am << 24 | 0 >>> 8)) ^ (at >>> 7 | 0 << 25) ^ (at >>> 1 | 0 << 31 | (am << 31 | 0 >>> 1)), ak, ar) | 0; + ar = fp(d, H, k, x) | 0; + d = fp(ar, H, (an >>> 29 | 0 << 3 | (z << 3 | 0 >>> 29)) ^ (z >>> 6 | an << 26) ^ (z >>> 19 | an << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (an << 3 | z >>> 29)) ^ (an >>> 6 | 0 << 26) ^ (an >>> 19 | 0 << 13 | (z << 13 | 0 >>> 19))) | 0; + ar = H; + ak = fp(au, f, -366583396, -903397682) | 0; + as = fp(ak, H, aC, aw) | 0; + aw = fp(as, H, aG & aA ^ ay & ~aG, az & aB ^ ax & ~az) | 0; + as = fp(aw, H, (aG >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | aG >>> 9))) | 0; + aw = H; + aC = aQ & aM; + ak = aP & aL; + aO = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aK ^ aC, aP & aH ^ aq ^ ak) | 0; + aq = H; + aK = fp(as, aw, aE, aF) | 0; + aF = H; + aE = fp(aO, aq, as, aw) | 0; + aw = H; + as = fp(aN, i, 566280711, -779700025) | 0; + i = fp(as, H, ay, ax) | 0; + ax = fp(i, H, aK & aG ^ aA & ~aK, aF & az ^ aB & ~aF) | 0; + i = fp(ax, H, (aK >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aK >>> 9))) | 0; + ax = H; + ay = aE & aQ; + as = aw & aP; + aN = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aC ^ ay, aw & aL ^ ak ^ as) | 0; + ak = H; + aC = fp(i, ax, aI, aH) | 0; + aH = H; + aI = fp(aN, ak, i, ax) | 0; + ax = H; + i = fp(aD, l, -840897762, -354779690) | 0; + l = fp(i, H, aA, aB) | 0; + aB = fp(l, H, aC & aK ^ aG & ~aC, aH & aF ^ az & ~aH) | 0; + l = fp(aB, H, (aC >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aC >>> 9))) | 0; + aB = H; + aA = aI & aE; + i = ax & aw; + aD = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ ay ^ aA, ax & aP ^ as ^ i) | 0; + as = H; + ay = fp(l, aB, aM, aL) | 0; + aL = H; + aM = fp(aD, as, l, aB) | 0; + aB = H; + l = fp(aJ, o, -294727304, -176337025) | 0; + o = fp(l, H, aG, az) | 0; + az = fp(o, H, ay & aC ^ aK & ~ay, aL & aH ^ aF & ~aL) | 0; + o = fp(az, H, (ay >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | ay >>> 9))) | 0; + az = H; + aG = aM & aI; + l = aB & ax; + aJ = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aA ^ aG, aB & aw ^ i ^ l) | 0; + i = H; + aA = fp(o, az, aQ, aP) | 0; + aP = H; + aQ = fp(aJ, i, o, az) | 0; + az = H; + o = fp(e, r, 1914138554, 116418474) | 0; + r = fp(o, H, aK, aF) | 0; + aF = fp(r, H, aA & ay ^ aC & ~aA, aP & aL ^ aH & ~aP) | 0; + r = fp(aF, H, (aA >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aA >>> 9))) | 0; + aF = H; + aK = aQ & aM; + o = az & aB; + e = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ aG ^ aK, az & ax ^ l ^ o) | 0; + l = H; + aG = fp(r, aF, aE, aw) | 0; + aw = H; + aE = fp(e, l, r, aF) | 0; + aF = H; + r = fp(h, u, -1563912026, 174292421) | 0; + u = fp(r, H, aC, aH) | 0; + aH = fp(u, H, aG & aA ^ ay & ~aG, aw & aP ^ aL & ~aw) | 0; + u = fp(aH, H, (aG >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | aG >>> 9))) | 0; + aH = H; + aC = aE & aQ; + r = aF & az; + h = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aK ^ aC, aF & aB ^ o ^ r) | 0; + o = H; + aK = fp(u, aH, aI, ax) | 0; + ax = H; + aI = fp(h, o, u, aH) | 0; + aH = H; + u = fp(k, x, -1090974290, 289380356) | 0; + x = fp(u, H, ay, aL) | 0; + aL = fp(x, H, aK & aG ^ aA & ~aK, ax & aw ^ aP & ~ax) | 0; + x = fp(aL, H, (aK >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aK >>> 9))) | 0; + aL = H; + ay = aI & aE; + u = aH & aF; + k = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aC ^ ay, aH & az ^ r ^ u) | 0; + r = H; + aC = fp(x, aL, aM, aB) | 0; + aB = H; + aM = fp(k, r, x, aL) | 0; + aL = H; + x = fp(n, A, 320620315, 460393269) | 0; + r = fp(x, H, aA, aP) | 0; + aP = fp(r, H, aC & aK ^ aG & ~aC, aB & ax ^ aw & ~aB) | 0; + r = fp(aP, H, (aC >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aC >>> 9))) | 0; + aP = H; + aA = aM & aI; + x = aL & aH; + k = fp((aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7)), aM & aE ^ ay ^ aA, aL & aF ^ u ^ x) | 0; + u = H; + ay = fp(r, aP, aQ, az) | 0; + az = H; + aQ = fp(k, u, r, aP) | 0; + aP = H; + r = fp(q, c, 587496836, 685471733) | 0; + u = fp(r, H, aG, aw) | 0; + aw = fp(u, H, ay & aC ^ aK & ~ay, az & aB ^ ax & ~az) | 0; + u = fp(aw, H, (ay >>> 14 | az << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | az << 14 | (0 << 14 | 0 >>> 18)) ^ (az >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (az >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (az >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (az << 23 | ay >>> 9))) | 0; + aw = H; + aG = aQ & aM; + r = aP & aL; + k = fp((aQ >>> 28 | aP << 4 | (0 << 4 | 0 >>> 28)) ^ (aP >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (aP >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (aP >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aP << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aP << 25 | aQ >>> 7)), aQ & aI ^ aA ^ aG, aP & aH ^ x ^ r) | 0; + x = H; + aA = fp(u, aw, aE, aF) | 0; + aF = H; + aE = fp(k, x, u, aw) | 0; + aw = H; + u = fp(t, B, 1086792851, 852142971) | 0; + B = fp(u, H, aK, ax) | 0; + ax = fp(B, H, aA & ay ^ aC & ~aA, aF & az ^ aB & ~aF) | 0; + B = fp(ax, H, (aA >>> 14 | aF << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | aF << 14 | (0 << 14 | 0 >>> 18)) ^ (aF >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (aF >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (aF >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aF << 23 | aA >>> 9))) | 0; + ax = H; + aK = aE & aQ; + u = aw & aP; + t = fp((aE >>> 28 | aw << 4 | (0 << 4 | 0 >>> 28)) ^ (aw >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aw >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aw >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aw << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aw << 25 | aE >>> 7)), aE & aM ^ aG ^ aK, aw & aL ^ r ^ u) | 0; + r = H; + aG = fp(B, ax, aI, aH) | 0; + aH = H; + aI = fp(t, r, B, ax) | 0; + ax = H; + B = fp(w, al, 365543100, 1017036298) | 0; + al = fp(B, H, aC, aB) | 0; + aB = fp(al, H, aG & aA ^ ay & ~aG, aH & aF ^ az & ~aH) | 0; + al = fp(aB, H, (aG >>> 14 | aH << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aH << 14 | (0 << 14 | 0 >>> 18)) ^ (aH >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aH >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aH >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aH << 23 | aG >>> 9))) | 0; + aB = H; + aC = aI & aE; + B = ax & aw; + w = fp((aI >>> 28 | ax << 4 | (0 << 4 | 0 >>> 28)) ^ (ax >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (ax >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (ax >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (ax << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (ax << 25 | aI >>> 7)), aI & aQ ^ aK ^ aC, ax & aP ^ u ^ B) | 0; + u = H; + aK = fp(al, aB, aM, aL) | 0; + aL = H; + aM = fp(w, u, al, aB) | 0; + aB = H; + al = fp(z, an, -1676669620, 1126000580) | 0; + an = fp(al, H, ay, az) | 0; + az = fp(an, H, aK & aG ^ aA & ~aK, aL & aH ^ aF & ~aL) | 0; + an = fp(az, H, (aK >>> 14 | aL << 18 | (0 << 18 | 0 >>> 14)) ^ (aK >>> 18 | aL << 14 | (0 << 14 | 0 >>> 18)) ^ (aL >>> 9 | 0 << 23 | (aK << 23 | 0 >>> 9)), (aL >>> 14 | 0 << 18 | (aK << 18 | 0 >>> 14)) ^ (aL >>> 18 | 0 << 14 | (aK << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aL << 23 | aK >>> 9))) | 0; + az = H; + ay = aM & aI; + al = aB & ax; + z = fp((aM >>> 28 | aB << 4 | (0 << 4 | 0 >>> 28)) ^ (aB >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aB >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aB >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aB << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aB << 25 | aM >>> 7)), aM & aE ^ aC ^ ay, aB & aw ^ B ^ al) | 0; + B = H; + aC = fp(an, az, aQ, aP) | 0; + aP = H; + aQ = fp(z, B, an, az) | 0; + az = H; + an = fp(b, ap, -885112138, 1288033470) | 0; + B = fp(an, H, aA, aF) | 0; + aF = fp(B, H, aC & aK ^ aG & ~aC, aP & aL ^ aH & ~aP) | 0; + B = fp(aF, H, (aC >>> 14 | aP << 18 | (0 << 18 | 0 >>> 14)) ^ (aC >>> 18 | aP << 14 | (0 << 14 | 0 >>> 18)) ^ (aP >>> 9 | 0 << 23 | (aC << 23 | 0 >>> 9)), (aP >>> 14 | 0 << 18 | (aC << 18 | 0 >>> 14)) ^ (aP >>> 18 | 0 << 14 | (aC << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aP << 23 | aC >>> 9))) | 0; + aF = H; + aA = aQ & aM; + an = az & aB; + z = fp((aQ >>> 28 | az << 4 | (0 << 4 | 0 >>> 28)) ^ (az >>> 2 | 0 << 30 | (aQ << 30 | 0 >>> 2)) ^ (az >>> 7 | 0 << 25 | (aQ << 25 | 0 >>> 7)), (az >>> 28 | 0 << 4 | (aQ << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (az << 30 | aQ >>> 2)) ^ (0 >>> 7 | 0 << 25 | (az << 25 | aQ >>> 7)), aQ & aI ^ ay ^ aA, az & ax ^ al ^ an) | 0; + al = H; + ay = fp(B, aF, aE, aw) | 0; + aw = H; + aE = fp(z, al, B, aF) | 0; + aF = H; + B = fp(d, ar, -60457430, 1501505948) | 0; + al = fp(B, H, aG, aH) | 0; + aH = fp(al, H, ay & aC ^ aK & ~ay, aw & aP ^ aL & ~aw) | 0; + al = fp(aH, H, (ay >>> 14 | aw << 18 | (0 << 18 | 0 >>> 14)) ^ (ay >>> 18 | aw << 14 | (0 << 14 | 0 >>> 18)) ^ (aw >>> 9 | 0 << 23 | (ay << 23 | 0 >>> 9)), (aw >>> 14 | 0 << 18 | (ay << 18 | 0 >>> 14)) ^ (aw >>> 18 | 0 << 14 | (ay << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aw << 23 | ay >>> 9))) | 0; + aH = H; + aG = aE & aQ; + B = aF & az; + z = fp((aE >>> 28 | aF << 4 | (0 << 4 | 0 >>> 28)) ^ (aF >>> 2 | 0 << 30 | (aE << 30 | 0 >>> 2)) ^ (aF >>> 7 | 0 << 25 | (aE << 25 | 0 >>> 7)), (aF >>> 28 | 0 << 4 | (aE << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aF << 30 | aE >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aF << 25 | aE >>> 7)), aE & aM ^ aA ^ aG, aF & aB ^ an ^ B) | 0; + an = H; + aA = fp(al, aH, aI, ax) | 0; + ax = H; + aI = fp(z, an, al, aH) | 0; + aH = H; + al = fp(am, at, 987167468, 1607167915) | 0; + at = fp(al, H, (ao >>> 8 | av << 24 | (0 << 24 | 0 >>> 8)) ^ (ao >>> 7 | av << 25) ^ (ao >>> 1 | av << 31 | (0 << 31 | 0 >>> 1)), (av >>> 8 | 0 << 24 | (ao << 24 | 0 >>> 8)) ^ (av >>> 7 | 0 << 25) ^ (av >>> 1 | 0 << 31 | (ao << 31 | 0 >>> 1))) | 0; + al = fp(at, H, n, A) | 0; + A = fp(al, H, (ap >>> 29 | 0 << 3 | (b << 3 | 0 >>> 29)) ^ (b >>> 6 | ap << 26) ^ (b >>> 19 | ap << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ap << 3 | b >>> 29)) ^ (ap >>> 6 | 0 << 26) ^ (ap >>> 19 | 0 << 13 | (b << 13 | 0 >>> 19))) | 0; + b = fp(A, H, aK, aL) | 0; + aL = fp(b, H, aA & ay ^ aC & ~aA, ax & aw ^ aP & ~ax) | 0; + b = fp(aL, H, (aA >>> 14 | ax << 18 | (0 << 18 | 0 >>> 14)) ^ (aA >>> 18 | ax << 14 | (0 << 14 | 0 >>> 18)) ^ (ax >>> 9 | 0 << 23 | (aA << 23 | 0 >>> 9)), (ax >>> 14 | 0 << 18 | (aA << 18 | 0 >>> 14)) ^ (ax >>> 18 | 0 << 14 | (aA << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (ax << 23 | aA >>> 9))) | 0; + aL = H; + aK = aI & aE; + A = aH & aF; + ap = fp((aI >>> 28 | aH << 4 | (0 << 4 | 0 >>> 28)) ^ (aH >>> 2 | 0 << 30 | (aI << 30 | 0 >>> 2)) ^ (aH >>> 7 | 0 << 25 | (aI << 25 | 0 >>> 7)), (aH >>> 28 | 0 << 4 | (aI << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aH << 30 | aI >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aH << 25 | aI >>> 7)), aI & aQ ^ aG ^ aK, aH & az ^ B ^ A) | 0; + B = H; + aG = fp(b, aL, aM, aB) | 0; + aB = H; + aM = fp(ap, B, b, aL) | 0; + aL = H; + b = fp(ao, av, 1246189591, 1816402316) | 0; + av = fp(b, H, (au >>> 8 | f << 24 | (0 << 24 | 0 >>> 8)) ^ (au >>> 7 | f << 25) ^ (au >>> 1 | f << 31 | (0 << 31 | 0 >>> 1)), (f >>> 8 | 0 << 24 | (au << 24 | 0 >>> 8)) ^ (f >>> 7 | 0 << 25) ^ (f >>> 1 | 0 << 31 | (au << 31 | 0 >>> 1))) | 0; + au = fp(av, H, q, c) | 0; + c = fp(au, H, (ar >>> 29 | 0 << 3 | (d << 3 | 0 >>> 29)) ^ (d >>> 6 | ar << 26) ^ (d >>> 19 | ar << 13 | (0 << 13 | 0 >>> 19)), (0 >>> 29 | 0 << 3 | (ar << 3 | d >>> 29)) ^ (ar >>> 6 | 0 << 26) ^ (ar >>> 19 | 0 << 13 | (d << 13 | 0 >>> 19))) | 0; + d = fp(c, H, aC, aP) | 0; + aP = fp(d, H, aG & aA ^ ay & ~aG, aB & ax ^ aw & ~aB) | 0; + d = fp(aP, H, (aG >>> 14 | aB << 18 | (0 << 18 | 0 >>> 14)) ^ (aG >>> 18 | aB << 14 | (0 << 14 | 0 >>> 18)) ^ (aB >>> 9 | 0 << 23 | (aG << 23 | 0 >>> 9)), (aB >>> 14 | 0 << 18 | (aG << 18 | 0 >>> 14)) ^ (aB >>> 18 | 0 << 14 | (aG << 14 | 0 >>> 18)) ^ (0 >>> 9 | 0 << 23 | (aB << 23 | aG >>> 9))) | 0; + aP = H; + aC = fp(aM & (aI ^ aE) ^ aK, aL & (aH ^ aF) ^ A, S, R) | 0; + A = fp(aC, H, (aM >>> 28 | aL << 4 | (0 << 4 | 0 >>> 28)) ^ (aL >>> 2 | 0 << 30 | (aM << 30 | 0 >>> 2)) ^ (aL >>> 7 | 0 << 25 | (aM << 25 | 0 >>> 7)), (aL >>> 28 | 0 << 4 | (aM << 4 | 0 >>> 28)) ^ (0 >>> 2 | 0 << 30 | (aL << 30 | aM >>> 2)) ^ (0 >>> 7 | 0 << 25 | (aL << 25 | aM >>> 7))) | 0; + aC = fp(A, H, d, aP) | 0; + A = H; + aK = fp(aM, aL, Q, P) | 0; + aL = H; + aM = fp(aI, aH, O, N) | 0; + aH = H; + aI = fp(aE, aF, M, L) | 0; + aF = H; + aE = fp(aQ, az, K, J) | 0; + az = fp(aE, H, d, aP) | 0; + aP = H; + d = fp(aG, aB, I, G) | 0; + aB = H; + aG = fp(aA, ax, F, E) | 0; + ax = H; + aA = fp(ay, aw, D, C) | 0; + aw = H; + ay = fp(U, T, -128, -1) | 0; + aE = H; + aQ = 0; + if (aE >>> 0 > aQ >>> 0 | aE >>> 0 == aQ >>> 0 & ay >>> 0 > 127 >>> 0) { + C = aw; + D = aA; + E = ax; + F = aG; + G = aB; + I = d; + J = aP; + K = az; + L = aF; + M = aI; + N = aH; + O = aM; + P = aL; + Q = aK; + R = A; + S = aC; + T = aE; + U = ay; + V = V + 128 | 0; + } else { + W = aw; + X = aA; + Y = ax; + Z = aG; + _ = aB; + $ = d; + aa = aP; + ab = az; + ac = aF; + ad = aI; + ae = aH; + af = aM; + ag = aL; + ah = aK; + ai = A; + aj = aC; + break; + } + } + bX(a, aj, ai); + bX(g, ah, ag); + bX(j, af, ae); + bX(m, ad, ac); + bX(p, ab, aa); + bX(s, $, _); + bX(v, Z, Y); + bX(y, X, W); + return 0; +} +function bW(a) { + a = a | 0; + var b = 0, c = 0, e = 0; + b = d[a + 6 | 0] | 0; + c = d[a + 5 | 0] | 0; + e = d[a + 4 | 0] | 0; + return (H = 0 << 8 | b >>> 24 | (0 << 16 | c >>> 16) | (0 << 24 | e >>> 8) | (d[a + 3 | 0] | 0) | ((d[a + 2 | 0] | 0) << 8 | 0 >>> 24) | ((d[a + 1 | 0] | 0) << 16 | 0 >>> 16) | ((d[a] | 0) << 24 | 0 >>> 8), b << 8 | 0 >>> 24 | (d[a + 7 | 0] | 0) | (c << 16 | 0 >>> 16) | (e << 24 | 0 >>> 8) | (0 << 8 | 0 >>> 24) | (0 << 16 | 0 >>> 16) | (0 << 24 | 0 >>> 8)) | 0; +} +function bX(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + a[b + 7 | 0] = c & 255; + a[b + 6 | 0] = (c >>> 8 | d << 24) & 255; + a[b + 5 | 0] = (c >>> 16 | d << 16) & 255; + a[b + 4 | 0] = (c >>> 24 | d << 8) & 255; + a[b + 3 | 0] = d & 255; + a[b + 2 | 0] = (d >>> 8 | 0 << 24) & 255; + a[b + 1 | 0] = (d >>> 16 | 0 << 16) & 255; + a[b] = (d >>> 24 | 0 << 8) & 255; + return; +} +function bY(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0; + d = 0; + e = 0; + while (1) { + f = a + (d << 2) | 0; + g = (c[f >> 2] | 0) + e + (c[b + (d << 2) >> 2] | 0) | 0; + c[f >> 2] = g & 255; + f = d + 1 | 0; + if (f >>> 0 < 17) { + d = f; + e = g >>> 8; + } else { + break; + } + } + return; +} +function bZ(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0; + b = c[a >> 2] | 0; + c[a >> 2] = b & 255; + d = a + 4 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 8 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 12 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 16 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 20 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 24 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 28 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 32 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 36 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 40 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 44 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 48 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 52 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 56 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 255; + d = a + 60 | 0; + e = (c[d >> 2] | 0) + (b >>> 8) | 0; + c[d >> 2] = e & 255; + d = a + 64 | 0; + b = (c[d >> 2] | 0) + (e >>> 8) | 0; + c[d >> 2] = b & 3; + e = (c[a >> 2] | 0) + ((b >>> 2) * 5 | 0) | 0; + c[a >> 2] = e & 255; + b = a + 4 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 8 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 12 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 16 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 20 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 24 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 28 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 32 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 36 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 40 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 44 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 48 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 52 | 0; + f = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = f & 255; + b = a + 56 | 0; + e = (c[b >> 2] | 0) + (f >>> 8) | 0; + c[b >> 2] = e & 255; + b = a + 60 | 0; + a = (c[b >> 2] | 0) + (e >>> 8) | 0; + c[b >> 2] = a & 255; + c[d >> 2] = (c[d >> 2] | 0) + (a >>> 8); + return; +} +function b_(b, e, f, g, h) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0; + j = i; + i = i + 144 | 0; + k = j | 0; + l = j + 72 | 0; + m = i; + i = i + 68 | 0; + i = i + 7 >> 3 << 3; + n = k | 0; + c[n >> 2] = d[h] | 0; + c[k + 4 >> 2] = d[h + 1 | 0] | 0; + c[k + 8 >> 2] = d[h + 2 | 0] | 0; + c[k + 12 >> 2] = a[h + 3 | 0] & 15; + c[k + 16 >> 2] = a[h + 4 | 0] & 252; + c[k + 20 >> 2] = d[h + 5 | 0] | 0; + c[k + 24 >> 2] = d[h + 6 | 0] | 0; + c[k + 28 >> 2] = a[h + 7 | 0] & 15; + c[k + 32 >> 2] = a[h + 8 | 0] & 252; + c[k + 36 >> 2] = d[h + 9 | 0] | 0; + c[k + 40 >> 2] = d[h + 10 | 0] | 0; + c[k + 44 >> 2] = a[h + 11 | 0] & 15; + c[k + 48 >> 2] = a[h + 12 | 0] & 252; + c[k + 52 >> 2] = d[h + 13 | 0] | 0; + c[k + 56 >> 2] = d[h + 14 | 0] | 0; + c[k + 60 >> 2] = a[h + 15 | 0] & 15; + c[k + 64 >> 2] = 0; + fm(l | 0, 0, 68); + k = m; + if (!((f | 0) == 0 & (g | 0) == 0)) { + o = l | 0; + p = m | 0; + q = g; + g = f; + f = e; + while (1) { + fm(k | 0, 0, 68); + if ((g | 0) == 0 & (q | 0) == 0) { + r = 0; + s = 0; + t = 0; + } else { + e = 0; + while (1) { + c[m + (e << 2) >> 2] = d[f + e | 0] | 0; + u = e + 1 | 0; + v = u; + w = 0; + if (u >>> 0 < 16 & (w >>> 0 < q >>> 0 | w >>> 0 == q >>> 0 & v >>> 0 < g >>> 0)) { + e = u; + } else { + r = u; + s = w; + t = v; + break; + } + } + } + c[m + (r << 2) >> 2] = 1; + e = fq(g, q, t, s) | 0; + v = H; + bY(o, p); + b$(o, n); + if ((g | 0) == (t | 0) & (q | 0) == (s | 0)) { + break; + } else { + q = v; + g = e; + f = f + r | 0; + } + } + } + r = l | 0; + b0(r); + c[m >> 2] = d[h + 16 | 0] | 0; + c[m + 4 >> 2] = d[h + 17 | 0] | 0; + c[m + 8 >> 2] = d[h + 18 | 0] | 0; + c[m + 12 >> 2] = d[h + 19 | 0] | 0; + c[m + 16 >> 2] = d[h + 20 | 0] | 0; + c[m + 20 >> 2] = d[h + 21 | 0] | 0; + c[m + 24 >> 2] = d[h + 22 | 0] | 0; + c[m + 28 >> 2] = d[h + 23 | 0] | 0; + c[m + 32 >> 2] = d[h + 24 | 0] | 0; + c[m + 36 >> 2] = d[h + 25 | 0] | 0; + c[m + 40 >> 2] = d[h + 26 | 0] | 0; + c[m + 44 >> 2] = d[h + 27 | 0] | 0; + c[m + 48 >> 2] = d[h + 28 | 0] | 0; + c[m + 52 >> 2] = d[h + 29 | 0] | 0; + c[m + 56 >> 2] = d[h + 30 | 0] | 0; + c[m + 60 >> 2] = d[h + 31 | 0] | 0; + c[m + 64 >> 2] = 0; + bY(r, m | 0); + a[b] = c[l >> 2] & 255; + a[b + 1 | 0] = c[l + 4 >> 2] & 255; + a[b + 2 | 0] = c[l + 8 >> 2] & 255; + a[b + 3 | 0] = c[l + 12 >> 2] & 255; + a[b + 4 | 0] = c[l + 16 >> 2] & 255; + a[b + 5 | 0] = c[l + 20 >> 2] & 255; + a[b + 6 | 0] = c[l + 24 >> 2] & 255; + a[b + 7 | 0] = c[l + 28 >> 2] & 255; + a[b + 8 | 0] = c[l + 32 >> 2] & 255; + a[b + 9 | 0] = c[l + 36 >> 2] & 255; + a[b + 10 | 0] = c[l + 40 >> 2] & 255; + a[b + 11 | 0] = c[l + 44 >> 2] & 255; + a[b + 12 | 0] = c[l + 48 >> 2] & 255; + a[b + 13 | 0] = c[l + 52 >> 2] & 255; + a[b + 14 | 0] = c[l + 56 >> 2] & 255; + a[b + 15 | 0] = c[l + 60 >> 2] & 255; + i = j; + return 0; +} +function b$(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + d = i; + i = i + 72 | 0; + e = d | 0; + f = 0; + while (1) { + g = 0; + h = 0; + do { + h = (ad(c[b + (f - g << 2) >> 2] | 0, c[a + (g << 2) >> 2] | 0) | 0) + h | 0; + g = g + 1 | 0; + } while (g >>> 0 <= f >>> 0); + g = f + 1 | 0; + if (g >>> 0 >= 17) { + break; + } + j = f + 17 | 0; + k = g; + l = h; + do { + l = (ad((c[a + (k << 2) >> 2] | 0) * 320 | 0, c[b + (j - k << 2) >> 2] | 0) | 0) + l | 0; + k = k + 1 | 0; + } while (k >>> 0 < 17); + c[e + (f << 2) >> 2] = l; + if (g >>> 0 < 17) { + f = g; + } else { + m = 124; + break; + } + } + if ((m | 0) == 124) { + n = a; + o = e; + fn(n | 0, o | 0, 68) | 0; + bZ(a); + i = d; + return; + } + c[e + (f << 2) >> 2] = h; + n = a; + o = e; + fn(n | 0, o | 0, 68) | 0; + bZ(a); + i = d; + return; +} +function b0(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0; + b = i; + d = a; + e = i; + i = i + 68 | 0; + i = i + 7 >> 3 << 3; + f = e; + fn(f | 0, d | 0, 68) | 0; + bY(a, 792); + d = -((c[a + 64 >> 2] | 0) >>> 7) | 0; + f = 0; + do { + g = a + (f << 2) | 0; + h = c[g >> 2] | 0; + c[g >> 2] = (h ^ c[e + (f << 2) >> 2]) & d ^ h; + f = f + 1 | 0; + } while (f >>> 0 < 17); + i = b; + return; +} +function b1(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 16 | 0; + g = f | 0; + b_(g, b, c, d, e) | 0; + e = ed(a, g) | 0; + i = f; + return e | 0; +} +function b2(a, b) { + a = a | 0; + b = b | 0; + return b3(a, b, 111576) | 0; +} +function b3(b, e, f) { + b = b | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, j = 0, k = 0; + g = i; + i = i + 416 | 0; + h = g | 0; + j = g + 384 | 0; + k = j | 0; + fn(k | 0, e | 0, 32) | 0; + e = j | 0; + a[e] = a[e] & -8; + k = j + 31 | 0; + a[k] = a[k] & 63 | 64; + k = 0; + do { + c[h + (k << 2) >> 2] = d[f + k | 0] | 0; + k = k + 1 | 0; + } while (k >>> 0 < 32); + k = h | 0; + b4(k, e); + e = h + 128 | 0; + b5(e, e); + f = h + 256 | 0; + cf(f, k, e); + cg(f); + f = 0; + do { + a[b + f | 0] = c[h + (f + 64 << 2) >> 2] & 255; + f = f + 1 | 0; + } while (f >>> 0 < 32); + i = g; + return 0; +} +function b4(a, b) { + a = a | 0; + b = b | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0; + e = i; + f = a; + g = i; + i = i + 256 | 0; + h = g; + j = i; + i = i + 256 | 0; + k = i; + i = i + 256 | 0; + l = i; + i = i + 256 | 0; + m = i; + i = i + 256 | 0; + n = i; + i = i + 256 | 0; + o = i; + i = i + 256 | 0; + p = i; + i = i + 256 | 0; + q = i; + i = i + 256 | 0; + r = i; + i = i + 256 | 0; + s = i; + i = i + 256 | 0; + t = i; + i = i + 128 | 0; + u = i; + i = i + 128 | 0; + v = i; + i = i + 128 | 0; + w = i; + i = i + 128 | 0; + fn(h | 0, f | 0, 128) | 0; + h = j; + c[g + 128 >> 2] = 1; + fm(g + 132 | 0, 0, 124); + x = j | 0; + c[x >> 2] = 1; + fm(j + 4 | 0, 0, 252); + j = k | 0; + y = l | 0; + z = g | 0; + g = o | 0; + A = k + 128 | 0; + k = o + 128 | 0; + o = p | 0; + B = l + 128 | 0; + l = p + 128 | 0; + p = q | 0; + C = q + 128 | 0; + q = r | 0; + D = r + 128 | 0; + r = s | 0; + E = s + 128 | 0; + s = t | 0; + t = u | 0; + u = v | 0; + v = w | 0; + w = m | 0; + F = m + 128 | 0; + m = n | 0; + G = n + 128 | 0; + n = 254; + while (1) { + H = (d[b + ((n | 0) / 8 | 0) | 0] | 0) >>> ((n & 7) >>> 0) & 1; + ca(j, y, x, z, H); + b8(g, j, A); + cb(k, j, A); + b8(o, y, B); + cb(l, y, B); + ch(p, g); + ch(C, k); + cf(q, o, k); + cf(D, l, g); + b8(r, q, D); + cb(E, q, D); + ch(s, E); + cb(t, p, C); + cc(u, t); + b8(v, u, p); + cf(w, p, C); + cf(F, t, v); + ch(m, r); + cf(G, s, a); + ca(x, z, w, m, H); + if ((n | 0) > 0) { + n = n - 1 | 0; + } else { + break; + } + } + fn(f | 0, h | 0, 256) | 0; + i = e; + return; +} +function b5(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0; + c = i; + i = i + 1280 | 0; + d = c + 896 | 0; + e = c | 0; + ch(e, b); + f = c + 1152 | 0; + ch(f, e); + g = c + 1024 | 0; + ch(g, f); + h = c + 128 | 0; + cf(h, g, b); + b = c + 256 | 0; + cf(b, h, e); + ch(g, b); + e = c + 384 | 0; + cf(e, g, h); + ch(g, e); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + h = c + 512 | 0; + cf(h, g, e); + ch(g, h); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + e = c + 640 | 0; + cf(e, f, h); + ch(g, e); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + cf(g, f, e); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + e = c + 768 | 0; + cf(e, g, h); + ch(g, e); + ch(f, g); + h = 2; + do { + ch(g, f); + ch(f, g); + h = h + 2 | 0; + } while ((h | 0) < 50); + h = d | 0; + cf(h, f, e); + ch(f, h); + ch(g, f); + d = 2; + do { + ch(f, g); + ch(g, f); + d = d + 2 | 0; + } while ((d | 0) < 100); + cf(f, g, h); + ch(g, f); + ch(f, g); + h = 2; + do { + ch(g, f); + ch(f, g); + h = h + 2 | 0; + } while ((h | 0) < 50); + cf(g, f, e); + ch(f, g); + ch(g, f); + ch(f, g); + ch(g, f); + ch(f, g); + cf(a, f, b); + i = c; + return; +} +function b6(a, b) { + a = a | 0; + b = b | 0; + return ((b ^ a) - 1 | 0) >>> 31 | 0; +} +function b7(a) { + a = a | 0; + return (a - 237 | 0) >>> 31 ^ 1 | 0; +} +function b8(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + e = 0; + f = 0; + do { + g = (c[b + (e << 2) >> 2] | 0) + f + (c[d + (e << 2) >> 2] | 0) | 0; + c[a + (e << 2) >> 2] = g & 255; + f = g >>> 8; + e = e + 1 | 0; + } while (e >>> 0 < 31); + c[a + 124 >> 2] = (c[b + 124 >> 2] | 0) + f + (c[d + 124 >> 2] | 0); + return; +} +function b9(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = 0; + d = 0; + do { + e = a + (b << 2) | 0; + f = (c[e >> 2] | 0) + d | 0; + c[e >> 2] = f & 255; + d = f >>> 8; + b = b + 1 | 0; + } while (b >>> 0 < 31); + b = a + 124 | 0; + f = (c[b >> 2] | 0) + d | 0; + c[b >> 2] = f & 127; + d = 0; + e = (f >>> 7) * 19 | 0; + do { + f = a + (d << 2) | 0; + g = (c[f >> 2] | 0) + e | 0; + c[f >> 2] = g & 255; + e = g >>> 8; + d = d + 1 | 0; + } while (d >>> 0 < 31); + c[b >> 2] = (c[b >> 2] | 0) + e; + return; +} +function ca(a, b, d, e, f) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, i = 0, j = 0; + g = f - 1 | 0; + f = 0; + do { + h = d + (f << 2) | 0; + i = c[e + (f << 2) >> 2] | 0; + j = (i ^ c[h >> 2]) & g; + c[a + (f << 2) >> 2] = j ^ i; + c[b + (f << 2) >> 2] = j ^ c[h >> 2]; + f = f + 1 | 0; + } while (f >>> 0 < 64); + return; +} +function cb(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + e = 0; + f = 218; + do { + g = f + 65280 + (c[b + (e << 2) >> 2] | 0) - (c[d + (e << 2) >> 2] | 0) | 0; + c[a + (e << 2) >> 2] = g & 255; + f = g >>> 8; + e = e + 1 | 0; + } while (e >>> 0 < 31); + c[a + 124 >> 2] = (c[b + 124 >> 2] | 0) + f - (c[d + 124 >> 2] | 0); + return; +} +function cc(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = 0; + e = 0; + do { + f = ((c[b + (d << 2) >> 2] | 0) * 121665 | 0) + e | 0; + c[a + (d << 2) >> 2] = f & 255; + e = f >>> 8; + d = d + 1 | 0; + } while (d >>> 0 < 31); + d = ((c[b + 124 >> 2] | 0) * 121665 | 0) + e | 0; + c[a + 124 >> 2] = d & 127; + e = 0; + b = a; + f = (c[a >> 2] | 0) + ((d >>> 7) * 19 | 0) | 0; + do { + c[b >> 2] = f & 255; + e = e + 1 | 0; + b = a + (e << 2) | 0; + f = (c[b >> 2] | 0) + (f >>> 8) | 0; + } while (e >>> 0 < 31); + c[a + 124 >> 2] = f; + return; +} +function cd(a, b) { + a = a | 0; + b = b | 0; + var e = 0; + e = 0; + do { + c[a + (e << 2) >> 2] = d[b + e | 0] | 0; + e = e + 1 | 0; + } while ((e | 0) < 32); + e = a + 124 | 0; + c[e >> 2] = c[e >> 2] & 127; + return; +} +function ce(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + e = -(d & 255) | 0; + d = 0; + do { + f = a + (d << 2) | 0; + g = c[f >> 2] | 0; + c[f >> 2] = (g ^ c[b + (d << 2) >> 2]) & e ^ g; + d = d + 1 | 0; + } while ((d | 0) < 32); + return; +} +function cf(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0; + e = 0; + while (1) { + f = 0; + g = 0; + do { + g = (ad(c[d + (e - f << 2) >> 2] | 0, c[b + (f << 2) >> 2] | 0) | 0) + g | 0; + f = f + 1 | 0; + } while (f >>> 0 <= e >>> 0); + f = e + 1 | 0; + if (f >>> 0 >= 32) { + break; + } + h = e + 32 | 0; + i = f; + j = g; + do { + j = (ad((c[b + (i << 2) >> 2] | 0) * 38 | 0, c[d + (h - i << 2) >> 2] | 0) | 0) + j | 0; + i = i + 1 | 0; + } while (i >>> 0 < 32); + c[a + (e << 2) >> 2] = j; + if (f >>> 0 < 32) { + e = f; + } else { + k = 182; + break; + } + } + if ((k | 0) == 182) { + b9(a); + return; + } + c[a + (e << 2) >> 2] = g; + b9(a); + return; +} +function cg(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0; + b = i; + d = a; + e = i; + i = i + 128 | 0; + f = e; + fn(f | 0, d | 0, 128) | 0; + b8(a, a, 664); + d = -((c[a + 124 >> 2] | 0) >>> 7 & 1) | 0; + f = 0; + do { + g = a + (f << 2) | 0; + h = c[g >> 2] | 0; + c[g >> 2] = (h ^ c[e + (f << 2) >> 2]) & d ^ h; + f = f + 1 | 0; + } while (f >>> 0 < 32); + i = b; + return; +} +function ch(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0; + d = 0; + while (1) { + if ((d | 0) == 0) { + e = 0; + f = 1; + g = 32; + h = 190; + } else { + i = 0; + j = 0; + k = d; + do { + j = (ad(c[b + (k << 2) >> 2] | 0, c[b + (i << 2) >> 2] | 0) | 0) + j | 0; + i = i + 1 | 0; + k = d - i | 0; + } while (i >>> 0 < k >>> 0); + k = d + 1 | 0; + if (k >>> 0 < 31) { + e = j; + f = k; + g = d + 32 | 0; + h = 190; + } else { + l = j; + m = k; + } + } + if ((h | 0) == 190) { + h = 0; + k = f; + i = e; + n = 31; + while (1) { + o = (ad((c[b + (k << 2) >> 2] | 0) * 38 | 0, c[b + (n << 2) >> 2] | 0) | 0) + i | 0; + p = k + 1 | 0; + q = g + ~k | 0; + if (p >>> 0 < q >>> 0) { + k = p; + i = o; + n = q; + } else { + l = o; + m = f; + break; + } + } + } + n = l << 1; + if ((d & 1 | 0) == 0) { + i = d >>> 1; + k = c[b + (i << 2) >> 2] | 0; + j = (ad(k, k) | 0) + n | 0; + k = c[b + (i + 16 << 2) >> 2] | 0; + r = j + (ad(k * 38 | 0, k) | 0) | 0; + } else { + r = n; + } + c[a + (d << 2) >> 2] = r; + if (m >>> 0 < 32) { + d = m; + } else { + break; + } + } + b9(a); + return; +} +function ci(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0; + g = 0; + if (d >>> 0 < g >>> 0 | d >>> 0 == g >>> 0 & c >>> 0 < 32 >>> 0) { + h = -1; + return h | 0; + } + el(a, b, c, d, e, f) | 0; + f = fp(c, d, -32, -1) | 0; + b_(a + 16 | 0, a + 32 | 0, f, H, a) | 0; + fm(a | 0, 0, 16); + h = 0; + return h | 0; +} +function cj(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, j = 0, k = 0; + g = i; + i = i + 32 | 0; + h = 0; + if (d >>> 0 < h >>> 0 | d >>> 0 == h >>> 0 & c >>> 0 < 32 >>> 0) { + j = -1; + i = g; + return j | 0; + } + h = g | 0; + ek(h, 32, 0, e, f) | 0; + k = fp(c, d, -32, -1) | 0; + if ((b1(b + 16 | 0, b + 32 | 0, k, H, h) | 0) != 0) { + j = -1; + i = g; + return j | 0; + } + el(a, b, c, d, e, f) | 0; + fm(a | 0, 0, 32); + j = 0; + i = g; + return j | 0; +} +function ck(b, c) { + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0; + d = i; + i = i + 704 | 0; + e = d | 0; + f = d + 128 | 0; + g = d + 640 | 0; + at(c | 0, 32, 0); + h = g | 0; + bR(h, c, 32, 0) | 0; + a[h] = a[h] & -8; + j = g + 31 | 0; + a[j] = a[j] & 63 | 64; + cV(e, h); + cR(f, e); + cJ(b, f); + f = 0; + do { + a[c + (f + 32) | 0] = a[b + f | 0] | 0; + f = f + 1 | 0; + } while ((f | 0) < 32); + i = d; + return 0; +} +function cl(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0; + j = i; + i = i + 928 | 0; + k = j | 0; + l = j + 128 | 0; + m = j + 256 | 0; + n = j + 384 | 0; + o = j + 896 | 0; + p = o | 0; + q = i; + i = i + 32 | 0; + r = q | 0; + s = i; + i = i + 64 | 0; + t = i; + i = i + 64 | 0; + u = i; + i = i + 64 | 0; + v = s | 0; + bR(v, h, 32, 0) | 0; + a[v] = a[v] & -8; + w = s + 31 | 0; + a[w] = a[w] & 63 | 64; + w = fp(f, g, 64, 0) | 0; + x = H; + c[d >> 2] = w; + c[d + 4 >> 2] = x; + if (!((f | 0) == 0 & (g | 0) == 0)) { + d = 0; + y = 0; + do { + z = a[e + y | 0] | 0; + A = fp(y, d, 64, 0) | 0; + a[b + A | 0] = z; + y = fp(y, d, 1, 0) | 0; + d = H; + } while (d >>> 0 < g >>> 0 | d >>> 0 == g >>> 0 & y >>> 0 < f >>> 0); + } + y = b + 32 | 0; + d = s + 32 | 0; + fn(y | 0, d | 0, 32) | 0; + d = t | 0; + t = fp(f, g, 32, 0) | 0; + bR(d, b + 32 | 0, t, H) | 0; + c7(k, d); + cR(n, k); + cJ(o | 0, n); + fn(b | 0, p | 0, 32) | 0; + p = u | 0; + cm(p, b, h + 32 | 0, b, w, x); + c7(l, p); + cV(m, v); + db(l, l, m); + c9(l, l, k); + cY(q | 0, l); + l = b + 32 | 0; + fn(l | 0, r | 0, 32) | 0; + i = j; + return 0; +} +function cm(b, c, d, e, f, g) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0; + h = 0; + i = 0; + while (1) { + j = i; + a[e + j | 0] = a[c + j | 0] | 0; + j = fp(i, h, 1, 0) | 0; + k = H; + l = 0; + if (k >>> 0 < l >>> 0 | k >>> 0 == l >>> 0 & j >>> 0 < 32 >>> 0) { + h = k; + i = j; + } else { + m = 0; + n = 32; + break; + } + } + do { + i = fp(n, m, -32, 0) | 0; + a[e + n | 0] = a[d + i | 0] | 0; + n = fp(n, m, 1, 0) | 0; + m = H; + i = 0; + } while (m >>> 0 < i >>> 0 | m >>> 0 == i >>> 0 & n >>> 0 < 64 >>> 0); + n = 0; + if (g >>> 0 > n >>> 0 | g >>> 0 == n >>> 0 & f >>> 0 > 64 >>> 0) { + o = 0; + p = 64; + } else { + q = bR(b, e, f, g) | 0; + return; + } + do { + n = p; + a[e + n | 0] = a[c + n | 0] | 0; + p = fp(p, o, 1, 0) | 0; + o = H; + } while (o >>> 0 < g >>> 0 | o >>> 0 == g >>> 0 & p >>> 0 < f >>> 0); + q = bR(b, e, f, g) | 0; + return; +} +function cn(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + j = i; + i = i + 1376 | 0; + k = j + 32 | 0; + l = j + 544 | 0; + m = j + 1056 | 0; + n = j + 1184 | 0; + c[d >> 2] = -1; + c[d + 4 >> 2] = -1; + o = 0; + if (g >>> 0 < o >>> 0 | g >>> 0 == o >>> 0 & f >>> 0 < 64 >>> 0) { + p = -1; + i = j; + return p | 0; + } + if ((cI(k, h) | 0) != 0) { + p = -1; + i = j; + return p | 0; + } + o = j + 1312 | 0; + cm(o, e, h, b, f, g); + c7(m, o); + cV(n, e + 32 | 0); + cL(l, k, m, 111064, n); + n = j | 0; + cJ(n, l); + l = em(e, n) | 0; + if ((l | 0) == 0) { + n = fp(f, g, -64, -1) | 0; + m = H; + if (!((n | 0) == 0 & (m | 0) == 0)) { + k = 0; + do { + a[b + k | 0] = a[e + (k + 64) | 0] | 0; + k = k + 1 | 0; + o = (k | 0) < 0 ? -1 : 0; + } while (o >>> 0 < m >>> 0 | o >>> 0 == m >>> 0 & k >>> 0 < n >>> 0); + } + c[d >> 2] = n; + c[d + 4 >> 2] = m; + p = l; + i = j; + return p | 0; + } else { + if ((f | 0) == 64 & (g | 0) == 0) { + p = l; + i = j; + return p | 0; + } + m = fp(f, g, -65, 0) | 0; + fm(b | 0, 0, m + 1 | 0); + p = l; + i = j; + return p | 0; + } + return 0; +} +function co(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = 30; + e = b6(c[b >> 2] | 0, 127) | 0; + do { + e = (b6(c[a + (d << 2) >> 2] | 0, 255) | 0) & e; + d = d - 1 | 0; + } while ((d | 0) > 0); + d = a | 0; + f = -((b7(c[d >> 2] | 0) | 0) & e) | 0; + c[b >> 2] = (c[b >> 2] | 0) - (f & 127); + b = f & 255; + e = 30; + do { + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) - b; + e = e - 1 | 0; + } while ((e | 0) > 0); + c[d >> 2] = (c[d >> 2] | 0) - (f & 237); + return; +} +function cp(b, d) { + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0; + e = i; + i = i + 128 | 0; + f = e | 0; + g = f; + h = d; + fn(g | 0, h | 0, 128) | 0; + co(f); + h = 0; + do { + a[b + h | 0] = c[f + (h << 2) >> 2] & 255; + h = h + 1 | 0; + } while ((h | 0) < 32); + i = e; + return; +} +function cq(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0; + b = i; + i = i + 128 | 0; + d = b | 0; + e = d; + f = a; + fn(e | 0, f | 0, 128) | 0; + co(d); + f = 1; + e = b6(c[d >> 2] | 0, 0) | 0; + do { + e = (b6(c[d + (f << 2) >> 2] | 0, 0) | 0) & e; + f = f + 1 | 0; + } while ((f | 0) < 32); + i = b; + return e | 0; +} +function cr(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0; + d = i; + i = i + 256 | 0; + e = d | 0; + f = d + 128 | 0; + g = e; + h = a; + fn(g | 0, h | 0, 128) | 0; + h = f; + g = b; + fn(h | 0, g | 0, 128) | 0; + co(e); + co(f); + g = 0; + while (1) { + if ((g | 0) >= 32) { + j = 1; + k = 252; + break; + } + if ((c[e + (g << 2) >> 2] | 0) == (c[f + (g << 2) >> 2] | 0)) { + g = g + 1 | 0; + } else { + j = 0; + k = 251; + break; + } + } + if ((k | 0) == 251) { + i = d; + return j | 0; + } else if ((k | 0) == 252) { + i = d; + return j | 0; + } + return 0; +} +function cs(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0; + b = i; + i = i + 128 | 0; + d = b | 0; + e = d; + f = a; + fn(e | 0, f | 0, 128) | 0; + co(d); + i = b; + return c[d >> 2] & 1 | 0; +} +function ct(a) { + a = a | 0; + c[a >> 2] = 1; + fm(a + 4 | 0, 0, 124); + return; +} +function cu(a) { + a = a | 0; + fm(a | 0, 0, 128); + return; +} +function cv(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0; + c = i; + d = b; + b = i; + i = i + 128 | 0; + e = b; + fn(e | 0, d | 0, 128) | 0; + cu(a); + cw(a, a, b); + i = c; + return; +} +function cw(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0; + e = i; + i = i + 128 | 0; + f = e | 0; + c[f >> 2] = (c[b >> 2] | 0) + 474; + c[f + 124 >> 2] = (c[b + 124 >> 2] | 0) + 254; + g = 1; + while (1) { + c[f + (g << 2) >> 2] = (c[b + (g << 2) >> 2] | 0) + 510; + h = g + 1 | 0; + if ((h | 0) < 31) { + g = h; + } else { + j = 0; + break; + } + } + do { + c[a + (j << 2) >> 2] = (c[f + (j << 2) >> 2] | 0) - (c[d + (j << 2) >> 2] | 0); + j = j + 1 | 0; + } while ((j | 0) < 32); + cC(a); + i = e; + return; +} +function cx(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0; + e = 0; + do { + c[a + (e << 2) >> 2] = (c[d + (e << 2) >> 2] | 0) + (c[b + (e << 2) >> 2] | 0); + e = e + 1 | 0; + } while ((e | 0) < 32); + cC(a); + return; +} +function cy(a) { + a = a | 0; + return a * 38 | 0 | 0; +} +function cz(a) { + a = a | 0; + return a * 19 | 0 | 0; +} +function cA(a, b) { + a = a | 0; + b = b | 0; + return (((b ^ a) & 255) - 1 | 0) >>> 31 & 255 | 0; +} +function cB(a) { + a = a | 0; + return ((a << 24 >> 24 < 0 ? -1 : 0) >>> 31 | 0 << 1) & 255 | 0; +} +function cC(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = a | 0; + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + f = cz(e >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + f; + f = 0; + do { + e = a + (f << 2) | 0; + f = f + 1 | 0; + g = a + (f << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((f | 0) < 31); + f = c[b >> 2] | 0; + c[b >> 2] = f & 127; + e = cz(f >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + e; + e = 0; + do { + f = a + (e << 2) | 0; + e = e + 1 | 0; + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[f >> 2] | 0) >>> 8); + c[f >> 2] = c[f >> 2] & 255; + } while ((e | 0) < 31); + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + f = cz(e >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + f; + f = 0; + do { + e = a + (f << 2) | 0; + f = f + 1 | 0; + g = a + (f << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((f | 0) < 31); + f = c[b >> 2] | 0; + c[b >> 2] = f & 127; + b = cz(f >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + b; + b = 0; + do { + d = a + (b << 2) | 0; + b = b + 1 | 0; + f = a + (b << 2) | 0; + c[f >> 2] = (c[f >> 2] | 0) + ((c[d >> 2] | 0) >>> 8); + c[d >> 2] = c[d >> 2] & 255; + } while ((b | 0) < 31); + return; +} +function cD(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 252); + g = 0; + while (1) { + h = c[b + (g << 2) >> 2] | 0; + j = 0; + do { + k = ad(c[d + (j << 2) >> 2] | 0, h) | 0; + l = f + (j + g << 2) | 0; + c[l >> 2] = (c[l >> 2] | 0) + k; + j = j + 1 | 0; + } while ((j | 0) < 32); + j = g + 1 | 0; + if ((j | 0) < 32) { + g = j; + } else { + m = 32; + break; + } + } + do { + g = m - 32 | 0; + d = c[f + (g << 2) >> 2] | 0; + c[a + (g << 2) >> 2] = (cy(c[f + (m << 2) >> 2] | 0) | 0) + d; + m = m + 1 | 0; + } while ((m | 0) < 63); + c[a + 124 >> 2] = c[f + 124 >> 2]; + cE(a); + i = e; + return; +} +function cE(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = a | 0; + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + f = cz(e >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + f; + f = 0; + do { + e = a + (f << 2) | 0; + f = f + 1 | 0; + g = a + (f << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((f | 0) < 31); + f = c[b >> 2] | 0; + c[b >> 2] = f & 127; + b = cz(f >>> 7) | 0; + c[d >> 2] = (c[d >> 2] | 0) + b; + b = 0; + do { + d = a + (b << 2) | 0; + b = b + 1 | 0; + f = a + (b << 2) | 0; + c[f >> 2] = (c[f >> 2] | 0) + ((c[d >> 2] | 0) >>> 8); + c[d >> 2] = c[d >> 2] & 255; + } while ((b | 0) < 31); + return; +} +function cF(a, b) { + a = a | 0; + b = b | 0; + cD(a, b, b); + return; +} +function cG(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0; + c = i; + i = i + 1280 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = c + 512 | 0; + j = c + 640 | 0; + k = c + 768 | 0; + l = c + 896 | 0; + m = c + 1024 | 0; + n = c + 1152 | 0; + cF(d, b); + cF(n, d); + cF(m, n); + cD(e, m, b); + cD(f, e, d); + cF(m, f); + cD(g, m, e); + cF(m, g); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cD(h, m, g); + cF(m, h); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cD(j, n, h); + cF(m, j); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cD(m, n, j); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cD(k, m, h); + cF(m, k); + cF(n, m); + h = 2; + do { + cF(m, n); + cF(n, m); + h = h + 2 | 0; + } while ((h | 0) < 50); + cD(l, n, k); + cF(n, l); + cF(m, n); + h = 2; + do { + cF(n, m); + cF(m, n); + h = h + 2 | 0; + } while ((h | 0) < 100); + cD(n, m, l); + cF(m, n); + cF(n, m); + l = 2; + do { + cF(m, n); + cF(n, m); + l = l + 2 | 0; + } while ((l | 0) < 50); + cD(m, n, k); + cF(n, m); + cF(m, n); + cF(n, m); + cF(m, n); + cF(n, m); + cD(a, n, f); + i = c; + return; +} +function cH(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + c = i; + i = i + 1152 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = c + 512 | 0; + j = c + 640 | 0; + k = c + 768 | 0; + l = c + 896 | 0; + m = c + 1024 | 0; + cF(d, b); + cF(m, d); + cF(m, m); + cD(e, m, b); + cD(f, e, d); + cF(m, f); + cD(g, m, e); + cF(m, g); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cD(h, m, g); + cF(m, h); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cD(j, m, h); + cF(m, j); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cD(m, m, j); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cF(m, m); + cD(k, m, h); + cF(m, k); + h = 1; + do { + cF(m, m); + h = h + 1 | 0; + } while ((h | 0) < 50); + cD(l, m, k); + cF(m, l); + h = 1; + do { + cF(m, m); + h = h + 1 | 0; + } while ((h | 0) < 100); + cD(m, m, l); + cF(m, m); + l = 1; + do { + cF(m, m); + l = l + 1 | 0; + } while ((l | 0) < 50); + cD(m, m, k); + cF(m, m); + cF(m, m); + cD(a, m, b); + i = c; + return; +} +function cI(a, b) { + a = a | 0; + b = b | 0; + var c = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + c = i; + i = i + 896 | 0; + e = c | 0; + f = c + 128 | 0; + g = c + 256 | 0; + h = c + 384 | 0; + j = c + 512 | 0; + k = c + 640 | 0; + l = c + 768 | 0; + m = a + 256 | 0; + ct(m); + n = (d[b + 31 | 0] | 0) >>> 7; + o = a + 128 | 0; + cd(o, b); + cF(g, o); + cD(h, g, 1592); + cw(g, g, m); + cx(h, m, h); + cF(j, h); + cF(k, j); + cD(l, k, j); + cD(e, l, g); + cD(e, e, h); + cH(e, e); + cD(e, e, g); + cD(e, e, h); + cD(e, e, h); + l = a | 0; + cD(l, e, h); + cF(f, l); + cD(f, f, h); + if ((cr(f, g) | 0) == 0) { + cD(l, l, 1400); + } + cF(f, l); + cD(f, f, h); + if ((cr(f, g) | 0) == 0) { + p = -1; + i = c; + return p | 0; + } + if (((cs(l) | 0) & 255 | 0) != (n & 255 ^ 1 | 0)) { + cv(l, l); + } + cD(a + 384 | 0, l, o); + p = 0; + i = c; + return p | 0; +} +function cJ(b, c) { + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0; + d = i; + i = i + 384 | 0; + e = d | 0; + f = d + 128 | 0; + g = d + 256 | 0; + cG(g, c + 256 | 0); + cD(e, c | 0, g); + cD(f, c + 128 | 0, g); + cp(b, f); + f = (cs(e) | 0) << 7; + e = b + 31 | 0; + a[e] = a[e] ^ f; + i = d; + return; +} +function cK(a) { + a = a | 0; + var b = 0; + b = (cq(a | 0) | 0) != 0 | 0; + return ((cr(a + 128 | 0, a + 256 | 0) | 0) == 0 ? 0 : b) | 0; +} +function cL(b, c, e, f, g) { + b = b | 0; + c = c | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0; + h = i; + i = i + 8832 | 0; + j = h | 0; + k = h + 512 | 0; + l = h + 8704 | 0; + cM(k | 0); + m = k + 512 | 0; + n = m; + o = c; + fn(n | 0, o | 0, 512) | 0; + cN(j, c); + c = k + 1024 | 0; + cO(c, j); + cP(j, m, c); + o = k + 1536 | 0; + cO(o, j); + n = k + 2048 | 0; + p = n; + q = f; + fn(p | 0, q | 0, 512) | 0; + cP(j, m, n); + q = k + 2560 | 0; + cO(q, j); + cP(j, c, n); + cO(k + 3072 | 0, j); + cP(j, o, n); + cO(k + 3584 | 0, j); + cN(j, f); + f = k + 4096 | 0; + cO(f, j); + cP(j, m, f); + cO(k + 4608 | 0, j); + cN(j, q); + cO(k + 5120 | 0, j); + cP(j, o, f); + cO(k + 5632 | 0, j); + cP(j, n, f); + f = k + 6144 | 0; + cO(f, j); + cP(j, m, f); + cO(k + 6656 | 0, j); + cP(j, c, f); + cO(k + 7168 | 0, j); + cP(j, o, f); + cO(k + 7680 | 0, j); + c3(l | 0, e, g); + g = b; + e = k + (d[l + 126 | 0] << 9) | 0; + fn(g | 0, e | 0, 512) | 0; + e = b; + g = 125; + while (1) { + cN(j, e); + cQ(e, j); + cN(j, e); + f = l + g | 0; + if ((a[f] | 0) != 0) { + cO(b, j); + cP(j, b, k + (d[f] << 9) | 0); + } + if ((g | 0) == 0) { + break; + } + cQ(e, j); + if ((g | 0) > 0) { + g = g - 1 | 0; + } else { + r = 322; + break; + } + } + if ((r | 0) == 322) { + i = h; + return; + } + cO(b, j); + i = h; + return; +} +function cM(a) { + a = a | 0; + cu(a | 0); + ct(a + 128 | 0); + ct(a + 256 | 0); + cu(a + 384 | 0); + return; +} +function cN(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0; + c = i; + i = i + 512 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = b | 0; + cF(d, h); + j = b + 128 | 0; + cF(e, j); + cF(f, b + 256 | 0); + cx(f, f, f); + cv(g, d); + b = a | 0; + cx(b, h, j); + cF(b, b); + cw(b, b, d); + cw(b, b, e); + b = a + 128 | 0; + cx(b, g, e); + cw(a + 384 | 0, b, f); + cw(a + 256 | 0, g, e); + i = c; + return; +} +function cO(a, b) { + a = a | 0; + b = b | 0; + cQ(a, b); + cD(a + 384 | 0, b | 0, b + 256 | 0); + return; +} +function cP(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0; + d = i; + i = i + 640 | 0; + e = d | 0; + f = d + 128 | 0; + g = d + 256 | 0; + h = d + 384 | 0; + j = d + 512 | 0; + k = b + 128 | 0; + l = b | 0; + cw(e, k, l); + m = c + 128 | 0; + n = c | 0; + cw(j, m, n); + cD(e, e, j); + cx(f, l, k); + cx(j, n, m); + cD(f, f, j); + cD(g, b + 384 | 0, c + 384 | 0); + cD(g, g, 1720); + cD(h, b + 256 | 0, c + 256 | 0); + cx(h, h, h); + cw(a | 0, f, e); + cw(a + 384 | 0, h, g); + cx(a + 128 | 0, h, g); + cx(a + 256 | 0, f, e); + i = d; + return; +} +function cQ(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0; + c = b + 384 | 0; + cD(a | 0, b | 0, c); + d = b + 128 | 0; + cD(a + 128 | 0, b + 256 | 0, d); + cD(a + 256 | 0, d, c); + return; +} +function cR(b, c) { + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0; + d = i; + i = i + 344 | 0; + e = d | 0; + f = d + 88 | 0; + g = e | 0; + c1(g, c); + cS(b, 0, 0, a[g] | 0); + ct(b + 256 | 0); + cD(b + 384 | 0, b | 0, b + 128 | 0); + g = 1; + do { + cS(f, g, (g | 0) < 0 ? -1 : 0, a[e + g | 0] | 0); + cT(b, f); + g = g + 1 | 0; + } while ((g | 0) < 85); + i = d; + return; +} +function cS(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0; + e = i; + i = i + 128 | 0; + f = e | 0; + g = fz(b, c, 5, 0) | 0; + c = H; + b = a; + h = 1976 + (g << 8) | 0; + fn(b | 0, h | 0, 256) | 0; + h = fp(g, c, 1, 0) | 0; + b = cA(d, 1) | 0; + cU(a, 1976 + (h << 8) | 0, cA(d, -1) | 0 | b); + b = fp(g, c, 2, 0) | 0; + h = cA(d, 2) | 0; + cU(a, 1976 + (b << 8) | 0, cA(d, -2) | 0 | h); + h = fp(g, c, 3, 0) | 0; + b = cA(d, 3) | 0; + cU(a, 1976 + (h << 8) | 0, cA(d, -3) | 0 | b); + b = fp(g, c, 4, 0) | 0; + cU(a, 1976 + (b << 8) | 0, cA(d, -4) | 0); + b = a | 0; + cv(f, b); + ce(b, f, cB(d) | 0); + i = e; + return; +} +function cT(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0; + c = i; + i = i + 1408 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = c + 512 | 0; + j = c + 640 | 0; + k = c + 768 | 0; + l = c + 896 | 0; + m = c + 1024 | 0; + n = c + 1152 | 0; + o = c + 1280 | 0; + p = b | 0; + q = b + 128 | 0; + cD(o, p, q); + b = a + 128 | 0; + r = a | 0; + cw(d, b, r); + cx(e, b, r); + cw(f, q, p); + cx(g, q, p); + cD(d, d, f); + cD(e, e, g); + cw(k, e, d); + cx(n, e, d); + d = a + 384 | 0; + cD(h, d, o); + cD(h, h, 1720); + o = a + 256 | 0; + cx(j, o, o); + cw(l, j, h); + cx(m, j, h); + cD(r, k, l); + cD(b, n, m); + cD(o, m, l); + cD(d, k, n); + i = c; + return; +} +function cU(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + ce(a | 0, b | 0, c); + ce(a + 128 | 0, b + 128 | 0, c); + return; +} +function cV(a, b) { + a = a | 0; + b = b | 0; + var e = 0, f = 0, g = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + g = 0; + do { + c[f + (g << 2) >> 2] = d[b + g | 0] | 0; + g = g + 1 | 0; + } while ((g | 0) < 32); + fm(f + 128 | 0, 0, 128); + c6(a, f | 0); + i = e; + return; +} +function cW(a, b) { + a = a | 0; + b = b | 0; + return (a - b | 0) >>> 31 | 0; +} +function cX(a, b) { + a = a | 0; + b = b | 0; + c[a >> 2] = d[b] | 0; + c[a + 4 >> 2] = d[b + 1 | 0] | 0; + c[a + 8 >> 2] = d[b + 2 | 0] | 0; + c[a + 12 >> 2] = d[b + 3 | 0] | 0; + c[a + 16 >> 2] = d[b + 4 | 0] | 0; + c[a + 20 >> 2] = d[b + 5 | 0] | 0; + c[a + 24 >> 2] = d[b + 6 | 0] | 0; + c[a + 28 >> 2] = d[b + 7 | 0] | 0; + c[a + 32 >> 2] = d[b + 8 | 0] | 0; + c[a + 36 >> 2] = d[b + 9 | 0] | 0; + c[a + 40 >> 2] = d[b + 10 | 0] | 0; + c[a + 44 >> 2] = d[b + 11 | 0] | 0; + c[a + 48 >> 2] = d[b + 12 | 0] | 0; + c[a + 52 >> 2] = d[b + 13 | 0] | 0; + c[a + 56 >> 2] = d[b + 14 | 0] | 0; + c[a + 60 >> 2] = d[b + 15 | 0] | 0; + return; +} +function cY(b, d) { + b = b | 0; + d = d | 0; + var e = 0; + e = 0; + do { + a[b + e | 0] = c[d + (e << 2) >> 2] & 255; + e = e + 1 | 0; + } while ((e | 0) < 32); + return; +} +function cZ(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = 0; + while (1) { + if ((b | 0) >= 32) { + d = 1; + e = 347; + break; + } + if ((c[a + (b << 2) >> 2] | 0) == 0) { + b = b + 1 | 0; + } else { + d = 0; + e = 346; + break; + } + } + if ((e | 0) == 346) { + return d | 0; + } else if ((e | 0) == 347) { + return d | 0; + } + return 0; +} +function c_(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = 31; + while (1) { + if ((b | 0) <= 15) { + d = 1; + e = 353; + break; + } + if ((c[a + (b << 2) >> 2] | 0) == 0) { + b = b - 1 | 0; + } else { + d = 0; + e = 352; + break; + } + } + if ((e | 0) == 352) { + return d | 0; + } else if ((e | 0) == 353) { + return d | 0; + } + return 0; +} +function c$(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0; + d = 31; + while (1) { + if ((d | 0) <= -1) { + e = 0; + f = 359; + break; + } + g = c[a + (d << 2) >> 2] | 0; + h = c[b + (d << 2) >> 2] | 0; + if (g >>> 0 < h >>> 0) { + e = 1; + f = 361; + break; + } + if (g >>> 0 > h >>> 0) { + e = 0; + f = 360; + break; + } else { + d = d - 1 | 0; + } + } + if ((f | 0) == 360) { + return e | 0; + } else if ((f | 0) == 359) { + return e | 0; + } else if ((f | 0) == 361) { + return e | 0; + } + return 0; +} +function c0(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0; + e = 0; + f = 0; + while (1) { + g = (c[b + (f << 2) >> 2] | 0) - (c[d + (f << 2) >> 2] | 0) - e | 0; + c[a + (f << 2) >> 2] = g & 255; + h = f + 1 | 0; + if ((h | 0) < 32) { + e = g >>> 8 & 1; + f = h; + } else { + break; + } + } + return; +} +function c1(b, e) { + b = b | 0; + e = e | 0; + var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0; + f = 0; + while (1) { + g = f * 3 | 0; + h = e + (g << 2) | 0; + i = f << 3; + a[b + i | 0] = c[h >> 2] & 7; + a[b + (i | 1) | 0] = (c[h >> 2] | 0) >>> 3 & 7; + j = (c[h >> 2] | 0) >>> 6 & 7; + h = b + (i | 2) | 0; + a[h] = j; + k = e + (g + 1 << 2) | 0; + a[h] = (j & 255 ^ c[k >> 2] << 2 & 4) & 255; + a[b + (i | 3) | 0] = (c[k >> 2] | 0) >>> 1 & 7; + a[b + (i | 4) | 0] = (c[k >> 2] | 0) >>> 4 & 7; + if ((f | 0) >= 10) { + l = 0; + m = 0; + break; + } + j = (c[k >> 2] | 0) >>> 7 & 7; + k = b + (i | 5) | 0; + a[k] = j; + h = e + (g + 2 << 2) | 0; + a[k] = (j & 255 ^ c[h >> 2] << 1 & 6) & 255; + a[b + (i | 6) | 0] = (c[h >> 2] | 0) >>> 2 & 7; + a[b + (i | 7) | 0] = (c[h >> 2] | 0) >>> 5 & 7; + f = f + 1 | 0; + } + do { + f = b + m | 0; + e = (d[f] | 0) + l & 255; + a[f] = e; + m = m + 1 | 0; + h = b + m | 0; + a[h] = (e << 24 >> 24 >>> 3) + (d[h] | 0) & 255; + h = a[f] & 7; + l = h >>> 2; + a[f] = h - (l << 3) & 255; + } while ((m | 0) < 84); + m = b + 84 | 0; + a[m] = (d[m] | 0) + l & 255; + return; +} +function c2(b, e) { + b = b | 0; + e = e | 0; + var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0; + f = 0; + while (1) { + g = f * 5 | 0; + h = e + (g << 2) | 0; + i = f << 3; + a[b + i | 0] = c[h >> 2] & 31; + j = (c[h >> 2] | 0) >>> 5 & 31; + h = b + (i | 1) | 0; + a[h] = j; + k = e + (g + 1 << 2) | 0; + a[h] = (j & 255 ^ c[k >> 2] << 3 & 24) & 255; + a[b + (i | 2) | 0] = (c[k >> 2] | 0) >>> 2 & 31; + if ((f | 0) >= 6) { + l = 0; + m = 0; + break; + } + j = (c[k >> 2] | 0) >>> 7 & 31; + k = b + (i | 3) | 0; + a[k] = j; + h = e + (g + 2 << 2) | 0; + a[k] = (j & 255 ^ c[h >> 2] << 1 & 30) & 255; + j = (c[h >> 2] | 0) >>> 4 & 31; + h = b + (i | 4) | 0; + a[h] = j; + k = e + (g + 3 << 2) | 0; + a[h] = (j & 255 ^ c[k >> 2] << 4 & 16) & 255; + a[b + (i | 5) | 0] = (c[k >> 2] | 0) >>> 1 & 31; + j = (c[k >> 2] | 0) >>> 6 & 31; + k = b + (i | 6) | 0; + a[k] = j; + h = e + (g + 4 << 2) | 0; + a[k] = (j & 255 ^ c[h >> 2] << 2 & 28) & 255; + a[b + (i | 7) | 0] = (c[h >> 2] | 0) >>> 3 & 31; + f = f + 1 | 0; + } + do { + f = b + m | 0; + e = (d[f] | 0) + l & 255; + a[f] = e; + m = m + 1 | 0; + h = b + m | 0; + a[h] = (e << 24 >> 24 >>> 5) + (d[h] | 0) & 255; + h = a[f] & 31; + l = h >>> 4; + a[f] = h - (l << 5) & 255; + } while ((m | 0) < 50); + m = b + 50 | 0; + a[m] = (d[m] | 0) + l & 255; + return; +} +function c3(b, d, e) { + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, i = 0; + f = 0; + do { + g = d + (f << 2) | 0; + h = e + (f << 2) | 0; + i = f << 2; + a[b + i | 0] = (c[h >> 2] << 2 & 12 | c[g >> 2] & 3) & 255; + a[b + (i | 1) | 0] = ((c[g >> 2] | 0) >>> 2 & 3 | c[h >> 2] & 12) & 255; + a[b + (i | 2) | 0] = ((c[h >> 2] | 0) >>> 4 << 2 & 12 | (c[g >> 2] | 0) >>> 4 & 3) & 255; + a[b + (i | 3) | 0] = ((c[h >> 2] | 0) >>> 6 << 2 & 12 | (c[g >> 2] | 0) >>> 6 & 3) & 255; + f = f + 1 | 0; + } while ((f | 0) < 31); + f = d + 124 | 0; + d = e + 124 | 0; + a[b + 124 | 0] = (c[d >> 2] << 2 & 12 | c[f >> 2] & 3) & 255; + a[b + 125 | 0] = ((c[f >> 2] | 0) >>> 2 & 3 | c[d >> 2] & 12) & 255; + a[b + 126 | 0] = ((c[d >> 2] | 0) >>> 4 << 2 & 12 | (c[f >> 2] | 0) >>> 4 & 3) & 255; + return; +} +function c4(a, b) { + a = a | 0; + b = b | 0; + var e = 0; + e = 0; + do { + c[a + (e << 2) >> 2] = d[b + e | 0] | 0; + e = e + 1 | 0; + } while ((e | 0) < 32); + e = a + 124 | 0; + c[e >> 2] = c[e >> 2] & 127; + return; +} +function c5(b, e) { + b = b | 0; + e = e | 0; + var f = 0, g = 0, h = 0; + f = 0; + do { + a[b + f | 0] = c[e + (f << 2) >> 2] & 255; + f = f + 1 | 0; + } while ((f | 0) < 32); + f = b + 31 | 0; + e = 30; + g = (a[f] | 0) == 127 | 0; + do { + g = g & -((a[b + e | 0] | 0) == -1 | 0); + e = e - 1 | 0; + } while ((e | 0) > 1); + e = g & -((d[b] | 0) > 236 | 0); + a[f] = (e * -127 | 0) + (d[f] | 0) & 255; + f = e * -255 | 0; + g = 30; + do { + h = b + g | 0; + a[h] = (d[h] | 0) + f & 255; + g = g - 1 | 0; + } while ((g | 0) > 0); + a[b] = (d[b] | 0) + (e * -237 | 0) & 255; + return; +} +function c6(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0; + d = i; + i = i + 264 | 0; + e = d | 0; + f = i; + i = i + 132 | 0; + i = i + 7 >> 3 << 3; + g = i; + i = i + 132 | 0; + i = i + 7 >> 3 << 3; + fm(e | 0, 0, 264); + h = b; + j = f; + fm(g | 0, 0, 132); + k = 0; + do { + l = 528 + (k << 2) | 0; + m = 0; + do { + n = m + k | 0; + if ((n | 0) > 30) { + o = ad(c[b + (m + 31 << 2) >> 2] | 0, c[l >> 2] | 0) | 0; + p = e + (n << 2) | 0; + c[p >> 2] = (c[p >> 2] | 0) + o; + } + m = m + 1 | 0; + } while ((m | 0) < 33); + k = k + 1 | 0; + } while ((k | 0) < 33); + k = e + 128 | 0; + b = (c[k >> 2] | 0) + ((c[e + 124 >> 2] | 0) >>> 8) | 0; + c[k >> 2] = b; + k = e + 132 | 0; + c[k >> 2] = (b >>> 8) + (c[k >> 2] | 0); + fn(j | 0, h | 0, 132) | 0; + h = 0; + while (1) { + j = 992 + (h << 2) | 0; + k = 0; + do { + b = k + h | 0; + if ((b | 0) < 33) { + m = ad(c[e + (k + 33 << 2) >> 2] | 0, c[j >> 2] | 0) | 0; + l = g + (b << 2) | 0; + c[l >> 2] = (c[l >> 2] | 0) + m; + } + k = k + 1 | 0; + } while ((k | 0) < 33); + k = h + 1 | 0; + if ((k | 0) < 32) { + h = k; + } else { + q = 0; + break; + } + } + while (1) { + h = g + (q << 2) | 0; + e = q + 1 | 0; + k = g + (e << 2) | 0; + c[k >> 2] = (c[k >> 2] | 0) + ((c[h >> 2] | 0) >>> 8); + c[h >> 2] = c[h >> 2] & 255; + if ((e | 0) < 32) { + q = e; + } else { + r = 0; + s = 0; + break; + } + } + do { + q = (c[g + (s << 2) >> 2] | 0) + r | 0; + e = c[f + (s << 2) >> 2] | 0; + r = cW(e, q) | 0; + c[a + (s << 2) >> 2] = e - q + (r << 8); + s = s + 1 | 0; + } while ((s | 0) < 32); + da(a); + da(a); + i = d; + return; +} +function c7(a, b) { + a = a | 0; + b = b | 0; + var e = 0, f = 0, g = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + g = 0; + do { + c[f + (g << 2) >> 2] = d[b + g | 0] | 0; + g = g + 1 | 0; + } while ((g | 0) < 64); + c6(a, f | 0); + i = e; + return; +} +function c8(a, b) { + a = a | 0; + b = b | 0; + c[a >> 2] = c[b >> 2]; + c[a + 4 >> 2] = c[b + 4 >> 2]; + c[a + 8 >> 2] = c[b + 8 >> 2]; + c[a + 12 >> 2] = c[b + 12 >> 2]; + c[a + 16 >> 2] = c[b + 16 >> 2]; + c[a + 20 >> 2] = c[b + 20 >> 2]; + c[a + 24 >> 2] = c[b + 24 >> 2]; + c[a + 28 >> 2] = c[b + 28 >> 2]; + c[a + 32 >> 2] = c[b + 32 >> 2]; + c[a + 36 >> 2] = c[b + 36 >> 2]; + c[a + 40 >> 2] = c[b + 40 >> 2]; + c[a + 44 >> 2] = c[b + 44 >> 2]; + c[a + 48 >> 2] = c[b + 48 >> 2]; + c[a + 52 >> 2] = c[b + 52 >> 2]; + c[a + 56 >> 2] = c[b + 56 >> 2]; + c[a + 60 >> 2] = c[b + 60 >> 2]; + fm(a + 64 | 0, 0, 64); + return; +} +function c9(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + e = 0; + while (1) { + c[a + (e << 2) >> 2] = (c[d + (e << 2) >> 2] | 0) + (c[b + (e << 2) >> 2] | 0); + f = e + 1 | 0; + if ((f | 0) < 32) { + e = f; + } else { + g = 0; + break; + } + } + do { + e = a + (g << 2) | 0; + g = g + 1 | 0; + b = a + (g << 2) | 0; + c[b >> 2] = (c[b >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((g | 0) < 31); + da(a); + return; +} +function da(b) { + b = b | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0; + e = i; + i = i + 32 | 0; + f = e | 0; + g = 0; + h = 0; + while (1) { + j = (c[992 + (h << 2) >> 2] | 0) + g | 0; + k = c[b + (h << 2) >> 2] | 0; + l = cW(k, j) | 0; + a[f + h | 0] = k - j & 255; + j = h + 1 | 0; + m = l - 1 | 0; + if ((j | 0) < 32) { + g = l; + h = j; + } else { + n = 0; + break; + } + } + do { + h = b + (n << 2) | 0; + g = c[h >> 2] | 0; + c[h >> 2] = ((d[f + n | 0] | 0) ^ g) & m ^ g; + n = n + 1 | 0; + } while ((n | 0) < 32); + i = e; + return; +} +function db(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 256); + g = 0; + while (1) { + h = c[b + (g << 2) >> 2] | 0; + j = 0; + do { + k = ad(c[d + (j << 2) >> 2] | 0, h) | 0; + l = f + (j + g << 2) | 0; + c[l >> 2] = (c[l >> 2] | 0) + k; + j = j + 1 | 0; + } while ((j | 0) < 32); + j = g + 1 | 0; + if ((j | 0) < 32) { + g = j; + } else { + m = 0; + break; + } + } + do { + g = f + (m << 2) | 0; + m = m + 1 | 0; + d = f + (m << 2) | 0; + c[d >> 2] = (c[d >> 2] | 0) + ((c[g >> 2] | 0) >>> 8); + c[g >> 2] = c[g >> 2] & 255; + } while ((m | 0) < 63); + c6(a, f | 0); + i = e; + return; +} +function dc(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0; + d = i; + i = i + 128 | 0; + e = d | 0; + c8(e, c); + db(a, b, e); + i = d; + return; +} +function dd(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0; + e = d & 255; + f = 1 - d & 255; + d = 0; + do { + g = a + (d << 2) | 0; + h = ad(c[g >> 2] | 0, f) | 0; + c[g >> 2] = (ad(c[b + (d << 2) >> 2] | 0, e) | 0) + h; + d = d + 1 | 0; + } while ((d | 0) < 32); + return; +} +function de(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = 30; + e = (c[b >> 2] | 0) == 127 | 0; + do { + e = e & -((c[a + (d << 2) >> 2] | 0) == 255 | 0); + d = d - 1 | 0; + } while ((d | 0) > 1); + d = a | 0; + f = e & -((c[d >> 2] | 0) >>> 0 > 236 | 0); + c[b >> 2] = (f * -127 | 0) + (c[b >> 2] | 0); + b = f * -255 | 0; + e = 30; + do { + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + b; + e = e - 1 | 0; + } while ((e | 0) > 0); + c[d >> 2] = (c[d >> 2] | 0) + (f * -237 | 0); + return; +} +function df(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = a | 0; + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + e = 0; + do { + f = a + (e << 2) | 0; + e = e + 1 | 0; + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[f >> 2] | 0) >>> 8); + c[f >> 2] = c[f >> 2] & 255; + } while ((e | 0) < 31); + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + e = 0; + do { + f = a + (e << 2) | 0; + e = e + 1 | 0; + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[f >> 2] | 0) >>> 8); + c[f >> 2] = c[f >> 2] & 255; + } while ((e | 0) < 31); + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + e = 0; + do { + f = a + (e << 2) | 0; + e = e + 1 | 0; + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[f >> 2] | 0) >>> 8); + c[f >> 2] = c[f >> 2] & 255; + } while ((e | 0) < 31); + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + d = 0; + do { + e = a + (d << 2) | 0; + d = d + 1 | 0; + b = a + (d << 2) | 0; + c[b >> 2] = (c[b >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((d | 0) < 31); + return; +} +function dg(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0; + b = a + 124 | 0; + d = a | 0; + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + e = 0; + do { + f = a + (e << 2) | 0; + e = e + 1 | 0; + g = a + (e << 2) | 0; + c[g >> 2] = (c[g >> 2] | 0) + ((c[f >> 2] | 0) >>> 8); + c[f >> 2] = c[f >> 2] & 255; + } while ((e | 0) < 31); + e = c[b >> 2] | 0; + c[b >> 2] = e & 127; + c[d >> 2] = ((e >>> 7) * 19 | 0) + (c[d >> 2] | 0); + d = 0; + do { + e = a + (d << 2) | 0; + d = d + 1 | 0; + b = a + (d << 2) | 0; + c[b >> 2] = (c[b >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((d | 0) < 31); + return; +} +function dh(a) { + a = a | 0; + var b = 0, d = 0; + b = 1; + d = (c[a >> 2] | 0) == 1 | 0; + do { + d = d & -((c[a + (b << 2) >> 2] | 0) == 0 | 0); + b = b + 1 | 0; + } while ((b | 0) < 32); + return d | 0; +} +function di(a) { + a = a | 0; + var b = 0, d = 0; + b = 1; + d = (c[a >> 2] | 0) == 0 | 0; + do { + d = d & -((c[a + (b << 2) >> 2] | 0) == 0 | 0); + b = b + 1 | 0; + } while ((b | 0) < 32); + return d | 0; +} +function dj(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = i; + d = a; + a = i; + i = i + 128 | 0; + e = a; + fn(e | 0, d | 0, 128) | 0; + de(a); + i = b; + return c[a >> 2] & 1 | 0; +} +function dk(a) { + a = a | 0; + c[a >> 2] = 1; + fm(a + 4 | 0, 0, 124); + return; +} +function dl(a) { + a = a | 0; + fm(a | 0, 0, 128); + return; +} +function dm(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0; + c = i; + d = b; + b = i; + i = i + 128 | 0; + e = b; + fn(e | 0, d | 0, 128) | 0; + dl(a); + dn(a, a, b); + i = c; + return; +} +function dn(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0; + e = i; + i = i + 128 | 0; + f = e | 0; + c[f >> 2] = (c[b >> 2] | 0) + 474; + c[f + 124 >> 2] = (c[b + 124 >> 2] | 0) + 254; + g = 1; + while (1) { + c[f + (g << 2) >> 2] = (c[b + (g << 2) >> 2] | 0) + 510; + h = g + 1 | 0; + if ((h | 0) < 31) { + g = h; + } else { + j = 0; + break; + } + } + do { + c[a + (j << 2) >> 2] = (c[f + (j << 2) >> 2] | 0) - (c[d + (j << 2) >> 2] | 0); + j = j + 1 | 0; + } while ((j | 0) < 32); + df(a); + i = e; + return; +} +function dp(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0; + e = 0; + do { + c[a + (e << 2) >> 2] = (c[d + (e << 2) >> 2] | 0) + (c[b + (e << 2) >> 2] | 0); + e = e + 1 | 0; + } while ((e | 0) < 32); + df(a); + return; +} +function dq(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 252); + g = 0; + while (1) { + h = c[b + (g << 2) >> 2] | 0; + j = 0; + do { + k = ad(c[d + (j << 2) >> 2] | 0, h) | 0; + l = f + (j + g << 2) | 0; + c[l >> 2] = (c[l >> 2] | 0) + k; + j = j + 1 | 0; + } while ((j | 0) < 32); + j = g + 1 | 0; + if ((j | 0) < 32) { + g = j; + } else { + m = 32; + break; + } + } + do { + g = m - 32 | 0; + c[a + (g << 2) >> 2] = ((c[f + (m << 2) >> 2] | 0) * 38 | 0) + (c[f + (g << 2) >> 2] | 0); + m = m + 1 | 0; + } while ((m | 0) < 63); + c[a + 124 >> 2] = c[f + 124 >> 2]; + dg(a); + i = e; + return; +} +function dr(a, b) { + a = a | 0; + b = b | 0; + dq(a, b, b); + return; +} +function ds(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + e = i; + i = i + 2304 | 0; + f = e | 0; + g = e + 128 | 0; + h = e + 2176 | 0; + dk(f); + dk(g | 0); + j = g + 128 | 0; + k = j; + l = b; + fn(k | 0, l | 0, 128) | 0; + l = g + 256 | 0; + dr(l, g + 128 | 0); + dq(g + 384 | 0, l, j); + l = g + 512 | 0; + dr(l, g + 256 | 0); + dq(g + 640 | 0, l, j); + l = g + 768 | 0; + dr(l, g + 384 | 0); + dq(g + 896 | 0, l, j); + l = g + 1024 | 0; + dr(l, g + 512 | 0); + dq(g + 1152 | 0, l, j); + l = g + 1280 | 0; + dr(l, g + 640 | 0); + dq(g + 1408 | 0, l, j); + l = g + 1536 | 0; + dr(l, g + 768 | 0); + dq(g + 1664 | 0, l, j); + l = g + 1792 | 0; + dr(l, g + 896 | 0); + dq(g + 1920 | 0, l, j); + j = h; + l = g; + k = 32; + do { + b = c + (k - 1) | 0; + m = g + 128 | 0; + n = 4; + do { + dr(f, f); + dr(f, f); + dr(f, f); + dr(f, f); + o = (d[b] | 0) >>> (n >>> 0); + fn(j | 0, l | 0, 128) | 0; + p = o & 15; + dd(h, m, (p | 0) == 1 | 0); + dd(h, g + 256 | 0, (p | 0) == 2 | 0); + dd(h, g + 384 | 0, (p | 0) == 3 | 0); + dd(h, g + 512 | 0, (p | 0) == 4 | 0); + dd(h, g + 640 | 0, (p | 0) == 5 | 0); + dd(h, g + 768 | 0, (p | 0) == 6 | 0); + dd(h, g + 896 | 0, (p | 0) == 7 | 0); + dd(h, g + 1024 | 0, (p | 0) == 8 | 0); + dd(h, g + 1152 | 0, (p | 0) == 9 | 0); + dd(h, g + 1280 | 0, (p | 0) == 10 | 0); + dd(h, g + 1408 | 0, (p | 0) == 11 | 0); + dd(h, g + 1536 | 0, (p | 0) == 12 | 0); + dd(h, g + 1664 | 0, (p | 0) == 13 | 0); + dd(h, g + 1792 | 0, (p | 0) == 14 | 0); + dd(h, g + 1920 | 0, (p | 0) == 15 | 0); + dq(f, f, h); + n = n - 4 | 0; + } while ((n | 0) > -1); + k = k - 1 | 0; + } while ((k | 0) > 0); + k = a; + a = f; + fn(k | 0, a | 0, 128) | 0; + i = e; + return; +} +function dt(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + e = i; + i = i + 352 | 0; + f = e + 32 | 0; + g = e + 64 | 0; + h = e + 96 | 0; + j = e + 224 | 0; + if ((du(b) | 0) == 0) { + k = -1; + i = e; + return k | 0; + } + l = e | 0; + fn(l | 0, 111032, 32) | 0; + m = f | 0; + fn(m | 0, 111e3, 32) | 0; + f = g | 0; + fn(f | 0, 110968, 32) | 0; + fm(h | 0, 0, 128); + ds(j, b, l); + de(j); + if ((dh(j) | 0) == 0) { + l = 0; + do { + c[j + (l << 2) >> 2] = c[b + (l << 2) >> 2] << 2; + l = l + 1 | 0; + } while ((l | 0) < 32); + ds(j, j, f); + f = 0; + do { + c[a + (f << 2) >> 2] = c[b + (f << 2) >> 2] << 1; + f = f + 1 | 0; + } while ((f | 0) < 32); + dq(a, a, j); + } else { + ds(a, b, m); + } + de(a); + if (((c[a >> 2] ^ d & 255) & 1 | 0) == 0) { + k = 0; + i = e; + return k | 0; + } + dn(a, h, a); + k = 0; + i = e; + return k | 0; +} +function du(a) { + a = a | 0; + var b = 0, c = 0, d = 0, e = 0; + b = i; + i = i + 160 | 0; + c = b + 32 | 0; + d = b | 0; + fn(d | 0, 1312, 32) | 0; + ds(c, a, d); + de(c); + if ((dh(c) | 0) != 0) { + e = 1; + i = b; + return e | 0; + } + e = (di(c) | 0) != 0 | 0; + i = b; + return e | 0; +} +function dv(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0; + c = i; + i = i + 1280 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = c + 512 | 0; + j = c + 640 | 0; + k = c + 768 | 0; + l = c + 896 | 0; + m = c + 1024 | 0; + n = c + 1152 | 0; + dr(d, b); + dr(n, d); + dr(m, n); + dq(e, m, b); + dq(f, e, d); + dr(m, f); + dq(g, m, e); + dr(m, g); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dq(h, m, g); + dr(m, h); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dq(j, n, h); + dr(m, j); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dq(m, n, j); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dq(k, m, h); + dr(m, k); + dr(n, m); + h = 2; + do { + dr(m, n); + dr(n, m); + h = h + 2 | 0; + } while ((h | 0) < 50); + dq(l, n, k); + dr(n, l); + dr(m, n); + h = 2; + do { + dr(n, m); + dr(m, n); + h = h + 2 | 0; + } while ((h | 0) < 100); + dq(n, m, l); + dr(m, n); + dr(n, m); + l = 2; + do { + dr(m, n); + dr(n, m); + l = l + 2 | 0; + } while ((l | 0) < 50); + dq(m, n, k); + dr(n, m); + dr(m, n); + dr(n, m); + dr(m, n); + dr(n, m); + dq(a, n, f); + i = c; + return; +} +function dw(a, b) { + a = a | 0; + b = b | 0; + var c = 0, e = 0, f = 0, g = 0, h = 0, j = 0; + c = i; + i = i + 256 | 0; + e = c | 0; + f = c + 128 | 0; + g = a + 256 | 0; + dk(g); + c4(f, 110776); + h = (d[b + 31 | 0] | 0) >>> 7; + j = a + 128 | 0; + c4(j, b); + b = a | 0; + dr(b, j); + dq(e, b, f); + dn(b, b, g); + dp(e, g, e); + dv(e, e); + dq(b, b, e); + e = dt(b, b, h) | 0; + dq(a + 384 | 0, b, j); + i = c; + return e | 0; +} +function dx(b, c) { + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0; + d = i; + i = i + 384 | 0; + e = d | 0; + f = d + 128 | 0; + g = d + 256 | 0; + dv(g, c + 256 | 0); + dq(e, c | 0, g); + dq(f, c + 128 | 0, g); + c5(b, f); + f = (dj(e) | 0) << 7; + e = b + 31 | 0; + a[e] = a[e] ^ f; + i = d; + return; +} +function dy(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0; + d = i; + i = i + 512 | 0; + e = d | 0; + dz(e, b, c); + dA(a, e); + i = d; + return; +} +function dz(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + d = i; + i = i + 768 | 0; + e = d | 0; + f = d + 128 | 0; + g = d + 256 | 0; + h = d + 384 | 0; + j = d + 512 | 0; + k = d + 640 | 0; + c4(k, 110776); + l = b + 128 | 0; + m = b | 0; + dn(e, l, m); + n = c + 128 | 0; + o = c | 0; + dn(j, n, o); + dq(e, e, j); + dp(f, m, l); + dp(j, o, n); + dq(f, f, j); + dq(g, b + 384 | 0, c + 384 | 0); + dq(g, g, k); + dp(g, g, g); + dq(h, b + 256 | 0, c + 256 | 0); + dp(h, h, h); + dn(a | 0, f, e); + dn(a + 384 | 0, h, g); + dp(a + 128 | 0, h, g); + dp(a + 256 | 0, f, e); + i = d; + return; +} +function dA(a, b) { + a = a | 0; + b = b | 0; + dG(a, b); + dq(a + 384 | 0, b | 0, b + 256 | 0); + return; +} +function dB(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0; + c = i; + i = i + 512 | 0; + d = c | 0; + dC(d, b); + dA(a, d); + i = c; + return; +} +function dC(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0; + c = i; + i = i + 512 | 0; + d = c | 0; + e = c + 128 | 0; + f = c + 256 | 0; + g = c + 384 | 0; + h = b | 0; + dr(d, h); + j = b + 128 | 0; + dr(e, j); + dr(f, b + 256 | 0); + dp(f, f, f); + dm(g, d); + b = a | 0; + dp(b, h, j); + dr(b, b); + dn(b, b, d); + dn(b, b, e); + b = a + 128 | 0; + dp(b, g, e); + dn(a + 384 | 0, b, f); + dn(a + 256 | 0, g, e); + i = c; + return; +} +function dD(b, d) { + b = b | 0; + d = d | 0; + var e = 0; + e = 0; + do { + a[b + e | 0] = c[d + (e << 2) >> 2] & 255; + e = e + 1 | 0; + } while ((e | 0) < 32); + return; +} +function dE(b) { + b = b | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0; + e = i; + i = i + 32 | 0; + f = e | 0; + g = 0; + h = 0; + while (1) { + j = c[b + (h << 2) >> 2] | 0; + k = c[864 + (h << 2) >> 2] | 0; + l = j >>> 0 < (k + g | 0) >>> 0 | 0; + a[f + h | 0] = j - g - k & 255; + k = h + 1 | 0; + if ((k | 0) < 32) { + g = l; + h = k; + } else { + break; + } + } + h = l ^ 1; + g = 0; + do { + k = b + (g << 2) | 0; + c[k >> 2] = ((d[f + g | 0] | 0) & -h) + (c[k >> 2] & -l); + g = g + 1 | 0; + } while ((g | 0) < 32); + i = e; + return; +} +function dF(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0; + e = i; + i = i + 3616 | 0; + f = e | 0; + g = e + 512 | 0; + h = e + 2560 | 0; + j = e + 3072 | 0; + k = e + 3584 | 0; + c4(f | 0, 112080); + l = f + 128 | 0; + c4(l, 1560); + m = f + 256 | 0; + c4(m, 1528); + n = f + 384 | 0; + c4(n, 112112); + dD(k | 0, c); + c = g; + o = f; + fn(c | 0, o | 0, 512) | 0; + p = g + 512 | 0; + q = p; + r = b; + fn(q | 0, r | 0, 512) | 0; + dC(j, g + 512 | 0); + r = g + 1024 | 0; + dA(r, j); + dz(j, r, p); + dA(g + 1536 | 0, j); + p = f; + r = h; + q = 32; + do { + b = k + (q - 1) | 0; + s = 6; + do { + dC(j, p); + dG(p, j); + dC(j, p); + dA(f, j); + t = (d[b] | 0) >>> (s >>> 0); + fn(r | 0, c | 0, 512) | 0; + u = t & 3; + t = 1; + do { + dH(h, g + (t << 9) | 0, (t | 0) == (u | 0) | 0); + t = t + 1 | 0; + } while ((t | 0) < 4); + dz(j, f, h); + if ((s | 0) == 0) { + v = 518; + break; + } + dG(p, j); + s = s - 2 | 0; + } while ((s | 0) > -1); + if ((v | 0) == 518) { + v = 0; + dA(f, j); + } + q = q - 1 | 0; + } while ((q | 0) > 0); + q = a; + fn(q | 0, o | 0, 128) | 0; + o = a + 128 | 0; + q = l; + fn(o | 0, q | 0, 128) | 0; + q = a + 256 | 0; + o = m; + fn(q | 0, o | 0, 128) | 0; + o = a + 384 | 0; + a = n; + fn(o | 0, a | 0, 128) | 0; + i = e; + return; +} +function dG(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0; + c = b + 384 | 0; + dq(a | 0, b | 0, c); + d = b + 128 | 0; + dq(a + 128 | 0, b + 256 | 0, d); + dq(a + 256 | 0, d, c); + return; +} +function dH(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + dd(a | 0, b | 0, c); + dd(a + 128 | 0, b + 128 | 0, c); + dd(a + 256 | 0, b + 256 | 0, c); + dd(a + 384 | 0, b + 384 | 0, c); + return; +} +function dI(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0; + c = i; + i = i + 512 | 0; + d = c | 0; + c4(d | 0, 1912); + c4(d + 128 | 0, 1880); + c4(d + 256 | 0, 1848); + c4(d + 384 | 0, 1944); + dF(a, d, b); + i = c; + return; +} +function dJ(a, b) { + a = a | 0; + b = b | 0; + var e = 0, f = 0, g = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 256); + g = 0; + do { + c[f + (g << 2) >> 2] = d[b + g | 0] | 0; + g = g + 1 | 0; + } while ((g | 0) < 32); + dK(a, f | 0); + i = e; + return; +} +function dK(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0; + d = i; + i = i + 536 | 0; + e = d | 0; + f = d + 264 | 0; + g = d + 400 | 0; + fm(e | 0, 0, 264); + fm(g | 0, 0, 132); + h = 0; + do { + j = 392 + (h << 2) | 0; + k = 0; + do { + l = k + h | 0; + if ((l | 0) > 30) { + m = ad(c[b + (k + 31 << 2) >> 2] | 0, c[j >> 2] | 0) | 0; + n = e + (l << 2) | 0; + c[n >> 2] = (c[n >> 2] | 0) + m; + } + k = k + 1 | 0; + } while ((k | 0) < 33); + h = h + 1 | 0; + } while ((h | 0) < 33); + h = b; + b = f; + k = e + 128 | 0; + j = (c[k >> 2] | 0) + ((c[e + 124 >> 2] | 0) >>> 8) | 0; + c[k >> 2] = j; + k = e + 132 | 0; + c[k >> 2] = (j >>> 8) + (c[k >> 2] | 0); + fn(b | 0, h | 0, 132) | 0; + h = 0; + while (1) { + b = 864 + (h << 2) | 0; + k = 0; + do { + j = k + h | 0; + if ((j | 0) < 33) { + m = ad(c[e + (k + 33 << 2) >> 2] | 0, c[b >> 2] | 0) | 0; + n = g + (j << 2) | 0; + c[n >> 2] = (c[n >> 2] | 0) + m; + } + k = k + 1 | 0; + } while ((k | 0) < 33); + k = h + 1 | 0; + if ((k | 0) < 32) { + h = k; + } else { + o = 0; + break; + } + } + while (1) { + h = g + (o << 2) | 0; + e = o + 1 | 0; + k = g + (e << 2) | 0; + c[k >> 2] = (c[k >> 2] | 0) + ((c[h >> 2] | 0) >>> 8); + c[h >> 2] = c[h >> 2] & 255; + if ((e | 0) < 32) { + o = e; + } else { + p = 0; + q = 0; + break; + } + } + while (1) { + o = c[f + (p << 2) >> 2] | 0; + e = c[g + (p << 2) >> 2] | 0; + h = o >>> 0 < (e + q | 0) >>> 0 | 0; + c[a + (p << 2) >> 2] = o - q - e + (h << 8); + e = p + 1 | 0; + if ((e | 0) < 32) { + p = e; + q = h; + } else { + break; + } + } + dE(a); + dE(a); + i = d; + return; +} +function dL(a, b) { + a = a | 0; + b = b | 0; + var e = 0, f = 0, g = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 256); + g = 0; + do { + c[f + (g << 2) >> 2] = d[b + g | 0] | 0; + g = g + 1 | 0; + } while ((g | 0) < 64); + dK(a, f | 0); + i = e; + return; +} +function dM(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + e = 0; + while (1) { + c[a + (e << 2) >> 2] = (c[d + (e << 2) >> 2] | 0) + (c[b + (e << 2) >> 2] | 0); + f = e + 1 | 0; + if ((f | 0) < 32) { + e = f; + } else { + g = 0; + break; + } + } + do { + e = a + (g << 2) | 0; + g = g + 1 | 0; + b = a + (g << 2) | 0; + c[b >> 2] = (c[b >> 2] | 0) + ((c[e >> 2] | 0) >>> 8); + c[e >> 2] = c[e >> 2] & 255; + } while ((g | 0) < 31); + dE(a); + return; +} +function dN(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + e = i; + i = i + 256 | 0; + f = e | 0; + fm(f | 0, 0, 256); + g = 0; + while (1) { + h = c[b + (g << 2) >> 2] | 0; + j = 0; + do { + k = ad(c[d + (j << 2) >> 2] | 0, h) | 0; + l = f + (j + g << 2) | 0; + c[l >> 2] = (c[l >> 2] | 0) + k; + j = j + 1 | 0; + } while ((j | 0) < 32); + j = g + 1 | 0; + if ((j | 0) < 32) { + g = j; + } else { + m = 0; + break; + } + } + do { + g = f + (m << 2) | 0; + m = m + 1 | 0; + d = f + (m << 2) | 0; + c[d >> 2] = (c[d >> 2] | 0) + ((c[g >> 2] | 0) >>> 8); + c[g >> 2] = c[g >> 2] & 255; + } while ((m | 0) < 63); + dK(a, f | 0); + i = e; + return; +} +function dO(a, b) { + a = a | 0; + b = b | 0; + dN(a, b, b); + return; +} +function dP(b, c) { + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0; + d = i; + i = i + 640 | 0; + e = d | 0; + f = d + 128 | 0; + at(c | 0, 32, 0); + bR(c, c, 32, 0) | 0; + a[c] = a[c] & -8; + g = c + 31 | 0; + a[g] = a[g] & 63 | 64; + dJ(e, c); + dI(f, e); + dx(b, f); + i = d; + return 0; +} +function dQ(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0; + j = i; + i = i + 928 | 0; + k = j | 0; + l = j + 128 | 0; + m = j + 256 | 0; + n = j + 384 | 0; + o = j + 896 | 0; + p = o | 0; + q = i; + i = i + 32 | 0; + r = q | 0; + s = i; + i = i + 64 | 0; + t = i; + i = i + 64 | 0; + u = fp(f, g, 64, 0) | 0; + c[d >> 2] = u; + c[d + 4 >> 2] = H; + if ((f | 0) == 0 & (g | 0) == 0) { + v = 0; + w = 0; + } else { + d = 0; + u = 0; + while (1) { + x = a[e + u | 0] | 0; + y = fp(u, d, 32, 0) | 0; + a[b + y | 0] = x; + x = fp(u, d, 1, 0) | 0; + y = H; + if (y >>> 0 < g >>> 0 | y >>> 0 == g >>> 0 & x >>> 0 < f >>> 0) { + d = y; + u = x; + } else { + v = 0; + w = 0; + break; + } + } + } + do { + u = fp(w, v, 32, 0) | 0; + a[b + w | 0] = a[h + u | 0] | 0; + w = fp(w, v, 1, 0) | 0; + v = H; + u = 0; + } while (v >>> 0 < u >>> 0 | v >>> 0 == u >>> 0 & w >>> 0 < 32 >>> 0); + w = s | 0; + s = fp(f, g, 32, 0) | 0; + v = H; + bR(w, b, s, v) | 0; + dL(k, w); + dI(n, k); + dx(o | 0, n); + fn(b | 0, p | 0, 32) | 0; + p = t | 0; + bR(p, b, s, v) | 0; + dL(l, p); + dN(l, l, k); + dJ(m, h); + dM(l, l, m); + dD(q | 0, l); + l = fp(f, g, 32, 0) | 0; + g = b + l | 0; + fn(g | 0, r | 0, 32) | 0; + i = j; + return 0; +} +function dR(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0; + j = i; + i = i + 1920 | 0; + k = j + 64 | 0; + l = j + 576 | 0; + m = j + 1088 | 0; + n = j + 1600 | 0; + o = j + 1728 | 0; + if ((dw(k, e) | 0) != 0) { + p = -1; + i = j; + return p | 0; + } + if ((dw(m, h) | 0) != 0) { + p = -1; + i = j; + return p | 0; + } + h = j + 1856 | 0; + q = fp(f, g, -32, -1) | 0; + bR(h, e, q, H) | 0; + dL(n, h); + dF(k, k, n); + dy(k, k, m); + m = j | 0; + dx(m, k); + dJ(o, e + q | 0); + dI(l, o); + o = j + 32 | 0; + dx(o, l); + l = fp(f, g, -64, -1) | 0; + g = H; + if (!((l | 0) == 0 & (g | 0) == 0)) { + f = 0; + do { + a[b + f | 0] = a[e + (f + 32) | 0] | 0; + f = f + 1 | 0; + q = (f | 0) < 0 ? -1 : 0; + } while (q >>> 0 < g >>> 0 | q >>> 0 == g >>> 0 & f >>> 0 < l >>> 0); + } + c[d >> 2] = l; + c[d + 4 >> 2] = g; + p = em(m, o) | 0; + i = j; + return p | 0; +} +function dS(b, d, e, f, g) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0, ae = 0, af = 0, ag = 0, ah = 0, ai = 0, aj = 0, ak = 0, al = 0, am = 0, an = 0, ao = 0, ap = 0, aq = 0, ar = 0, as = 0, at = 0, au = 0, av = 0, aw = 0, ax = 0, ay = 0, az = 0, aA = 0, aB = 0, aC = 0, aD = 0, aE = 0, aF = 0, aG = 0, aH = 0, aI = 0, aJ = 0, aK = 0, aL = 0, aM = 0, aN = 0, aO = 0, aP = 0, aQ = 0, aR = 0, aS = 0, aT = 0, aU = 0, aV = 0, aW = 0, aX = 0, aY = 0, aZ = 0, a_ = 0, a$ = 0, a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0, a7 = 0, a8 = 0, a9 = 0, ba = 0, bb = 0, bc = 0, bd = 0, be = 0, bf = 0, bg = 0, bh = 0, bi = 0, bj = 0, bk = 0, bl = 0; + h = i; + i = i + 400 | 0; + j = h | 0; + k = h + 16 | 0; + l = h + 32 | 0; + m = h + 48 | 0; + n = h + 64 | 0; + o = h + 80 | 0; + p = h + 96 | 0; + q = h + 112 | 0; + r = h + 128 | 0; + s = h + 144 | 0; + t = h + 160 | 0; + u = h + 176 | 0; + v = h + 192 | 0; + w = h + 208 | 0; + x = h + 224 | 0; + y = h + 240 | 0; + z = h + 256 | 0; + A = h + 272 | 0; + d1(z, f); + f = z; + z = j; + B = g; + C = g + 16 | 0; + D = g + 32 | 0; + E = g + 48 | 0; + F = g + 64 | 0; + G = g + 80 | 0; + I = g + 96 | 0; + J = g + 112 | 0; + K = g + 128 | 0; + L = g + 144 | 0; + M = g + 160 | 0; + N = g + 176 | 0; + O = g + 192 | 0; + P = g + 208 | 0; + Q = g + 224 | 0; + R = g + 240 | 0; + S = g + 256 | 0; + T = g + 272 | 0; + U = g + 288 | 0; + V = g + 304 | 0; + W = g + 320 | 0; + X = g + 336 | 0; + Y = g + 352 | 0; + Z = g + 368 | 0; + _ = g + 384 | 0; + $ = g + 400 | 0; + aa = g + 416 | 0; + ab = g + 432 | 0; + ac = g + 448 | 0; + ad = g + 464 | 0; + ae = g + 480 | 0; + af = g + 496 | 0; + ag = g + 512 | 0; + ah = g + 528 | 0; + ai = g + 544 | 0; + aj = g + 560 | 0; + ak = g + 576 | 0; + al = g + 592 | 0; + am = g + 608 | 0; + an = g + 624 | 0; + ao = g + 640 | 0; + ap = g + 656 | 0; + aq = g + 672 | 0; + ar = g + 688 | 0; + as = g + 704 | 0; + at = g + 720 | 0; + au = g + 736 | 0; + av = g + 752 | 0; + aw = g + 768 | 0; + ax = g + 784 | 0; + ay = g + 800 | 0; + az = g + 816 | 0; + aA = g + 832 | 0; + aB = g + 848 | 0; + aC = g + 864 | 0; + aD = g + 880 | 0; + aE = g + 896 | 0; + aF = g + 912 | 0; + aG = g + 928 | 0; + aH = g + 944 | 0; + aI = g + 960 | 0; + aJ = g + 976 | 0; + aK = g + 992 | 0; + aL = g + 1008 | 0; + aM = g + 1024 | 0; + aN = g + 1040 | 0; + aO = g + 1056 | 0; + aP = g + 1072 | 0; + aQ = g + 1088 | 0; + aR = g + 1104 | 0; + aS = g + 1120 | 0; + aT = g + 1136 | 0; + aU = g + 1152 | 0; + aV = g + 1168 | 0; + aW = g + 1184 | 0; + aX = g + 1200 | 0; + aY = g + 1216 | 0; + aZ = g + 1232 | 0; + a_ = g + 1248 | 0; + a$ = g + 1264 | 0; + a0 = g + 1280 | 0; + a1 = g + 1296 | 0; + a2 = g + 1312 | 0; + a3 = g + 1328 | 0; + a4 = g + 1344 | 0; + a5 = g + 1360 | 0; + a6 = g + 1376 | 0; + a7 = g + 1392 | 0; + g = f + 12 | 0; + a8 = r; + a9 = s; + ba = v; + bb = x; + bc = u; + bd = y; + be = t; + bf = w; + bg = b; + b = e; + e = d; + while (1) { + c[z >> 2] = c[f >> 2]; + c[z + 4 >> 2] = c[f + 4 >> 2]; + c[z + 8 >> 2] = c[f + 8 >> 2]; + c[z + 12 >> 2] = c[f + 12 >> 2]; + d1(k, j); + d3(k, 110808); + d1(l, k); + d1(m, k); + d1(n, k); + d1(o, k); + d1(p, k); + d1(q, k); + d9(k, 1); + d9(l, 2); + d9(m, 3); + d9(n, 4); + d9(o, 5); + d9(p, 6); + d9(q, 7); + d3(j, 110888); + d3(k, 110872); + d3(l, 110872); + d3(m, 110872); + d3(n, 110872); + d3(o, 110872); + d3(p, 110872); + d3(q, 110872); + d1(r, p); + d6(r, 1); + d_(r, q); + d$(r, 110952); + d_(q, r); + d7(r, 1); + d_(p, r); + d1(r, n); + d6(r, 1); + d_(r, o); + d$(r, 110952); + d_(o, r); + d7(r, 1); + d_(n, r); + d1(r, l); + d6(r, 1); + d_(r, m); + d$(r, 110952); + d_(m, r); + d7(r, 1); + d_(l, r); + d1(r, j); + d6(r, 1); + d_(r, k); + d$(r, 110952); + d_(k, r); + d7(r, 1); + d_(j, r); + d1(r, o); + d6(r, 2); + d_(r, q); + d$(r, 110936); + d_(q, r); + d7(r, 2); + d_(o, r); + d1(r, n); + d6(r, 2); + d_(r, p); + d$(r, 110936); + d_(p, r); + d7(r, 2); + d_(n, r); + d1(r, k); + d6(r, 2); + d_(r, m); + d$(r, 110936); + d_(m, r); + d7(r, 2); + d_(k, r); + d1(r, j); + d6(r, 2); + d_(r, l); + d$(r, 110936); + d_(l, r); + d7(r, 2); + d_(j, r); + d1(r, m); + d6(r, 4); + d_(r, q); + d$(r, 110920); + d_(q, r); + d7(r, 4); + d_(m, r); + d1(r, l); + d6(r, 4); + d_(r, p); + d$(r, 110920); + d_(p, r); + d7(r, 4); + d_(l, r); + d1(r, k); + d6(r, 4); + d_(r, o); + d$(r, 110920); + d_(o, r); + d7(r, 4); + d_(k, r); + d1(r, j); + d6(r, 4); + d_(r, n); + d$(r, 110920); + d_(n, r); + d7(r, 4); + d_(j, r); + d_(j, B); + d3(j, 110840); + d_(k, C); + d3(k, 110840); + d_(l, D); + d3(l, 110840); + d_(m, E); + d3(m, 110840); + d_(n, F); + d3(n, 110840); + d_(o, G); + d3(o, 110840); + d_(p, I); + d3(p, 110840); + d_(q, J); + d3(q, 110840); + d_(o, p); + d_(l, k); + d_(o, j); + d_(p, l); + d_(m, j); + d_(p, m); + d_(m, q); + d_(m, n); + d_(q, o); + d_(m, k); + d_(n, o); + d_(l, q); + d_(k, o); + d1(u, q); + d1(t, k); + d1(s, o); + d1(w, l); + d1(v, p); + d_(u, n); + d_(t, l); + d_(s, m); + d_(w, n); + d_(v, j); + d1(x, u); + d1(r, t); + d1(y, u); + d0(t, s); + d0(u, v); + d_(y, r); + d$(x, v); + d$(r, s); + d_(v, s); + d$(y, v); + d1(v, m); + d_(v, j); + d$(w, v); + d_(u, w); + d_(t, w); + d1(w, q); + d_(w, k); + d1(v, o); + d1(s, w); + d_(v, p); + d0(s, v); + d$(w, v); + d_(r, w); + d_(u, y); + d_(t, x); + d_(s, y); + d_(r, x); + d_(s, x); + d1(v, l); + d1(w, n); + d1(x, k); + d1(y, q); + d$(v, m); + d$(w, j); + d$(x, o); + d0(y, p); + d_(u, v); + d_(t, w); + d_(s, x); + d_(r, y); + d1(v, u); + d_(v, t); + d$(u, s); + d1(x, r); + d_(x, u); + d1(y, v); + d$(y, x); + d_(y, t); + d1(w, s); + d_(w, r); + d_(u, t); + d$(w, u); + d_(w, r); + d_(s, w); + d1(t, x); + d_(t, w); + d$(t, r); + d_(s, t); + d_(x, t); + d$(x, y); + d_(x, v); + d1(v, p); + d1(r, o); + d1(t, y); + d_(t, x); + d$(t, p); + d_(p, o); + d$(p, x); + d$(o, y); + d_(p, o); + d_(o, t); + d_(v, j); + d_(r, m); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, j); + d_(j, m); + d$(j, s); + d$(m, w); + d_(j, m); + d_(m, t); + d_(p, v); + d_(j, v); + d_(o, r); + d_(m, r); + d1(v, q); + d1(r, k); + d_(v, n); + d_(r, l); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, n); + d_(n, l); + d$(n, s); + d$(l, w); + d_(n, l); + d_(l, t); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, q); + d_(q, k); + d$(q, x); + d$(k, y); + d_(q, k); + d_(k, u); + d_(q, v); + d_(n, v); + d_(k, r); + d_(l, r); + d_(q, j); + d_(k, p); + d_(n, q); + d_(p, j); + d_(j, k); + d_(k, o); + d_(o, l); + d_(n, o); + d_(l, m); + d_(m, o); + d_(p, m); + d4(r, j, 147); + d4(s, k, 147); + d4(t, n, 147); + d4(u, p, 147); + d4(v, m, 147); + d4(w, q, 147); + d4(x, l, 147); + d4(y, o, 147); + d_(j, r); + d_(k, s); + d_(n, t); + d_(p, u); + d_(m, v); + d_(q, w); + d_(l, x); + d_(o, y); + d_(r, o); + d_(s, j); + d_(t, k); + d_(s, o); + d_(u, n); + d_(v, p); + d_(w, m); + d_(u, o); + d_(x, q); + d_(y, l); + d_(v, o); + d4(j, j, 78); + d4(k, k, 78); + d4(n, n, 78); + d4(p, p, 78); + d4(m, m, 78); + d4(q, q, 78); + d4(l, l, 78); + d4(o, o, 78); + d_(r, j); + d_(s, k); + d_(t, n); + d_(u, p); + d_(v, m); + d_(w, q); + d_(x, l); + d_(y, o); + d_(r, K); + d3(r, 110840); + d_(s, L); + d3(s, 110840); + d_(t, M); + d3(t, 110840); + d_(u, N); + d3(u, 110840); + d_(v, O); + d3(v, 110840); + d_(w, P); + d3(w, 110840); + d_(x, Q); + d3(x, 110840); + d_(y, R); + d3(y, 110840); + d_(w, x); + d_(t, s); + d_(w, r); + d_(x, t); + d_(u, r); + d_(x, u); + d_(u, y); + d_(u, v); + d_(y, w); + d_(u, s); + d_(v, w); + d_(t, y); + d_(s, w); + d1(m, y); + d1(l, s); + d1(k, w); + d1(o, t); + d1(n, x); + d_(m, v); + d_(l, t); + d_(k, u); + d_(o, v); + d_(n, r); + d1(p, m); + d1(j, l); + d1(q, m); + d0(l, k); + d0(m, n); + d_(q, j); + d$(p, n); + d$(j, k); + d_(n, k); + d$(q, n); + d1(n, u); + d_(n, r); + d$(o, n); + d_(m, o); + d_(l, o); + d1(o, y); + d_(o, s); + d1(n, w); + d1(k, o); + d_(n, x); + d0(k, n); + d$(o, n); + d_(j, o); + d_(m, q); + d_(l, p); + d_(k, q); + d_(j, p); + d_(k, p); + d1(n, t); + d1(o, v); + d1(p, s); + d1(q, y); + d$(n, u); + d$(o, r); + d$(p, w); + d0(q, x); + d_(m, n); + d_(l, o); + d_(k, p); + d_(j, q); + d1(n, m); + d_(n, l); + d$(m, k); + d1(p, j); + d_(p, m); + d1(q, n); + d$(q, p); + d_(q, l); + d1(o, k); + d_(o, j); + d_(m, l); + d$(o, m); + d_(o, j); + d_(k, o); + d1(l, p); + d_(l, o); + d$(l, j); + d_(k, l); + d_(p, l); + d$(p, q); + d_(p, n); + d1(n, x); + d1(j, w); + d1(l, q); + d_(l, p); + d$(l, x); + d_(x, w); + d$(x, p); + d$(w, q); + d_(x, w); + d_(w, l); + d_(n, r); + d_(j, u); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, r); + d_(r, u); + d$(r, k); + d$(u, o); + d_(r, u); + d_(u, l); + d_(x, n); + d_(r, n); + d_(w, j); + d_(u, j); + d1(n, y); + d1(j, s); + d_(n, v); + d_(j, t); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, v); + d_(v, t); + d$(v, k); + d$(t, o); + d_(v, t); + d_(t, l); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, y); + d_(y, s); + d$(y, p); + d$(s, q); + d_(y, s); + d_(s, m); + d_(y, n); + d_(v, n); + d_(s, j); + d_(t, j); + d_(y, r); + d_(s, x); + d_(v, y); + d_(x, r); + d_(r, s); + d_(s, w); + d_(w, t); + d_(v, w); + d_(t, u); + d_(u, w); + d_(x, u); + d4(j, r, 147); + d4(k, s, 147); + d4(l, v, 147); + d4(m, x, 147); + d4(n, u, 147); + d4(o, y, 147); + d4(p, t, 147); + d4(q, w, 147); + d_(r, j); + d_(s, k); + d_(v, l); + d_(x, m); + d_(u, n); + d_(y, o); + d_(t, p); + d_(w, q); + d_(j, w); + d_(k, r); + d_(l, s); + d_(k, w); + d_(m, v); + d_(n, x); + d_(o, u); + d_(m, w); + d_(p, y); + d_(q, t); + d_(n, w); + d4(r, r, 78); + d4(s, s, 78); + d4(v, v, 78); + d4(x, x, 78); + d4(u, u, 78); + d4(y, y, 78); + d4(t, t, 78); + d4(w, w, 78); + d_(j, r); + d_(k, s); + d_(l, v); + d_(m, x); + d_(n, u); + d_(o, y); + d_(p, t); + d_(q, w); + d_(j, S); + d3(j, 110840); + d_(k, T); + d3(k, 110840); + d_(l, U); + d3(l, 110840); + d_(m, V); + d3(m, 110840); + d_(n, W); + d3(n, 110840); + d_(o, X); + d3(o, 110840); + d_(p, Y); + d3(p, 110840); + d_(q, Z); + d3(q, 110840); + d_(o, p); + d_(l, k); + d_(o, j); + d_(p, l); + d_(m, j); + d_(p, m); + d_(m, q); + d_(m, n); + d_(q, o); + d_(m, k); + d_(n, o); + d_(l, q); + d_(k, o); + d1(u, q); + d1(t, k); + d1(s, o); + d1(w, l); + d1(v, p); + d_(u, n); + d_(t, l); + d_(s, m); + d_(w, n); + d_(v, j); + d1(x, u); + d1(r, t); + d1(y, u); + d0(t, s); + d0(u, v); + d_(y, r); + d$(x, v); + d$(r, s); + d_(v, s); + d$(y, v); + d1(v, m); + d_(v, j); + d$(w, v); + d_(u, w); + d_(t, w); + d1(w, q); + d_(w, k); + d1(v, o); + d1(s, w); + d_(v, p); + d0(s, v); + d$(w, v); + d_(r, w); + d_(u, y); + d_(t, x); + d_(s, y); + d_(r, x); + d_(s, x); + d1(v, l); + d1(w, n); + d1(x, k); + d1(y, q); + d$(v, m); + d$(w, j); + d$(x, o); + d0(y, p); + d_(u, v); + d_(t, w); + d_(s, x); + d_(r, y); + d1(v, u); + d_(v, t); + d$(u, s); + d1(x, r); + d_(x, u); + d1(y, v); + d$(y, x); + d_(y, t); + d1(w, s); + d_(w, r); + d_(u, t); + d$(w, u); + d_(w, r); + d_(s, w); + d1(t, x); + d_(t, w); + d$(t, r); + d_(s, t); + d_(x, t); + d$(x, y); + d_(x, v); + d1(v, p); + d1(r, o); + d1(t, y); + d_(t, x); + d$(t, p); + d_(p, o); + d$(p, x); + d$(o, y); + d_(p, o); + d_(o, t); + d_(v, j); + d_(r, m); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, j); + d_(j, m); + d$(j, s); + d$(m, w); + d_(j, m); + d_(m, t); + d_(p, v); + d_(j, v); + d_(o, r); + d_(m, r); + d1(v, q); + d1(r, k); + d_(v, n); + d_(r, l); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, n); + d_(n, l); + d$(n, s); + d$(l, w); + d_(n, l); + d_(l, t); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, q); + d_(q, k); + d$(q, x); + d$(k, y); + d_(q, k); + d_(k, u); + d_(q, v); + d_(n, v); + d_(k, r); + d_(l, r); + d_(q, j); + d_(k, p); + d_(n, q); + d_(p, j); + d_(j, k); + d_(k, o); + d_(o, l); + d_(n, o); + d_(l, m); + d_(m, o); + d_(p, m); + d4(r, j, 147); + d4(s, k, 147); + d4(t, n, 147); + d4(u, p, 147); + d4(v, m, 147); + d4(w, q, 147); + d4(x, l, 147); + d4(y, o, 147); + d_(j, r); + d_(k, s); + d_(n, t); + d_(p, u); + d_(m, v); + d_(q, w); + d_(l, x); + d_(o, y); + d_(r, o); + d_(s, j); + d_(t, k); + d_(s, o); + d_(u, n); + d_(v, p); + d_(w, m); + d_(u, o); + d_(x, q); + d_(y, l); + d_(v, o); + d4(j, j, 78); + d4(k, k, 78); + d4(n, n, 78); + d4(p, p, 78); + d4(m, m, 78); + d4(q, q, 78); + d4(l, l, 78); + d4(o, o, 78); + d_(r, j); + d_(s, k); + d_(t, n); + d_(u, p); + d_(v, m); + d_(w, q); + d_(x, l); + d_(y, o); + d_(r, _); + d3(r, 110840); + d_(s, $); + d3(s, 110840); + d_(t, aa); + d3(t, 110840); + d_(u, ab); + d3(u, 110840); + d_(v, ac); + d3(v, 110840); + d_(w, ad); + d3(w, 110840); + d_(x, ae); + d3(x, 110840); + d_(y, af); + d3(y, 110840); + d_(w, x); + d_(t, s); + d_(w, r); + d_(x, t); + d_(u, r); + d_(x, u); + d_(u, y); + d_(u, v); + d_(y, w); + d_(u, s); + d_(v, w); + d_(t, y); + d_(s, w); + d1(m, y); + d1(l, s); + d1(k, w); + d1(o, t); + d1(n, x); + d_(m, v); + d_(l, t); + d_(k, u); + d_(o, v); + d_(n, r); + d1(p, m); + d1(j, l); + d1(q, m); + d0(l, k); + d0(m, n); + d_(q, j); + d$(p, n); + d$(j, k); + d_(n, k); + d$(q, n); + d1(n, u); + d_(n, r); + d$(o, n); + d_(m, o); + d_(l, o); + d1(o, y); + d_(o, s); + d1(n, w); + d1(k, o); + d_(n, x); + d0(k, n); + d$(o, n); + d_(j, o); + d_(m, q); + d_(l, p); + d_(k, q); + d_(j, p); + d_(k, p); + d1(n, t); + d1(o, v); + d1(p, s); + d1(q, y); + d$(n, u); + d$(o, r); + d$(p, w); + d0(q, x); + d_(m, n); + d_(l, o); + d_(k, p); + d_(j, q); + d1(n, m); + d_(n, l); + d$(m, k); + d1(p, j); + d_(p, m); + d1(q, n); + d$(q, p); + d_(q, l); + d1(o, k); + d_(o, j); + d_(m, l); + d$(o, m); + d_(o, j); + d_(k, o); + d1(l, p); + d_(l, o); + d$(l, j); + d_(k, l); + d_(p, l); + d$(p, q); + d_(p, n); + d1(n, x); + d1(j, w); + d1(l, q); + d_(l, p); + d$(l, x); + d_(x, w); + d$(x, p); + d$(w, q); + d_(x, w); + d_(w, l); + d_(n, r); + d_(j, u); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, r); + d_(r, u); + d$(r, k); + d$(u, o); + d_(r, u); + d_(u, l); + d_(x, n); + d_(r, n); + d_(w, j); + d_(u, j); + d1(n, y); + d1(j, s); + d_(n, v); + d_(j, t); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, v); + d_(v, t); + d$(v, k); + d$(t, o); + d_(v, t); + d_(t, l); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, y); + d_(y, s); + d$(y, p); + d$(s, q); + d_(y, s); + d_(s, m); + d_(y, n); + d_(v, n); + d_(s, j); + d_(t, j); + d_(y, r); + d_(s, x); + d_(v, y); + d_(x, r); + d_(r, s); + d_(s, w); + d_(w, t); + d_(v, w); + d_(t, u); + d_(u, w); + d_(x, u); + d4(j, r, 147); + d4(k, s, 147); + d4(l, v, 147); + d4(m, x, 147); + d4(n, u, 147); + d4(o, y, 147); + d4(p, t, 147); + d4(q, w, 147); + d_(r, j); + d_(s, k); + d_(v, l); + d_(x, m); + d_(u, n); + d_(y, o); + d_(t, p); + d_(w, q); + d_(j, w); + d_(k, r); + d_(l, s); + d_(k, w); + d_(m, v); + d_(n, x); + d_(o, u); + d_(m, w); + d_(p, y); + d_(q, t); + d_(n, w); + d4(r, r, 78); + d4(s, s, 78); + d4(v, v, 78); + d4(x, x, 78); + d4(u, u, 78); + d4(y, y, 78); + d4(t, t, 78); + d4(w, w, 78); + d_(j, r); + d_(k, s); + d_(l, v); + d_(m, x); + d_(n, u); + d_(o, y); + d_(p, t); + d_(q, w); + d_(j, ag); + d3(j, 110840); + d_(k, ah); + d3(k, 110840); + d_(l, ai); + d3(l, 110840); + d_(m, aj); + d3(m, 110840); + d_(n, ak); + d3(n, 110840); + d_(o, al); + d3(o, 110840); + d_(p, am); + d3(p, 110840); + d_(q, an); + d3(q, 110840); + d_(o, p); + d_(l, k); + d_(o, j); + d_(p, l); + d_(m, j); + d_(p, m); + d_(m, q); + d_(m, n); + d_(q, o); + d_(m, k); + d_(n, o); + d_(l, q); + d_(k, o); + d1(u, q); + d1(t, k); + d1(s, o); + d1(w, l); + d1(v, p); + d_(u, n); + d_(t, l); + d_(s, m); + d_(w, n); + d_(v, j); + d1(x, u); + d1(r, t); + d1(y, u); + d0(t, s); + d0(u, v); + d_(y, r); + d$(x, v); + d$(r, s); + d_(v, s); + d$(y, v); + d1(v, m); + d_(v, j); + d$(w, v); + d_(u, w); + d_(t, w); + d1(w, q); + d_(w, k); + d1(v, o); + d1(s, w); + d_(v, p); + d0(s, v); + d$(w, v); + d_(r, w); + d_(u, y); + d_(t, x); + d_(s, y); + d_(r, x); + d_(s, x); + d1(v, l); + d1(w, n); + d1(x, k); + d1(y, q); + d$(v, m); + d$(w, j); + d$(x, o); + d0(y, p); + d_(u, v); + d_(t, w); + d_(s, x); + d_(r, y); + d1(v, u); + d_(v, t); + d$(u, s); + d1(x, r); + d_(x, u); + d1(y, v); + d$(y, x); + d_(y, t); + d1(w, s); + d_(w, r); + d_(u, t); + d$(w, u); + d_(w, r); + d_(s, w); + d1(t, x); + d_(t, w); + d$(t, r); + d_(s, t); + d_(x, t); + d$(x, y); + d_(x, v); + d1(v, p); + d1(r, o); + d1(t, y); + d_(t, x); + d$(t, p); + d_(p, o); + d$(p, x); + d$(o, y); + d_(p, o); + d_(o, t); + d_(v, j); + d_(r, m); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, j); + d_(j, m); + d$(j, s); + d$(m, w); + d_(j, m); + d_(m, t); + d_(p, v); + d_(j, v); + d_(o, r); + d_(m, r); + d1(v, q); + d1(r, k); + d_(v, n); + d_(r, l); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, n); + d_(n, l); + d$(n, s); + d$(l, w); + d_(n, l); + d_(l, t); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, q); + d_(q, k); + d$(q, x); + d$(k, y); + d_(q, k); + d_(k, u); + d_(q, v); + d_(n, v); + d_(k, r); + d_(l, r); + d_(q, j); + d_(k, p); + d_(n, q); + d_(p, j); + d_(j, k); + d_(k, o); + d_(o, l); + d_(n, o); + d_(l, m); + d_(m, o); + d_(p, m); + d4(r, j, 147); + d4(s, k, 147); + d4(t, n, 147); + d4(u, p, 147); + d4(v, m, 147); + d4(w, q, 147); + d4(x, l, 147); + d4(y, o, 147); + d_(j, r); + d_(k, s); + d_(n, t); + d_(p, u); + d_(m, v); + d_(q, w); + d_(l, x); + d_(o, y); + d_(r, o); + d_(s, j); + d_(t, k); + d_(s, o); + d_(u, n); + d_(v, p); + d_(w, m); + d_(u, o); + d_(x, q); + d_(y, l); + d_(v, o); + d4(j, j, 78); + d4(k, k, 78); + d4(n, n, 78); + d4(p, p, 78); + d4(m, m, 78); + d4(q, q, 78); + d4(l, l, 78); + d4(o, o, 78); + d_(r, j); + d_(s, k); + d_(t, n); + d_(u, p); + d_(v, m); + d_(w, q); + d_(x, l); + d_(y, o); + d_(r, ao); + d3(r, 110840); + d_(s, ap); + d3(s, 110840); + d_(t, aq); + d3(t, 110840); + d_(u, ar); + d3(u, 110840); + d_(v, as); + d3(v, 110840); + d_(w, at); + d3(w, 110840); + d_(x, au); + d3(x, 110840); + d_(y, av); + d3(y, 110840); + d_(w, x); + d_(t, s); + d_(w, r); + d_(x, t); + d_(u, r); + d_(x, u); + d_(u, y); + d_(u, v); + d_(y, w); + d_(u, s); + d_(v, w); + d_(t, y); + d_(s, w); + d1(m, y); + d1(l, s); + d1(k, w); + d1(o, t); + d1(n, x); + d_(m, v); + d_(l, t); + d_(k, u); + d_(o, v); + d_(n, r); + d1(p, m); + d1(j, l); + d1(q, m); + d0(l, k); + d0(m, n); + d_(q, j); + d$(p, n); + d$(j, k); + d_(n, k); + d$(q, n); + d1(n, u); + d_(n, r); + d$(o, n); + d_(m, o); + d_(l, o); + d1(o, y); + d_(o, s); + d1(n, w); + d1(k, o); + d_(n, x); + d0(k, n); + d$(o, n); + d_(j, o); + d_(m, q); + d_(l, p); + d_(k, q); + d_(j, p); + d_(k, p); + d1(n, t); + d1(o, v); + d1(p, s); + d1(q, y); + d$(n, u); + d$(o, r); + d$(p, w); + d0(q, x); + d_(m, n); + d_(l, o); + d_(k, p); + d_(j, q); + d1(n, m); + d_(n, l); + d$(m, k); + d1(p, j); + d_(p, m); + d1(q, n); + d$(q, p); + d_(q, l); + d1(o, k); + d_(o, j); + d_(m, l); + d$(o, m); + d_(o, j); + d_(k, o); + d1(l, p); + d_(l, o); + d$(l, j); + d_(k, l); + d_(p, l); + d$(p, q); + d_(p, n); + d1(n, x); + d1(j, w); + d1(l, q); + d_(l, p); + d$(l, x); + d_(x, w); + d$(x, p); + d$(w, q); + d_(x, w); + d_(w, l); + d_(n, r); + d_(j, u); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, r); + d_(r, u); + d$(r, k); + d$(u, o); + d_(r, u); + d_(u, l); + d_(x, n); + d_(r, n); + d_(w, j); + d_(u, j); + d1(n, y); + d1(j, s); + d_(n, v); + d_(j, t); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, v); + d_(v, t); + d$(v, k); + d$(t, o); + d_(v, t); + d_(t, l); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, y); + d_(y, s); + d$(y, p); + d$(s, q); + d_(y, s); + d_(s, m); + d_(y, n); + d_(v, n); + d_(s, j); + d_(t, j); + d_(y, r); + d_(s, x); + d_(v, y); + d_(x, r); + d_(r, s); + d_(s, w); + d_(w, t); + d_(v, w); + d_(t, u); + d_(u, w); + d_(x, u); + d4(j, r, 147); + d4(k, s, 147); + d4(l, v, 147); + d4(m, x, 147); + d4(n, u, 147); + d4(o, y, 147); + d4(p, t, 147); + d4(q, w, 147); + d_(r, j); + d_(s, k); + d_(v, l); + d_(x, m); + d_(u, n); + d_(y, o); + d_(t, p); + d_(w, q); + d_(j, w); + d_(k, r); + d_(l, s); + d_(k, w); + d_(m, v); + d_(n, x); + d_(o, u); + d_(m, w); + d_(p, y); + d_(q, t); + d_(n, w); + d4(r, r, 78); + d4(s, s, 78); + d4(v, v, 78); + d4(x, x, 78); + d4(u, u, 78); + d4(y, y, 78); + d4(t, t, 78); + d4(w, w, 78); + d_(j, r); + d_(k, s); + d_(l, v); + d_(m, x); + d_(n, u); + d_(o, y); + d_(p, t); + d_(q, w); + d_(j, aw); + d3(j, 110840); + d_(k, ax); + d3(k, 110840); + d_(l, ay); + d3(l, 110840); + d_(m, az); + d3(m, 110840); + d_(n, aA); + d3(n, 110840); + d_(o, aB); + d3(o, 110840); + d_(p, aC); + d3(p, 110840); + d_(q, aD); + d3(q, 110840); + d_(o, p); + d_(l, k); + d_(o, j); + d_(p, l); + d_(m, j); + d_(p, m); + d_(m, q); + d_(m, n); + d_(q, o); + d_(m, k); + d_(n, o); + d_(l, q); + d_(k, o); + d1(u, q); + d1(t, k); + d1(s, o); + d1(w, l); + d1(v, p); + d_(u, n); + d_(t, l); + d_(s, m); + d_(w, n); + d_(v, j); + d1(x, u); + d1(r, t); + d1(y, u); + d0(t, s); + d0(u, v); + d_(y, r); + d$(x, v); + d$(r, s); + d_(v, s); + d$(y, v); + d1(v, m); + d_(v, j); + d$(w, v); + d_(u, w); + d_(t, w); + d1(w, q); + d_(w, k); + d1(v, o); + d1(s, w); + d_(v, p); + d0(s, v); + d$(w, v); + d_(r, w); + d_(u, y); + d_(t, x); + d_(s, y); + d_(r, x); + d_(s, x); + d1(v, l); + d1(w, n); + d1(x, k); + d1(y, q); + d$(v, m); + d$(w, j); + d$(x, o); + d0(y, p); + d_(u, v); + d_(t, w); + d_(s, x); + d_(r, y); + d1(v, u); + d_(v, t); + d$(u, s); + d1(x, r); + d_(x, u); + d1(y, v); + d$(y, x); + d_(y, t); + d1(w, s); + d_(w, r); + d_(u, t); + d$(w, u); + d_(w, r); + d_(s, w); + d1(t, x); + d_(t, w); + d$(t, r); + d_(s, t); + d_(x, t); + d$(x, y); + d_(x, v); + d1(v, p); + d1(r, o); + d1(t, y); + d_(t, x); + d$(t, p); + d_(p, o); + d$(p, x); + d$(o, y); + d_(p, o); + d_(o, t); + d_(v, j); + d_(r, m); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, j); + d_(j, m); + d$(j, s); + d$(m, w); + d_(j, m); + d_(m, t); + d_(p, v); + d_(j, v); + d_(o, r); + d_(m, r); + d1(v, q); + d1(r, k); + d_(v, n); + d_(r, l); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, n); + d_(n, l); + d$(n, s); + d$(l, w); + d_(n, l); + d_(l, t); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, q); + d_(q, k); + d$(q, x); + d$(k, y); + d_(q, k); + d_(k, u); + d_(q, v); + d_(n, v); + d_(k, r); + d_(l, r); + d_(q, j); + d_(k, p); + d_(n, q); + d_(p, j); + d_(j, k); + d_(k, o); + d_(o, l); + d_(n, o); + d_(l, m); + d_(m, o); + d_(p, m); + d4(r, j, 147); + d4(s, k, 147); + d4(t, n, 147); + d4(u, p, 147); + d4(v, m, 147); + d4(w, q, 147); + d4(x, l, 147); + d4(y, o, 147); + d_(j, r); + d_(k, s); + d_(n, t); + d_(p, u); + d_(m, v); + d_(q, w); + d_(l, x); + d_(o, y); + d_(r, o); + d_(s, j); + d_(t, k); + d_(s, o); + d_(u, n); + d_(v, p); + d_(w, m); + d_(u, o); + d_(x, q); + d_(y, l); + d_(v, o); + d4(j, j, 78); + d4(k, k, 78); + d4(n, n, 78); + d4(p, p, 78); + d4(m, m, 78); + d4(q, q, 78); + d4(l, l, 78); + d4(o, o, 78); + d_(r, j); + d_(s, k); + d_(t, n); + d_(u, p); + d_(v, m); + d_(w, q); + d_(x, l); + d_(y, o); + d_(r, aE); + d3(r, 110840); + d_(s, aF); + d3(s, 110840); + d_(t, aG); + d3(t, 110840); + d_(u, aH); + d3(u, 110840); + d_(v, aI); + d3(v, 110840); + d_(w, aJ); + d3(w, 110840); + d_(x, aK); + d3(x, 110840); + d_(y, aL); + d3(y, 110840); + d_(w, x); + d_(t, s); + d_(w, r); + d_(x, t); + d_(u, r); + d_(x, u); + d_(u, y); + d_(u, v); + d_(y, w); + d_(u, s); + d_(v, w); + d_(t, y); + d_(s, w); + d1(m, y); + d1(l, s); + d1(k, w); + d1(o, t); + d1(n, x); + d_(m, v); + d_(l, t); + d_(k, u); + d_(o, v); + d_(n, r); + d1(p, m); + d1(j, l); + d1(q, m); + d0(l, k); + d0(m, n); + d_(q, j); + d$(p, n); + d$(j, k); + d_(n, k); + d$(q, n); + d1(n, u); + d_(n, r); + d$(o, n); + d_(m, o); + d_(l, o); + d1(o, y); + d_(o, s); + d1(n, w); + d1(k, o); + d_(n, x); + d0(k, n); + d$(o, n); + d_(j, o); + d_(m, q); + d_(l, p); + d_(k, q); + d_(j, p); + d_(k, p); + d1(n, t); + d1(o, v); + d1(p, s); + d1(q, y); + d$(n, u); + d$(o, r); + d$(p, w); + d0(q, x); + d_(m, n); + d_(l, o); + d_(k, p); + d_(j, q); + d1(n, m); + d_(n, l); + d$(m, k); + d1(p, j); + d_(p, m); + d1(q, n); + d$(q, p); + d_(q, l); + d1(o, k); + d_(o, j); + d_(m, l); + d$(o, m); + d_(o, j); + d_(k, o); + d1(l, p); + d_(l, o); + d$(l, j); + d_(k, l); + d_(p, l); + d$(p, q); + d_(p, n); + d1(n, x); + d1(j, w); + d1(l, q); + d_(l, p); + d$(l, x); + d_(x, w); + d$(x, p); + d$(w, q); + d_(x, w); + d_(w, l); + d_(n, r); + d_(j, u); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, r); + d_(r, u); + d$(r, k); + d$(u, o); + d_(r, u); + d_(u, l); + d_(x, n); + d_(r, n); + d_(w, j); + d_(u, j); + d1(n, y); + d1(j, s); + d_(n, v); + d_(j, t); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, v); + d_(v, t); + d$(v, k); + d$(t, o); + d_(v, t); + d_(t, l); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, y); + d_(y, s); + d$(y, p); + d$(s, q); + d_(y, s); + d_(s, m); + d_(y, n); + d_(v, n); + d_(s, j); + d_(t, j); + d_(y, r); + d_(s, x); + d_(v, y); + d_(x, r); + d_(r, s); + d_(s, w); + d_(w, t); + d_(v, w); + d_(t, u); + d_(u, w); + d_(x, u); + d4(j, r, 147); + d4(k, s, 147); + d4(l, v, 147); + d4(m, x, 147); + d4(n, u, 147); + d4(o, y, 147); + d4(p, t, 147); + d4(q, w, 147); + d_(r, j); + d_(s, k); + d_(v, l); + d_(x, m); + d_(u, n); + d_(y, o); + d_(t, p); + d_(w, q); + d_(j, w); + d_(k, r); + d_(l, s); + d_(k, w); + d_(m, v); + d_(n, x); + d_(o, u); + d_(m, w); + d_(p, y); + d_(q, t); + d_(n, w); + d4(r, r, 78); + d4(s, s, 78); + d4(v, v, 78); + d4(x, x, 78); + d4(u, u, 78); + d4(y, y, 78); + d4(t, t, 78); + d4(w, w, 78); + d_(j, r); + d_(k, s); + d_(l, v); + d_(m, x); + d_(n, u); + d_(o, y); + d_(p, t); + d_(q, w); + d_(j, aM); + d3(j, 110840); + d_(k, aN); + d3(k, 110840); + d_(l, aO); + d3(l, 110840); + d_(m, aP); + d3(m, 110840); + d_(n, aQ); + d3(n, 110840); + d_(o, aR); + d3(o, 110840); + d_(p, aS); + d3(p, 110840); + d_(q, aT); + d3(q, 110840); + d_(o, p); + d_(l, k); + d_(o, j); + d_(p, l); + d_(m, j); + d_(p, m); + d_(m, q); + d_(m, n); + d_(q, o); + d_(m, k); + d_(n, o); + d_(l, q); + d_(k, o); + d1(u, q); + d1(t, k); + d1(s, o); + d1(w, l); + d1(v, p); + d_(u, n); + d_(t, l); + d_(s, m); + d_(w, n); + d_(v, j); + d1(x, u); + d1(r, t); + d1(y, u); + d0(t, s); + d0(u, v); + d_(y, r); + d$(x, v); + d$(r, s); + d_(v, s); + d$(y, v); + d1(v, m); + d_(v, j); + d$(w, v); + d_(u, w); + d_(t, w); + d1(w, q); + d_(w, k); + d1(v, o); + d1(s, w); + d_(v, p); + d0(s, v); + d$(w, v); + d_(r, w); + d_(u, y); + d_(t, x); + d_(s, y); + d_(r, x); + d_(s, x); + d1(v, l); + d1(w, n); + d1(x, k); + d1(y, q); + d$(v, m); + d$(w, j); + d$(x, o); + d0(y, p); + d_(u, v); + d_(t, w); + d_(s, x); + d_(r, y); + d1(v, u); + d_(v, t); + d$(u, s); + d1(x, r); + d_(x, u); + d1(y, v); + d$(y, x); + d_(y, t); + d1(w, s); + d_(w, r); + d_(u, t); + d$(w, u); + d_(w, r); + d_(s, w); + d1(t, x); + d_(t, w); + d$(t, r); + d_(s, t); + d_(x, t); + d$(x, y); + d_(x, v); + d1(v, p); + d1(r, o); + d1(t, y); + d_(t, x); + d$(t, p); + d_(p, o); + d$(p, x); + d$(o, y); + d_(p, o); + d_(o, t); + d_(v, j); + d_(r, m); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, j); + d_(j, m); + d$(j, s); + d$(m, w); + d_(j, m); + d_(m, t); + d_(p, v); + d_(j, v); + d_(o, r); + d_(m, r); + d1(v, q); + d1(r, k); + d_(v, n); + d_(r, l); + d1(u, y); + d_(u, x); + d$(u, v); + d_(v, r); + d$(v, x); + d$(r, y); + d_(r, v); + d_(v, u); + d1(t, w); + d_(t, s); + d$(t, n); + d_(n, l); + d$(n, s); + d$(l, w); + d_(n, l); + d_(l, t); + d_(y, w); + d_(x, s); + d1(u, y); + d_(u, x); + d$(u, q); + d_(q, k); + d$(q, x); + d$(k, y); + d_(q, k); + d_(k, u); + d_(q, v); + d_(n, v); + d_(k, r); + d_(l, r); + d_(q, j); + d_(k, p); + d_(n, q); + d_(p, j); + d_(j, k); + d_(k, o); + d_(o, l); + d_(n, o); + d_(l, m); + d_(m, o); + d_(p, m); + d4(r, j, 147); + d4(s, k, 147); + d4(t, n, 147); + d4(u, p, 147); + d4(v, m, 147); + d4(w, q, 147); + d4(x, l, 147); + d4(y, o, 147); + d_(j, r); + d_(k, s); + d_(n, t); + d_(p, u); + d_(m, v); + d_(q, w); + d_(l, x); + d_(o, y); + d_(r, o); + d_(s, j); + d_(t, k); + d_(s, o); + d_(u, n); + d_(v, p); + d_(w, m); + d_(u, o); + d_(x, q); + d_(y, l); + d_(v, o); + d4(j, j, 78); + d4(k, k, 78); + d4(n, n, 78); + d4(p, p, 78); + d4(m, m, 78); + d4(q, q, 78); + d4(l, l, 78); + d4(o, o, 78); + d_(r, j); + d_(s, k); + d_(t, n); + d_(u, p); + d_(v, m); + d_(w, q); + d_(x, l); + d_(y, o); + d_(r, aU); + d3(r, 110824); + d_(s, aV); + d3(s, 110824); + d_(t, aW); + d3(t, 110824); + d_(u, aX); + d3(u, 110824); + d_(v, aY); + d3(v, 110824); + d_(w, aZ); + d3(w, 110824); + d_(x, a_); + d3(x, 110824); + d_(y, a$); + d3(y, 110824); + d_(w, x); + d_(t, s); + d_(w, r); + d_(x, t); + d_(u, r); + d_(x, u); + d_(u, y); + d_(u, v); + d_(y, w); + d_(u, s); + d_(v, w); + d_(t, y); + d_(s, w); + d1(m, y); + d1(l, s); + d1(k, w); + d1(o, t); + d1(n, x); + d_(m, v); + d_(l, t); + d_(k, u); + d_(o, v); + d_(n, r); + d1(p, m); + d1(j, l); + d1(q, m); + d0(l, k); + d0(m, n); + d_(q, j); + d$(p, n); + d$(j, k); + d_(n, k); + d$(q, n); + d1(n, u); + d_(n, r); + d$(o, n); + d_(m, o); + d_(l, o); + d1(o, y); + d_(o, s); + d1(n, w); + d1(k, o); + d_(n, x); + d0(k, n); + d$(o, n); + d_(j, o); + d_(m, q); + d_(l, p); + d_(k, q); + d_(j, p); + d_(k, p); + d1(n, t); + d1(o, v); + d1(p, s); + d1(q, y); + d$(n, u); + d$(o, r); + d$(p, w); + d0(q, x); + d_(m, n); + d_(l, o); + d_(k, p); + d_(j, q); + d1(n, m); + d_(n, l); + d$(m, k); + d1(p, j); + d_(p, m); + d1(q, n); + d$(q, p); + d_(q, l); + d1(o, k); + d_(o, j); + d_(m, l); + d$(o, m); + d_(o, j); + d_(k, o); + d1(l, p); + d_(l, o); + d$(l, j); + d_(k, l); + d_(p, l); + d$(p, q); + d_(p, n); + d1(n, x); + d1(j, w); + d1(l, q); + d_(l, p); + d$(l, x); + d_(x, w); + d$(x, p); + d$(w, q); + d_(x, w); + d_(w, l); + d_(n, r); + d_(j, u); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, r); + d_(r, u); + d$(r, k); + d$(u, o); + d_(r, u); + d_(u, l); + d_(x, n); + d_(r, n); + d_(w, j); + d_(u, j); + d1(n, y); + d1(j, s); + d_(n, v); + d_(j, t); + d1(m, q); + d_(m, p); + d$(m, n); + d_(n, j); + d$(n, p); + d$(j, q); + d_(j, n); + d_(n, m); + d1(l, o); + d_(l, k); + d$(l, v); + d_(v, t); + d$(v, k); + d$(t, o); + d_(v, t); + d_(t, l); + d_(q, o); + d_(p, k); + d1(m, q); + d_(m, p); + d$(m, y); + d_(y, s); + d$(y, p); + d$(s, q); + d_(y, s); + d_(s, m); + d_(y, n); + d_(v, n); + d_(s, j); + d_(t, j); + d_(y, r); + d_(s, x); + d_(v, y); + d_(x, r); + d_(r, s); + d_(s, w); + d_(w, t); + d_(v, w); + d_(t, u); + d_(u, w); + d_(x, u); + d_(r, a0); + d_(s, a1); + d_(v, a2); + d_(x, a3); + d_(u, a4); + d_(y, a5); + d_(t, a6); + d_(w, a7); + d1(j, t); + d6(j, 1); + d_(j, w); + d$(j, 110952); + d_(w, j); + d7(j, 1); + d_(t, j); + d1(j, u); + d6(j, 1); + d_(j, y); + d$(j, 110952); + d_(y, j); + d7(j, 1); + d_(u, j); + d1(j, v); + d6(j, 1); + d_(j, x); + d$(j, 110952); + d_(x, j); + d7(j, 1); + d_(v, j); + d1(j, r); + d6(j, 1); + d_(j, s); + d$(j, 110952); + d_(s, j); + d7(j, 1); + d_(r, j); + d1(j, y); + d6(j, 2); + d_(j, w); + d$(j, 110936); + d_(w, j); + d7(j, 2); + d_(y, j); + d1(j, u); + d6(j, 2); + d_(j, t); + d$(j, 110936); + d_(t, j); + d7(j, 2); + d_(u, j); + d1(j, s); + d6(j, 2); + d_(j, x); + d$(j, 110936); + d_(x, j); + d7(j, 2); + d_(s, j); + d1(j, r); + d6(j, 2); + d_(j, v); + d$(j, 110936); + d_(v, j); + d7(j, 2); + d_(r, j); + d1(j, x); + d6(j, 4); + d_(j, w); + d$(j, 110920); + d_(w, j); + d7(j, 4); + d_(x, j); + d1(j, v); + d6(j, 4); + d_(j, t); + d$(j, 110920); + d_(t, j); + d7(j, 4); + d_(v, j); + d1(j, s); + d6(j, 4); + d_(j, y); + d$(j, 110920); + d_(y, j); + d7(j, 4); + d_(s, j); + d1(j, r); + d6(j, 4); + d_(j, u); + d$(j, 110920); + d_(u, j); + d7(j, 4); + d_(r, j); + d = 0; + if (b >>> 0 < d >>> 0 | b >>> 0 == d >>> 0 & e >>> 0 < 128 >>> 0) { + break; + } + dV(g, (dU(g) | 0) + 8 | 0); + c[bg >> 2] = c[a8 >> 2]; + c[bg + 4 >> 2] = c[a8 + 4 >> 2]; + c[bg + 8 >> 2] = c[a8 + 8 >> 2]; + c[bg + 12 >> 2] = c[a8 + 12 >> 2]; + d = bg + 16 | 0; + c[d >> 2] = c[a9 >> 2]; + c[d + 4 >> 2] = c[a9 + 4 >> 2]; + c[d + 8 >> 2] = c[a9 + 8 >> 2]; + c[d + 12 >> 2] = c[a9 + 12 >> 2]; + d = bg + 32 | 0; + c[d >> 2] = c[ba >> 2]; + c[d + 4 >> 2] = c[ba + 4 >> 2]; + c[d + 8 >> 2] = c[ba + 8 >> 2]; + c[d + 12 >> 2] = c[ba + 12 >> 2]; + d = bg + 48 | 0; + c[d >> 2] = c[bb >> 2]; + c[d + 4 >> 2] = c[bb + 4 >> 2]; + c[d + 8 >> 2] = c[bb + 8 >> 2]; + c[d + 12 >> 2] = c[bb + 12 >> 2]; + d = bg + 64 | 0; + c[d >> 2] = c[bc >> 2]; + c[d + 4 >> 2] = c[bc + 4 >> 2]; + c[d + 8 >> 2] = c[bc + 8 >> 2]; + c[d + 12 >> 2] = c[bc + 12 >> 2]; + d = bg + 80 | 0; + c[d >> 2] = c[bd >> 2]; + c[d + 4 >> 2] = c[bd + 4 >> 2]; + c[d + 8 >> 2] = c[bd + 8 >> 2]; + c[d + 12 >> 2] = c[bd + 12 >> 2]; + d = bg + 96 | 0; + c[d >> 2] = c[be >> 2]; + c[d + 4 >> 2] = c[be + 4 >> 2]; + c[d + 8 >> 2] = c[be + 8 >> 2]; + c[d + 12 >> 2] = c[be + 12 >> 2]; + d = bg + 112 | 0; + c[d >> 2] = c[bf >> 2]; + c[d + 4 >> 2] = c[bf + 4 >> 2]; + c[d + 8 >> 2] = c[bf + 8 >> 2]; + c[d + 12 >> 2] = c[bf + 12 >> 2]; + if ((e | 0) == 128 & (b | 0) == 0) { + bh = 578; + break; + } + d = fp(e, b, -128, -1) | 0; + bg = bg + 128 | 0; + b = H; + e = d; + } + if ((bh | 0) == 578) { + i = h; + return 0; + } + bh = f + 12 | 0; + f = fp(dU(bh) | 0, 0, e >>> 4 | b << 28, b >>> 4 | 0 << 28) | 0; + dV(bh, f); + f = A; + bh = r; + c[f >> 2] = c[bh >> 2]; + c[f + 4 >> 2] = c[bh + 4 >> 2]; + c[f + 8 >> 2] = c[bh + 8 >> 2]; + c[f + 12 >> 2] = c[bh + 12 >> 2]; + bh = A + 16 | 0; + r = s; + c[bh >> 2] = c[r >> 2]; + c[bh + 4 >> 2] = c[r + 4 >> 2]; + c[bh + 8 >> 2] = c[r + 8 >> 2]; + c[bh + 12 >> 2] = c[r + 12 >> 2]; + r = A + 32 | 0; + bh = v; + c[r >> 2] = c[bh >> 2]; + c[r + 4 >> 2] = c[bh + 4 >> 2]; + c[r + 8 >> 2] = c[bh + 8 >> 2]; + c[r + 12 >> 2] = c[bh + 12 >> 2]; + bh = A + 48 | 0; + r = x; + c[bh >> 2] = c[r >> 2]; + c[bh + 4 >> 2] = c[r + 4 >> 2]; + c[bh + 8 >> 2] = c[r + 8 >> 2]; + c[bh + 12 >> 2] = c[r + 12 >> 2]; + r = A + 64 | 0; + bh = u; + c[r >> 2] = c[bh >> 2]; + c[r + 4 >> 2] = c[bh + 4 >> 2]; + c[r + 8 >> 2] = c[bh + 8 >> 2]; + c[r + 12 >> 2] = c[bh + 12 >> 2]; + bh = A + 80 | 0; + r = y; + c[bh >> 2] = c[r >> 2]; + c[bh + 4 >> 2] = c[r + 4 >> 2]; + c[bh + 8 >> 2] = c[r + 8 >> 2]; + c[bh + 12 >> 2] = c[r + 12 >> 2]; + r = A + 96 | 0; + bh = t; + c[r >> 2] = c[bh >> 2]; + c[r + 4 >> 2] = c[bh + 4 >> 2]; + c[r + 8 >> 2] = c[bh + 8 >> 2]; + c[r + 12 >> 2] = c[bh + 12 >> 2]; + bh = A + 112 | 0; + A = w; + c[bh >> 2] = c[A >> 2]; + c[bh + 4 >> 2] = c[A + 4 >> 2]; + c[bh + 8 >> 2] = c[A + 8 >> 2]; + c[bh + 12 >> 2] = c[A + 12 >> 2]; + if ((e | 0) == 0 & (b | 0) == 0) { + i = h; + return 0; + } else { + bi = b; + bj = e; + bk = f; + bl = bg; + } + while (1) { + a[bl] = a[bk] | 0; + bg = fp(bj, bi, -1, -1) | 0; + f = H; + if ((bg | 0) == 0 & (f | 0) == 0) { + break; + } else { + bi = f; + bj = bg; + bk = bk + 1 | 0; + bl = bl + 1 | 0; + } + } + i = h; + return 0; +} +function dT(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0; + d = i; + i = i + 272 | 0; + e = d | 0; + f = d + 16 | 0; + g = d + 32 | 0; + h = d + 48 | 0; + j = d + 64 | 0; + k = d + 80 | 0; + l = d + 96 | 0; + m = d + 112 | 0; + n = d + 128 | 0; + o = d + 144 | 0; + p = d + 160 | 0; + q = d + 176 | 0; + r = d + 192 | 0; + s = d + 208 | 0; + t = d + 224 | 0; + u = d + 240 | 0; + v = d + 256 | 0; + w = e; + c[w >> 2] = c[b >> 2]; + c[w + 4 >> 2] = c[b + 4 >> 2]; + c[w + 8 >> 2] = c[b + 8 >> 2]; + c[w + 12 >> 2] = c[b + 12 >> 2]; + d3(e, 110888); + d1(f, e); + d1(g, e); + d1(h, e); + d1(j, e); + d1(k, e); + d1(l, e); + d1(m, e); + d1(v, l); + d6(v, 1); + d_(v, m); + d$(v, 110952); + d_(m, v); + d7(v, 1); + d_(l, v); + d1(v, j); + d6(v, 1); + d_(v, k); + d$(v, 110952); + d_(k, v); + d7(v, 1); + d_(j, v); + d1(v, g); + d6(v, 1); + d_(v, h); + d$(v, 110952); + d_(h, v); + d7(v, 1); + d_(g, v); + d1(v, e); + d6(v, 1); + d_(v, f); + d$(v, 110952); + d_(f, v); + d7(v, 1); + d_(e, v); + d1(v, k); + d6(v, 2); + d_(v, m); + d$(v, 110936); + d_(m, v); + d7(v, 2); + d_(k, v); + d1(v, j); + d6(v, 2); + d_(v, l); + d$(v, 110936); + d_(l, v); + d7(v, 2); + d_(j, v); + d1(v, f); + d6(v, 2); + d_(v, h); + d$(v, 110936); + d_(h, v); + d7(v, 2); + d_(f, v); + d1(v, e); + d6(v, 2); + d_(v, g); + d$(v, 110936); + d_(g, v); + d7(v, 2); + d_(e, v); + d1(v, h); + d6(v, 4); + d_(v, m); + d$(v, 110920); + d_(m, v); + d7(v, 4); + d_(h, v); + d1(v, g); + d6(v, 4); + d_(v, l); + d$(v, 110920); + d_(l, v); + d7(v, 4); + d_(g, v); + d1(v, f); + d6(v, 4); + d_(v, k); + d$(v, 110920); + d_(k, v); + d7(v, 4); + d_(f, v); + d1(v, e); + d6(v, 4); + d_(v, j); + d$(v, 110920); + d_(j, v); + d7(v, 4); + d_(e, v); + c[a >> 2] = c[w >> 2]; + c[a + 4 >> 2] = c[w + 4 >> 2]; + c[a + 8 >> 2] = c[w + 8 >> 2]; + c[a + 12 >> 2] = c[w + 12 >> 2]; + v = a + 16 | 0; + b = f; + c[v >> 2] = c[b >> 2]; + c[v + 4 >> 2] = c[b + 4 >> 2]; + c[v + 8 >> 2] = c[b + 8 >> 2]; + c[v + 12 >> 2] = c[b + 12 >> 2]; + x = a + 32 | 0; + y = g; + c[x >> 2] = c[y >> 2]; + c[x + 4 >> 2] = c[y + 4 >> 2]; + c[x + 8 >> 2] = c[y + 8 >> 2]; + c[x + 12 >> 2] = c[y + 12 >> 2]; + z = a + 48 | 0; + A = h; + c[z >> 2] = c[A >> 2]; + c[z + 4 >> 2] = c[A + 4 >> 2]; + c[z + 8 >> 2] = c[A + 8 >> 2]; + c[z + 12 >> 2] = c[A + 12 >> 2]; + B = a + 64 | 0; + C = j; + c[B >> 2] = c[C >> 2]; + c[B + 4 >> 2] = c[C + 4 >> 2]; + c[B + 8 >> 2] = c[C + 8 >> 2]; + c[B + 12 >> 2] = c[C + 12 >> 2]; + D = a + 80 | 0; + E = k; + c[D >> 2] = c[E >> 2]; + c[D + 4 >> 2] = c[E + 4 >> 2]; + c[D + 8 >> 2] = c[E + 8 >> 2]; + c[D + 12 >> 2] = c[E + 12 >> 2]; + F = a + 96 | 0; + G = l; + c[F >> 2] = c[G >> 2]; + c[F + 4 >> 2] = c[G + 4 >> 2]; + c[F + 8 >> 2] = c[G + 8 >> 2]; + c[F + 12 >> 2] = c[G + 12 >> 2]; + H = a + 112 | 0; + I = m; + c[H >> 2] = c[I >> 2]; + c[H + 4 >> 2] = c[I + 4 >> 2]; + c[H + 8 >> 2] = c[I + 8 >> 2]; + c[H + 12 >> 2] = c[I + 12 >> 2]; + d3(e, 110856); + d3(f, 110856); + d3(g, 110856); + d3(h, 110856); + d3(j, 110856); + d3(k, 110856); + d3(l, 110856); + d3(m, 110856); + d_(k, l); + d_(g, f); + d_(k, e); + d_(l, g); + d_(h, e); + d_(l, h); + d_(h, m); + d_(h, j); + d_(m, k); + d_(h, f); + d_(j, k); + d_(g, m); + d_(f, k); + d1(q, m); + d1(p, f); + d1(o, k); + d1(s, g); + d1(r, l); + d_(q, j); + d_(p, g); + d_(o, h); + d_(s, j); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, h); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, m); + d_(s, f); + d1(r, k); + d1(o, s); + d_(r, l); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, g); + d1(s, j); + d1(t, f); + d1(u, m); + d$(r, h); + d$(s, e); + d$(t, k); + d0(u, l); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, l); + d1(n, k); + d1(p, u); + d_(p, t); + d$(p, l); + d_(l, k); + d$(l, t); + d$(k, u); + d_(l, k); + d_(k, p); + d_(r, e); + d_(n, h); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, h); + d$(e, o); + d$(h, s); + d_(e, h); + d_(h, p); + d_(l, r); + d_(e, r); + d_(k, n); + d_(h, n); + d1(r, m); + d1(n, f); + d_(r, j); + d_(n, g); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, j); + d_(j, g); + d$(j, o); + d$(g, s); + d_(j, g); + d_(g, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, m); + d_(m, f); + d$(m, t); + d$(f, u); + d_(m, f); + d_(f, q); + d_(m, r); + d_(j, r); + d_(f, n); + d_(g, n); + d_(m, e); + d_(f, l); + d_(j, m); + d_(l, e); + d_(e, f); + d_(f, k); + d_(k, g); + d_(j, k); + d_(g, h); + d_(h, k); + d_(l, h); + d8(e); + d3(e, 110904); + d3(f, 110904); + d3(j, 110904); + d3(l, 110904); + d3(h, 110904); + d3(m, 110904); + d3(g, 110904); + d3(k, 110904); + d3(e, 110904); + J = n; + c[J >> 2] = c[a >> 2]; + c[J + 4 >> 2] = c[a + 4 >> 2]; + c[J + 8 >> 2] = c[a + 8 >> 2]; + c[J + 12 >> 2] = c[a + 12 >> 2]; + K = o; + c[K >> 2] = c[v >> 2]; + c[K + 4 >> 2] = c[v + 4 >> 2]; + c[K + 8 >> 2] = c[v + 8 >> 2]; + c[K + 12 >> 2] = c[v + 12 >> 2]; + v = p; + c[v >> 2] = c[x >> 2]; + c[v + 4 >> 2] = c[x + 4 >> 2]; + c[v + 8 >> 2] = c[x + 8 >> 2]; + c[v + 12 >> 2] = c[x + 12 >> 2]; + x = q; + c[x >> 2] = c[z >> 2]; + c[x + 4 >> 2] = c[z + 4 >> 2]; + c[x + 8 >> 2] = c[z + 8 >> 2]; + c[x + 12 >> 2] = c[z + 12 >> 2]; + z = r; + c[z >> 2] = c[B >> 2]; + c[z + 4 >> 2] = c[B + 4 >> 2]; + c[z + 8 >> 2] = c[B + 8 >> 2]; + c[z + 12 >> 2] = c[B + 12 >> 2]; + B = s; + c[B >> 2] = c[D >> 2]; + c[B + 4 >> 2] = c[D + 4 >> 2]; + c[B + 8 >> 2] = c[D + 8 >> 2]; + c[B + 12 >> 2] = c[D + 12 >> 2]; + D = t; + c[D >> 2] = c[F >> 2]; + c[D + 4 >> 2] = c[F + 4 >> 2]; + c[D + 8 >> 2] = c[F + 8 >> 2]; + c[D + 12 >> 2] = c[F + 12 >> 2]; + F = u; + c[F >> 2] = c[H >> 2]; + c[F + 4 >> 2] = c[H + 4 >> 2]; + c[F + 8 >> 2] = c[H + 8 >> 2]; + c[F + 12 >> 2] = c[H + 12 >> 2]; + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + H = a + 128 | 0; + c[H >> 2] = c[w >> 2]; + c[H + 4 >> 2] = c[w + 4 >> 2]; + c[H + 8 >> 2] = c[w + 8 >> 2]; + c[H + 12 >> 2] = c[w + 12 >> 2]; + L = a + 144 | 0; + c[L >> 2] = c[b >> 2]; + c[L + 4 >> 2] = c[b + 4 >> 2]; + c[L + 8 >> 2] = c[b + 8 >> 2]; + c[L + 12 >> 2] = c[b + 12 >> 2]; + M = a + 160 | 0; + c[M >> 2] = c[C >> 2]; + c[M + 4 >> 2] = c[C + 4 >> 2]; + c[M + 8 >> 2] = c[C + 8 >> 2]; + c[M + 12 >> 2] = c[C + 12 >> 2]; + N = a + 176 | 0; + c[N >> 2] = c[G >> 2]; + c[N + 4 >> 2] = c[G + 4 >> 2]; + c[N + 8 >> 2] = c[G + 8 >> 2]; + c[N + 12 >> 2] = c[G + 12 >> 2]; + O = a + 192 | 0; + c[O >> 2] = c[A >> 2]; + c[O + 4 >> 2] = c[A + 4 >> 2]; + c[O + 8 >> 2] = c[A + 8 >> 2]; + c[O + 12 >> 2] = c[A + 12 >> 2]; + P = a + 208 | 0; + c[P >> 2] = c[I >> 2]; + c[P + 4 >> 2] = c[I + 4 >> 2]; + c[P + 8 >> 2] = c[I + 8 >> 2]; + c[P + 12 >> 2] = c[I + 12 >> 2]; + Q = a + 224 | 0; + c[Q >> 2] = c[y >> 2]; + c[Q + 4 >> 2] = c[y + 4 >> 2]; + c[Q + 8 >> 2] = c[y + 8 >> 2]; + c[Q + 12 >> 2] = c[y + 12 >> 2]; + R = a + 240 | 0; + c[R >> 2] = c[E >> 2]; + c[R + 4 >> 2] = c[E + 4 >> 2]; + c[R + 8 >> 2] = c[E + 8 >> 2]; + c[R + 12 >> 2] = c[E + 12 >> 2]; + d2(e); + d2(f); + d2(m); + d2(g); + d3(e, 110856); + d3(f, 110856); + d3(j, 110856); + d3(l, 110856); + d3(h, 110856); + d3(m, 110856); + d3(g, 110856); + d3(k, 110856); + d_(m, g); + d_(j, f); + d_(m, e); + d_(g, j); + d_(l, e); + d_(g, l); + d_(l, k); + d_(l, h); + d_(k, m); + d_(l, f); + d_(h, m); + d_(j, k); + d_(f, m); + d1(q, k); + d1(p, f); + d1(o, m); + d1(s, j); + d1(r, g); + d_(q, h); + d_(p, j); + d_(o, l); + d_(s, h); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, l); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, k); + d_(s, f); + d1(r, m); + d1(o, s); + d_(r, g); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, j); + d1(s, h); + d1(t, f); + d1(u, k); + d$(r, l); + d$(s, e); + d$(t, m); + d0(u, g); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, g); + d1(n, m); + d1(p, u); + d_(p, t); + d$(p, g); + d_(g, m); + d$(g, t); + d$(m, u); + d_(g, m); + d_(m, p); + d_(r, e); + d_(n, l); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, l); + d$(e, o); + d$(l, s); + d_(e, l); + d_(l, p); + d_(g, r); + d_(e, r); + d_(m, n); + d_(l, n); + d1(r, k); + d1(n, f); + d_(r, h); + d_(n, j); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, h); + d_(h, j); + d$(h, o); + d$(j, s); + d_(h, j); + d_(j, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, k); + d_(k, f); + d$(k, t); + d$(f, u); + d_(k, f); + d_(f, q); + d_(k, r); + d_(h, r); + d_(f, n); + d_(j, n); + d_(k, e); + d_(f, g); + d_(h, k); + d_(g, e); + d_(e, f); + d_(f, m); + d_(m, j); + d_(h, m); + d_(j, l); + d_(l, m); + d_(g, l); + d8(f); + d3(e, 110904); + d3(f, 110904); + d3(h, 110904); + d3(g, 110904); + d3(l, 110904); + d3(k, 110904); + d3(j, 110904); + d3(m, 110904); + c[J >> 2] = c[H >> 2]; + c[J + 4 >> 2] = c[H + 4 >> 2]; + c[J + 8 >> 2] = c[H + 8 >> 2]; + c[J + 12 >> 2] = c[H + 12 >> 2]; + c[K >> 2] = c[L >> 2]; + c[K + 4 >> 2] = c[L + 4 >> 2]; + c[K + 8 >> 2] = c[L + 8 >> 2]; + c[K + 12 >> 2] = c[L + 12 >> 2]; + c[v >> 2] = c[M >> 2]; + c[v + 4 >> 2] = c[M + 4 >> 2]; + c[v + 8 >> 2] = c[M + 8 >> 2]; + c[v + 12 >> 2] = c[M + 12 >> 2]; + c[x >> 2] = c[N >> 2]; + c[x + 4 >> 2] = c[N + 4 >> 2]; + c[x + 8 >> 2] = c[N + 8 >> 2]; + c[x + 12 >> 2] = c[N + 12 >> 2]; + c[z >> 2] = c[O >> 2]; + c[z + 4 >> 2] = c[O + 4 >> 2]; + c[z + 8 >> 2] = c[O + 8 >> 2]; + c[z + 12 >> 2] = c[O + 12 >> 2]; + c[B >> 2] = c[P >> 2]; + c[B + 4 >> 2] = c[P + 4 >> 2]; + c[B + 8 >> 2] = c[P + 8 >> 2]; + c[B + 12 >> 2] = c[P + 12 >> 2]; + c[D >> 2] = c[Q >> 2]; + c[D + 4 >> 2] = c[Q + 4 >> 2]; + c[D + 8 >> 2] = c[Q + 8 >> 2]; + c[D + 12 >> 2] = c[Q + 12 >> 2]; + c[F >> 2] = c[R >> 2]; + c[F + 4 >> 2] = c[R + 4 >> 2]; + c[F + 8 >> 2] = c[R + 8 >> 2]; + c[F + 12 >> 2] = c[R + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + R = a + 256 | 0; + c[R >> 2] = c[w >> 2]; + c[R + 4 >> 2] = c[w + 4 >> 2]; + c[R + 8 >> 2] = c[w + 8 >> 2]; + c[R + 12 >> 2] = c[w + 12 >> 2]; + Q = a + 272 | 0; + c[Q >> 2] = c[b >> 2]; + c[Q + 4 >> 2] = c[b + 4 >> 2]; + c[Q + 8 >> 2] = c[b + 8 >> 2]; + c[Q + 12 >> 2] = c[b + 12 >> 2]; + P = a + 288 | 0; + c[P >> 2] = c[A >> 2]; + c[P + 4 >> 2] = c[A + 4 >> 2]; + c[P + 8 >> 2] = c[A + 8 >> 2]; + c[P + 12 >> 2] = c[A + 12 >> 2]; + O = a + 304 | 0; + c[O >> 2] = c[y >> 2]; + c[O + 4 >> 2] = c[y + 4 >> 2]; + c[O + 8 >> 2] = c[y + 8 >> 2]; + c[O + 12 >> 2] = c[y + 12 >> 2]; + N = a + 320 | 0; + c[N >> 2] = c[G >> 2]; + c[N + 4 >> 2] = c[G + 4 >> 2]; + c[N + 8 >> 2] = c[G + 8 >> 2]; + c[N + 12 >> 2] = c[G + 12 >> 2]; + M = a + 336 | 0; + c[M >> 2] = c[E >> 2]; + c[M + 4 >> 2] = c[E + 4 >> 2]; + c[M + 8 >> 2] = c[E + 8 >> 2]; + c[M + 12 >> 2] = c[E + 12 >> 2]; + L = a + 352 | 0; + c[L >> 2] = c[C >> 2]; + c[L + 4 >> 2] = c[C + 4 >> 2]; + c[L + 8 >> 2] = c[C + 8 >> 2]; + c[L + 12 >> 2] = c[C + 12 >> 2]; + H = a + 368 | 0; + c[H >> 2] = c[I >> 2]; + c[H + 4 >> 2] = c[I + 4 >> 2]; + c[H + 8 >> 2] = c[I + 8 >> 2]; + c[H + 12 >> 2] = c[I + 12 >> 2]; + d2(e); + d2(f); + d2(k); + d2(j); + d3(e, 110856); + d3(f, 110856); + d3(h, 110856); + d3(g, 110856); + d3(l, 110856); + d3(k, 110856); + d3(j, 110856); + d3(m, 110856); + d_(k, j); + d_(h, f); + d_(k, e); + d_(j, h); + d_(g, e); + d_(j, g); + d_(g, m); + d_(g, l); + d_(m, k); + d_(g, f); + d_(l, k); + d_(h, m); + d_(f, k); + d1(q, m); + d1(p, f); + d1(o, k); + d1(s, h); + d1(r, j); + d_(q, l); + d_(p, h); + d_(o, g); + d_(s, l); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, g); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, m); + d_(s, f); + d1(r, k); + d1(o, s); + d_(r, j); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, h); + d1(s, l); + d1(t, f); + d1(u, m); + d$(r, g); + d$(s, e); + d$(t, k); + d0(u, j); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, j); + d1(n, k); + d1(p, u); + d_(p, t); + d$(p, j); + d_(j, k); + d$(j, t); + d$(k, u); + d_(j, k); + d_(k, p); + d_(r, e); + d_(n, g); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, g); + d$(e, o); + d$(g, s); + d_(e, g); + d_(g, p); + d_(j, r); + d_(e, r); + d_(k, n); + d_(g, n); + d1(r, m); + d1(n, f); + d_(r, l); + d_(n, h); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, l); + d_(l, h); + d$(l, o); + d$(h, s); + d_(l, h); + d_(h, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, m); + d_(m, f); + d$(m, t); + d$(f, u); + d_(m, f); + d_(f, q); + d_(m, r); + d_(l, r); + d_(f, n); + d_(h, n); + d_(m, e); + d_(f, j); + d_(l, m); + d_(j, e); + d_(e, f); + d_(f, k); + d_(k, h); + d_(l, k); + d_(h, g); + d_(g, k); + d_(j, g); + d8(l); + d3(e, 110904); + d3(f, 110904); + d3(l, 110904); + d3(j, 110904); + d3(g, 110904); + d3(m, 110904); + d3(h, 110904); + d3(k, 110904); + c[J >> 2] = c[R >> 2]; + c[J + 4 >> 2] = c[R + 4 >> 2]; + c[J + 8 >> 2] = c[R + 8 >> 2]; + c[J + 12 >> 2] = c[R + 12 >> 2]; + c[K >> 2] = c[Q >> 2]; + c[K + 4 >> 2] = c[Q + 4 >> 2]; + c[K + 8 >> 2] = c[Q + 8 >> 2]; + c[K + 12 >> 2] = c[Q + 12 >> 2]; + c[v >> 2] = c[P >> 2]; + c[v + 4 >> 2] = c[P + 4 >> 2]; + c[v + 8 >> 2] = c[P + 8 >> 2]; + c[v + 12 >> 2] = c[P + 12 >> 2]; + c[x >> 2] = c[O >> 2]; + c[x + 4 >> 2] = c[O + 4 >> 2]; + c[x + 8 >> 2] = c[O + 8 >> 2]; + c[x + 12 >> 2] = c[O + 12 >> 2]; + c[z >> 2] = c[N >> 2]; + c[z + 4 >> 2] = c[N + 4 >> 2]; + c[z + 8 >> 2] = c[N + 8 >> 2]; + c[z + 12 >> 2] = c[N + 12 >> 2]; + c[B >> 2] = c[M >> 2]; + c[B + 4 >> 2] = c[M + 4 >> 2]; + c[B + 8 >> 2] = c[M + 8 >> 2]; + c[B + 12 >> 2] = c[M + 12 >> 2]; + c[D >> 2] = c[L >> 2]; + c[D + 4 >> 2] = c[L + 4 >> 2]; + c[D + 8 >> 2] = c[L + 8 >> 2]; + c[D + 12 >> 2] = c[L + 12 >> 2]; + c[F >> 2] = c[H >> 2]; + c[F + 4 >> 2] = c[H + 4 >> 2]; + c[F + 8 >> 2] = c[H + 8 >> 2]; + c[F + 12 >> 2] = c[H + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + H = a + 384 | 0; + c[H >> 2] = c[w >> 2]; + c[H + 4 >> 2] = c[w + 4 >> 2]; + c[H + 8 >> 2] = c[w + 8 >> 2]; + c[H + 12 >> 2] = c[w + 12 >> 2]; + L = a + 400 | 0; + c[L >> 2] = c[b >> 2]; + c[L + 4 >> 2] = c[b + 4 >> 2]; + c[L + 8 >> 2] = c[b + 8 >> 2]; + c[L + 12 >> 2] = c[b + 12 >> 2]; + M = a + 416 | 0; + c[M >> 2] = c[G >> 2]; + c[M + 4 >> 2] = c[G + 4 >> 2]; + c[M + 8 >> 2] = c[G + 8 >> 2]; + c[M + 12 >> 2] = c[G + 12 >> 2]; + N = a + 432 | 0; + c[N >> 2] = c[C >> 2]; + c[N + 4 >> 2] = c[C + 4 >> 2]; + c[N + 8 >> 2] = c[C + 8 >> 2]; + c[N + 12 >> 2] = c[C + 12 >> 2]; + O = a + 448 | 0; + c[O >> 2] = c[y >> 2]; + c[O + 4 >> 2] = c[y + 4 >> 2]; + c[O + 8 >> 2] = c[y + 8 >> 2]; + c[O + 12 >> 2] = c[y + 12 >> 2]; + P = a + 464 | 0; + c[P >> 2] = c[I >> 2]; + c[P + 4 >> 2] = c[I + 4 >> 2]; + c[P + 8 >> 2] = c[I + 8 >> 2]; + c[P + 12 >> 2] = c[I + 12 >> 2]; + Q = a + 480 | 0; + c[Q >> 2] = c[A >> 2]; + c[Q + 4 >> 2] = c[A + 4 >> 2]; + c[Q + 8 >> 2] = c[A + 8 >> 2]; + c[Q + 12 >> 2] = c[A + 12 >> 2]; + R = a + 496 | 0; + c[R >> 2] = c[E >> 2]; + c[R + 4 >> 2] = c[E + 4 >> 2]; + c[R + 8 >> 2] = c[E + 8 >> 2]; + c[R + 12 >> 2] = c[E + 12 >> 2]; + d2(e); + d2(f); + d2(m); + d2(h); + d3(e, 110856); + d3(f, 110856); + d3(l, 110856); + d3(j, 110856); + d3(g, 110856); + d3(m, 110856); + d3(h, 110856); + d3(k, 110856); + d_(m, h); + d_(l, f); + d_(m, e); + d_(h, l); + d_(j, e); + d_(h, j); + d_(j, k); + d_(j, g); + d_(k, m); + d_(j, f); + d_(g, m); + d_(l, k); + d_(f, m); + d1(q, k); + d1(p, f); + d1(o, m); + d1(s, l); + d1(r, h); + d_(q, g); + d_(p, l); + d_(o, j); + d_(s, g); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, j); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, k); + d_(s, f); + d1(r, m); + d1(o, s); + d_(r, h); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, l); + d1(s, g); + d1(t, f); + d1(u, k); + d$(r, j); + d$(s, e); + d$(t, m); + d0(u, h); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, h); + d1(n, m); + d1(p, u); + d_(p, t); + d$(p, h); + d_(h, m); + d$(h, t); + d$(m, u); + d_(h, m); + d_(m, p); + d_(r, e); + d_(n, j); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, j); + d$(e, o); + d$(j, s); + d_(e, j); + d_(j, p); + d_(h, r); + d_(e, r); + d_(m, n); + d_(j, n); + d1(r, k); + d1(n, f); + d_(r, g); + d_(n, l); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, g); + d_(g, l); + d$(g, o); + d$(l, s); + d_(g, l); + d_(l, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, k); + d_(k, f); + d$(k, t); + d$(f, u); + d_(k, f); + d_(f, q); + d_(k, r); + d_(g, r); + d_(f, n); + d_(l, n); + d_(k, e); + d_(f, h); + d_(g, k); + d_(h, e); + d_(e, f); + d_(f, m); + d_(m, l); + d_(g, m); + d_(l, j); + d_(j, m); + d_(h, j); + d8(h); + d3(e, 110904); + d3(f, 110904); + d3(g, 110904); + d3(h, 110904); + d3(j, 110904); + d3(k, 110904); + d3(l, 110904); + d3(m, 110904); + c[J >> 2] = c[H >> 2]; + c[J + 4 >> 2] = c[H + 4 >> 2]; + c[J + 8 >> 2] = c[H + 8 >> 2]; + c[J + 12 >> 2] = c[H + 12 >> 2]; + c[K >> 2] = c[L >> 2]; + c[K + 4 >> 2] = c[L + 4 >> 2]; + c[K + 8 >> 2] = c[L + 8 >> 2]; + c[K + 12 >> 2] = c[L + 12 >> 2]; + c[v >> 2] = c[M >> 2]; + c[v + 4 >> 2] = c[M + 4 >> 2]; + c[v + 8 >> 2] = c[M + 8 >> 2]; + c[v + 12 >> 2] = c[M + 12 >> 2]; + c[x >> 2] = c[N >> 2]; + c[x + 4 >> 2] = c[N + 4 >> 2]; + c[x + 8 >> 2] = c[N + 8 >> 2]; + c[x + 12 >> 2] = c[N + 12 >> 2]; + c[z >> 2] = c[O >> 2]; + c[z + 4 >> 2] = c[O + 4 >> 2]; + c[z + 8 >> 2] = c[O + 8 >> 2]; + c[z + 12 >> 2] = c[O + 12 >> 2]; + c[B >> 2] = c[P >> 2]; + c[B + 4 >> 2] = c[P + 4 >> 2]; + c[B + 8 >> 2] = c[P + 8 >> 2]; + c[B + 12 >> 2] = c[P + 12 >> 2]; + c[D >> 2] = c[Q >> 2]; + c[D + 4 >> 2] = c[Q + 4 >> 2]; + c[D + 8 >> 2] = c[Q + 8 >> 2]; + c[D + 12 >> 2] = c[Q + 12 >> 2]; + c[F >> 2] = c[R >> 2]; + c[F + 4 >> 2] = c[R + 4 >> 2]; + c[F + 8 >> 2] = c[R + 8 >> 2]; + c[F + 12 >> 2] = c[R + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + R = a + 512 | 0; + c[R >> 2] = c[w >> 2]; + c[R + 4 >> 2] = c[w + 4 >> 2]; + c[R + 8 >> 2] = c[w + 8 >> 2]; + c[R + 12 >> 2] = c[w + 12 >> 2]; + Q = a + 528 | 0; + c[Q >> 2] = c[b >> 2]; + c[Q + 4 >> 2] = c[b + 4 >> 2]; + c[Q + 8 >> 2] = c[b + 8 >> 2]; + c[Q + 12 >> 2] = c[b + 12 >> 2]; + P = a + 544 | 0; + c[P >> 2] = c[y >> 2]; + c[P + 4 >> 2] = c[y + 4 >> 2]; + c[P + 8 >> 2] = c[y + 8 >> 2]; + c[P + 12 >> 2] = c[y + 12 >> 2]; + O = a + 560 | 0; + c[O >> 2] = c[A >> 2]; + c[O + 4 >> 2] = c[A + 4 >> 2]; + c[O + 8 >> 2] = c[A + 8 >> 2]; + c[O + 12 >> 2] = c[A + 12 >> 2]; + N = a + 576 | 0; + c[N >> 2] = c[C >> 2]; + c[N + 4 >> 2] = c[C + 4 >> 2]; + c[N + 8 >> 2] = c[C + 8 >> 2]; + c[N + 12 >> 2] = c[C + 12 >> 2]; + M = a + 592 | 0; + c[M >> 2] = c[E >> 2]; + c[M + 4 >> 2] = c[E + 4 >> 2]; + c[M + 8 >> 2] = c[E + 8 >> 2]; + c[M + 12 >> 2] = c[E + 12 >> 2]; + L = a + 608 | 0; + c[L >> 2] = c[G >> 2]; + c[L + 4 >> 2] = c[G + 4 >> 2]; + c[L + 8 >> 2] = c[G + 8 >> 2]; + c[L + 12 >> 2] = c[G + 12 >> 2]; + H = a + 624 | 0; + c[H >> 2] = c[I >> 2]; + c[H + 4 >> 2] = c[I + 4 >> 2]; + c[H + 8 >> 2] = c[I + 8 >> 2]; + c[H + 12 >> 2] = c[I + 12 >> 2]; + d2(e); + d2(f); + d2(k); + d2(l); + d3(e, 110856); + d3(f, 110856); + d3(g, 110856); + d3(h, 110856); + d3(j, 110856); + d3(k, 110856); + d3(l, 110856); + d3(m, 110856); + d_(k, l); + d_(g, f); + d_(k, e); + d_(l, g); + d_(h, e); + d_(l, h); + d_(h, m); + d_(h, j); + d_(m, k); + d_(h, f); + d_(j, k); + d_(g, m); + d_(f, k); + d1(q, m); + d1(p, f); + d1(o, k); + d1(s, g); + d1(r, l); + d_(q, j); + d_(p, g); + d_(o, h); + d_(s, j); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, h); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, m); + d_(s, f); + d1(r, k); + d1(o, s); + d_(r, l); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, g); + d1(s, j); + d1(t, f); + d1(u, m); + d$(r, h); + d$(s, e); + d$(t, k); + d0(u, l); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, l); + d1(n, k); + d1(p, u); + d_(p, t); + d$(p, l); + d_(l, k); + d$(l, t); + d$(k, u); + d_(l, k); + d_(k, p); + d_(r, e); + d_(n, h); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, h); + d$(e, o); + d$(h, s); + d_(e, h); + d_(h, p); + d_(l, r); + d_(e, r); + d_(k, n); + d_(h, n); + d1(r, m); + d1(n, f); + d_(r, j); + d_(n, g); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, j); + d_(j, g); + d$(j, o); + d$(g, s); + d_(j, g); + d_(g, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, m); + d_(m, f); + d$(m, t); + d$(f, u); + d_(m, f); + d_(f, q); + d_(m, r); + d_(j, r); + d_(f, n); + d_(g, n); + d_(m, e); + d_(f, l); + d_(j, m); + d_(l, e); + d_(e, f); + d_(f, k); + d_(k, g); + d_(j, k); + d_(g, h); + d_(h, k); + d_(l, h); + d8(h); + d3(e, 110904); + d3(f, 110904); + d3(j, 110904); + d3(l, 110904); + d3(h, 110904); + d3(m, 110904); + d3(g, 110904); + d3(k, 110904); + c[J >> 2] = c[R >> 2]; + c[J + 4 >> 2] = c[R + 4 >> 2]; + c[J + 8 >> 2] = c[R + 8 >> 2]; + c[J + 12 >> 2] = c[R + 12 >> 2]; + c[K >> 2] = c[Q >> 2]; + c[K + 4 >> 2] = c[Q + 4 >> 2]; + c[K + 8 >> 2] = c[Q + 8 >> 2]; + c[K + 12 >> 2] = c[Q + 12 >> 2]; + c[v >> 2] = c[P >> 2]; + c[v + 4 >> 2] = c[P + 4 >> 2]; + c[v + 8 >> 2] = c[P + 8 >> 2]; + c[v + 12 >> 2] = c[P + 12 >> 2]; + c[x >> 2] = c[O >> 2]; + c[x + 4 >> 2] = c[O + 4 >> 2]; + c[x + 8 >> 2] = c[O + 8 >> 2]; + c[x + 12 >> 2] = c[O + 12 >> 2]; + c[z >> 2] = c[N >> 2]; + c[z + 4 >> 2] = c[N + 4 >> 2]; + c[z + 8 >> 2] = c[N + 8 >> 2]; + c[z + 12 >> 2] = c[N + 12 >> 2]; + c[B >> 2] = c[M >> 2]; + c[B + 4 >> 2] = c[M + 4 >> 2]; + c[B + 8 >> 2] = c[M + 8 >> 2]; + c[B + 12 >> 2] = c[M + 12 >> 2]; + c[D >> 2] = c[L >> 2]; + c[D + 4 >> 2] = c[L + 4 >> 2]; + c[D + 8 >> 2] = c[L + 8 >> 2]; + c[D + 12 >> 2] = c[L + 12 >> 2]; + c[F >> 2] = c[H >> 2]; + c[F + 4 >> 2] = c[H + 4 >> 2]; + c[F + 8 >> 2] = c[H + 8 >> 2]; + c[F + 12 >> 2] = c[H + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + H = a + 640 | 0; + c[H >> 2] = c[w >> 2]; + c[H + 4 >> 2] = c[w + 4 >> 2]; + c[H + 8 >> 2] = c[w + 8 >> 2]; + c[H + 12 >> 2] = c[w + 12 >> 2]; + L = a + 656 | 0; + c[L >> 2] = c[b >> 2]; + c[L + 4 >> 2] = c[b + 4 >> 2]; + c[L + 8 >> 2] = c[b + 8 >> 2]; + c[L + 12 >> 2] = c[b + 12 >> 2]; + M = a + 672 | 0; + c[M >> 2] = c[C >> 2]; + c[M + 4 >> 2] = c[C + 4 >> 2]; + c[M + 8 >> 2] = c[C + 8 >> 2]; + c[M + 12 >> 2] = c[C + 12 >> 2]; + N = a + 688 | 0; + c[N >> 2] = c[G >> 2]; + c[N + 4 >> 2] = c[G + 4 >> 2]; + c[N + 8 >> 2] = c[G + 8 >> 2]; + c[N + 12 >> 2] = c[G + 12 >> 2]; + O = a + 704 | 0; + c[O >> 2] = c[A >> 2]; + c[O + 4 >> 2] = c[A + 4 >> 2]; + c[O + 8 >> 2] = c[A + 8 >> 2]; + c[O + 12 >> 2] = c[A + 12 >> 2]; + P = a + 720 | 0; + c[P >> 2] = c[I >> 2]; + c[P + 4 >> 2] = c[I + 4 >> 2]; + c[P + 8 >> 2] = c[I + 8 >> 2]; + c[P + 12 >> 2] = c[I + 12 >> 2]; + Q = a + 736 | 0; + c[Q >> 2] = c[y >> 2]; + c[Q + 4 >> 2] = c[y + 4 >> 2]; + c[Q + 8 >> 2] = c[y + 8 >> 2]; + c[Q + 12 >> 2] = c[y + 12 >> 2]; + R = a + 752 | 0; + c[R >> 2] = c[E >> 2]; + c[R + 4 >> 2] = c[E + 4 >> 2]; + c[R + 8 >> 2] = c[E + 8 >> 2]; + c[R + 12 >> 2] = c[E + 12 >> 2]; + d2(e); + d2(f); + d2(m); + d2(g); + d3(e, 110856); + d3(f, 110856); + d3(j, 110856); + d3(l, 110856); + d3(h, 110856); + d3(m, 110856); + d3(g, 110856); + d3(k, 110856); + d_(m, g); + d_(j, f); + d_(m, e); + d_(g, j); + d_(l, e); + d_(g, l); + d_(l, k); + d_(l, h); + d_(k, m); + d_(l, f); + d_(h, m); + d_(j, k); + d_(f, m); + d1(q, k); + d1(p, f); + d1(o, m); + d1(s, j); + d1(r, g); + d_(q, h); + d_(p, j); + d_(o, l); + d_(s, h); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, l); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, k); + d_(s, f); + d1(r, m); + d1(o, s); + d_(r, g); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, j); + d1(s, h); + d1(t, f); + d1(u, k); + d$(r, l); + d$(s, e); + d$(t, m); + d0(u, g); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, g); + d1(n, m); + d1(p, u); + d_(p, t); + d$(p, g); + d_(g, m); + d$(g, t); + d$(m, u); + d_(g, m); + d_(m, p); + d_(r, e); + d_(n, l); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, l); + d$(e, o); + d$(l, s); + d_(e, l); + d_(l, p); + d_(g, r); + d_(e, r); + d_(m, n); + d_(l, n); + d1(r, k); + d1(n, f); + d_(r, h); + d_(n, j); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, h); + d_(h, j); + d$(h, o); + d$(j, s); + d_(h, j); + d_(j, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, k); + d_(k, f); + d$(k, t); + d$(f, u); + d_(k, f); + d_(f, q); + d_(k, r); + d_(h, r); + d_(f, n); + d_(j, n); + d_(k, e); + d_(f, g); + d_(h, k); + d_(g, e); + d_(e, f); + d_(f, m); + d_(m, j); + d_(h, m); + d_(j, l); + d_(l, m); + d_(g, l); + d8(k); + d3(e, 110904); + d3(f, 110904); + d3(h, 110904); + d3(g, 110904); + d3(l, 110904); + d3(k, 110904); + d3(j, 110904); + d3(m, 110904); + c[J >> 2] = c[H >> 2]; + c[J + 4 >> 2] = c[H + 4 >> 2]; + c[J + 8 >> 2] = c[H + 8 >> 2]; + c[J + 12 >> 2] = c[H + 12 >> 2]; + c[K >> 2] = c[L >> 2]; + c[K + 4 >> 2] = c[L + 4 >> 2]; + c[K + 8 >> 2] = c[L + 8 >> 2]; + c[K + 12 >> 2] = c[L + 12 >> 2]; + c[v >> 2] = c[M >> 2]; + c[v + 4 >> 2] = c[M + 4 >> 2]; + c[v + 8 >> 2] = c[M + 8 >> 2]; + c[v + 12 >> 2] = c[M + 12 >> 2]; + c[x >> 2] = c[N >> 2]; + c[x + 4 >> 2] = c[N + 4 >> 2]; + c[x + 8 >> 2] = c[N + 8 >> 2]; + c[x + 12 >> 2] = c[N + 12 >> 2]; + c[z >> 2] = c[O >> 2]; + c[z + 4 >> 2] = c[O + 4 >> 2]; + c[z + 8 >> 2] = c[O + 8 >> 2]; + c[z + 12 >> 2] = c[O + 12 >> 2]; + c[B >> 2] = c[P >> 2]; + c[B + 4 >> 2] = c[P + 4 >> 2]; + c[B + 8 >> 2] = c[P + 8 >> 2]; + c[B + 12 >> 2] = c[P + 12 >> 2]; + c[D >> 2] = c[Q >> 2]; + c[D + 4 >> 2] = c[Q + 4 >> 2]; + c[D + 8 >> 2] = c[Q + 8 >> 2]; + c[D + 12 >> 2] = c[Q + 12 >> 2]; + c[F >> 2] = c[R >> 2]; + c[F + 4 >> 2] = c[R + 4 >> 2]; + c[F + 8 >> 2] = c[R + 8 >> 2]; + c[F + 12 >> 2] = c[R + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + R = a + 768 | 0; + c[R >> 2] = c[w >> 2]; + c[R + 4 >> 2] = c[w + 4 >> 2]; + c[R + 8 >> 2] = c[w + 8 >> 2]; + c[R + 12 >> 2] = c[w + 12 >> 2]; + Q = a + 784 | 0; + c[Q >> 2] = c[b >> 2]; + c[Q + 4 >> 2] = c[b + 4 >> 2]; + c[Q + 8 >> 2] = c[b + 8 >> 2]; + c[Q + 12 >> 2] = c[b + 12 >> 2]; + P = a + 800 | 0; + c[P >> 2] = c[A >> 2]; + c[P + 4 >> 2] = c[A + 4 >> 2]; + c[P + 8 >> 2] = c[A + 8 >> 2]; + c[P + 12 >> 2] = c[A + 12 >> 2]; + O = a + 816 | 0; + c[O >> 2] = c[y >> 2]; + c[O + 4 >> 2] = c[y + 4 >> 2]; + c[O + 8 >> 2] = c[y + 8 >> 2]; + c[O + 12 >> 2] = c[y + 12 >> 2]; + N = a + 832 | 0; + c[N >> 2] = c[G >> 2]; + c[N + 4 >> 2] = c[G + 4 >> 2]; + c[N + 8 >> 2] = c[G + 8 >> 2]; + c[N + 12 >> 2] = c[G + 12 >> 2]; + M = a + 848 | 0; + c[M >> 2] = c[E >> 2]; + c[M + 4 >> 2] = c[E + 4 >> 2]; + c[M + 8 >> 2] = c[E + 8 >> 2]; + c[M + 12 >> 2] = c[E + 12 >> 2]; + L = a + 864 | 0; + c[L >> 2] = c[C >> 2]; + c[L + 4 >> 2] = c[C + 4 >> 2]; + c[L + 8 >> 2] = c[C + 8 >> 2]; + c[L + 12 >> 2] = c[C + 12 >> 2]; + H = a + 880 | 0; + c[H >> 2] = c[I >> 2]; + c[H + 4 >> 2] = c[I + 4 >> 2]; + c[H + 8 >> 2] = c[I + 8 >> 2]; + c[H + 12 >> 2] = c[I + 12 >> 2]; + d2(e); + d2(f); + d2(k); + d2(j); + d3(e, 110856); + d3(f, 110856); + d3(h, 110856); + d3(g, 110856); + d3(l, 110856); + d3(k, 110856); + d3(j, 110856); + d3(m, 110856); + d_(k, j); + d_(h, f); + d_(k, e); + d_(j, h); + d_(g, e); + d_(j, g); + d_(g, m); + d_(g, l); + d_(m, k); + d_(g, f); + d_(l, k); + d_(h, m); + d_(f, k); + d1(q, m); + d1(p, f); + d1(o, k); + d1(s, h); + d1(r, j); + d_(q, l); + d_(p, h); + d_(o, g); + d_(s, l); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, g); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, m); + d_(s, f); + d1(r, k); + d1(o, s); + d_(r, j); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, h); + d1(s, l); + d1(t, f); + d1(u, m); + d$(r, g); + d$(s, e); + d$(t, k); + d0(u, j); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, j); + d1(n, k); + d1(p, u); + d_(p, t); + d$(p, j); + d_(j, k); + d$(j, t); + d$(k, u); + d_(j, k); + d_(k, p); + d_(r, e); + d_(n, g); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, g); + d$(e, o); + d$(g, s); + d_(e, g); + d_(g, p); + d_(j, r); + d_(e, r); + d_(k, n); + d_(g, n); + d1(r, m); + d1(n, f); + d_(r, l); + d_(n, h); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, l); + d_(l, h); + d$(l, o); + d$(h, s); + d_(l, h); + d_(h, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, m); + d_(m, f); + d$(m, t); + d$(f, u); + d_(m, f); + d_(f, q); + d_(m, r); + d_(l, r); + d_(f, n); + d_(h, n); + d_(m, e); + d_(f, j); + d_(l, m); + d_(j, e); + d_(e, f); + d_(f, k); + d_(k, h); + d_(l, k); + d_(h, g); + d_(g, k); + d_(j, g); + d8(h); + d3(e, 110904); + d3(f, 110904); + d3(l, 110904); + d3(j, 110904); + d3(g, 110904); + d3(m, 110904); + d3(h, 110904); + d3(k, 110904); + c[J >> 2] = c[R >> 2]; + c[J + 4 >> 2] = c[R + 4 >> 2]; + c[J + 8 >> 2] = c[R + 8 >> 2]; + c[J + 12 >> 2] = c[R + 12 >> 2]; + c[K >> 2] = c[Q >> 2]; + c[K + 4 >> 2] = c[Q + 4 >> 2]; + c[K + 8 >> 2] = c[Q + 8 >> 2]; + c[K + 12 >> 2] = c[Q + 12 >> 2]; + c[v >> 2] = c[P >> 2]; + c[v + 4 >> 2] = c[P + 4 >> 2]; + c[v + 8 >> 2] = c[P + 8 >> 2]; + c[v + 12 >> 2] = c[P + 12 >> 2]; + c[x >> 2] = c[O >> 2]; + c[x + 4 >> 2] = c[O + 4 >> 2]; + c[x + 8 >> 2] = c[O + 8 >> 2]; + c[x + 12 >> 2] = c[O + 12 >> 2]; + c[z >> 2] = c[N >> 2]; + c[z + 4 >> 2] = c[N + 4 >> 2]; + c[z + 8 >> 2] = c[N + 8 >> 2]; + c[z + 12 >> 2] = c[N + 12 >> 2]; + c[B >> 2] = c[M >> 2]; + c[B + 4 >> 2] = c[M + 4 >> 2]; + c[B + 8 >> 2] = c[M + 8 >> 2]; + c[B + 12 >> 2] = c[M + 12 >> 2]; + c[D >> 2] = c[L >> 2]; + c[D + 4 >> 2] = c[L + 4 >> 2]; + c[D + 8 >> 2] = c[L + 8 >> 2]; + c[D + 12 >> 2] = c[L + 12 >> 2]; + c[F >> 2] = c[H >> 2]; + c[F + 4 >> 2] = c[H + 4 >> 2]; + c[F + 8 >> 2] = c[H + 8 >> 2]; + c[F + 12 >> 2] = c[H + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(l, p); + d_(j, q); + d_(g, r); + d_(m, s); + d_(h, t); + d_(k, u); + H = a + 896 | 0; + c[H >> 2] = c[w >> 2]; + c[H + 4 >> 2] = c[w + 4 >> 2]; + c[H + 8 >> 2] = c[w + 8 >> 2]; + c[H + 12 >> 2] = c[w + 12 >> 2]; + L = a + 912 | 0; + c[L >> 2] = c[b >> 2]; + c[L + 4 >> 2] = c[b + 4 >> 2]; + c[L + 8 >> 2] = c[b + 8 >> 2]; + c[L + 12 >> 2] = c[b + 12 >> 2]; + M = a + 928 | 0; + c[M >> 2] = c[G >> 2]; + c[M + 4 >> 2] = c[G + 4 >> 2]; + c[M + 8 >> 2] = c[G + 8 >> 2]; + c[M + 12 >> 2] = c[G + 12 >> 2]; + N = a + 944 | 0; + c[N >> 2] = c[C >> 2]; + c[N + 4 >> 2] = c[C + 4 >> 2]; + c[N + 8 >> 2] = c[C + 8 >> 2]; + c[N + 12 >> 2] = c[C + 12 >> 2]; + O = a + 960 | 0; + c[O >> 2] = c[y >> 2]; + c[O + 4 >> 2] = c[y + 4 >> 2]; + c[O + 8 >> 2] = c[y + 8 >> 2]; + c[O + 12 >> 2] = c[y + 12 >> 2]; + P = a + 976 | 0; + c[P >> 2] = c[I >> 2]; + c[P + 4 >> 2] = c[I + 4 >> 2]; + c[P + 8 >> 2] = c[I + 8 >> 2]; + c[P + 12 >> 2] = c[I + 12 >> 2]; + Q = a + 992 | 0; + c[Q >> 2] = c[A >> 2]; + c[Q + 4 >> 2] = c[A + 4 >> 2]; + c[Q + 8 >> 2] = c[A + 8 >> 2]; + c[Q + 12 >> 2] = c[A + 12 >> 2]; + R = a + 1008 | 0; + c[R >> 2] = c[E >> 2]; + c[R + 4 >> 2] = c[E + 4 >> 2]; + c[R + 8 >> 2] = c[E + 8 >> 2]; + c[R + 12 >> 2] = c[E + 12 >> 2]; + d2(e); + d2(f); + d2(m); + d2(h); + d3(e, 110856); + d3(f, 110856); + d3(l, 110856); + d3(j, 110856); + d3(g, 110856); + d3(m, 110856); + d3(h, 110856); + d3(k, 110856); + d_(m, h); + d_(l, f); + d_(m, e); + d_(h, l); + d_(j, e); + d_(h, j); + d_(j, k); + d_(j, g); + d_(k, m); + d_(j, f); + d_(g, m); + d_(l, k); + d_(f, m); + d1(q, k); + d1(p, f); + d1(o, m); + d1(s, l); + d1(r, h); + d_(q, g); + d_(p, l); + d_(o, j); + d_(s, g); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, j); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, k); + d_(s, f); + d1(r, m); + d1(o, s); + d_(r, h); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, l); + d1(s, g); + d1(t, f); + d1(u, k); + d$(r, j); + d$(s, e); + d$(t, m); + d0(u, h); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, h); + d1(n, m); + d1(p, u); + d_(p, t); + d$(p, h); + d_(h, m); + d$(h, t); + d$(m, u); + d_(h, m); + d_(m, p); + d_(r, e); + d_(n, j); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, j); + d$(e, o); + d$(j, s); + d_(e, j); + d_(j, p); + d_(h, r); + d_(e, r); + d_(m, n); + d_(j, n); + d1(r, k); + d1(n, f); + d_(r, g); + d_(n, l); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, g); + d_(g, l); + d$(g, o); + d$(l, s); + d_(g, l); + d_(l, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, k); + d_(k, f); + d$(k, t); + d$(f, u); + d_(k, f); + d_(f, q); + d_(k, r); + d_(g, r); + d_(f, n); + d_(l, n); + d_(k, e); + d_(f, h); + d_(g, k); + d_(h, e); + d_(e, f); + d_(f, m); + d_(m, l); + d_(g, m); + d_(l, j); + d_(j, m); + d_(h, j); + d8(m); + d3(e, 110904); + d3(f, 110904); + d3(g, 110904); + d3(h, 110904); + d3(j, 110904); + d3(k, 110904); + d3(l, 110904); + d3(m, 110904); + c[J >> 2] = c[H >> 2]; + c[J + 4 >> 2] = c[H + 4 >> 2]; + c[J + 8 >> 2] = c[H + 8 >> 2]; + c[J + 12 >> 2] = c[H + 12 >> 2]; + c[K >> 2] = c[L >> 2]; + c[K + 4 >> 2] = c[L + 4 >> 2]; + c[K + 8 >> 2] = c[L + 8 >> 2]; + c[K + 12 >> 2] = c[L + 12 >> 2]; + c[v >> 2] = c[M >> 2]; + c[v + 4 >> 2] = c[M + 4 >> 2]; + c[v + 8 >> 2] = c[M + 8 >> 2]; + c[v + 12 >> 2] = c[M + 12 >> 2]; + c[x >> 2] = c[N >> 2]; + c[x + 4 >> 2] = c[N + 4 >> 2]; + c[x + 8 >> 2] = c[N + 8 >> 2]; + c[x + 12 >> 2] = c[N + 12 >> 2]; + c[z >> 2] = c[O >> 2]; + c[z + 4 >> 2] = c[O + 4 >> 2]; + c[z + 8 >> 2] = c[O + 8 >> 2]; + c[z + 12 >> 2] = c[O + 12 >> 2]; + c[B >> 2] = c[P >> 2]; + c[B + 4 >> 2] = c[P + 4 >> 2]; + c[B + 8 >> 2] = c[P + 8 >> 2]; + c[B + 12 >> 2] = c[P + 12 >> 2]; + c[D >> 2] = c[Q >> 2]; + c[D + 4 >> 2] = c[Q + 4 >> 2]; + c[D + 8 >> 2] = c[Q + 8 >> 2]; + c[D + 12 >> 2] = c[Q + 12 >> 2]; + c[F >> 2] = c[R >> 2]; + c[F + 4 >> 2] = c[R + 4 >> 2]; + c[F + 8 >> 2] = c[R + 8 >> 2]; + c[F + 12 >> 2] = c[R + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(g, p); + d_(h, q); + d_(j, r); + d_(k, s); + d_(l, t); + d_(m, u); + R = a + 1024 | 0; + c[R >> 2] = c[w >> 2]; + c[R + 4 >> 2] = c[w + 4 >> 2]; + c[R + 8 >> 2] = c[w + 8 >> 2]; + c[R + 12 >> 2] = c[w + 12 >> 2]; + Q = a + 1040 | 0; + c[Q >> 2] = c[b >> 2]; + c[Q + 4 >> 2] = c[b + 4 >> 2]; + c[Q + 8 >> 2] = c[b + 8 >> 2]; + c[Q + 12 >> 2] = c[b + 12 >> 2]; + P = a + 1056 | 0; + c[P >> 2] = c[y >> 2]; + c[P + 4 >> 2] = c[y + 4 >> 2]; + c[P + 8 >> 2] = c[y + 8 >> 2]; + c[P + 12 >> 2] = c[y + 12 >> 2]; + O = a + 1072 | 0; + c[O >> 2] = c[A >> 2]; + c[O + 4 >> 2] = c[A + 4 >> 2]; + c[O + 8 >> 2] = c[A + 8 >> 2]; + c[O + 12 >> 2] = c[A + 12 >> 2]; + N = a + 1088 | 0; + c[N >> 2] = c[C >> 2]; + c[N + 4 >> 2] = c[C + 4 >> 2]; + c[N + 8 >> 2] = c[C + 8 >> 2]; + c[N + 12 >> 2] = c[C + 12 >> 2]; + M = a + 1104 | 0; + c[M >> 2] = c[E >> 2]; + c[M + 4 >> 2] = c[E + 4 >> 2]; + c[M + 8 >> 2] = c[E + 8 >> 2]; + c[M + 12 >> 2] = c[E + 12 >> 2]; + L = a + 1120 | 0; + c[L >> 2] = c[G >> 2]; + c[L + 4 >> 2] = c[G + 4 >> 2]; + c[L + 8 >> 2] = c[G + 8 >> 2]; + c[L + 12 >> 2] = c[G + 12 >> 2]; + H = a + 1136 | 0; + c[H >> 2] = c[I >> 2]; + c[H + 4 >> 2] = c[I + 4 >> 2]; + c[H + 8 >> 2] = c[I + 8 >> 2]; + c[H + 12 >> 2] = c[I + 12 >> 2]; + d2(e); + d2(f); + d2(k); + d2(l); + d3(e, 110856); + d3(f, 110856); + d3(g, 110856); + d3(h, 110856); + d3(j, 110856); + d3(k, 110856); + d3(l, 110856); + d3(m, 110856); + d_(k, l); + d_(g, f); + d_(k, e); + d_(l, g); + d_(h, e); + d_(l, h); + d_(h, m); + d_(h, j); + d_(m, k); + d_(h, f); + d_(j, k); + d_(g, m); + d_(f, k); + d1(q, m); + d1(p, f); + d1(o, k); + d1(s, g); + d1(r, l); + d_(q, j); + d_(p, g); + d_(o, h); + d_(s, j); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, h); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, m); + d_(s, f); + d1(r, k); + d1(o, s); + d_(r, l); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, g); + d1(s, j); + d1(t, f); + d1(u, m); + d$(r, h); + d$(s, e); + d$(t, k); + d0(u, l); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, l); + d1(n, k); + d1(p, u); + d_(p, t); + d$(p, l); + d_(l, k); + d$(l, t); + d$(k, u); + d_(l, k); + d_(k, p); + d_(r, e); + d_(n, h); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, h); + d$(e, o); + d$(h, s); + d_(e, h); + d_(h, p); + d_(l, r); + d_(e, r); + d_(k, n); + d_(h, n); + d1(r, m); + d1(n, f); + d_(r, j); + d_(n, g); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, j); + d_(j, g); + d$(j, o); + d$(g, s); + d_(j, g); + d_(g, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, m); + d_(m, f); + d$(m, t); + d$(f, u); + d_(m, f); + d_(f, q); + d_(m, r); + d_(j, r); + d_(f, n); + d_(g, n); + d_(m, e); + d_(f, l); + d_(j, m); + d_(l, e); + d_(e, f); + d_(f, k); + d_(k, g); + d_(j, k); + d_(g, h); + d_(h, k); + d_(l, h); + d8(e); + d8(f); + d8(l); + d8(h); + d3(e, 110904); + d3(f, 110904); + d3(j, 110904); + d3(l, 110904); + d3(h, 110904); + d3(m, 110904); + d3(g, 110904); + d3(k, 110904); + c[J >> 2] = c[R >> 2]; + c[J + 4 >> 2] = c[R + 4 >> 2]; + c[J + 8 >> 2] = c[R + 8 >> 2]; + c[J + 12 >> 2] = c[R + 12 >> 2]; + c[K >> 2] = c[Q >> 2]; + c[K + 4 >> 2] = c[Q + 4 >> 2]; + c[K + 8 >> 2] = c[Q + 8 >> 2]; + c[K + 12 >> 2] = c[Q + 12 >> 2]; + c[v >> 2] = c[P >> 2]; + c[v + 4 >> 2] = c[P + 4 >> 2]; + c[v + 8 >> 2] = c[P + 8 >> 2]; + c[v + 12 >> 2] = c[P + 12 >> 2]; + c[x >> 2] = c[O >> 2]; + c[x + 4 >> 2] = c[O + 4 >> 2]; + c[x + 8 >> 2] = c[O + 8 >> 2]; + c[x + 12 >> 2] = c[O + 12 >> 2]; + c[z >> 2] = c[N >> 2]; + c[z + 4 >> 2] = c[N + 4 >> 2]; + c[z + 8 >> 2] = c[N + 8 >> 2]; + c[z + 12 >> 2] = c[N + 12 >> 2]; + c[B >> 2] = c[M >> 2]; + c[B + 4 >> 2] = c[M + 4 >> 2]; + c[B + 8 >> 2] = c[M + 8 >> 2]; + c[B + 12 >> 2] = c[M + 12 >> 2]; + c[D >> 2] = c[L >> 2]; + c[D + 4 >> 2] = c[L + 4 >> 2]; + c[D + 8 >> 2] = c[L + 8 >> 2]; + c[D + 12 >> 2] = c[L + 12 >> 2]; + c[F >> 2] = c[H >> 2]; + c[F + 4 >> 2] = c[H + 4 >> 2]; + c[F + 8 >> 2] = c[H + 8 >> 2]; + c[F + 12 >> 2] = c[H + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(j, p); + d_(l, q); + d_(h, r); + d_(m, s); + d_(g, t); + d_(k, u); + H = a + 1152 | 0; + c[H >> 2] = c[w >> 2]; + c[H + 4 >> 2] = c[w + 4 >> 2]; + c[H + 8 >> 2] = c[w + 8 >> 2]; + c[H + 12 >> 2] = c[w + 12 >> 2]; + L = a + 1168 | 0; + c[L >> 2] = c[b >> 2]; + c[L + 4 >> 2] = c[b + 4 >> 2]; + c[L + 8 >> 2] = c[b + 8 >> 2]; + c[L + 12 >> 2] = c[b + 12 >> 2]; + M = a + 1184 | 0; + c[M >> 2] = c[C >> 2]; + c[M + 4 >> 2] = c[C + 4 >> 2]; + c[M + 8 >> 2] = c[C + 8 >> 2]; + c[M + 12 >> 2] = c[C + 12 >> 2]; + N = a + 1200 | 0; + c[N >> 2] = c[G >> 2]; + c[N + 4 >> 2] = c[G + 4 >> 2]; + c[N + 8 >> 2] = c[G + 8 >> 2]; + c[N + 12 >> 2] = c[G + 12 >> 2]; + O = a + 1216 | 0; + c[O >> 2] = c[A >> 2]; + c[O + 4 >> 2] = c[A + 4 >> 2]; + c[O + 8 >> 2] = c[A + 8 >> 2]; + c[O + 12 >> 2] = c[A + 12 >> 2]; + P = a + 1232 | 0; + c[P >> 2] = c[I >> 2]; + c[P + 4 >> 2] = c[I + 4 >> 2]; + c[P + 8 >> 2] = c[I + 8 >> 2]; + c[P + 12 >> 2] = c[I + 12 >> 2]; + Q = a + 1248 | 0; + c[Q >> 2] = c[y >> 2]; + c[Q + 4 >> 2] = c[y + 4 >> 2]; + c[Q + 8 >> 2] = c[y + 8 >> 2]; + c[Q + 12 >> 2] = c[y + 12 >> 2]; + R = a + 1264 | 0; + c[R >> 2] = c[E >> 2]; + c[R + 4 >> 2] = c[E + 4 >> 2]; + c[R + 8 >> 2] = c[E + 8 >> 2]; + c[R + 12 >> 2] = c[E + 12 >> 2]; + d2(e); + d2(f); + d2(m); + d2(g); + d3(e, 110856); + d3(f, 110856); + d3(j, 110856); + d3(l, 110856); + d3(h, 110856); + d3(m, 110856); + d3(g, 110856); + d3(k, 110856); + d_(m, g); + d_(j, f); + d_(m, e); + d_(g, j); + d_(l, e); + d_(g, l); + d_(l, k); + d_(l, h); + d_(k, m); + d_(l, f); + d_(h, m); + d_(j, k); + d_(f, m); + d1(q, k); + d1(p, f); + d1(o, m); + d1(s, j); + d1(r, g); + d_(q, h); + d_(p, j); + d_(o, l); + d_(s, h); + d_(r, e); + d1(t, q); + d1(n, p); + d1(u, q); + d0(p, o); + d0(q, r); + d_(u, n); + d$(t, r); + d$(n, o); + d_(r, o); + d$(u, r); + d1(r, l); + d_(r, e); + d$(s, r); + d_(q, s); + d_(p, s); + d1(s, k); + d_(s, f); + d1(r, m); + d1(o, s); + d_(r, g); + d0(o, r); + d$(s, r); + d_(n, s); + d_(q, u); + d_(p, t); + d_(o, u); + d_(n, t); + d_(o, t); + d1(r, j); + d1(s, h); + d1(t, f); + d1(u, k); + d$(r, l); + d$(s, e); + d$(t, m); + d0(u, g); + d_(q, r); + d_(p, s); + d_(o, t); + d_(n, u); + d1(r, q); + d_(r, p); + d$(q, o); + d1(t, n); + d_(t, q); + d1(u, r); + d$(u, t); + d_(u, p); + d1(s, o); + d_(s, n); + d_(q, p); + d$(s, q); + d_(s, n); + d_(o, s); + d1(p, t); + d_(p, s); + d$(p, n); + d_(o, p); + d_(t, p); + d$(t, u); + d_(t, r); + d1(r, g); + d1(n, m); + d1(p, u); + d_(p, t); + d$(p, g); + d_(g, m); + d$(g, t); + d$(m, u); + d_(g, m); + d_(m, p); + d_(r, e); + d_(n, l); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, e); + d_(e, l); + d$(e, o); + d$(l, s); + d_(e, l); + d_(l, p); + d_(g, r); + d_(e, r); + d_(m, n); + d_(l, n); + d1(r, k); + d1(n, f); + d_(r, h); + d_(n, j); + d1(q, u); + d_(q, t); + d$(q, r); + d_(r, n); + d$(r, t); + d$(n, u); + d_(n, r); + d_(r, q); + d1(p, s); + d_(p, o); + d$(p, h); + d_(h, j); + d$(h, o); + d$(j, s); + d_(h, j); + d_(j, p); + d_(u, s); + d_(t, o); + d1(q, u); + d_(q, t); + d$(q, k); + d_(k, f); + d$(k, t); + d$(f, u); + d_(k, f); + d_(f, q); + d_(k, r); + d_(h, r); + d_(f, n); + d_(j, n); + d_(k, e); + d_(f, g); + d_(h, k); + d_(g, e); + d_(e, f); + d_(f, m); + d_(m, j); + d_(h, m); + d_(j, l); + d_(l, m); + d_(g, l); + d8(f); + d8(h); + d8(l); + d8(k); + d3(e, 110904); + d3(f, 110904); + d3(h, 110904); + d3(g, 110904); + d3(l, 110904); + d3(k, 110904); + d3(j, 110904); + d3(m, 110904); + c[J >> 2] = c[H >> 2]; + c[J + 4 >> 2] = c[H + 4 >> 2]; + c[J + 8 >> 2] = c[H + 8 >> 2]; + c[J + 12 >> 2] = c[H + 12 >> 2]; + c[K >> 2] = c[L >> 2]; + c[K + 4 >> 2] = c[L + 4 >> 2]; + c[K + 8 >> 2] = c[L + 8 >> 2]; + c[K + 12 >> 2] = c[L + 12 >> 2]; + c[v >> 2] = c[M >> 2]; + c[v + 4 >> 2] = c[M + 4 >> 2]; + c[v + 8 >> 2] = c[M + 8 >> 2]; + c[v + 12 >> 2] = c[M + 12 >> 2]; + c[x >> 2] = c[N >> 2]; + c[x + 4 >> 2] = c[N + 4 >> 2]; + c[x + 8 >> 2] = c[N + 8 >> 2]; + c[x + 12 >> 2] = c[N + 12 >> 2]; + c[z >> 2] = c[O >> 2]; + c[z + 4 >> 2] = c[O + 4 >> 2]; + c[z + 8 >> 2] = c[O + 8 >> 2]; + c[z + 12 >> 2] = c[O + 12 >> 2]; + c[B >> 2] = c[P >> 2]; + c[B + 4 >> 2] = c[P + 4 >> 2]; + c[B + 8 >> 2] = c[P + 8 >> 2]; + c[B + 12 >> 2] = c[P + 12 >> 2]; + c[D >> 2] = c[Q >> 2]; + c[D + 4 >> 2] = c[Q + 4 >> 2]; + c[D + 8 >> 2] = c[Q + 8 >> 2]; + c[D + 12 >> 2] = c[Q + 12 >> 2]; + c[F >> 2] = c[R >> 2]; + c[F + 4 >> 2] = c[R + 4 >> 2]; + c[F + 8 >> 2] = c[R + 8 >> 2]; + c[F + 12 >> 2] = c[R + 12 >> 2]; + d2(n); + d2(o); + d2(s); + d2(t); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d5(n, 8); + d5(o, 8); + d5(p, 8); + d5(q, 8); + d5(r, 8); + d5(s, 8); + d5(t, 8); + d5(u, 8); + d_(e, n); + d_(f, o); + d_(h, p); + d_(g, q); + d_(l, r); + d_(k, s); + d_(j, t); + d_(m, u); + d3(e, 110888); + d3(f, 110888); + d3(j, 110888); + d3(l, 110888); + d3(h, 110888); + d3(m, 110888); + d3(g, 110888); + d3(k, 110888); + k = a + 1280 | 0; + c[k >> 2] = c[w >> 2]; + c[k + 4 >> 2] = c[w + 4 >> 2]; + c[k + 8 >> 2] = c[w + 8 >> 2]; + c[k + 12 >> 2] = c[w + 12 >> 2]; + w = a + 1296 | 0; + c[w >> 2] = c[b >> 2]; + c[w + 4 >> 2] = c[b + 4 >> 2]; + c[w + 8 >> 2] = c[b + 8 >> 2]; + c[w + 12 >> 2] = c[b + 12 >> 2]; + b = a + 1312 | 0; + c[b >> 2] = c[A >> 2]; + c[b + 4 >> 2] = c[A + 4 >> 2]; + c[b + 8 >> 2] = c[A + 8 >> 2]; + c[b + 12 >> 2] = c[A + 12 >> 2]; + A = a + 1328 | 0; + c[A >> 2] = c[y >> 2]; + c[A + 4 >> 2] = c[y + 4 >> 2]; + c[A + 8 >> 2] = c[y + 8 >> 2]; + c[A + 12 >> 2] = c[y + 12 >> 2]; + y = a + 1344 | 0; + c[y >> 2] = c[G >> 2]; + c[y + 4 >> 2] = c[G + 4 >> 2]; + c[y + 8 >> 2] = c[G + 8 >> 2]; + c[y + 12 >> 2] = c[G + 12 >> 2]; + G = a + 1360 | 0; + c[G >> 2] = c[E >> 2]; + c[G + 4 >> 2] = c[E + 4 >> 2]; + c[G + 8 >> 2] = c[E + 8 >> 2]; + c[G + 12 >> 2] = c[E + 12 >> 2]; + E = a + 1376 | 0; + c[E >> 2] = c[C >> 2]; + c[E + 4 >> 2] = c[C + 4 >> 2]; + c[E + 8 >> 2] = c[C + 8 >> 2]; + c[E + 12 >> 2] = c[C + 12 >> 2]; + C = a + 1392 | 0; + c[C >> 2] = c[I >> 2]; + c[C + 4 >> 2] = c[I + 4 >> 2]; + c[C + 8 >> 2] = c[I + 8 >> 2]; + c[C + 12 >> 2] = c[I + 12 >> 2]; + i = d; + return 0; +} +function dU(a) { + a = a | 0; + return (d[a + 2 | 0] | 0) << 8 | (d[a + 3 | 0] | 0) | (d[a + 1 | 0] | 0) << 16 | (d[a] | 0) << 24 | 0; +} +function dV(b, c) { + b = b | 0; + c = c | 0; + a[b + 3 | 0] = c & 255; + a[b + 2 | 0] = c >>> 8 & 255; + a[b + 1 | 0] = c >>> 16 & 255; + a[b] = c >>> 24 & 255; + return; +} +function dW(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function dX(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function dY(a) { + a = a | 0; + var b = 0, c = 0, e = 0; + b = d[a + 1 | 0] | 0; + c = d[a + 2 | 0] | 0; + e = d[a + 3 | 0] | 0; + return (H = 0 << 8 | b >>> 24 | (0 << 16 | c >>> 16) | (0 << 24 | e >>> 8) | (d[a + 4 | 0] | 0) | ((d[a + 5 | 0] | 0) << 8 | 0 >>> 24) | ((d[a + 6 | 0] | 0) << 16 | 0 >>> 16) | ((d[a + 7 | 0] | 0) << 24 | 0 >>> 8), b << 8 | 0 >>> 24 | (d[a] | 0) | (c << 16 | 0 >>> 16) | (e << 24 | 0 >>> 8) | (0 << 8 | 0 >>> 24) | (0 << 16 | 0 >>> 16) | (0 << 24 | 0 >>> 8)) | 0; +} +function dZ(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + a[b] = c & 255; + a[b + 1 | 0] = (c >>> 8 | d << 24) & 255; + a[b + 2 | 0] = (c >>> 16 | d << 16) & 255; + a[b + 3 | 0] = (c >>> 24 | d << 8) & 255; + a[b + 4 | 0] = d & 255; + a[b + 5 | 0] = (d >>> 8 | 0 << 24) & 255; + a[b + 6 | 0] = (d >>> 16 | 0 << 16) & 255; + a[b + 7 | 0] = (d >>> 24 | 0 << 8) & 255; + return; +} +function d_(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = b | 0; + e = a | 0; + f = c[e + 4 >> 2] ^ c[d + 4 >> 2]; + c[e >> 2] = c[e >> 2] ^ c[d >> 2]; + c[e + 4 >> 2] = f; + f = b + 8 | 0; + b = a + 8 | 0; + a = c[b + 4 >> 2] ^ c[f + 4 >> 2]; + c[b >> 2] = c[b >> 2] ^ c[f >> 2]; + c[b + 4 >> 2] = a; + return; +} +function d$(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = b | 0; + e = a | 0; + f = c[e + 4 >> 2] & c[d + 4 >> 2]; + c[e >> 2] = c[e >> 2] & c[d >> 2]; + c[e + 4 >> 2] = f; + f = b + 8 | 0; + b = a + 8 | 0; + a = c[b + 4 >> 2] & c[f + 4 >> 2]; + c[b >> 2] = c[b >> 2] & c[f >> 2]; + c[b + 4 >> 2] = a; + return; +} +function d0(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = b | 0; + e = a | 0; + f = c[e + 4 >> 2] | c[d + 4 >> 2]; + c[e >> 2] = c[e >> 2] | c[d >> 2]; + c[e + 4 >> 2] = f; + f = b + 8 | 0; + b = a + 8 | 0; + a = c[b + 4 >> 2] | c[f + 4 >> 2]; + c[b >> 2] = c[b >> 2] | c[f >> 2]; + c[b + 4 >> 2] = a; + return; +} +function d1(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = b | 0; + e = c[d + 4 >> 2] | 0; + f = a | 0; + c[f >> 2] = c[d >> 2]; + c[f + 4 >> 2] = e; + e = b + 8 | 0; + b = c[e + 4 >> 2] | 0; + f = a + 8 | 0; + c[f >> 2] = c[e >> 2]; + c[f + 4 >> 2] = b; + return; +} +function d2(a) { + a = a | 0; + var b = 0, d = 0; + b = a | 0; + d = ~c[b + 4 >> 2]; + c[b >> 2] = ~c[b >> 2]; + c[b + 4 >> 2] = d; + d = a + 8 | 0; + a = ~c[d + 4 >> 2]; + c[d >> 2] = ~c[d >> 2]; + c[d + 4 >> 2] = a; + return; +} +function d3(b, c) { + b = b | 0; + c = c | 0; + var e = 0, f = 0, g = 0, h = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + d1(f, b); + g = b; + h = f; + a[g] = a[h + (d[c] | 0) | 0] | 0; + a[g + 1 | 0] = a[h + (d[c + 1 | 0] | 0) | 0] | 0; + a[g + 2 | 0] = a[h + (d[c + 2 | 0] | 0) | 0] | 0; + a[g + 3 | 0] = a[h + (d[c + 3 | 0] | 0) | 0] | 0; + a[g + 4 | 0] = a[h + (d[c + 4 | 0] | 0) | 0] | 0; + a[g + 5 | 0] = a[h + (d[c + 5 | 0] | 0) | 0] | 0; + a[g + 6 | 0] = a[h + (d[c + 6 | 0] | 0) | 0] | 0; + a[g + 7 | 0] = a[h + (d[c + 7 | 0] | 0) | 0] | 0; + a[b + 8 | 0] = a[h + (d[c + 8 | 0] | 0) | 0] | 0; + a[g + 9 | 0] = a[h + (d[c + 9 | 0] | 0) | 0] | 0; + a[g + 10 | 0] = a[h + (d[c + 10 | 0] | 0) | 0] | 0; + a[g + 11 | 0] = a[h + (d[c + 11 | 0] | 0) | 0] | 0; + a[g + 12 | 0] = a[h + (d[c + 12 | 0] | 0) | 0] | 0; + a[g + 13 | 0] = a[h + (d[c + 13 | 0] | 0) | 0] | 0; + a[g + 14 | 0] = a[h + (d[c + 14 | 0] | 0) | 0] | 0; + a[g + 15 | 0] = a[h + (d[c + 15 | 0] | 0) | 0] | 0; + i = e; + return; +} +function d4(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + g = f; + h = b; + c[g >> 2] = c[h + ((d & 3) << 2) >> 2]; + c[g + 4 >> 2] = c[h + ((d >>> 2 & 3) << 2) >> 2]; + c[f + 8 >> 2] = c[h + ((d >>> 4 & 3) << 2) >> 2]; + c[g + 12 >> 2] = c[h + ((d >>> 6 & 3) << 2) >> 2]; + d1(a, f); + i = e; + return; +} +function d5(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0; + c = a; + dX(c, (dW(c) | 0) >>> (b >>> 0)); + d = c + 4 | 0; + dX(d, (dW(d) | 0) >>> (b >>> 0)); + d = a + 8 | 0; + dX(d, (dW(d) | 0) >>> (b >>> 0)); + d = c + 12 | 0; + dX(d, (dW(d) | 0) >>> (b >>> 0)); + return; +} +function d6(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0; + c = a; + d = dY(c) | 0; + e = b; + b = fs(d | 0, H | 0, e | 0) | 0; + d = H; + dZ(c, b, d); + d = a + 8 | 0; + a = dY(d) | 0; + b = fs(a | 0, H | 0, e | 0) | 0; + e = H; + dZ(d, b, e); + return; +} +function d7(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0; + c = a; + d = dY(c) | 0; + e = b; + b = fr(d | 0, H | 0, e | 0) | 0; + d = H; + dZ(c, b, d); + d = a + 8 | 0; + a = dY(d) | 0; + b = fr(a | 0, H | 0, e | 0) | 0; + e = H; + dZ(d, b, e); + return; +} +function d8(a) { + a = a | 0; + var b = 0; + b = a + 12 | 0; + dX(b, ~(dW(b) | 0)); + return; +} +function d9(a, b) { + a = a | 0; + b = b | 0; + var c = 0; + c = a + 12 | 0; + dX(c, (dW(c) | 0) + b | 0); + return; +} +function ea(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 1408 | 0; + g = f | 0; + dT(g, e) | 0; + dS(a, b, c, d, g) | 0; + i = f; + return 0; +} +function eb(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0; + g = i; + i = i + 1408 | 0; + h = g | 0; + dT(h, f) | 0; + ec(a, b, c, d, e, h) | 0; + i = g; + return 0; +} +function ec(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0, ae = 0, af = 0, ag = 0, ah = 0, ai = 0, aj = 0, ak = 0, al = 0, am = 0, an = 0, ao = 0, ap = 0, aq = 0, ar = 0, as = 0, at = 0, au = 0, av = 0, aw = 0, ax = 0, ay = 0, az = 0, aA = 0, aB = 0, aC = 0, aD = 0, aE = 0, aF = 0, aG = 0, aH = 0, aI = 0, aJ = 0, aK = 0, aL = 0, aM = 0, aN = 0, aO = 0, aP = 0, aQ = 0, aR = 0, aS = 0, aT = 0, aU = 0, aV = 0, aW = 0, aX = 0, aY = 0, aZ = 0, a_ = 0, a$ = 0, a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0, a7 = 0, a8 = 0, a9 = 0, ba = 0, bb = 0, bc = 0, bd = 0, be = 0, bf = 0, bg = 0, bh = 0, bi = 0, bj = 0, bk = 0, bl = 0, bm = 0, bn = 0; + j = i; + i = i + 400 | 0; + k = j | 0; + l = j + 16 | 0; + m = j + 32 | 0; + n = j + 48 | 0; + o = j + 64 | 0; + p = j + 80 | 0; + q = j + 96 | 0; + r = j + 112 | 0; + s = j + 128 | 0; + t = j + 144 | 0; + u = j + 160 | 0; + v = j + 176 | 0; + w = j + 192 | 0; + x = j + 208 | 0; + y = j + 224 | 0; + z = j + 240 | 0; + A = j + 256 | 0; + B = j + 272 | 0; + d1(A, g); + g = A; + A = k; + C = h; + D = h + 16 | 0; + E = h + 32 | 0; + F = h + 48 | 0; + G = h + 64 | 0; + I = h + 80 | 0; + J = h + 96 | 0; + K = h + 112 | 0; + L = h + 128 | 0; + M = h + 144 | 0; + N = h + 160 | 0; + O = h + 176 | 0; + P = h + 192 | 0; + Q = h + 208 | 0; + R = h + 224 | 0; + S = h + 240 | 0; + T = h + 256 | 0; + U = h + 272 | 0; + V = h + 288 | 0; + W = h + 304 | 0; + X = h + 320 | 0; + Y = h + 336 | 0; + Z = h + 352 | 0; + _ = h + 368 | 0; + $ = h + 384 | 0; + aa = h + 400 | 0; + ab = h + 416 | 0; + ac = h + 432 | 0; + ad = h + 448 | 0; + ae = h + 464 | 0; + af = h + 480 | 0; + ag = h + 496 | 0; + ah = h + 512 | 0; + ai = h + 528 | 0; + aj = h + 544 | 0; + ak = h + 560 | 0; + al = h + 576 | 0; + am = h + 592 | 0; + an = h + 608 | 0; + ao = h + 624 | 0; + ap = h + 640 | 0; + aq = h + 656 | 0; + ar = h + 672 | 0; + as = h + 688 | 0; + at = h + 704 | 0; + au = h + 720 | 0; + av = h + 736 | 0; + aw = h + 752 | 0; + ax = h + 768 | 0; + ay = h + 784 | 0; + az = h + 800 | 0; + aA = h + 816 | 0; + aB = h + 832 | 0; + aC = h + 848 | 0; + aD = h + 864 | 0; + aE = h + 880 | 0; + aF = h + 896 | 0; + aG = h + 912 | 0; + aH = h + 928 | 0; + aI = h + 944 | 0; + aJ = h + 960 | 0; + aK = h + 976 | 0; + aL = h + 992 | 0; + aM = h + 1008 | 0; + aN = h + 1024 | 0; + aO = h + 1040 | 0; + aP = h + 1056 | 0; + aQ = h + 1072 | 0; + aR = h + 1088 | 0; + aS = h + 1104 | 0; + aT = h + 1120 | 0; + aU = h + 1136 | 0; + aV = h + 1152 | 0; + aW = h + 1168 | 0; + aX = h + 1184 | 0; + aY = h + 1200 | 0; + aZ = h + 1216 | 0; + a_ = h + 1232 | 0; + a$ = h + 1248 | 0; + a0 = h + 1264 | 0; + a1 = h + 1280 | 0; + a2 = h + 1296 | 0; + a3 = h + 1312 | 0; + a4 = h + 1328 | 0; + a5 = h + 1344 | 0; + a6 = h + 1360 | 0; + a7 = h + 1376 | 0; + a8 = h + 1392 | 0; + h = g + 12 | 0; + a9 = s; + ba = t; + bb = w; + bc = y; + bd = v; + be = z; + bf = u; + bg = x; + bh = b; + b = d; + d = f; + f = e; + while (1) { + c[A >> 2] = c[g >> 2]; + c[A + 4 >> 2] = c[g + 4 >> 2]; + c[A + 8 >> 2] = c[g + 8 >> 2]; + c[A + 12 >> 2] = c[g + 12 >> 2]; + d1(l, k); + d3(l, 110808); + d1(m, l); + d1(n, l); + d1(o, l); + d1(p, l); + d1(q, l); + d1(r, l); + d9(l, 1); + d9(m, 2); + d9(n, 3); + d9(o, 4); + d9(p, 5); + d9(q, 6); + d9(r, 7); + d3(k, 110888); + d3(l, 110872); + d3(m, 110872); + d3(n, 110872); + d3(o, 110872); + d3(p, 110872); + d3(q, 110872); + d3(r, 110872); + d1(s, q); + d6(s, 1); + d_(s, r); + d$(s, 110952); + d_(r, s); + d7(s, 1); + d_(q, s); + d1(s, o); + d6(s, 1); + d_(s, p); + d$(s, 110952); + d_(p, s); + d7(s, 1); + d_(o, s); + d1(s, m); + d6(s, 1); + d_(s, n); + d$(s, 110952); + d_(n, s); + d7(s, 1); + d_(m, s); + d1(s, k); + d6(s, 1); + d_(s, l); + d$(s, 110952); + d_(l, s); + d7(s, 1); + d_(k, s); + d1(s, p); + d6(s, 2); + d_(s, r); + d$(s, 110936); + d_(r, s); + d7(s, 2); + d_(p, s); + d1(s, o); + d6(s, 2); + d_(s, q); + d$(s, 110936); + d_(q, s); + d7(s, 2); + d_(o, s); + d1(s, l); + d6(s, 2); + d_(s, n); + d$(s, 110936); + d_(n, s); + d7(s, 2); + d_(l, s); + d1(s, k); + d6(s, 2); + d_(s, m); + d$(s, 110936); + d_(m, s); + d7(s, 2); + d_(k, s); + d1(s, n); + d6(s, 4); + d_(s, r); + d$(s, 110920); + d_(r, s); + d7(s, 4); + d_(n, s); + d1(s, m); + d6(s, 4); + d_(s, q); + d$(s, 110920); + d_(q, s); + d7(s, 4); + d_(m, s); + d1(s, l); + d6(s, 4); + d_(s, p); + d$(s, 110920); + d_(p, s); + d7(s, 4); + d_(l, s); + d1(s, k); + d6(s, 4); + d_(s, o); + d$(s, 110920); + d_(o, s); + d7(s, 4); + d_(k, s); + d_(k, C); + d3(k, 110840); + d_(l, D); + d3(l, 110840); + d_(m, E); + d3(m, 110840); + d_(n, F); + d3(n, 110840); + d_(o, G); + d3(o, 110840); + d_(p, I); + d3(p, 110840); + d_(q, J); + d3(q, 110840); + d_(r, K); + d3(r, 110840); + d_(p, q); + d_(m, l); + d_(p, k); + d_(q, m); + d_(n, k); + d_(q, n); + d_(n, r); + d_(n, o); + d_(r, p); + d_(n, l); + d_(o, p); + d_(m, r); + d_(l, p); + d1(v, r); + d1(u, l); + d1(t, p); + d1(x, m); + d1(w, q); + d_(v, o); + d_(u, m); + d_(t, n); + d_(x, o); + d_(w, k); + d1(y, v); + d1(s, u); + d1(z, v); + d0(u, t); + d0(v, w); + d_(z, s); + d$(y, w); + d$(s, t); + d_(w, t); + d$(z, w); + d1(w, n); + d_(w, k); + d$(x, w); + d_(v, x); + d_(u, x); + d1(x, r); + d_(x, l); + d1(w, p); + d1(t, x); + d_(w, q); + d0(t, w); + d$(x, w); + d_(s, x); + d_(v, z); + d_(u, y); + d_(t, z); + d_(s, y); + d_(t, y); + d1(w, m); + d1(x, o); + d1(y, l); + d1(z, r); + d$(w, n); + d$(x, k); + d$(y, p); + d0(z, q); + d_(v, w); + d_(u, x); + d_(t, y); + d_(s, z); + d1(w, v); + d_(w, u); + d$(v, t); + d1(y, s); + d_(y, v); + d1(z, w); + d$(z, y); + d_(z, u); + d1(x, t); + d_(x, s); + d_(v, u); + d$(x, v); + d_(x, s); + d_(t, x); + d1(u, y); + d_(u, x); + d$(u, s); + d_(t, u); + d_(y, u); + d$(y, z); + d_(y, w); + d1(w, q); + d1(s, p); + d1(u, z); + d_(u, y); + d$(u, q); + d_(q, p); + d$(q, y); + d$(p, z); + d_(q, p); + d_(p, u); + d_(w, k); + d_(s, n); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, k); + d_(k, n); + d$(k, t); + d$(n, x); + d_(k, n); + d_(n, u); + d_(q, w); + d_(k, w); + d_(p, s); + d_(n, s); + d1(w, r); + d1(s, l); + d_(w, o); + d_(s, m); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, o); + d_(o, m); + d$(o, t); + d$(m, x); + d_(o, m); + d_(m, u); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, r); + d_(r, l); + d$(r, y); + d$(l, z); + d_(r, l); + d_(l, v); + d_(r, w); + d_(o, w); + d_(l, s); + d_(m, s); + d_(r, k); + d_(l, q); + d_(o, r); + d_(q, k); + d_(k, l); + d_(l, p); + d_(p, m); + d_(o, p); + d_(m, n); + d_(n, p); + d_(q, n); + d4(s, k, 147); + d4(t, l, 147); + d4(u, o, 147); + d4(v, q, 147); + d4(w, n, 147); + d4(x, r, 147); + d4(y, m, 147); + d4(z, p, 147); + d_(k, s); + d_(l, t); + d_(o, u); + d_(q, v); + d_(n, w); + d_(r, x); + d_(m, y); + d_(p, z); + d_(s, p); + d_(t, k); + d_(u, l); + d_(t, p); + d_(v, o); + d_(w, q); + d_(x, n); + d_(v, p); + d_(y, r); + d_(z, m); + d_(w, p); + d4(k, k, 78); + d4(l, l, 78); + d4(o, o, 78); + d4(q, q, 78); + d4(n, n, 78); + d4(r, r, 78); + d4(m, m, 78); + d4(p, p, 78); + d_(s, k); + d_(t, l); + d_(u, o); + d_(v, q); + d_(w, n); + d_(x, r); + d_(y, m); + d_(z, p); + d_(s, L); + d3(s, 110840); + d_(t, M); + d3(t, 110840); + d_(u, N); + d3(u, 110840); + d_(v, O); + d3(v, 110840); + d_(w, P); + d3(w, 110840); + d_(x, Q); + d3(x, 110840); + d_(y, R); + d3(y, 110840); + d_(z, S); + d3(z, 110840); + d_(x, y); + d_(u, t); + d_(x, s); + d_(y, u); + d_(v, s); + d_(y, v); + d_(v, z); + d_(v, w); + d_(z, x); + d_(v, t); + d_(w, x); + d_(u, z); + d_(t, x); + d1(n, z); + d1(m, t); + d1(l, x); + d1(p, u); + d1(o, y); + d_(n, w); + d_(m, u); + d_(l, v); + d_(p, w); + d_(o, s); + d1(q, n); + d1(k, m); + d1(r, n); + d0(m, l); + d0(n, o); + d_(r, k); + d$(q, o); + d$(k, l); + d_(o, l); + d$(r, o); + d1(o, v); + d_(o, s); + d$(p, o); + d_(n, p); + d_(m, p); + d1(p, z); + d_(p, t); + d1(o, x); + d1(l, p); + d_(o, y); + d0(l, o); + d$(p, o); + d_(k, p); + d_(n, r); + d_(m, q); + d_(l, r); + d_(k, q); + d_(l, q); + d1(o, u); + d1(p, w); + d1(q, t); + d1(r, z); + d$(o, v); + d$(p, s); + d$(q, x); + d0(r, y); + d_(n, o); + d_(m, p); + d_(l, q); + d_(k, r); + d1(o, n); + d_(o, m); + d$(n, l); + d1(q, k); + d_(q, n); + d1(r, o); + d$(r, q); + d_(r, m); + d1(p, l); + d_(p, k); + d_(n, m); + d$(p, n); + d_(p, k); + d_(l, p); + d1(m, q); + d_(m, p); + d$(m, k); + d_(l, m); + d_(q, m); + d$(q, r); + d_(q, o); + d1(o, y); + d1(k, x); + d1(m, r); + d_(m, q); + d$(m, y); + d_(y, x); + d$(y, q); + d$(x, r); + d_(y, x); + d_(x, m); + d_(o, s); + d_(k, v); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, s); + d_(s, v); + d$(s, l); + d$(v, p); + d_(s, v); + d_(v, m); + d_(y, o); + d_(s, o); + d_(x, k); + d_(v, k); + d1(o, z); + d1(k, t); + d_(o, w); + d_(k, u); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, w); + d_(w, u); + d$(w, l); + d$(u, p); + d_(w, u); + d_(u, m); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, z); + d_(z, t); + d$(z, q); + d$(t, r); + d_(z, t); + d_(t, n); + d_(z, o); + d_(w, o); + d_(t, k); + d_(u, k); + d_(z, s); + d_(t, y); + d_(w, z); + d_(y, s); + d_(s, t); + d_(t, x); + d_(x, u); + d_(w, x); + d_(u, v); + d_(v, x); + d_(y, v); + d4(k, s, 147); + d4(l, t, 147); + d4(m, w, 147); + d4(n, y, 147); + d4(o, v, 147); + d4(p, z, 147); + d4(q, u, 147); + d4(r, x, 147); + d_(s, k); + d_(t, l); + d_(w, m); + d_(y, n); + d_(v, o); + d_(z, p); + d_(u, q); + d_(x, r); + d_(k, x); + d_(l, s); + d_(m, t); + d_(l, x); + d_(n, w); + d_(o, y); + d_(p, v); + d_(n, x); + d_(q, z); + d_(r, u); + d_(o, x); + d4(s, s, 78); + d4(t, t, 78); + d4(w, w, 78); + d4(y, y, 78); + d4(v, v, 78); + d4(z, z, 78); + d4(u, u, 78); + d4(x, x, 78); + d_(k, s); + d_(l, t); + d_(m, w); + d_(n, y); + d_(o, v); + d_(p, z); + d_(q, u); + d_(r, x); + d_(k, T); + d3(k, 110840); + d_(l, U); + d3(l, 110840); + d_(m, V); + d3(m, 110840); + d_(n, W); + d3(n, 110840); + d_(o, X); + d3(o, 110840); + d_(p, Y); + d3(p, 110840); + d_(q, Z); + d3(q, 110840); + d_(r, _); + d3(r, 110840); + d_(p, q); + d_(m, l); + d_(p, k); + d_(q, m); + d_(n, k); + d_(q, n); + d_(n, r); + d_(n, o); + d_(r, p); + d_(n, l); + d_(o, p); + d_(m, r); + d_(l, p); + d1(v, r); + d1(u, l); + d1(t, p); + d1(x, m); + d1(w, q); + d_(v, o); + d_(u, m); + d_(t, n); + d_(x, o); + d_(w, k); + d1(y, v); + d1(s, u); + d1(z, v); + d0(u, t); + d0(v, w); + d_(z, s); + d$(y, w); + d$(s, t); + d_(w, t); + d$(z, w); + d1(w, n); + d_(w, k); + d$(x, w); + d_(v, x); + d_(u, x); + d1(x, r); + d_(x, l); + d1(w, p); + d1(t, x); + d_(w, q); + d0(t, w); + d$(x, w); + d_(s, x); + d_(v, z); + d_(u, y); + d_(t, z); + d_(s, y); + d_(t, y); + d1(w, m); + d1(x, o); + d1(y, l); + d1(z, r); + d$(w, n); + d$(x, k); + d$(y, p); + d0(z, q); + d_(v, w); + d_(u, x); + d_(t, y); + d_(s, z); + d1(w, v); + d_(w, u); + d$(v, t); + d1(y, s); + d_(y, v); + d1(z, w); + d$(z, y); + d_(z, u); + d1(x, t); + d_(x, s); + d_(v, u); + d$(x, v); + d_(x, s); + d_(t, x); + d1(u, y); + d_(u, x); + d$(u, s); + d_(t, u); + d_(y, u); + d$(y, z); + d_(y, w); + d1(w, q); + d1(s, p); + d1(u, z); + d_(u, y); + d$(u, q); + d_(q, p); + d$(q, y); + d$(p, z); + d_(q, p); + d_(p, u); + d_(w, k); + d_(s, n); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, k); + d_(k, n); + d$(k, t); + d$(n, x); + d_(k, n); + d_(n, u); + d_(q, w); + d_(k, w); + d_(p, s); + d_(n, s); + d1(w, r); + d1(s, l); + d_(w, o); + d_(s, m); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, o); + d_(o, m); + d$(o, t); + d$(m, x); + d_(o, m); + d_(m, u); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, r); + d_(r, l); + d$(r, y); + d$(l, z); + d_(r, l); + d_(l, v); + d_(r, w); + d_(o, w); + d_(l, s); + d_(m, s); + d_(r, k); + d_(l, q); + d_(o, r); + d_(q, k); + d_(k, l); + d_(l, p); + d_(p, m); + d_(o, p); + d_(m, n); + d_(n, p); + d_(q, n); + d4(s, k, 147); + d4(t, l, 147); + d4(u, o, 147); + d4(v, q, 147); + d4(w, n, 147); + d4(x, r, 147); + d4(y, m, 147); + d4(z, p, 147); + d_(k, s); + d_(l, t); + d_(o, u); + d_(q, v); + d_(n, w); + d_(r, x); + d_(m, y); + d_(p, z); + d_(s, p); + d_(t, k); + d_(u, l); + d_(t, p); + d_(v, o); + d_(w, q); + d_(x, n); + d_(v, p); + d_(y, r); + d_(z, m); + d_(w, p); + d4(k, k, 78); + d4(l, l, 78); + d4(o, o, 78); + d4(q, q, 78); + d4(n, n, 78); + d4(r, r, 78); + d4(m, m, 78); + d4(p, p, 78); + d_(s, k); + d_(t, l); + d_(u, o); + d_(v, q); + d_(w, n); + d_(x, r); + d_(y, m); + d_(z, p); + d_(s, $); + d3(s, 110840); + d_(t, aa); + d3(t, 110840); + d_(u, ab); + d3(u, 110840); + d_(v, ac); + d3(v, 110840); + d_(w, ad); + d3(w, 110840); + d_(x, ae); + d3(x, 110840); + d_(y, af); + d3(y, 110840); + d_(z, ag); + d3(z, 110840); + d_(x, y); + d_(u, t); + d_(x, s); + d_(y, u); + d_(v, s); + d_(y, v); + d_(v, z); + d_(v, w); + d_(z, x); + d_(v, t); + d_(w, x); + d_(u, z); + d_(t, x); + d1(n, z); + d1(m, t); + d1(l, x); + d1(p, u); + d1(o, y); + d_(n, w); + d_(m, u); + d_(l, v); + d_(p, w); + d_(o, s); + d1(q, n); + d1(k, m); + d1(r, n); + d0(m, l); + d0(n, o); + d_(r, k); + d$(q, o); + d$(k, l); + d_(o, l); + d$(r, o); + d1(o, v); + d_(o, s); + d$(p, o); + d_(n, p); + d_(m, p); + d1(p, z); + d_(p, t); + d1(o, x); + d1(l, p); + d_(o, y); + d0(l, o); + d$(p, o); + d_(k, p); + d_(n, r); + d_(m, q); + d_(l, r); + d_(k, q); + d_(l, q); + d1(o, u); + d1(p, w); + d1(q, t); + d1(r, z); + d$(o, v); + d$(p, s); + d$(q, x); + d0(r, y); + d_(n, o); + d_(m, p); + d_(l, q); + d_(k, r); + d1(o, n); + d_(o, m); + d$(n, l); + d1(q, k); + d_(q, n); + d1(r, o); + d$(r, q); + d_(r, m); + d1(p, l); + d_(p, k); + d_(n, m); + d$(p, n); + d_(p, k); + d_(l, p); + d1(m, q); + d_(m, p); + d$(m, k); + d_(l, m); + d_(q, m); + d$(q, r); + d_(q, o); + d1(o, y); + d1(k, x); + d1(m, r); + d_(m, q); + d$(m, y); + d_(y, x); + d$(y, q); + d$(x, r); + d_(y, x); + d_(x, m); + d_(o, s); + d_(k, v); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, s); + d_(s, v); + d$(s, l); + d$(v, p); + d_(s, v); + d_(v, m); + d_(y, o); + d_(s, o); + d_(x, k); + d_(v, k); + d1(o, z); + d1(k, t); + d_(o, w); + d_(k, u); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, w); + d_(w, u); + d$(w, l); + d$(u, p); + d_(w, u); + d_(u, m); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, z); + d_(z, t); + d$(z, q); + d$(t, r); + d_(z, t); + d_(t, n); + d_(z, o); + d_(w, o); + d_(t, k); + d_(u, k); + d_(z, s); + d_(t, y); + d_(w, z); + d_(y, s); + d_(s, t); + d_(t, x); + d_(x, u); + d_(w, x); + d_(u, v); + d_(v, x); + d_(y, v); + d4(k, s, 147); + d4(l, t, 147); + d4(m, w, 147); + d4(n, y, 147); + d4(o, v, 147); + d4(p, z, 147); + d4(q, u, 147); + d4(r, x, 147); + d_(s, k); + d_(t, l); + d_(w, m); + d_(y, n); + d_(v, o); + d_(z, p); + d_(u, q); + d_(x, r); + d_(k, x); + d_(l, s); + d_(m, t); + d_(l, x); + d_(n, w); + d_(o, y); + d_(p, v); + d_(n, x); + d_(q, z); + d_(r, u); + d_(o, x); + d4(s, s, 78); + d4(t, t, 78); + d4(w, w, 78); + d4(y, y, 78); + d4(v, v, 78); + d4(z, z, 78); + d4(u, u, 78); + d4(x, x, 78); + d_(k, s); + d_(l, t); + d_(m, w); + d_(n, y); + d_(o, v); + d_(p, z); + d_(q, u); + d_(r, x); + d_(k, ah); + d3(k, 110840); + d_(l, ai); + d3(l, 110840); + d_(m, aj); + d3(m, 110840); + d_(n, ak); + d3(n, 110840); + d_(o, al); + d3(o, 110840); + d_(p, am); + d3(p, 110840); + d_(q, an); + d3(q, 110840); + d_(r, ao); + d3(r, 110840); + d_(p, q); + d_(m, l); + d_(p, k); + d_(q, m); + d_(n, k); + d_(q, n); + d_(n, r); + d_(n, o); + d_(r, p); + d_(n, l); + d_(o, p); + d_(m, r); + d_(l, p); + d1(v, r); + d1(u, l); + d1(t, p); + d1(x, m); + d1(w, q); + d_(v, o); + d_(u, m); + d_(t, n); + d_(x, o); + d_(w, k); + d1(y, v); + d1(s, u); + d1(z, v); + d0(u, t); + d0(v, w); + d_(z, s); + d$(y, w); + d$(s, t); + d_(w, t); + d$(z, w); + d1(w, n); + d_(w, k); + d$(x, w); + d_(v, x); + d_(u, x); + d1(x, r); + d_(x, l); + d1(w, p); + d1(t, x); + d_(w, q); + d0(t, w); + d$(x, w); + d_(s, x); + d_(v, z); + d_(u, y); + d_(t, z); + d_(s, y); + d_(t, y); + d1(w, m); + d1(x, o); + d1(y, l); + d1(z, r); + d$(w, n); + d$(x, k); + d$(y, p); + d0(z, q); + d_(v, w); + d_(u, x); + d_(t, y); + d_(s, z); + d1(w, v); + d_(w, u); + d$(v, t); + d1(y, s); + d_(y, v); + d1(z, w); + d$(z, y); + d_(z, u); + d1(x, t); + d_(x, s); + d_(v, u); + d$(x, v); + d_(x, s); + d_(t, x); + d1(u, y); + d_(u, x); + d$(u, s); + d_(t, u); + d_(y, u); + d$(y, z); + d_(y, w); + d1(w, q); + d1(s, p); + d1(u, z); + d_(u, y); + d$(u, q); + d_(q, p); + d$(q, y); + d$(p, z); + d_(q, p); + d_(p, u); + d_(w, k); + d_(s, n); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, k); + d_(k, n); + d$(k, t); + d$(n, x); + d_(k, n); + d_(n, u); + d_(q, w); + d_(k, w); + d_(p, s); + d_(n, s); + d1(w, r); + d1(s, l); + d_(w, o); + d_(s, m); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, o); + d_(o, m); + d$(o, t); + d$(m, x); + d_(o, m); + d_(m, u); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, r); + d_(r, l); + d$(r, y); + d$(l, z); + d_(r, l); + d_(l, v); + d_(r, w); + d_(o, w); + d_(l, s); + d_(m, s); + d_(r, k); + d_(l, q); + d_(o, r); + d_(q, k); + d_(k, l); + d_(l, p); + d_(p, m); + d_(o, p); + d_(m, n); + d_(n, p); + d_(q, n); + d4(s, k, 147); + d4(t, l, 147); + d4(u, o, 147); + d4(v, q, 147); + d4(w, n, 147); + d4(x, r, 147); + d4(y, m, 147); + d4(z, p, 147); + d_(k, s); + d_(l, t); + d_(o, u); + d_(q, v); + d_(n, w); + d_(r, x); + d_(m, y); + d_(p, z); + d_(s, p); + d_(t, k); + d_(u, l); + d_(t, p); + d_(v, o); + d_(w, q); + d_(x, n); + d_(v, p); + d_(y, r); + d_(z, m); + d_(w, p); + d4(k, k, 78); + d4(l, l, 78); + d4(o, o, 78); + d4(q, q, 78); + d4(n, n, 78); + d4(r, r, 78); + d4(m, m, 78); + d4(p, p, 78); + d_(s, k); + d_(t, l); + d_(u, o); + d_(v, q); + d_(w, n); + d_(x, r); + d_(y, m); + d_(z, p); + d_(s, ap); + d3(s, 110840); + d_(t, aq); + d3(t, 110840); + d_(u, ar); + d3(u, 110840); + d_(v, as); + d3(v, 110840); + d_(w, at); + d3(w, 110840); + d_(x, au); + d3(x, 110840); + d_(y, av); + d3(y, 110840); + d_(z, aw); + d3(z, 110840); + d_(x, y); + d_(u, t); + d_(x, s); + d_(y, u); + d_(v, s); + d_(y, v); + d_(v, z); + d_(v, w); + d_(z, x); + d_(v, t); + d_(w, x); + d_(u, z); + d_(t, x); + d1(n, z); + d1(m, t); + d1(l, x); + d1(p, u); + d1(o, y); + d_(n, w); + d_(m, u); + d_(l, v); + d_(p, w); + d_(o, s); + d1(q, n); + d1(k, m); + d1(r, n); + d0(m, l); + d0(n, o); + d_(r, k); + d$(q, o); + d$(k, l); + d_(o, l); + d$(r, o); + d1(o, v); + d_(o, s); + d$(p, o); + d_(n, p); + d_(m, p); + d1(p, z); + d_(p, t); + d1(o, x); + d1(l, p); + d_(o, y); + d0(l, o); + d$(p, o); + d_(k, p); + d_(n, r); + d_(m, q); + d_(l, r); + d_(k, q); + d_(l, q); + d1(o, u); + d1(p, w); + d1(q, t); + d1(r, z); + d$(o, v); + d$(p, s); + d$(q, x); + d0(r, y); + d_(n, o); + d_(m, p); + d_(l, q); + d_(k, r); + d1(o, n); + d_(o, m); + d$(n, l); + d1(q, k); + d_(q, n); + d1(r, o); + d$(r, q); + d_(r, m); + d1(p, l); + d_(p, k); + d_(n, m); + d$(p, n); + d_(p, k); + d_(l, p); + d1(m, q); + d_(m, p); + d$(m, k); + d_(l, m); + d_(q, m); + d$(q, r); + d_(q, o); + d1(o, y); + d1(k, x); + d1(m, r); + d_(m, q); + d$(m, y); + d_(y, x); + d$(y, q); + d$(x, r); + d_(y, x); + d_(x, m); + d_(o, s); + d_(k, v); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, s); + d_(s, v); + d$(s, l); + d$(v, p); + d_(s, v); + d_(v, m); + d_(y, o); + d_(s, o); + d_(x, k); + d_(v, k); + d1(o, z); + d1(k, t); + d_(o, w); + d_(k, u); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, w); + d_(w, u); + d$(w, l); + d$(u, p); + d_(w, u); + d_(u, m); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, z); + d_(z, t); + d$(z, q); + d$(t, r); + d_(z, t); + d_(t, n); + d_(z, o); + d_(w, o); + d_(t, k); + d_(u, k); + d_(z, s); + d_(t, y); + d_(w, z); + d_(y, s); + d_(s, t); + d_(t, x); + d_(x, u); + d_(w, x); + d_(u, v); + d_(v, x); + d_(y, v); + d4(k, s, 147); + d4(l, t, 147); + d4(m, w, 147); + d4(n, y, 147); + d4(o, v, 147); + d4(p, z, 147); + d4(q, u, 147); + d4(r, x, 147); + d_(s, k); + d_(t, l); + d_(w, m); + d_(y, n); + d_(v, o); + d_(z, p); + d_(u, q); + d_(x, r); + d_(k, x); + d_(l, s); + d_(m, t); + d_(l, x); + d_(n, w); + d_(o, y); + d_(p, v); + d_(n, x); + d_(q, z); + d_(r, u); + d_(o, x); + d4(s, s, 78); + d4(t, t, 78); + d4(w, w, 78); + d4(y, y, 78); + d4(v, v, 78); + d4(z, z, 78); + d4(u, u, 78); + d4(x, x, 78); + d_(k, s); + d_(l, t); + d_(m, w); + d_(n, y); + d_(o, v); + d_(p, z); + d_(q, u); + d_(r, x); + d_(k, ax); + d3(k, 110840); + d_(l, ay); + d3(l, 110840); + d_(m, az); + d3(m, 110840); + d_(n, aA); + d3(n, 110840); + d_(o, aB); + d3(o, 110840); + d_(p, aC); + d3(p, 110840); + d_(q, aD); + d3(q, 110840); + d_(r, aE); + d3(r, 110840); + d_(p, q); + d_(m, l); + d_(p, k); + d_(q, m); + d_(n, k); + d_(q, n); + d_(n, r); + d_(n, o); + d_(r, p); + d_(n, l); + d_(o, p); + d_(m, r); + d_(l, p); + d1(v, r); + d1(u, l); + d1(t, p); + d1(x, m); + d1(w, q); + d_(v, o); + d_(u, m); + d_(t, n); + d_(x, o); + d_(w, k); + d1(y, v); + d1(s, u); + d1(z, v); + d0(u, t); + d0(v, w); + d_(z, s); + d$(y, w); + d$(s, t); + d_(w, t); + d$(z, w); + d1(w, n); + d_(w, k); + d$(x, w); + d_(v, x); + d_(u, x); + d1(x, r); + d_(x, l); + d1(w, p); + d1(t, x); + d_(w, q); + d0(t, w); + d$(x, w); + d_(s, x); + d_(v, z); + d_(u, y); + d_(t, z); + d_(s, y); + d_(t, y); + d1(w, m); + d1(x, o); + d1(y, l); + d1(z, r); + d$(w, n); + d$(x, k); + d$(y, p); + d0(z, q); + d_(v, w); + d_(u, x); + d_(t, y); + d_(s, z); + d1(w, v); + d_(w, u); + d$(v, t); + d1(y, s); + d_(y, v); + d1(z, w); + d$(z, y); + d_(z, u); + d1(x, t); + d_(x, s); + d_(v, u); + d$(x, v); + d_(x, s); + d_(t, x); + d1(u, y); + d_(u, x); + d$(u, s); + d_(t, u); + d_(y, u); + d$(y, z); + d_(y, w); + d1(w, q); + d1(s, p); + d1(u, z); + d_(u, y); + d$(u, q); + d_(q, p); + d$(q, y); + d$(p, z); + d_(q, p); + d_(p, u); + d_(w, k); + d_(s, n); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, k); + d_(k, n); + d$(k, t); + d$(n, x); + d_(k, n); + d_(n, u); + d_(q, w); + d_(k, w); + d_(p, s); + d_(n, s); + d1(w, r); + d1(s, l); + d_(w, o); + d_(s, m); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, o); + d_(o, m); + d$(o, t); + d$(m, x); + d_(o, m); + d_(m, u); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, r); + d_(r, l); + d$(r, y); + d$(l, z); + d_(r, l); + d_(l, v); + d_(r, w); + d_(o, w); + d_(l, s); + d_(m, s); + d_(r, k); + d_(l, q); + d_(o, r); + d_(q, k); + d_(k, l); + d_(l, p); + d_(p, m); + d_(o, p); + d_(m, n); + d_(n, p); + d_(q, n); + d4(s, k, 147); + d4(t, l, 147); + d4(u, o, 147); + d4(v, q, 147); + d4(w, n, 147); + d4(x, r, 147); + d4(y, m, 147); + d4(z, p, 147); + d_(k, s); + d_(l, t); + d_(o, u); + d_(q, v); + d_(n, w); + d_(r, x); + d_(m, y); + d_(p, z); + d_(s, p); + d_(t, k); + d_(u, l); + d_(t, p); + d_(v, o); + d_(w, q); + d_(x, n); + d_(v, p); + d_(y, r); + d_(z, m); + d_(w, p); + d4(k, k, 78); + d4(l, l, 78); + d4(o, o, 78); + d4(q, q, 78); + d4(n, n, 78); + d4(r, r, 78); + d4(m, m, 78); + d4(p, p, 78); + d_(s, k); + d_(t, l); + d_(u, o); + d_(v, q); + d_(w, n); + d_(x, r); + d_(y, m); + d_(z, p); + d_(s, aF); + d3(s, 110840); + d_(t, aG); + d3(t, 110840); + d_(u, aH); + d3(u, 110840); + d_(v, aI); + d3(v, 110840); + d_(w, aJ); + d3(w, 110840); + d_(x, aK); + d3(x, 110840); + d_(y, aL); + d3(y, 110840); + d_(z, aM); + d3(z, 110840); + d_(x, y); + d_(u, t); + d_(x, s); + d_(y, u); + d_(v, s); + d_(y, v); + d_(v, z); + d_(v, w); + d_(z, x); + d_(v, t); + d_(w, x); + d_(u, z); + d_(t, x); + d1(n, z); + d1(m, t); + d1(l, x); + d1(p, u); + d1(o, y); + d_(n, w); + d_(m, u); + d_(l, v); + d_(p, w); + d_(o, s); + d1(q, n); + d1(k, m); + d1(r, n); + d0(m, l); + d0(n, o); + d_(r, k); + d$(q, o); + d$(k, l); + d_(o, l); + d$(r, o); + d1(o, v); + d_(o, s); + d$(p, o); + d_(n, p); + d_(m, p); + d1(p, z); + d_(p, t); + d1(o, x); + d1(l, p); + d_(o, y); + d0(l, o); + d$(p, o); + d_(k, p); + d_(n, r); + d_(m, q); + d_(l, r); + d_(k, q); + d_(l, q); + d1(o, u); + d1(p, w); + d1(q, t); + d1(r, z); + d$(o, v); + d$(p, s); + d$(q, x); + d0(r, y); + d_(n, o); + d_(m, p); + d_(l, q); + d_(k, r); + d1(o, n); + d_(o, m); + d$(n, l); + d1(q, k); + d_(q, n); + d1(r, o); + d$(r, q); + d_(r, m); + d1(p, l); + d_(p, k); + d_(n, m); + d$(p, n); + d_(p, k); + d_(l, p); + d1(m, q); + d_(m, p); + d$(m, k); + d_(l, m); + d_(q, m); + d$(q, r); + d_(q, o); + d1(o, y); + d1(k, x); + d1(m, r); + d_(m, q); + d$(m, y); + d_(y, x); + d$(y, q); + d$(x, r); + d_(y, x); + d_(x, m); + d_(o, s); + d_(k, v); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, s); + d_(s, v); + d$(s, l); + d$(v, p); + d_(s, v); + d_(v, m); + d_(y, o); + d_(s, o); + d_(x, k); + d_(v, k); + d1(o, z); + d1(k, t); + d_(o, w); + d_(k, u); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, w); + d_(w, u); + d$(w, l); + d$(u, p); + d_(w, u); + d_(u, m); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, z); + d_(z, t); + d$(z, q); + d$(t, r); + d_(z, t); + d_(t, n); + d_(z, o); + d_(w, o); + d_(t, k); + d_(u, k); + d_(z, s); + d_(t, y); + d_(w, z); + d_(y, s); + d_(s, t); + d_(t, x); + d_(x, u); + d_(w, x); + d_(u, v); + d_(v, x); + d_(y, v); + d4(k, s, 147); + d4(l, t, 147); + d4(m, w, 147); + d4(n, y, 147); + d4(o, v, 147); + d4(p, z, 147); + d4(q, u, 147); + d4(r, x, 147); + d_(s, k); + d_(t, l); + d_(w, m); + d_(y, n); + d_(v, o); + d_(z, p); + d_(u, q); + d_(x, r); + d_(k, x); + d_(l, s); + d_(m, t); + d_(l, x); + d_(n, w); + d_(o, y); + d_(p, v); + d_(n, x); + d_(q, z); + d_(r, u); + d_(o, x); + d4(s, s, 78); + d4(t, t, 78); + d4(w, w, 78); + d4(y, y, 78); + d4(v, v, 78); + d4(z, z, 78); + d4(u, u, 78); + d4(x, x, 78); + d_(k, s); + d_(l, t); + d_(m, w); + d_(n, y); + d_(o, v); + d_(p, z); + d_(q, u); + d_(r, x); + d_(k, aN); + d3(k, 110840); + d_(l, aO); + d3(l, 110840); + d_(m, aP); + d3(m, 110840); + d_(n, aQ); + d3(n, 110840); + d_(o, aR); + d3(o, 110840); + d_(p, aS); + d3(p, 110840); + d_(q, aT); + d3(q, 110840); + d_(r, aU); + d3(r, 110840); + d_(p, q); + d_(m, l); + d_(p, k); + d_(q, m); + d_(n, k); + d_(q, n); + d_(n, r); + d_(n, o); + d_(r, p); + d_(n, l); + d_(o, p); + d_(m, r); + d_(l, p); + d1(v, r); + d1(u, l); + d1(t, p); + d1(x, m); + d1(w, q); + d_(v, o); + d_(u, m); + d_(t, n); + d_(x, o); + d_(w, k); + d1(y, v); + d1(s, u); + d1(z, v); + d0(u, t); + d0(v, w); + d_(z, s); + d$(y, w); + d$(s, t); + d_(w, t); + d$(z, w); + d1(w, n); + d_(w, k); + d$(x, w); + d_(v, x); + d_(u, x); + d1(x, r); + d_(x, l); + d1(w, p); + d1(t, x); + d_(w, q); + d0(t, w); + d$(x, w); + d_(s, x); + d_(v, z); + d_(u, y); + d_(t, z); + d_(s, y); + d_(t, y); + d1(w, m); + d1(x, o); + d1(y, l); + d1(z, r); + d$(w, n); + d$(x, k); + d$(y, p); + d0(z, q); + d_(v, w); + d_(u, x); + d_(t, y); + d_(s, z); + d1(w, v); + d_(w, u); + d$(v, t); + d1(y, s); + d_(y, v); + d1(z, w); + d$(z, y); + d_(z, u); + d1(x, t); + d_(x, s); + d_(v, u); + d$(x, v); + d_(x, s); + d_(t, x); + d1(u, y); + d_(u, x); + d$(u, s); + d_(t, u); + d_(y, u); + d$(y, z); + d_(y, w); + d1(w, q); + d1(s, p); + d1(u, z); + d_(u, y); + d$(u, q); + d_(q, p); + d$(q, y); + d$(p, z); + d_(q, p); + d_(p, u); + d_(w, k); + d_(s, n); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, k); + d_(k, n); + d$(k, t); + d$(n, x); + d_(k, n); + d_(n, u); + d_(q, w); + d_(k, w); + d_(p, s); + d_(n, s); + d1(w, r); + d1(s, l); + d_(w, o); + d_(s, m); + d1(v, z); + d_(v, y); + d$(v, w); + d_(w, s); + d$(w, y); + d$(s, z); + d_(s, w); + d_(w, v); + d1(u, x); + d_(u, t); + d$(u, o); + d_(o, m); + d$(o, t); + d$(m, x); + d_(o, m); + d_(m, u); + d_(z, x); + d_(y, t); + d1(v, z); + d_(v, y); + d$(v, r); + d_(r, l); + d$(r, y); + d$(l, z); + d_(r, l); + d_(l, v); + d_(r, w); + d_(o, w); + d_(l, s); + d_(m, s); + d_(r, k); + d_(l, q); + d_(o, r); + d_(q, k); + d_(k, l); + d_(l, p); + d_(p, m); + d_(o, p); + d_(m, n); + d_(n, p); + d_(q, n); + d4(s, k, 147); + d4(t, l, 147); + d4(u, o, 147); + d4(v, q, 147); + d4(w, n, 147); + d4(x, r, 147); + d4(y, m, 147); + d4(z, p, 147); + d_(k, s); + d_(l, t); + d_(o, u); + d_(q, v); + d_(n, w); + d_(r, x); + d_(m, y); + d_(p, z); + d_(s, p); + d_(t, k); + d_(u, l); + d_(t, p); + d_(v, o); + d_(w, q); + d_(x, n); + d_(v, p); + d_(y, r); + d_(z, m); + d_(w, p); + d4(k, k, 78); + d4(l, l, 78); + d4(o, o, 78); + d4(q, q, 78); + d4(n, n, 78); + d4(r, r, 78); + d4(m, m, 78); + d4(p, p, 78); + d_(s, k); + d_(t, l); + d_(u, o); + d_(v, q); + d_(w, n); + d_(x, r); + d_(y, m); + d_(z, p); + d_(s, aV); + d3(s, 110824); + d_(t, aW); + d3(t, 110824); + d_(u, aX); + d3(u, 110824); + d_(v, aY); + d3(v, 110824); + d_(w, aZ); + d3(w, 110824); + d_(x, a_); + d3(x, 110824); + d_(y, a$); + d3(y, 110824); + d_(z, a0); + d3(z, 110824); + d_(x, y); + d_(u, t); + d_(x, s); + d_(y, u); + d_(v, s); + d_(y, v); + d_(v, z); + d_(v, w); + d_(z, x); + d_(v, t); + d_(w, x); + d_(u, z); + d_(t, x); + d1(n, z); + d1(m, t); + d1(l, x); + d1(p, u); + d1(o, y); + d_(n, w); + d_(m, u); + d_(l, v); + d_(p, w); + d_(o, s); + d1(q, n); + d1(k, m); + d1(r, n); + d0(m, l); + d0(n, o); + d_(r, k); + d$(q, o); + d$(k, l); + d_(o, l); + d$(r, o); + d1(o, v); + d_(o, s); + d$(p, o); + d_(n, p); + d_(m, p); + d1(p, z); + d_(p, t); + d1(o, x); + d1(l, p); + d_(o, y); + d0(l, o); + d$(p, o); + d_(k, p); + d_(n, r); + d_(m, q); + d_(l, r); + d_(k, q); + d_(l, q); + d1(o, u); + d1(p, w); + d1(q, t); + d1(r, z); + d$(o, v); + d$(p, s); + d$(q, x); + d0(r, y); + d_(n, o); + d_(m, p); + d_(l, q); + d_(k, r); + d1(o, n); + d_(o, m); + d$(n, l); + d1(q, k); + d_(q, n); + d1(r, o); + d$(r, q); + d_(r, m); + d1(p, l); + d_(p, k); + d_(n, m); + d$(p, n); + d_(p, k); + d_(l, p); + d1(m, q); + d_(m, p); + d$(m, k); + d_(l, m); + d_(q, m); + d$(q, r); + d_(q, o); + d1(o, y); + d1(k, x); + d1(m, r); + d_(m, q); + d$(m, y); + d_(y, x); + d$(y, q); + d$(x, r); + d_(y, x); + d_(x, m); + d_(o, s); + d_(k, v); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, s); + d_(s, v); + d$(s, l); + d$(v, p); + d_(s, v); + d_(v, m); + d_(y, o); + d_(s, o); + d_(x, k); + d_(v, k); + d1(o, z); + d1(k, t); + d_(o, w); + d_(k, u); + d1(n, r); + d_(n, q); + d$(n, o); + d_(o, k); + d$(o, q); + d$(k, r); + d_(k, o); + d_(o, n); + d1(m, p); + d_(m, l); + d$(m, w); + d_(w, u); + d$(w, l); + d$(u, p); + d_(w, u); + d_(u, m); + d_(r, p); + d_(q, l); + d1(n, r); + d_(n, q); + d$(n, z); + d_(z, t); + d$(z, q); + d$(t, r); + d_(z, t); + d_(t, n); + d_(z, o); + d_(w, o); + d_(t, k); + d_(u, k); + d_(z, s); + d_(t, y); + d_(w, z); + d_(y, s); + d_(s, t); + d_(t, x); + d_(x, u); + d_(w, x); + d_(u, v); + d_(v, x); + d_(y, v); + d_(s, a1); + d_(t, a2); + d_(w, a3); + d_(y, a4); + d_(v, a5); + d_(z, a6); + d_(u, a7); + d_(x, a8); + d1(k, u); + d6(k, 1); + d_(k, x); + d$(k, 110952); + d_(x, k); + d7(k, 1); + d_(u, k); + d1(k, v); + d6(k, 1); + d_(k, z); + d$(k, 110952); + d_(z, k); + d7(k, 1); + d_(v, k); + d1(k, w); + d6(k, 1); + d_(k, y); + d$(k, 110952); + d_(y, k); + d7(k, 1); + d_(w, k); + d1(k, s); + d6(k, 1); + d_(k, t); + d$(k, 110952); + d_(t, k); + d7(k, 1); + d_(s, k); + d1(k, z); + d6(k, 2); + d_(k, x); + d$(k, 110936); + d_(x, k); + d7(k, 2); + d_(z, k); + d1(k, v); + d6(k, 2); + d_(k, u); + d$(k, 110936); + d_(u, k); + d7(k, 2); + d_(v, k); + d1(k, t); + d6(k, 2); + d_(k, y); + d$(k, 110936); + d_(y, k); + d7(k, 2); + d_(t, k); + d1(k, s); + d6(k, 2); + d_(k, w); + d$(k, 110936); + d_(w, k); + d7(k, 2); + d_(s, k); + d1(k, y); + d6(k, 4); + d_(k, x); + d$(k, 110920); + d_(x, k); + d7(k, 4); + d_(y, k); + d1(k, w); + d6(k, 4); + d_(k, u); + d$(k, 110920); + d_(u, k); + d7(k, 4); + d_(w, k); + d1(k, t); + d6(k, 4); + d_(k, z); + d$(k, 110920); + d_(z, k); + d7(k, 4); + d_(t, k); + d1(k, s); + d6(k, 4); + d_(k, v); + d$(k, 110920); + d_(v, k); + d7(k, 4); + d_(s, k); + e = 0; + if (d >>> 0 < e >>> 0 | d >>> 0 == e >>> 0 & f >>> 0 < 128 >>> 0) { + break; + } + dV(h, (dU(h) | 0) + 8 | 0); + d_(s, b); + d_(t, b + 16 | 0); + d_(w, b + 32 | 0); + d_(y, b + 48 | 0); + d_(v, b + 64 | 0); + d_(z, b + 80 | 0); + d_(u, b + 96 | 0); + d_(x, b + 112 | 0); + c[bh >> 2] = c[a9 >> 2]; + c[bh + 4 >> 2] = c[a9 + 4 >> 2]; + c[bh + 8 >> 2] = c[a9 + 8 >> 2]; + c[bh + 12 >> 2] = c[a9 + 12 >> 2]; + e = bh + 16 | 0; + c[e >> 2] = c[ba >> 2]; + c[e + 4 >> 2] = c[ba + 4 >> 2]; + c[e + 8 >> 2] = c[ba + 8 >> 2]; + c[e + 12 >> 2] = c[ba + 12 >> 2]; + e = bh + 32 | 0; + c[e >> 2] = c[bb >> 2]; + c[e + 4 >> 2] = c[bb + 4 >> 2]; + c[e + 8 >> 2] = c[bb + 8 >> 2]; + c[e + 12 >> 2] = c[bb + 12 >> 2]; + e = bh + 48 | 0; + c[e >> 2] = c[bc >> 2]; + c[e + 4 >> 2] = c[bc + 4 >> 2]; + c[e + 8 >> 2] = c[bc + 8 >> 2]; + c[e + 12 >> 2] = c[bc + 12 >> 2]; + e = bh + 64 | 0; + c[e >> 2] = c[bd >> 2]; + c[e + 4 >> 2] = c[bd + 4 >> 2]; + c[e + 8 >> 2] = c[bd + 8 >> 2]; + c[e + 12 >> 2] = c[bd + 12 >> 2]; + e = bh + 80 | 0; + c[e >> 2] = c[be >> 2]; + c[e + 4 >> 2] = c[be + 4 >> 2]; + c[e + 8 >> 2] = c[be + 8 >> 2]; + c[e + 12 >> 2] = c[be + 12 >> 2]; + e = bh + 96 | 0; + c[e >> 2] = c[bf >> 2]; + c[e + 4 >> 2] = c[bf + 4 >> 2]; + c[e + 8 >> 2] = c[bf + 8 >> 2]; + c[e + 12 >> 2] = c[bf + 12 >> 2]; + e = bh + 112 | 0; + c[e >> 2] = c[bg >> 2]; + c[e + 4 >> 2] = c[bg + 4 >> 2]; + c[e + 8 >> 2] = c[bg + 8 >> 2]; + c[e + 12 >> 2] = c[bg + 12 >> 2]; + if ((f | 0) == 128 & (d | 0) == 0) { + bi = 29; + break; + } + e = fp(f, d, -128, -1) | 0; + bh = bh + 128 | 0; + b = b + 128 | 0; + d = H; + f = e; + } + if ((bi | 0) == 29) { + i = j; + return 0; + } + bi = g + 12 | 0; + g = fp(dU(bi) | 0, 0, f >>> 4 | d << 28, d >>> 4 | 0 << 28) | 0; + dV(bi, g); + g = B; + bi = s; + c[g >> 2] = c[bi >> 2]; + c[g + 4 >> 2] = c[bi + 4 >> 2]; + c[g + 8 >> 2] = c[bi + 8 >> 2]; + c[g + 12 >> 2] = c[bi + 12 >> 2]; + bi = B + 16 | 0; + s = t; + c[bi >> 2] = c[s >> 2]; + c[bi + 4 >> 2] = c[s + 4 >> 2]; + c[bi + 8 >> 2] = c[s + 8 >> 2]; + c[bi + 12 >> 2] = c[s + 12 >> 2]; + s = B + 32 | 0; + bi = w; + c[s >> 2] = c[bi >> 2]; + c[s + 4 >> 2] = c[bi + 4 >> 2]; + c[s + 8 >> 2] = c[bi + 8 >> 2]; + c[s + 12 >> 2] = c[bi + 12 >> 2]; + bi = B + 48 | 0; + s = y; + c[bi >> 2] = c[s >> 2]; + c[bi + 4 >> 2] = c[s + 4 >> 2]; + c[bi + 8 >> 2] = c[s + 8 >> 2]; + c[bi + 12 >> 2] = c[s + 12 >> 2]; + s = B + 64 | 0; + bi = v; + c[s >> 2] = c[bi >> 2]; + c[s + 4 >> 2] = c[bi + 4 >> 2]; + c[s + 8 >> 2] = c[bi + 8 >> 2]; + c[s + 12 >> 2] = c[bi + 12 >> 2]; + bi = B + 80 | 0; + s = z; + c[bi >> 2] = c[s >> 2]; + c[bi + 4 >> 2] = c[s + 4 >> 2]; + c[bi + 8 >> 2] = c[s + 8 >> 2]; + c[bi + 12 >> 2] = c[s + 12 >> 2]; + s = B + 96 | 0; + bi = u; + c[s >> 2] = c[bi >> 2]; + c[s + 4 >> 2] = c[bi + 4 >> 2]; + c[s + 8 >> 2] = c[bi + 8 >> 2]; + c[s + 12 >> 2] = c[bi + 12 >> 2]; + bi = B + 112 | 0; + B = x; + c[bi >> 2] = c[B >> 2]; + c[bi + 4 >> 2] = c[B + 4 >> 2]; + c[bi + 8 >> 2] = c[B + 8 >> 2]; + c[bi + 12 >> 2] = c[B + 12 >> 2]; + if ((f | 0) == 0 & (d | 0) == 0) { + i = j; + return 0; + } else { + bj = d; + bk = f; + bl = g; + bm = b; + bn = bh; + } + while (1) { + a[bn] = a[bm] ^ a[bl]; + bh = fp(bk, bj, -1, -1) | 0; + b = H; + if ((bh | 0) == 0 & (b | 0) == 0) { + break; + } else { + bj = b; + bk = bh; + bl = bl + 1 | 0; + bm = bm + 1 | 0; + bn = bn + 1 | 0; + } + } + i = j; + return 0; +} +function ed(b, c) { + b = b | 0; + c = c | 0; + return ((((a[c + 1 | 0] ^ a[b + 1 | 0] | a[c] ^ a[b] | a[c + 2 | 0] ^ a[b + 2 | 0] | a[c + 3 | 0] ^ a[b + 3 | 0] | a[c + 4 | 0] ^ a[b + 4 | 0] | a[c + 5 | 0] ^ a[b + 5 | 0] | a[c + 6 | 0] ^ a[b + 6 | 0] | a[c + 7 | 0] ^ a[b + 7 | 0] | a[c + 8 | 0] ^ a[b + 8 | 0] | a[c + 9 | 0] ^ a[b + 9 | 0] | a[c + 10 | 0] ^ a[b + 10 | 0] | a[c + 11 | 0] ^ a[b + 11 | 0] | a[c + 12 | 0] ^ a[b + 12 | 0] | a[c + 13 | 0] ^ a[b + 13 | 0] | a[c + 14 | 0] ^ a[b + 14 | 0] | a[c + 15 | 0] ^ a[b + 15 | 0]) & 255) + 511 | 0) >>> 8 & 1) - 1 | 0; +} +function ee(b, e, f, g, h) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + j = i; + i = i + 16 | 0; + k = j | 0; + l = k; + m = i; + i = i + 64 | 0; + if ((e | 0) == 0 & (f | 0) == 0) { + i = j; + return 0; + } + n = k | 0; + o = g; + g = o | 0; + p = o + 4 | 0; + o = d[p] | d[p + 1 | 0] << 8 | d[p + 2 | 0] << 16 | d[p + 3 | 0] << 24 | 0; + c[n >> 2] = d[g] | d[g + 1 | 0] << 8 | d[g + 2 | 0] << 16 | d[g + 3 | 0] << 24; + c[n + 4 >> 2] = o; + o = k + 8 | 0; + c[o >> 2] = 0; + c[o + 4 >> 2] = 0; + o = 0; + do { + if (f >>> 0 > o >>> 0 | f >>> 0 == o >>> 0 & e >>> 0 > 63 >>> 0) { + n = k; + g = k + 8 | 0; + p = f; + q = e; + r = b; + do { + bH(r, n, h, 120) | 0; + s = (d[g] | 0) + 1 | 0; + a[g] = s & 255; + t = l + 9 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 10 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 11 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 12 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 13 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 14 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 15 | 0; + a[t] = (d[t] | 0) + (s >>> 8) & 255; + q = fp(q, p, -64, -1) | 0; + p = H; + r = r + 64 | 0; + s = 0; + } while (p >>> 0 > s >>> 0 | p >>> 0 == s >>> 0 & q >>> 0 > 63 >>> 0); + if (!((q | 0) == 0 & (p | 0) == 0)) { + v = r; + w = p; + x = q; + break; + } + i = j; + return 0; + } else { + v = b; + w = f; + x = e; + } + } while (0); + bH(m | 0, k, h, 120) | 0; + h = 0; + do { + a[v + h | 0] = a[m + h | 0] | 0; + h = h + 1 | 0; + k = (h | 0) < 0 ? -1 : 0; + } while (k >>> 0 < w >>> 0 | k >>> 0 == w >>> 0 & h >>> 0 < x >>> 0); + i = j; + return 0; +} +function ef(b, e, f, g, h, j) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + j = j | 0; + var k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0; + k = i; + i = i + 16 | 0; + l = k | 0; + m = l; + n = i; + i = i + 64 | 0; + if ((f | 0) == 0 & (g | 0) == 0) { + i = k; + return 0; + } + o = l | 0; + p = h; + h = p | 0; + q = p + 4 | 0; + p = d[q] | d[q + 1 | 0] << 8 | d[q + 2 | 0] << 16 | d[q + 3 | 0] << 24 | 0; + c[o >> 2] = d[h] | d[h + 1 | 0] << 8 | d[h + 2 | 0] << 16 | d[h + 3 | 0] << 24; + c[o + 4 >> 2] = p; + p = l + 8 | 0; + c[p >> 2] = 0; + c[p + 4 >> 2] = 0; + p = 0; + do { + if (g >>> 0 > p >>> 0 | g >>> 0 == p >>> 0 & f >>> 0 > 63 >>> 0) { + o = n | 0; + h = l; + q = l + 8 | 0; + r = e; + s = g; + t = f; + u = b; + do { + bH(o, h, j, 104) | 0; + v = 0; + do { + a[u + v | 0] = a[n + v | 0] ^ a[r + v | 0]; + v = v + 1 | 0; + } while ((v | 0) < 64); + v = (d[q] | 0) + 1 | 0; + a[q] = v & 255; + w = m + 9 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 10 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 11 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 12 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 13 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 14 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 15 | 0; + a[w] = (d[w] | 0) + (v >>> 8) & 255; + t = fp(t, s, -64, -1) | 0; + s = H; + u = u + 64 | 0; + r = r + 64 | 0; + v = 0; + } while (s >>> 0 > v >>> 0 | s >>> 0 == v >>> 0 & t >>> 0 > 63 >>> 0); + if (!((t | 0) == 0 & (s | 0) == 0)) { + y = u; + z = s; + A = t; + B = r; + break; + } + i = k; + return 0; + } else { + y = b; + z = g; + A = f; + B = e; + } + } while (0); + bH(n | 0, l, j, 104) | 0; + j = 0; + do { + a[y + j | 0] = a[n + j | 0] ^ a[B + j | 0]; + j = j + 1 | 0; + l = (j | 0) < 0 ? -1 : 0; + } while (l >>> 0 < z >>> 0 | l >>> 0 == z >>> 0 & j >>> 0 < A >>> 0); + i = k; + return 0; +} +function eg(b, e, f, g, h) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + j = i; + i = i + 16 | 0; + k = j | 0; + l = k; + m = i; + i = i + 64 | 0; + if ((e | 0) == 0 & (f | 0) == 0) { + i = j; + return 0; + } + n = k | 0; + o = g; + g = o | 0; + p = o + 4 | 0; + o = d[p] | d[p + 1 | 0] << 8 | d[p + 2 | 0] << 16 | d[p + 3 | 0] << 24 | 0; + c[n >> 2] = d[g] | d[g + 1 | 0] << 8 | d[g + 2 | 0] << 16 | d[g + 3 | 0] << 24; + c[n + 4 >> 2] = o; + o = k + 8 | 0; + c[o >> 2] = 0; + c[o + 4 >> 2] = 0; + o = 0; + do { + if (f >>> 0 > o >>> 0 | f >>> 0 == o >>> 0 & e >>> 0 > 63 >>> 0) { + n = k; + g = k + 8 | 0; + p = f; + q = e; + r = b; + do { + bO(r, n, h, 88) | 0; + s = (d[g] | 0) + 1 | 0; + a[g] = s & 255; + t = l + 9 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 10 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 11 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 12 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 13 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 14 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 15 | 0; + a[t] = (d[t] | 0) + (s >>> 8) & 255; + q = fp(q, p, -64, -1) | 0; + p = H; + r = r + 64 | 0; + s = 0; + } while (p >>> 0 > s >>> 0 | p >>> 0 == s >>> 0 & q >>> 0 > 63 >>> 0); + if (!((q | 0) == 0 & (p | 0) == 0)) { + v = r; + w = p; + x = q; + break; + } + i = j; + return 0; + } else { + v = b; + w = f; + x = e; + } + } while (0); + bO(m | 0, k, h, 88) | 0; + h = 0; + do { + a[v + h | 0] = a[m + h | 0] | 0; + h = h + 1 | 0; + k = (h | 0) < 0 ? -1 : 0; + } while (k >>> 0 < w >>> 0 | k >>> 0 == w >>> 0 & h >>> 0 < x >>> 0); + i = j; + return 0; +} +function eh(b, e, f, g, h, j) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + j = j | 0; + var k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0; + k = i; + i = i + 16 | 0; + l = k | 0; + m = l; + n = i; + i = i + 64 | 0; + if ((f | 0) == 0 & (g | 0) == 0) { + i = k; + return 0; + } + o = l | 0; + p = h; + h = p | 0; + q = p + 4 | 0; + p = d[q] | d[q + 1 | 0] << 8 | d[q + 2 | 0] << 16 | d[q + 3 | 0] << 24 | 0; + c[o >> 2] = d[h] | d[h + 1 | 0] << 8 | d[h + 2 | 0] << 16 | d[h + 3 | 0] << 24; + c[o + 4 >> 2] = p; + p = l + 8 | 0; + c[p >> 2] = 0; + c[p + 4 >> 2] = 0; + p = 0; + do { + if (g >>> 0 > p >>> 0 | g >>> 0 == p >>> 0 & f >>> 0 > 63 >>> 0) { + o = n | 0; + h = l; + q = l + 8 | 0; + r = e; + s = g; + t = f; + u = b; + do { + bO(o, h, j, 72) | 0; + v = 0; + do { + a[u + v | 0] = a[n + v | 0] ^ a[r + v | 0]; + v = v + 1 | 0; + } while ((v | 0) < 64); + v = (d[q] | 0) + 1 | 0; + a[q] = v & 255; + w = m + 9 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 10 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 11 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 12 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 13 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 14 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 15 | 0; + a[w] = (d[w] | 0) + (v >>> 8) & 255; + t = fp(t, s, -64, -1) | 0; + s = H; + u = u + 64 | 0; + r = r + 64 | 0; + v = 0; + } while (s >>> 0 > v >>> 0 | s >>> 0 == v >>> 0 & t >>> 0 > 63 >>> 0); + if (!((t | 0) == 0 & (s | 0) == 0)) { + y = u; + z = s; + A = t; + B = r; + break; + } + i = k; + return 0; + } else { + y = b; + z = g; + A = f; + B = e; + } + } while (0); + bO(n | 0, l, j, 72) | 0; + j = 0; + do { + a[y + j | 0] = a[n + j | 0] ^ a[B + j | 0]; + j = j + 1 | 0; + l = (j | 0) < 0 ? -1 : 0; + } while (l >>> 0 < z >>> 0 | l >>> 0 == z >>> 0 & j >>> 0 < A >>> 0); + i = k; + return 0; +} +function ei(b, e, f, g, h) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + j = i; + i = i + 16 | 0; + k = j | 0; + l = k; + m = i; + i = i + 64 | 0; + if ((e | 0) == 0 & (f | 0) == 0) { + i = j; + return 0; + } + n = k | 0; + o = g; + g = o | 0; + p = o + 4 | 0; + o = d[p] | d[p + 1 | 0] << 8 | d[p + 2 | 0] << 16 | d[p + 3 | 0] << 24 | 0; + c[n >> 2] = d[g] | d[g + 1 | 0] << 8 | d[g + 2 | 0] << 16 | d[g + 3 | 0] << 24; + c[n + 4 >> 2] = o; + o = k + 8 | 0; + c[o >> 2] = 0; + c[o + 4 >> 2] = 0; + o = 0; + do { + if (f >>> 0 > o >>> 0 | f >>> 0 == o >>> 0 & e >>> 0 > 63 >>> 0) { + n = k; + g = k + 8 | 0; + p = f; + q = e; + r = b; + do { + bP(r, n, h, 56) | 0; + s = (d[g] | 0) + 1 | 0; + a[g] = s & 255; + t = l + 9 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 10 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 11 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 12 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 13 | 0; + u = (d[t] | 0) + (s >>> 8) | 0; + a[t] = u & 255; + t = l + 14 | 0; + s = (d[t] | 0) + (u >>> 8) | 0; + a[t] = s & 255; + t = l + 15 | 0; + a[t] = (d[t] | 0) + (s >>> 8) & 255; + q = fp(q, p, -64, -1) | 0; + p = H; + r = r + 64 | 0; + s = 0; + } while (p >>> 0 > s >>> 0 | p >>> 0 == s >>> 0 & q >>> 0 > 63 >>> 0); + if (!((q | 0) == 0 & (p | 0) == 0)) { + v = r; + w = p; + x = q; + break; + } + i = j; + return 0; + } else { + v = b; + w = f; + x = e; + } + } while (0); + bP(m | 0, k, h, 56) | 0; + h = 0; + do { + a[v + h | 0] = a[m + h | 0] | 0; + h = h + 1 | 0; + k = (h | 0) < 0 ? -1 : 0; + } while (k >>> 0 < w >>> 0 | k >>> 0 == w >>> 0 & h >>> 0 < x >>> 0); + i = j; + return 0; +} +function ej(b, e, f, g, h, j) { + b = b | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + j = j | 0; + var k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0; + k = i; + i = i + 16 | 0; + l = k | 0; + m = l; + n = i; + i = i + 64 | 0; + if ((f | 0) == 0 & (g | 0) == 0) { + i = k; + return 0; + } + o = l | 0; + p = h; + h = p | 0; + q = p + 4 | 0; + p = d[q] | d[q + 1 | 0] << 8 | d[q + 2 | 0] << 16 | d[q + 3 | 0] << 24 | 0; + c[o >> 2] = d[h] | d[h + 1 | 0] << 8 | d[h + 2 | 0] << 16 | d[h + 3 | 0] << 24; + c[o + 4 >> 2] = p; + p = l + 8 | 0; + c[p >> 2] = 0; + c[p + 4 >> 2] = 0; + p = 0; + do { + if (g >>> 0 > p >>> 0 | g >>> 0 == p >>> 0 & f >>> 0 > 63 >>> 0) { + o = n | 0; + h = l; + q = l + 8 | 0; + r = e; + s = g; + t = f; + u = b; + do { + bP(o, h, j, 40) | 0; + v = 0; + do { + a[u + v | 0] = a[n + v | 0] ^ a[r + v | 0]; + v = v + 1 | 0; + } while ((v | 0) < 64); + v = (d[q] | 0) + 1 | 0; + a[q] = v & 255; + w = m + 9 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 10 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 11 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 12 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 13 | 0; + x = (d[w] | 0) + (v >>> 8) | 0; + a[w] = x & 255; + w = m + 14 | 0; + v = (d[w] | 0) + (x >>> 8) | 0; + a[w] = v & 255; + w = m + 15 | 0; + a[w] = (d[w] | 0) + (v >>> 8) & 255; + t = fp(t, s, -64, -1) | 0; + s = H; + u = u + 64 | 0; + r = r + 64 | 0; + v = 0; + } while (s >>> 0 > v >>> 0 | s >>> 0 == v >>> 0 & t >>> 0 > 63 >>> 0); + if (!((t | 0) == 0 & (s | 0) == 0)) { + y = u; + z = s; + A = t; + B = r; + break; + } + i = k; + return 0; + } else { + y = b; + z = g; + A = f; + B = e; + } + } while (0); + bP(n | 0, l, j, 40) | 0; + j = 0; + do { + a[y + j | 0] = a[n + j | 0] ^ a[B + j | 0]; + j = j + 1 | 0; + l = (j | 0) < 0 ? -1 : 0; + } while (l >>> 0 < z >>> 0 | l >>> 0 == z >>> 0 & j >>> 0 < A >>> 0); + i = k; + return 0; +} +function ek(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 32 | 0; + g = f | 0; + bG(g, d, e, 24) | 0; + e = ee(a, b, c, d + 16 | 0, g) | 0; + i = f; + return e | 0; +} +function el(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0; + g = i; + i = i + 32 | 0; + h = g | 0; + bG(h, e, f, 8) | 0; + f = ef(a, b, c, d, e + 16 | 0, h) | 0; + i = g; + return f | 0; +} +function em(b, c) { + b = b | 0; + c = c | 0; + return ((((a[c + 1 | 0] ^ a[b + 1 | 0] | a[c] ^ a[b] | a[c + 2 | 0] ^ a[b + 2 | 0] | a[c + 3 | 0] ^ a[b + 3 | 0] | a[c + 4 | 0] ^ a[b + 4 | 0] | a[c + 5 | 0] ^ a[b + 5 | 0] | a[c + 6 | 0] ^ a[b + 6 | 0] | a[c + 7 | 0] ^ a[b + 7 | 0] | a[c + 8 | 0] ^ a[b + 8 | 0] | a[c + 9 | 0] ^ a[b + 9 | 0] | a[c + 10 | 0] ^ a[b + 10 | 0] | a[c + 11 | 0] ^ a[b + 11 | 0] | a[c + 12 | 0] ^ a[b + 12 | 0] | a[c + 13 | 0] ^ a[b + 13 | 0] | a[c + 14 | 0] ^ a[b + 14 | 0] | a[c + 15 | 0] ^ a[b + 15 | 0] | a[c + 16 | 0] ^ a[b + 16 | 0] | a[c + 17 | 0] ^ a[b + 17 | 0] | a[c + 18 | 0] ^ a[b + 18 | 0] | a[c + 19 | 0] ^ a[b + 19 | 0] | a[c + 20 | 0] ^ a[b + 20 | 0] | a[c + 21 | 0] ^ a[b + 21 | 0] | a[c + 22 | 0] ^ a[b + 22 | 0] | a[c + 23 | 0] ^ a[b + 23 | 0] | a[c + 24 | 0] ^ a[b + 24 | 0] | a[c + 25 | 0] ^ a[b + 25 | 0] | a[c + 26 | 0] ^ a[b + 26 | 0] | a[c + 27 | 0] ^ a[b + 27 | 0] | a[c + 28 | 0] ^ a[b + 28 | 0] | a[c + 29 | 0] ^ a[b + 29 | 0] | a[c + 30 | 0] ^ a[b + 30 | 0] | a[c + 31 | 0] ^ a[b + 31 | 0]) & 255) + 511 | 0) >>> 8 & 1) - 1 | 0; +} +function en(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0, ae = 0, af = 0, ag = 0, ah = 0, ai = 0, aj = 0, ak = 0, al = 0, am = 0, an = 0, ao = 0, ap = 0, aq = 0, as = 0, at = 0, au = 0, aw = 0, ax = 0, ay = 0, az = 0, aA = 0, aB = 0, aC = 0, aD = 0, aE = 0, aF = 0, aG = 0, aH = 0, aI = 0; + do { + if (a >>> 0 < 245) { + if (a >>> 0 < 11) { + b = 16; + } else { + b = a + 11 & -8; + } + d = b >>> 3; + e = c[28038] | 0; + f = e >>> (d >>> 0); + if ((f & 3 | 0) != 0) { + g = (f & 1 ^ 1) + d | 0; + h = g << 1; + i = 112192 + (h << 2) | 0; + j = 112192 + (h + 2 << 2) | 0; + h = c[j >> 2] | 0; + k = h + 8 | 0; + l = c[k >> 2] | 0; + do { + if ((i | 0) == (l | 0)) { + c[28038] = e & ~(1 << g); + } else { + if (l >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + m = l + 12 | 0; + if ((c[m >> 2] | 0) == (h | 0)) { + c[m >> 2] = i; + c[j >> 2] = l; + break; + } else { + av(); + return 0; + } + } + } while (0); + l = g << 3; + c[h + 4 >> 2] = l | 3; + j = h + (l | 4) | 0; + c[j >> 2] = c[j >> 2] | 1; + n = k; + return n | 0; + } + if (b >>> 0 <= (c[28040] | 0) >>> 0) { + o = b; + break; + } + if ((f | 0) != 0) { + j = 2 << d; + l = f << d & (j | -j); + j = (l & -l) - 1 | 0; + l = j >>> 12 & 16; + i = j >>> (l >>> 0); + j = i >>> 5 & 8; + m = i >>> (j >>> 0); + i = m >>> 2 & 4; + p = m >>> (i >>> 0); + m = p >>> 1 & 2; + q = p >>> (m >>> 0); + p = q >>> 1 & 1; + r = (j | l | i | m | p) + (q >>> (p >>> 0)) | 0; + p = r << 1; + q = 112192 + (p << 2) | 0; + m = 112192 + (p + 2 << 2) | 0; + p = c[m >> 2] | 0; + i = p + 8 | 0; + l = c[i >> 2] | 0; + do { + if ((q | 0) == (l | 0)) { + c[28038] = e & ~(1 << r); + } else { + if (l >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + j = l + 12 | 0; + if ((c[j >> 2] | 0) == (p | 0)) { + c[j >> 2] = q; + c[m >> 2] = l; + break; + } else { + av(); + return 0; + } + } + } while (0); + l = r << 3; + m = l - b | 0; + c[p + 4 >> 2] = b | 3; + q = p; + e = q + b | 0; + c[q + (b | 4) >> 2] = m | 1; + c[q + l >> 2] = m; + l = c[28040] | 0; + if ((l | 0) != 0) { + q = c[28043] | 0; + d = l >>> 3; + l = d << 1; + f = 112192 + (l << 2) | 0; + k = c[28038] | 0; + h = 1 << d; + do { + if ((k & h | 0) == 0) { + c[28038] = k | h; + s = f; + t = 112192 + (l + 2 << 2) | 0; + } else { + d = 112192 + (l + 2 << 2) | 0; + g = c[d >> 2] | 0; + if (g >>> 0 >= (c[28042] | 0) >>> 0) { + s = g; + t = d; + break; + } + av(); + return 0; + } + } while (0); + c[t >> 2] = q; + c[s + 12 >> 2] = q; + c[q + 8 >> 2] = s; + c[q + 12 >> 2] = f; + } + c[28040] = m; + c[28043] = e; + n = i; + return n | 0; + } + l = c[28039] | 0; + if ((l | 0) == 0) { + o = b; + break; + } + h = (l & -l) - 1 | 0; + l = h >>> 12 & 16; + k = h >>> (l >>> 0); + h = k >>> 5 & 8; + p = k >>> (h >>> 0); + k = p >>> 2 & 4; + r = p >>> (k >>> 0); + p = r >>> 1 & 2; + d = r >>> (p >>> 0); + r = d >>> 1 & 1; + g = c[112456 + ((h | l | k | p | r) + (d >>> (r >>> 0)) << 2) >> 2] | 0; + r = g; + d = g; + p = (c[g + 4 >> 2] & -8) - b | 0; + while (1) { + g = c[r + 16 >> 2] | 0; + if ((g | 0) == 0) { + k = c[r + 20 >> 2] | 0; + if ((k | 0) == 0) { + break; + } else { + u = k; + } + } else { + u = g; + } + g = (c[u + 4 >> 2] & -8) - b | 0; + k = g >>> 0 < p >>> 0; + r = u; + d = k ? u : d; + p = k ? g : p; + } + r = d; + i = c[28042] | 0; + if (r >>> 0 < i >>> 0) { + av(); + return 0; + } + e = r + b | 0; + m = e; + if (r >>> 0 >= e >>> 0) { + av(); + return 0; + } + e = c[d + 24 >> 2] | 0; + f = c[d + 12 >> 2] | 0; + do { + if ((f | 0) == (d | 0)) { + q = d + 20 | 0; + g = c[q >> 2] | 0; + if ((g | 0) == 0) { + k = d + 16 | 0; + l = c[k >> 2] | 0; + if ((l | 0) == 0) { + v = 0; + break; + } else { + w = l; + x = k; + } + } else { + w = g; + x = q; + } + while (1) { + q = w + 20 | 0; + g = c[q >> 2] | 0; + if ((g | 0) != 0) { + w = g; + x = q; + continue; + } + q = w + 16 | 0; + g = c[q >> 2] | 0; + if ((g | 0) == 0) { + break; + } else { + w = g; + x = q; + } + } + if (x >>> 0 < i >>> 0) { + av(); + return 0; + } else { + c[x >> 2] = 0; + v = w; + break; + } + } else { + q = c[d + 8 >> 2] | 0; + if (q >>> 0 < i >>> 0) { + av(); + return 0; + } + g = q + 12 | 0; + if ((c[g >> 2] | 0) != (d | 0)) { + av(); + return 0; + } + k = f + 8 | 0; + if ((c[k >> 2] | 0) == (d | 0)) { + c[g >> 2] = f; + c[k >> 2] = q; + v = f; + break; + } else { + av(); + return 0; + } + } + } while (0); + L209 : do { + if ((e | 0) != 0) { + f = d + 28 | 0; + i = 112456 + (c[f >> 2] << 2) | 0; + do { + if ((d | 0) == (c[i >> 2] | 0)) { + c[i >> 2] = v; + if ((v | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[f >> 2]); + break L209; + } else { + if (e >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + q = e + 16 | 0; + if ((c[q >> 2] | 0) == (d | 0)) { + c[q >> 2] = v; + } else { + c[e + 20 >> 2] = v; + } + if ((v | 0) == 0) { + break L209; + } + } + } while (0); + if (v >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + c[v + 24 >> 2] = e; + f = c[d + 16 >> 2] | 0; + do { + if ((f | 0) != 0) { + if (f >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[v + 16 >> 2] = f; + c[f + 24 >> 2] = v; + break; + } + } + } while (0); + f = c[d + 20 >> 2] | 0; + if ((f | 0) == 0) { + break; + } + if (f >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[v + 20 >> 2] = f; + c[f + 24 >> 2] = v; + break; + } + } + } while (0); + if (p >>> 0 < 16) { + e = p + b | 0; + c[d + 4 >> 2] = e | 3; + f = r + (e + 4) | 0; + c[f >> 2] = c[f >> 2] | 1; + } else { + c[d + 4 >> 2] = b | 3; + c[r + (b | 4) >> 2] = p | 1; + c[r + (p + b) >> 2] = p; + f = c[28040] | 0; + if ((f | 0) != 0) { + e = c[28043] | 0; + i = f >>> 3; + f = i << 1; + q = 112192 + (f << 2) | 0; + k = c[28038] | 0; + g = 1 << i; + do { + if ((k & g | 0) == 0) { + c[28038] = k | g; + y = q; + z = 112192 + (f + 2 << 2) | 0; + } else { + i = 112192 + (f + 2 << 2) | 0; + l = c[i >> 2] | 0; + if (l >>> 0 >= (c[28042] | 0) >>> 0) { + y = l; + z = i; + break; + } + av(); + return 0; + } + } while (0); + c[z >> 2] = e; + c[y + 12 >> 2] = e; + c[e + 8 >> 2] = y; + c[e + 12 >> 2] = q; + } + c[28040] = p; + c[28043] = m; + } + f = d + 8 | 0; + if ((f | 0) == 0) { + o = b; + break; + } else { + n = f; + } + return n | 0; + } else { + if (a >>> 0 > 4294967231) { + o = -1; + break; + } + f = a + 11 | 0; + g = f & -8; + k = c[28039] | 0; + if ((k | 0) == 0) { + o = g; + break; + } + r = -g | 0; + i = f >>> 8; + do { + if ((i | 0) == 0) { + A = 0; + } else { + if (g >>> 0 > 16777215) { + A = 31; + break; + } + f = (i + 1048320 | 0) >>> 16 & 8; + l = i << f; + h = (l + 520192 | 0) >>> 16 & 4; + j = l << h; + l = (j + 245760 | 0) >>> 16 & 2; + B = 14 - (h | f | l) + (j << l >>> 15) | 0; + A = g >>> ((B + 7 | 0) >>> 0) & 1 | B << 1; + } + } while (0); + i = c[112456 + (A << 2) >> 2] | 0; + L257 : do { + if ((i | 0) == 0) { + C = 0; + D = r; + E = 0; + } else { + if ((A | 0) == 31) { + F = 0; + } else { + F = 25 - (A >>> 1) | 0; + } + d = 0; + m = r; + p = i; + q = g << F; + e = 0; + while (1) { + B = c[p + 4 >> 2] & -8; + l = B - g | 0; + if (l >>> 0 < m >>> 0) { + if ((B | 0) == (g | 0)) { + C = p; + D = l; + E = p; + break L257; + } else { + G = p; + H = l; + } + } else { + G = d; + H = m; + } + l = c[p + 20 >> 2] | 0; + B = c[p + 16 + (q >>> 31 << 2) >> 2] | 0; + j = (l | 0) == 0 | (l | 0) == (B | 0) ? e : l; + if ((B | 0) == 0) { + C = G; + D = H; + E = j; + break; + } else { + d = G; + m = H; + p = B; + q = q << 1; + e = j; + } + } + } + } while (0); + if ((E | 0) == 0 & (C | 0) == 0) { + i = 2 << A; + r = k & (i | -i); + if ((r | 0) == 0) { + o = g; + break; + } + i = (r & -r) - 1 | 0; + r = i >>> 12 & 16; + e = i >>> (r >>> 0); + i = e >>> 5 & 8; + q = e >>> (i >>> 0); + e = q >>> 2 & 4; + p = q >>> (e >>> 0); + q = p >>> 1 & 2; + m = p >>> (q >>> 0); + p = m >>> 1 & 1; + I = c[112456 + ((i | r | e | q | p) + (m >>> (p >>> 0)) << 2) >> 2] | 0; + } else { + I = E; + } + if ((I | 0) == 0) { + J = D; + K = C; + } else { + p = I; + m = D; + q = C; + while (1) { + e = (c[p + 4 >> 2] & -8) - g | 0; + r = e >>> 0 < m >>> 0; + i = r ? e : m; + e = r ? p : q; + r = c[p + 16 >> 2] | 0; + if ((r | 0) != 0) { + p = r; + m = i; + q = e; + continue; + } + r = c[p + 20 >> 2] | 0; + if ((r | 0) == 0) { + J = i; + K = e; + break; + } else { + p = r; + m = i; + q = e; + } + } + } + if ((K | 0) == 0) { + o = g; + break; + } + if (J >>> 0 >= ((c[28040] | 0) - g | 0) >>> 0) { + o = g; + break; + } + q = K; + m = c[28042] | 0; + if (q >>> 0 < m >>> 0) { + av(); + return 0; + } + p = q + g | 0; + k = p; + if (q >>> 0 >= p >>> 0) { + av(); + return 0; + } + e = c[K + 24 >> 2] | 0; + i = c[K + 12 >> 2] | 0; + do { + if ((i | 0) == (K | 0)) { + r = K + 20 | 0; + d = c[r >> 2] | 0; + if ((d | 0) == 0) { + j = K + 16 | 0; + B = c[j >> 2] | 0; + if ((B | 0) == 0) { + L = 0; + break; + } else { + M = B; + N = j; + } + } else { + M = d; + N = r; + } + while (1) { + r = M + 20 | 0; + d = c[r >> 2] | 0; + if ((d | 0) != 0) { + M = d; + N = r; + continue; + } + r = M + 16 | 0; + d = c[r >> 2] | 0; + if ((d | 0) == 0) { + break; + } else { + M = d; + N = r; + } + } + if (N >>> 0 < m >>> 0) { + av(); + return 0; + } else { + c[N >> 2] = 0; + L = M; + break; + } + } else { + r = c[K + 8 >> 2] | 0; + if (r >>> 0 < m >>> 0) { + av(); + return 0; + } + d = r + 12 | 0; + if ((c[d >> 2] | 0) != (K | 0)) { + av(); + return 0; + } + j = i + 8 | 0; + if ((c[j >> 2] | 0) == (K | 0)) { + c[d >> 2] = i; + c[j >> 2] = r; + L = i; + break; + } else { + av(); + return 0; + } + } + } while (0); + L307 : do { + if ((e | 0) != 0) { + i = K + 28 | 0; + m = 112456 + (c[i >> 2] << 2) | 0; + do { + if ((K | 0) == (c[m >> 2] | 0)) { + c[m >> 2] = L; + if ((L | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[i >> 2]); + break L307; + } else { + if (e >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + r = e + 16 | 0; + if ((c[r >> 2] | 0) == (K | 0)) { + c[r >> 2] = L; + } else { + c[e + 20 >> 2] = L; + } + if ((L | 0) == 0) { + break L307; + } + } + } while (0); + if (L >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + c[L + 24 >> 2] = e; + i = c[K + 16 >> 2] | 0; + do { + if ((i | 0) != 0) { + if (i >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[L + 16 >> 2] = i; + c[i + 24 >> 2] = L; + break; + } + } + } while (0); + i = c[K + 20 >> 2] | 0; + if ((i | 0) == 0) { + break; + } + if (i >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[L + 20 >> 2] = i; + c[i + 24 >> 2] = L; + break; + } + } + } while (0); + do { + if (J >>> 0 < 16) { + e = J + g | 0; + c[K + 4 >> 2] = e | 3; + i = q + (e + 4) | 0; + c[i >> 2] = c[i >> 2] | 1; + } else { + c[K + 4 >> 2] = g | 3; + c[q + (g | 4) >> 2] = J | 1; + c[q + (J + g) >> 2] = J; + i = J >>> 3; + if (J >>> 0 < 256) { + e = i << 1; + m = 112192 + (e << 2) | 0; + r = c[28038] | 0; + j = 1 << i; + do { + if ((r & j | 0) == 0) { + c[28038] = r | j; + O = m; + P = 112192 + (e + 2 << 2) | 0; + } else { + i = 112192 + (e + 2 << 2) | 0; + d = c[i >> 2] | 0; + if (d >>> 0 >= (c[28042] | 0) >>> 0) { + O = d; + P = i; + break; + } + av(); + return 0; + } + } while (0); + c[P >> 2] = k; + c[O + 12 >> 2] = k; + c[q + (g + 8) >> 2] = O; + c[q + (g + 12) >> 2] = m; + break; + } + e = p; + j = J >>> 8; + do { + if ((j | 0) == 0) { + Q = 0; + } else { + if (J >>> 0 > 16777215) { + Q = 31; + break; + } + r = (j + 1048320 | 0) >>> 16 & 8; + i = j << r; + d = (i + 520192 | 0) >>> 16 & 4; + B = i << d; + i = (B + 245760 | 0) >>> 16 & 2; + l = 14 - (d | r | i) + (B << i >>> 15) | 0; + Q = J >>> ((l + 7 | 0) >>> 0) & 1 | l << 1; + } + } while (0); + j = 112456 + (Q << 2) | 0; + c[q + (g + 28) >> 2] = Q; + c[q + (g + 20) >> 2] = 0; + c[q + (g + 16) >> 2] = 0; + m = c[28039] | 0; + l = 1 << Q; + if ((m & l | 0) == 0) { + c[28039] = m | l; + c[j >> 2] = e; + c[q + (g + 24) >> 2] = j; + c[q + (g + 12) >> 2] = e; + c[q + (g + 8) >> 2] = e; + break; + } + if ((Q | 0) == 31) { + R = 0; + } else { + R = 25 - (Q >>> 1) | 0; + } + l = J << R; + m = c[j >> 2] | 0; + while (1) { + if ((c[m + 4 >> 2] & -8 | 0) == (J | 0)) { + break; + } + S = m + 16 + (l >>> 31 << 2) | 0; + j = c[S >> 2] | 0; + if ((j | 0) == 0) { + T = 258; + break; + } else { + l = l << 1; + m = j; + } + } + if ((T | 0) == 258) { + if (S >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[S >> 2] = e; + c[q + (g + 24) >> 2] = m; + c[q + (g + 12) >> 2] = e; + c[q + (g + 8) >> 2] = e; + break; + } + } + l = m + 8 | 0; + j = c[l >> 2] | 0; + i = c[28042] | 0; + if (m >>> 0 < i >>> 0) { + av(); + return 0; + } + if (j >>> 0 < i >>> 0) { + av(); + return 0; + } else { + c[j + 12 >> 2] = e; + c[l >> 2] = e; + c[q + (g + 8) >> 2] = j; + c[q + (g + 12) >> 2] = m; + c[q + (g + 24) >> 2] = 0; + break; + } + } + } while (0); + q = K + 8 | 0; + if ((q | 0) == 0) { + o = g; + break; + } else { + n = q; + } + return n | 0; + } + } while (0); + K = c[28040] | 0; + if (o >>> 0 <= K >>> 0) { + S = K - o | 0; + J = c[28043] | 0; + if (S >>> 0 > 15) { + R = J; + c[28043] = R + o; + c[28040] = S; + c[R + (o + 4) >> 2] = S | 1; + c[R + K >> 2] = S; + c[J + 4 >> 2] = o | 3; + } else { + c[28040] = 0; + c[28043] = 0; + c[J + 4 >> 2] = K | 3; + S = J + (K + 4) | 0; + c[S >> 2] = c[S >> 2] | 1; + } + n = J + 8 | 0; + return n | 0; + } + J = c[28041] | 0; + if (o >>> 0 < J >>> 0) { + S = J - o | 0; + c[28041] = S; + J = c[28044] | 0; + K = J; + c[28044] = K + o; + c[K + (o + 4) >> 2] = S | 1; + c[J + 4 >> 2] = o | 3; + n = J + 8 | 0; + return n | 0; + } + do { + if ((c[28014] | 0) == 0) { + J = ar(8) | 0; + if ((J - 1 & J | 0) == 0) { + c[28016] = J; + c[28015] = J; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + return 0; + } + } + } while (0); + J = o + 48 | 0; + S = c[28016] | 0; + K = o + 47 | 0; + R = S + K | 0; + Q = -S | 0; + S = R & Q; + if (S >>> 0 <= o >>> 0) { + n = 0; + return n | 0; + } + O = c[28148] | 0; + do { + if ((O | 0) != 0) { + P = c[28146] | 0; + L = P + S | 0; + if (L >>> 0 <= P >>> 0 | L >>> 0 > O >>> 0) { + n = 0; + } else { + break; + } + return n | 0; + } + } while (0); + L399 : do { + if ((c[28149] & 4 | 0) == 0) { + O = c[28044] | 0; + L401 : do { + if ((O | 0) == 0) { + T = 288; + } else { + L = O; + P = 112600; + while (1) { + U = P | 0; + M = c[U >> 2] | 0; + if (M >>> 0 <= L >>> 0) { + V = P + 4 | 0; + if ((M + (c[V >> 2] | 0) | 0) >>> 0 > L >>> 0) { + break; + } + } + M = c[P + 8 >> 2] | 0; + if ((M | 0) == 0) { + T = 288; + break L401; + } else { + P = M; + } + } + if ((P | 0) == 0) { + T = 288; + break; + } + L = R - (c[28041] | 0) & Q; + if (L >>> 0 >= 2147483647) { + W = 0; + break; + } + m = aW(L | 0) | 0; + e = (m | 0) == ((c[U >> 2] | 0) + (c[V >> 2] | 0) | 0); + X = e ? m : -1; + Y = e ? L : 0; + Z = m; + _ = L; + T = 297; + } + } while (0); + do { + if ((T | 0) == 288) { + O = aW(0) | 0; + if ((O | 0) == -1) { + W = 0; + break; + } + g = O; + L = c[28015] | 0; + m = L - 1 | 0; + if ((m & g | 0) == 0) { + $ = S; + } else { + $ = S - g + (m + g & -L) | 0; + } + L = c[28146] | 0; + g = L + $ | 0; + if (!($ >>> 0 > o >>> 0 & $ >>> 0 < 2147483647)) { + W = 0; + break; + } + m = c[28148] | 0; + if ((m | 0) != 0) { + if (g >>> 0 <= L >>> 0 | g >>> 0 > m >>> 0) { + W = 0; + break; + } + } + m = aW($ | 0) | 0; + g = (m | 0) == (O | 0); + X = g ? O : -1; + Y = g ? $ : 0; + Z = m; + _ = $; + T = 297; + } + } while (0); + L421 : do { + if ((T | 0) == 297) { + m = -_ | 0; + if ((X | 0) != -1) { + aa = Y; + ab = X; + T = 308; + break L399; + } + do { + if ((Z | 0) != -1 & _ >>> 0 < 2147483647 & _ >>> 0 < J >>> 0) { + g = c[28016] | 0; + O = K - _ + g & -g; + if (O >>> 0 >= 2147483647) { + ac = _; + break; + } + if ((aW(O | 0) | 0) == -1) { + aW(m | 0) | 0; + W = Y; + break L421; + } else { + ac = O + _ | 0; + break; + } + } else { + ac = _; + } + } while (0); + if ((Z | 0) == -1) { + W = Y; + } else { + aa = ac; + ab = Z; + T = 308; + break L399; + } + } + } while (0); + c[28149] = c[28149] | 4; + ad = W; + T = 305; + } else { + ad = 0; + T = 305; + } + } while (0); + do { + if ((T | 0) == 305) { + if (S >>> 0 >= 2147483647) { + break; + } + W = aW(S | 0) | 0; + Z = aW(0) | 0; + if (!((Z | 0) != -1 & (W | 0) != -1 & W >>> 0 < Z >>> 0)) { + break; + } + ac = Z - W | 0; + Z = ac >>> 0 > (o + 40 | 0) >>> 0; + Y = Z ? W : -1; + if ((Y | 0) != -1) { + aa = Z ? ac : ad; + ab = Y; + T = 308; + } + } + } while (0); + do { + if ((T | 0) == 308) { + ad = (c[28146] | 0) + aa | 0; + c[28146] = ad; + if (ad >>> 0 > (c[28147] | 0) >>> 0) { + c[28147] = ad; + } + ad = c[28044] | 0; + L441 : do { + if ((ad | 0) == 0) { + S = c[28042] | 0; + if ((S | 0) == 0 | ab >>> 0 < S >>> 0) { + c[28042] = ab; + } + c[28150] = ab; + c[28151] = aa; + c[28153] = 0; + c[28047] = c[28014]; + c[28046] = -1; + S = 0; + do { + Y = S << 1; + ac = 112192 + (Y << 2) | 0; + c[112192 + (Y + 3 << 2) >> 2] = ac; + c[112192 + (Y + 2 << 2) >> 2] = ac; + S = S + 1 | 0; + } while (S >>> 0 < 32); + S = ab + 8 | 0; + if ((S & 7 | 0) == 0) { + ae = 0; + } else { + ae = -S & 7; + } + S = aa - 40 - ae | 0; + c[28044] = ab + ae; + c[28041] = S; + c[ab + (ae + 4) >> 2] = S | 1; + c[ab + (aa - 36) >> 2] = 40; + c[28045] = c[28018]; + } else { + S = 112600; + while (1) { + af = c[S >> 2] | 0; + ag = S + 4 | 0; + ah = c[ag >> 2] | 0; + if ((ab | 0) == (af + ah | 0)) { + T = 320; + break; + } + ac = c[S + 8 >> 2] | 0; + if ((ac | 0) == 0) { + break; + } else { + S = ac; + } + } + do { + if ((T | 0) == 320) { + if ((c[S + 12 >> 2] & 8 | 0) != 0) { + break; + } + ac = ad; + if (!(ac >>> 0 >= af >>> 0 & ac >>> 0 < ab >>> 0)) { + break; + } + c[ag >> 2] = ah + aa; + ac = c[28044] | 0; + Y = (c[28041] | 0) + aa | 0; + Z = ac; + W = ac + 8 | 0; + if ((W & 7 | 0) == 0) { + ai = 0; + } else { + ai = -W & 7; + } + W = Y - ai | 0; + c[28044] = Z + ai; + c[28041] = W; + c[Z + (ai + 4) >> 2] = W | 1; + c[Z + (Y + 4) >> 2] = 40; + c[28045] = c[28018]; + break L441; + } + } while (0); + if (ab >>> 0 < (c[28042] | 0) >>> 0) { + c[28042] = ab; + } + S = ab + aa | 0; + Y = 112600; + while (1) { + aj = Y | 0; + if ((c[aj >> 2] | 0) == (S | 0)) { + T = 330; + break; + } + Z = c[Y + 8 >> 2] | 0; + if ((Z | 0) == 0) { + break; + } else { + Y = Z; + } + } + do { + if ((T | 0) == 330) { + if ((c[Y + 12 >> 2] & 8 | 0) != 0) { + break; + } + c[aj >> 2] = ab; + S = Y + 4 | 0; + c[S >> 2] = (c[S >> 2] | 0) + aa; + S = ab + 8 | 0; + if ((S & 7 | 0) == 0) { + ak = 0; + } else { + ak = -S & 7; + } + S = ab + (aa + 8) | 0; + if ((S & 7 | 0) == 0) { + al = 0; + } else { + al = -S & 7; + } + S = ab + (al + aa) | 0; + Z = S; + W = ak + o | 0; + ac = ab + W | 0; + _ = ac; + K = S - (ab + ak) - o | 0; + c[ab + (ak + 4) >> 2] = o | 3; + do { + if ((Z | 0) == (c[28044] | 0)) { + J = (c[28041] | 0) + K | 0; + c[28041] = J; + c[28044] = _; + c[ab + (W + 4) >> 2] = J | 1; + } else { + if ((Z | 0) == (c[28043] | 0)) { + J = (c[28040] | 0) + K | 0; + c[28040] = J; + c[28043] = _; + c[ab + (W + 4) >> 2] = J | 1; + c[ab + (J + W) >> 2] = J; + break; + } + J = aa + 4 | 0; + X = c[ab + (J + al) >> 2] | 0; + if ((X & 3 | 0) == 1) { + $ = X & -8; + V = X >>> 3; + L486 : do { + if (X >>> 0 < 256) { + U = c[ab + ((al | 8) + aa) >> 2] | 0; + Q = c[ab + (aa + 12 + al) >> 2] | 0; + R = 112192 + (V << 1 << 2) | 0; + do { + if ((U | 0) != (R | 0)) { + if (U >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + if ((c[U + 12 >> 2] | 0) == (Z | 0)) { + break; + } + av(); + return 0; + } + } while (0); + if ((Q | 0) == (U | 0)) { + c[28038] = c[28038] & ~(1 << V); + break; + } + do { + if ((Q | 0) == (R | 0)) { + am = Q + 8 | 0; + } else { + if (Q >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + m = Q + 8 | 0; + if ((c[m >> 2] | 0) == (Z | 0)) { + am = m; + break; + } + av(); + return 0; + } + } while (0); + c[U + 12 >> 2] = Q; + c[am >> 2] = U; + } else { + R = S; + m = c[ab + ((al | 24) + aa) >> 2] | 0; + P = c[ab + (aa + 12 + al) >> 2] | 0; + do { + if ((P | 0) == (R | 0)) { + O = al | 16; + g = ab + (J + O) | 0; + L = c[g >> 2] | 0; + if ((L | 0) == 0) { + e = ab + (O + aa) | 0; + O = c[e >> 2] | 0; + if ((O | 0) == 0) { + an = 0; + break; + } else { + ao = O; + ap = e; + } + } else { + ao = L; + ap = g; + } + while (1) { + g = ao + 20 | 0; + L = c[g >> 2] | 0; + if ((L | 0) != 0) { + ao = L; + ap = g; + continue; + } + g = ao + 16 | 0; + L = c[g >> 2] | 0; + if ((L | 0) == 0) { + break; + } else { + ao = L; + ap = g; + } + } + if (ap >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[ap >> 2] = 0; + an = ao; + break; + } + } else { + g = c[ab + ((al | 8) + aa) >> 2] | 0; + if (g >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + L = g + 12 | 0; + if ((c[L >> 2] | 0) != (R | 0)) { + av(); + return 0; + } + e = P + 8 | 0; + if ((c[e >> 2] | 0) == (R | 0)) { + c[L >> 2] = P; + c[e >> 2] = g; + an = P; + break; + } else { + av(); + return 0; + } + } + } while (0); + if ((m | 0) == 0) { + break; + } + P = ab + (aa + 28 + al) | 0; + U = 112456 + (c[P >> 2] << 2) | 0; + do { + if ((R | 0) == (c[U >> 2] | 0)) { + c[U >> 2] = an; + if ((an | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[P >> 2]); + break L486; + } else { + if (m >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + Q = m + 16 | 0; + if ((c[Q >> 2] | 0) == (R | 0)) { + c[Q >> 2] = an; + } else { + c[m + 20 >> 2] = an; + } + if ((an | 0) == 0) { + break L486; + } + } + } while (0); + if (an >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + c[an + 24 >> 2] = m; + R = al | 16; + P = c[ab + (R + aa) >> 2] | 0; + do { + if ((P | 0) != 0) { + if (P >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[an + 16 >> 2] = P; + c[P + 24 >> 2] = an; + break; + } + } + } while (0); + P = c[ab + (J + R) >> 2] | 0; + if ((P | 0) == 0) { + break; + } + if (P >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[an + 20 >> 2] = P; + c[P + 24 >> 2] = an; + break; + } + } + } while (0); + aq = ab + (($ | al) + aa) | 0; + as = $ + K | 0; + } else { + aq = Z; + as = K; + } + J = aq + 4 | 0; + c[J >> 2] = c[J >> 2] & -2; + c[ab + (W + 4) >> 2] = as | 1; + c[ab + (as + W) >> 2] = as; + J = as >>> 3; + if (as >>> 0 < 256) { + V = J << 1; + X = 112192 + (V << 2) | 0; + P = c[28038] | 0; + m = 1 << J; + do { + if ((P & m | 0) == 0) { + c[28038] = P | m; + at = X; + au = 112192 + (V + 2 << 2) | 0; + } else { + J = 112192 + (V + 2 << 2) | 0; + U = c[J >> 2] | 0; + if (U >>> 0 >= (c[28042] | 0) >>> 0) { + at = U; + au = J; + break; + } + av(); + return 0; + } + } while (0); + c[au >> 2] = _; + c[at + 12 >> 2] = _; + c[ab + (W + 8) >> 2] = at; + c[ab + (W + 12) >> 2] = X; + break; + } + V = ac; + m = as >>> 8; + do { + if ((m | 0) == 0) { + aw = 0; + } else { + if (as >>> 0 > 16777215) { + aw = 31; + break; + } + P = (m + 1048320 | 0) >>> 16 & 8; + $ = m << P; + J = ($ + 520192 | 0) >>> 16 & 4; + U = $ << J; + $ = (U + 245760 | 0) >>> 16 & 2; + Q = 14 - (J | P | $) + (U << $ >>> 15) | 0; + aw = as >>> ((Q + 7 | 0) >>> 0) & 1 | Q << 1; + } + } while (0); + m = 112456 + (aw << 2) | 0; + c[ab + (W + 28) >> 2] = aw; + c[ab + (W + 20) >> 2] = 0; + c[ab + (W + 16) >> 2] = 0; + X = c[28039] | 0; + Q = 1 << aw; + if ((X & Q | 0) == 0) { + c[28039] = X | Q; + c[m >> 2] = V; + c[ab + (W + 24) >> 2] = m; + c[ab + (W + 12) >> 2] = V; + c[ab + (W + 8) >> 2] = V; + break; + } + if ((aw | 0) == 31) { + ax = 0; + } else { + ax = 25 - (aw >>> 1) | 0; + } + Q = as << ax; + X = c[m >> 2] | 0; + while (1) { + if ((c[X + 4 >> 2] & -8 | 0) == (as | 0)) { + break; + } + ay = X + 16 + (Q >>> 31 << 2) | 0; + m = c[ay >> 2] | 0; + if ((m | 0) == 0) { + T = 403; + break; + } else { + Q = Q << 1; + X = m; + } + } + if ((T | 0) == 403) { + if (ay >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[ay >> 2] = V; + c[ab + (W + 24) >> 2] = X; + c[ab + (W + 12) >> 2] = V; + c[ab + (W + 8) >> 2] = V; + break; + } + } + Q = X + 8 | 0; + m = c[Q >> 2] | 0; + $ = c[28042] | 0; + if (X >>> 0 < $ >>> 0) { + av(); + return 0; + } + if (m >>> 0 < $ >>> 0) { + av(); + return 0; + } else { + c[m + 12 >> 2] = V; + c[Q >> 2] = V; + c[ab + (W + 8) >> 2] = m; + c[ab + (W + 12) >> 2] = X; + c[ab + (W + 24) >> 2] = 0; + break; + } + } + } while (0); + n = ab + (ak | 8) | 0; + return n | 0; + } + } while (0); + Y = ad; + W = 112600; + while (1) { + az = c[W >> 2] | 0; + if (az >>> 0 <= Y >>> 0) { + aA = c[W + 4 >> 2] | 0; + aB = az + aA | 0; + if (aB >>> 0 > Y >>> 0) { + break; + } + } + W = c[W + 8 >> 2] | 0; + } + W = az + (aA - 39) | 0; + if ((W & 7 | 0) == 0) { + aC = 0; + } else { + aC = -W & 7; + } + W = az + (aA - 47 + aC) | 0; + ac = W >>> 0 < (ad + 16 | 0) >>> 0 ? Y : W; + W = ac + 8 | 0; + _ = ab + 8 | 0; + if ((_ & 7 | 0) == 0) { + aD = 0; + } else { + aD = -_ & 7; + } + _ = aa - 40 - aD | 0; + c[28044] = ab + aD; + c[28041] = _; + c[ab + (aD + 4) >> 2] = _ | 1; + c[ab + (aa - 36) >> 2] = 40; + c[28045] = c[28018]; + c[ac + 4 >> 2] = 27; + c[W >> 2] = c[28150]; + c[W + 4 >> 2] = c[112604 >> 2]; + c[W + 8 >> 2] = c[112608 >> 2]; + c[W + 12 >> 2] = c[112612 >> 2]; + c[28150] = ab; + c[28151] = aa; + c[28153] = 0; + c[28152] = W; + W = ac + 28 | 0; + c[W >> 2] = 7; + if ((ac + 32 | 0) >>> 0 < aB >>> 0) { + _ = W; + while (1) { + W = _ + 4 | 0; + c[W >> 2] = 7; + if ((_ + 8 | 0) >>> 0 < aB >>> 0) { + _ = W; + } else { + break; + } + } + } + if ((ac | 0) == (Y | 0)) { + break; + } + _ = ac - ad | 0; + W = Y + (_ + 4) | 0; + c[W >> 2] = c[W >> 2] & -2; + c[ad + 4 >> 2] = _ | 1; + c[Y + _ >> 2] = _; + W = _ >>> 3; + if (_ >>> 0 < 256) { + K = W << 1; + Z = 112192 + (K << 2) | 0; + S = c[28038] | 0; + m = 1 << W; + do { + if ((S & m | 0) == 0) { + c[28038] = S | m; + aE = Z; + aF = 112192 + (K + 2 << 2) | 0; + } else { + W = 112192 + (K + 2 << 2) | 0; + Q = c[W >> 2] | 0; + if (Q >>> 0 >= (c[28042] | 0) >>> 0) { + aE = Q; + aF = W; + break; + } + av(); + return 0; + } + } while (0); + c[aF >> 2] = ad; + c[aE + 12 >> 2] = ad; + c[ad + 8 >> 2] = aE; + c[ad + 12 >> 2] = Z; + break; + } + K = ad; + m = _ >>> 8; + do { + if ((m | 0) == 0) { + aG = 0; + } else { + if (_ >>> 0 > 16777215) { + aG = 31; + break; + } + S = (m + 1048320 | 0) >>> 16 & 8; + Y = m << S; + ac = (Y + 520192 | 0) >>> 16 & 4; + W = Y << ac; + Y = (W + 245760 | 0) >>> 16 & 2; + Q = 14 - (ac | S | Y) + (W << Y >>> 15) | 0; + aG = _ >>> ((Q + 7 | 0) >>> 0) & 1 | Q << 1; + } + } while (0); + m = 112456 + (aG << 2) | 0; + c[ad + 28 >> 2] = aG; + c[ad + 20 >> 2] = 0; + c[ad + 16 >> 2] = 0; + Z = c[28039] | 0; + Q = 1 << aG; + if ((Z & Q | 0) == 0) { + c[28039] = Z | Q; + c[m >> 2] = K; + c[ad + 24 >> 2] = m; + c[ad + 12 >> 2] = ad; + c[ad + 8 >> 2] = ad; + break; + } + if ((aG | 0) == 31) { + aH = 0; + } else { + aH = 25 - (aG >>> 1) | 0; + } + Q = _ << aH; + Z = c[m >> 2] | 0; + while (1) { + if ((c[Z + 4 >> 2] & -8 | 0) == (_ | 0)) { + break; + } + aI = Z + 16 + (Q >>> 31 << 2) | 0; + m = c[aI >> 2] | 0; + if ((m | 0) == 0) { + T = 438; + break; + } else { + Q = Q << 1; + Z = m; + } + } + if ((T | 0) == 438) { + if (aI >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[aI >> 2] = K; + c[ad + 24 >> 2] = Z; + c[ad + 12 >> 2] = ad; + c[ad + 8 >> 2] = ad; + break; + } + } + Q = Z + 8 | 0; + _ = c[Q >> 2] | 0; + m = c[28042] | 0; + if (Z >>> 0 < m >>> 0) { + av(); + return 0; + } + if (_ >>> 0 < m >>> 0) { + av(); + return 0; + } else { + c[_ + 12 >> 2] = K; + c[Q >> 2] = K; + c[ad + 8 >> 2] = _; + c[ad + 12 >> 2] = Z; + c[ad + 24 >> 2] = 0; + break; + } + } + } while (0); + ad = c[28041] | 0; + if (ad >>> 0 <= o >>> 0) { + break; + } + _ = ad - o | 0; + c[28041] = _; + ad = c[28044] | 0; + Q = ad; + c[28044] = Q + o; + c[Q + (o + 4) >> 2] = _ | 1; + c[ad + 4 >> 2] = o | 3; + n = ad + 8 | 0; + return n | 0; + } + } while (0); + c[(aY() | 0) >> 2] = 12; + n = 0; + return n | 0; +} +function eo(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0; + if ((a | 0) == 0) { + return; + } + b = a - 8 | 0; + d = b; + e = c[28042] | 0; + if (b >>> 0 < e >>> 0) { + av(); + } + f = c[a - 4 >> 2] | 0; + g = f & 3; + if ((g | 0) == 1) { + av(); + } + h = f & -8; + i = a + (h - 8) | 0; + j = i; + L658 : do { + if ((f & 1 | 0) == 0) { + k = c[b >> 2] | 0; + if ((g | 0) == 0) { + return; + } + l = -8 - k | 0; + m = a + l | 0; + n = m; + o = k + h | 0; + if (m >>> 0 < e >>> 0) { + av(); + } + if ((n | 0) == (c[28043] | 0)) { + p = a + (h - 4) | 0; + if ((c[p >> 2] & 3 | 0) != 3) { + q = n; + r = o; + break; + } + c[28040] = o; + c[p >> 2] = c[p >> 2] & -2; + c[a + (l + 4) >> 2] = o | 1; + c[i >> 2] = o; + return; + } + p = k >>> 3; + if (k >>> 0 < 256) { + k = c[a + (l + 8) >> 2] | 0; + s = c[a + (l + 12) >> 2] | 0; + t = 112192 + (p << 1 << 2) | 0; + do { + if ((k | 0) != (t | 0)) { + if (k >>> 0 < e >>> 0) { + av(); + } + if ((c[k + 12 >> 2] | 0) == (n | 0)) { + break; + } + av(); + } + } while (0); + if ((s | 0) == (k | 0)) { + c[28038] = c[28038] & ~(1 << p); + q = n; + r = o; + break; + } + do { + if ((s | 0) == (t | 0)) { + u = s + 8 | 0; + } else { + if (s >>> 0 < e >>> 0) { + av(); + } + v = s + 8 | 0; + if ((c[v >> 2] | 0) == (n | 0)) { + u = v; + break; + } + av(); + } + } while (0); + c[k + 12 >> 2] = s; + c[u >> 2] = k; + q = n; + r = o; + break; + } + t = m; + p = c[a + (l + 24) >> 2] | 0; + v = c[a + (l + 12) >> 2] | 0; + do { + if ((v | 0) == (t | 0)) { + w = a + (l + 20) | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + y = a + (l + 16) | 0; + z = c[y >> 2] | 0; + if ((z | 0) == 0) { + A = 0; + break; + } else { + B = z; + C = y; + } + } else { + B = x; + C = w; + } + while (1) { + w = B + 20 | 0; + x = c[w >> 2] | 0; + if ((x | 0) != 0) { + B = x; + C = w; + continue; + } + w = B + 16 | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + break; + } else { + B = x; + C = w; + } + } + if (C >>> 0 < e >>> 0) { + av(); + } else { + c[C >> 2] = 0; + A = B; + break; + } + } else { + w = c[a + (l + 8) >> 2] | 0; + if (w >>> 0 < e >>> 0) { + av(); + } + x = w + 12 | 0; + if ((c[x >> 2] | 0) != (t | 0)) { + av(); + } + y = v + 8 | 0; + if ((c[y >> 2] | 0) == (t | 0)) { + c[x >> 2] = v; + c[y >> 2] = w; + A = v; + break; + } else { + av(); + } + } + } while (0); + if ((p | 0) == 0) { + q = n; + r = o; + break; + } + v = a + (l + 28) | 0; + m = 112456 + (c[v >> 2] << 2) | 0; + do { + if ((t | 0) == (c[m >> 2] | 0)) { + c[m >> 2] = A; + if ((A | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[v >> 2]); + q = n; + r = o; + break L658; + } else { + if (p >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + k = p + 16 | 0; + if ((c[k >> 2] | 0) == (t | 0)) { + c[k >> 2] = A; + } else { + c[p + 20 >> 2] = A; + } + if ((A | 0) == 0) { + q = n; + r = o; + break L658; + } + } + } while (0); + if (A >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + c[A + 24 >> 2] = p; + t = c[a + (l + 16) >> 2] | 0; + do { + if ((t | 0) != 0) { + if (t >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[A + 16 >> 2] = t; + c[t + 24 >> 2] = A; + break; + } + } + } while (0); + t = c[a + (l + 20) >> 2] | 0; + if ((t | 0) == 0) { + q = n; + r = o; + break; + } + if (t >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[A + 20 >> 2] = t; + c[t + 24 >> 2] = A; + q = n; + r = o; + break; + } + } else { + q = d; + r = h; + } + } while (0); + d = q; + if (d >>> 0 >= i >>> 0) { + av(); + } + A = a + (h - 4) | 0; + e = c[A >> 2] | 0; + if ((e & 1 | 0) == 0) { + av(); + } + do { + if ((e & 2 | 0) == 0) { + if ((j | 0) == (c[28044] | 0)) { + B = (c[28041] | 0) + r | 0; + c[28041] = B; + c[28044] = q; + c[q + 4 >> 2] = B | 1; + if ((q | 0) == (c[28043] | 0)) { + c[28043] = 0; + c[28040] = 0; + } + if (B >>> 0 <= (c[28045] | 0) >>> 0) { + return; + } + eu(0) | 0; + return; + } + if ((j | 0) == (c[28043] | 0)) { + B = (c[28040] | 0) + r | 0; + c[28040] = B; + c[28043] = q; + c[q + 4 >> 2] = B | 1; + c[d + B >> 2] = B; + return; + } + B = (e & -8) + r | 0; + C = e >>> 3; + L764 : do { + if (e >>> 0 < 256) { + u = c[a + h >> 2] | 0; + g = c[a + (h | 4) >> 2] | 0; + b = 112192 + (C << 1 << 2) | 0; + do { + if ((u | 0) != (b | 0)) { + if (u >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + if ((c[u + 12 >> 2] | 0) == (j | 0)) { + break; + } + av(); + } + } while (0); + if ((g | 0) == (u | 0)) { + c[28038] = c[28038] & ~(1 << C); + break; + } + do { + if ((g | 0) == (b | 0)) { + D = g + 8 | 0; + } else { + if (g >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + f = g + 8 | 0; + if ((c[f >> 2] | 0) == (j | 0)) { + D = f; + break; + } + av(); + } + } while (0); + c[u + 12 >> 2] = g; + c[D >> 2] = u; + } else { + b = i; + f = c[a + (h + 16) >> 2] | 0; + t = c[a + (h | 4) >> 2] | 0; + do { + if ((t | 0) == (b | 0)) { + p = a + (h + 12) | 0; + v = c[p >> 2] | 0; + if ((v | 0) == 0) { + m = a + (h + 8) | 0; + k = c[m >> 2] | 0; + if ((k | 0) == 0) { + E = 0; + break; + } else { + F = k; + G = m; + } + } else { + F = v; + G = p; + } + while (1) { + p = F + 20 | 0; + v = c[p >> 2] | 0; + if ((v | 0) != 0) { + F = v; + G = p; + continue; + } + p = F + 16 | 0; + v = c[p >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + F = v; + G = p; + } + } + if (G >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[G >> 2] = 0; + E = F; + break; + } + } else { + p = c[a + h >> 2] | 0; + if (p >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + v = p + 12 | 0; + if ((c[v >> 2] | 0) != (b | 0)) { + av(); + } + m = t + 8 | 0; + if ((c[m >> 2] | 0) == (b | 0)) { + c[v >> 2] = t; + c[m >> 2] = p; + E = t; + break; + } else { + av(); + } + } + } while (0); + if ((f | 0) == 0) { + break; + } + t = a + (h + 20) | 0; + u = 112456 + (c[t >> 2] << 2) | 0; + do { + if ((b | 0) == (c[u >> 2] | 0)) { + c[u >> 2] = E; + if ((E | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[t >> 2]); + break L764; + } else { + if (f >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + g = f + 16 | 0; + if ((c[g >> 2] | 0) == (b | 0)) { + c[g >> 2] = E; + } else { + c[f + 20 >> 2] = E; + } + if ((E | 0) == 0) { + break L764; + } + } + } while (0); + if (E >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + c[E + 24 >> 2] = f; + b = c[a + (h + 8) >> 2] | 0; + do { + if ((b | 0) != 0) { + if (b >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[E + 16 >> 2] = b; + c[b + 24 >> 2] = E; + break; + } + } + } while (0); + b = c[a + (h + 12) >> 2] | 0; + if ((b | 0) == 0) { + break; + } + if (b >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[E + 20 >> 2] = b; + c[b + 24 >> 2] = E; + break; + } + } + } while (0); + c[q + 4 >> 2] = B | 1; + c[d + B >> 2] = B; + if ((q | 0) != (c[28043] | 0)) { + H = B; + break; + } + c[28040] = B; + return; + } else { + c[A >> 2] = e & -2; + c[q + 4 >> 2] = r | 1; + c[d + r >> 2] = r; + H = r; + } + } while (0); + r = H >>> 3; + if (H >>> 0 < 256) { + d = r << 1; + e = 112192 + (d << 2) | 0; + A = c[28038] | 0; + E = 1 << r; + do { + if ((A & E | 0) == 0) { + c[28038] = A | E; + I = e; + J = 112192 + (d + 2 << 2) | 0; + } else { + r = 112192 + (d + 2 << 2) | 0; + h = c[r >> 2] | 0; + if (h >>> 0 >= (c[28042] | 0) >>> 0) { + I = h; + J = r; + break; + } + av(); + } + } while (0); + c[J >> 2] = q; + c[I + 12 >> 2] = q; + c[q + 8 >> 2] = I; + c[q + 12 >> 2] = e; + return; + } + e = q; + I = H >>> 8; + do { + if ((I | 0) == 0) { + K = 0; + } else { + if (H >>> 0 > 16777215) { + K = 31; + break; + } + J = (I + 1048320 | 0) >>> 16 & 8; + d = I << J; + E = (d + 520192 | 0) >>> 16 & 4; + A = d << E; + d = (A + 245760 | 0) >>> 16 & 2; + r = 14 - (E | J | d) + (A << d >>> 15) | 0; + K = H >>> ((r + 7 | 0) >>> 0) & 1 | r << 1; + } + } while (0); + I = 112456 + (K << 2) | 0; + c[q + 28 >> 2] = K; + c[q + 20 >> 2] = 0; + c[q + 16 >> 2] = 0; + r = c[28039] | 0; + d = 1 << K; + do { + if ((r & d | 0) == 0) { + c[28039] = r | d; + c[I >> 2] = e; + c[q + 24 >> 2] = I; + c[q + 12 >> 2] = q; + c[q + 8 >> 2] = q; + } else { + if ((K | 0) == 31) { + L = 0; + } else { + L = 25 - (K >>> 1) | 0; + } + A = H << L; + J = c[I >> 2] | 0; + while (1) { + if ((c[J + 4 >> 2] & -8 | 0) == (H | 0)) { + break; + } + M = J + 16 + (A >>> 31 << 2) | 0; + E = c[M >> 2] | 0; + if ((E | 0) == 0) { + N = 617; + break; + } else { + A = A << 1; + J = E; + } + } + if ((N | 0) == 617) { + if (M >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[M >> 2] = e; + c[q + 24 >> 2] = J; + c[q + 12 >> 2] = q; + c[q + 8 >> 2] = q; + break; + } + } + A = J + 8 | 0; + B = c[A >> 2] | 0; + E = c[28042] | 0; + if (J >>> 0 < E >>> 0) { + av(); + } + if (B >>> 0 < E >>> 0) { + av(); + } else { + c[B + 12 >> 2] = e; + c[A >> 2] = e; + c[q + 8 >> 2] = B; + c[q + 12 >> 2] = J; + c[q + 24 >> 2] = 0; + break; + } + } + } while (0); + q = (c[28046] | 0) - 1 | 0; + c[28046] = q; + if ((q | 0) == 0) { + O = 112608; + } else { + return; + } + while (1) { + q = c[O >> 2] | 0; + if ((q | 0) == 0) { + break; + } else { + O = q + 8 | 0; + } + } + c[28046] = -1; + return; +} +function ep(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + do { + if ((a | 0) == 0) { + d = 0; + } else { + e = ad(b, a) | 0; + if ((b | a) >>> 0 <= 65535) { + d = e; + break; + } + d = ((e >>> 0) / (a >>> 0) | 0 | 0) == (b | 0) ? e : -1; + } + } while (0); + b = en(d) | 0; + if ((b | 0) == 0) { + return b | 0; + } + if ((c[b - 4 >> 2] & 3 | 0) == 0) { + return b | 0; + } + fm(b | 0, 0, d | 0); + return b | 0; +} +function eq(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0; + if ((a | 0) == 0) { + d = en(b) | 0; + return d | 0; + } + if (b >>> 0 > 4294967231) { + c[(aY() | 0) >> 2] = 12; + d = 0; + return d | 0; + } + if (b >>> 0 < 11) { + e = 16; + } else { + e = b + 11 & -8; + } + f = ev(a - 8 | 0, e) | 0; + if ((f | 0) != 0) { + d = f + 8 | 0; + return d | 0; + } + f = en(b) | 0; + if ((f | 0) == 0) { + d = 0; + return d | 0; + } + e = c[a - 4 >> 2] | 0; + g = (e & -8) - ((e & 3 | 0) == 0 ? 8 : 4) | 0; + e = g >>> 0 < b >>> 0 ? g : b; + fn(f | 0, a | 0, e) | 0; + eo(a); + d = f; + return d | 0; +} +function er(a, b) { + a = a | 0; + b = b | 0; + var d = 0; + if ((a | 0) == 0) { + return 0; + } + if (b >>> 0 > 4294967231) { + c[(aY() | 0) >> 2] = 12; + return 0; + } + if (b >>> 0 < 11) { + d = 16; + } else { + d = b + 11 & -8; + } + b = a - 8 | 0; + return ((ev(b, d) | 0) == (b | 0) ? a : 0) | 0; +} +function es(a, b) { + a = a | 0; + b = b | 0; + var c = 0; + if (a >>> 0 < 9) { + c = en(b) | 0; + return c | 0; + } else { + c = et(a, b) | 0; + return c | 0; + } + return 0; +} +function et(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + d = a >>> 0 < 16 ? 16 : a; + if ((d - 1 & d | 0) == 0) { + e = d; + } else { + a = 16; + while (1) { + if (a >>> 0 < d >>> 0) { + a = a << 1; + } else { + e = a; + break; + } + } + } + if ((-64 - e | 0) >>> 0 <= b >>> 0) { + c[(aY() | 0) >> 2] = 12; + f = 0; + return f | 0; + } + if (b >>> 0 < 11) { + g = 16; + } else { + g = b + 11 & -8; + } + b = en(e + 12 + g | 0) | 0; + if ((b | 0) == 0) { + f = 0; + return f | 0; + } + a = b - 8 | 0; + d = a; + h = e - 1 | 0; + do { + if ((b & h | 0) == 0) { + i = d; + } else { + j = b + h & -e; + k = j - 8 | 0; + l = a; + if ((k - l | 0) >>> 0 > 15) { + m = k; + } else { + m = j + (e - 8) | 0; + } + j = m; + k = m - l | 0; + l = b - 4 | 0; + n = c[l >> 2] | 0; + o = (n & -8) - k | 0; + if ((n & 3 | 0) == 0) { + c[m >> 2] = (c[a >> 2] | 0) + k; + c[m + 4 >> 2] = o; + i = j; + break; + } else { + n = m + 4 | 0; + c[n >> 2] = o | c[n >> 2] & 1 | 2; + n = m + (o + 4) | 0; + c[n >> 2] = c[n >> 2] | 1; + c[l >> 2] = k | c[l >> 2] & 1 | 2; + l = b + (k - 4) | 0; + c[l >> 2] = c[l >> 2] | 1; + eN(d, k); + i = j; + break; + } + } + } while (0); + d = i + 4 | 0; + b = c[d >> 2] | 0; + do { + if ((b & 3 | 0) != 0) { + m = b & -8; + if (m >>> 0 <= (g + 16 | 0) >>> 0) { + break; + } + a = m - g | 0; + e = i; + c[d >> 2] = g | b & 1 | 2; + c[e + (g | 4) >> 2] = a | 3; + h = e + (m | 4) | 0; + c[h >> 2] = c[h >> 2] | 1; + eN(e + g | 0, a); + } + } while (0); + f = i + 8 | 0; + return f | 0; +} +function eu(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + do { + if ((c[28014] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[28016] = b; + c[28015] = b; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + return 0; + } + } + } while (0); + if (a >>> 0 >= 4294967232) { + d = 0; + return d | 0; + } + b = c[28044] | 0; + if ((b | 0) == 0) { + d = 0; + return d | 0; + } + e = c[28041] | 0; + do { + if (e >>> 0 > (a + 40 | 0) >>> 0) { + f = c[28016] | 0; + g = ad((((-40 - a - 1 + e + f | 0) >>> 0) / (f >>> 0) | 0) - 1 | 0, f) | 0; + h = b; + i = 112600; + while (1) { + j = c[i >> 2] | 0; + if (j >>> 0 <= h >>> 0) { + if ((j + (c[i + 4 >> 2] | 0) | 0) >>> 0 > h >>> 0) { + k = i; + break; + } + } + j = c[i + 8 >> 2] | 0; + if ((j | 0) == 0) { + k = 0; + break; + } else { + i = j; + } + } + if ((c[k + 12 >> 2] & 8 | 0) != 0) { + break; + } + i = aW(0) | 0; + h = k + 4 | 0; + if ((i | 0) != ((c[k >> 2] | 0) + (c[h >> 2] | 0) | 0)) { + break; + } + j = aW(-(g >>> 0 > 2147483646 ? -2147483648 - f | 0 : g) | 0) | 0; + l = aW(0) | 0; + if (!((j | 0) != -1 & l >>> 0 < i >>> 0)) { + break; + } + j = i - l | 0; + if ((i | 0) == (l | 0)) { + break; + } + c[h >> 2] = (c[h >> 2] | 0) - j; + c[28146] = (c[28146] | 0) - j; + h = c[28044] | 0; + m = (c[28041] | 0) - j | 0; + j = h; + n = h + 8 | 0; + if ((n & 7 | 0) == 0) { + o = 0; + } else { + o = -n & 7; + } + n = m - o | 0; + c[28044] = j + o; + c[28041] = n; + c[j + (o + 4) >> 2] = n | 1; + c[j + (m + 4) >> 2] = 40; + c[28045] = c[28018]; + d = (i | 0) != (l | 0) | 0; + return d | 0; + } + } while (0); + if ((c[28041] | 0) >>> 0 <= (c[28045] | 0) >>> 0) { + d = 0; + return d | 0; + } + c[28045] = -1; + d = 0; + return d | 0; +} +function ev(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0; + d = a + 4 | 0; + e = c[d >> 2] | 0; + f = e & -8; + g = a; + h = g + f | 0; + i = h; + j = c[28042] | 0; + if (g >>> 0 < j >>> 0) { + av(); + return 0; + } + k = e & 3; + if (!((k | 0) != 1 & g >>> 0 < h >>> 0)) { + av(); + return 0; + } + l = g + (f | 4) | 0; + m = c[l >> 2] | 0; + if ((m & 1 | 0) == 0) { + av(); + return 0; + } + if ((k | 0) == 0) { + if (b >>> 0 < 256) { + n = 0; + return n | 0; + } + do { + if (f >>> 0 >= (b + 4 | 0) >>> 0) { + if ((f - b | 0) >>> 0 > c[28016] << 1 >>> 0) { + break; + } else { + n = a; + } + return n | 0; + } + } while (0); + n = 0; + return n | 0; + } + if (f >>> 0 >= b >>> 0) { + k = f - b | 0; + if (k >>> 0 <= 15) { + n = a; + return n | 0; + } + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = k | 3; + c[l >> 2] = c[l >> 2] | 1; + eN(g + b | 0, k); + n = a; + return n | 0; + } + if ((i | 0) == (c[28044] | 0)) { + k = (c[28041] | 0) + f | 0; + if (k >>> 0 <= b >>> 0) { + n = 0; + return n | 0; + } + l = k - b | 0; + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = l | 1; + c[28044] = g + b; + c[28041] = l; + n = a; + return n | 0; + } + if ((i | 0) == (c[28043] | 0)) { + l = (c[28040] | 0) + f | 0; + if (l >>> 0 < b >>> 0) { + n = 0; + return n | 0; + } + k = l - b | 0; + if (k >>> 0 > 15) { + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = k | 1; + c[g + l >> 2] = k; + o = g + (l + 4) | 0; + c[o >> 2] = c[o >> 2] & -2; + p = g + b | 0; + q = k; + } else { + c[d >> 2] = e & 1 | l | 2; + e = g + (l + 4) | 0; + c[e >> 2] = c[e >> 2] | 1; + p = 0; + q = 0; + } + c[28040] = q; + c[28043] = p; + n = a; + return n | 0; + } + if ((m & 2 | 0) != 0) { + n = 0; + return n | 0; + } + p = (m & -8) + f | 0; + if (p >>> 0 < b >>> 0) { + n = 0; + return n | 0; + } + q = p - b | 0; + e = m >>> 3; + L1042 : do { + if (m >>> 0 < 256) { + l = c[g + (f + 8) >> 2] | 0; + k = c[g + (f + 12) >> 2] | 0; + o = 112192 + (e << 1 << 2) | 0; + do { + if ((l | 0) != (o | 0)) { + if (l >>> 0 < j >>> 0) { + av(); + return 0; + } + if ((c[l + 12 >> 2] | 0) == (i | 0)) { + break; + } + av(); + return 0; + } + } while (0); + if ((k | 0) == (l | 0)) { + c[28038] = c[28038] & ~(1 << e); + break; + } + do { + if ((k | 0) == (o | 0)) { + r = k + 8 | 0; + } else { + if (k >>> 0 < j >>> 0) { + av(); + return 0; + } + s = k + 8 | 0; + if ((c[s >> 2] | 0) == (i | 0)) { + r = s; + break; + } + av(); + return 0; + } + } while (0); + c[l + 12 >> 2] = k; + c[r >> 2] = l; + } else { + o = h; + s = c[g + (f + 24) >> 2] | 0; + t = c[g + (f + 12) >> 2] | 0; + do { + if ((t | 0) == (o | 0)) { + u = g + (f + 20) | 0; + v = c[u >> 2] | 0; + if ((v | 0) == 0) { + w = g + (f + 16) | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + y = 0; + break; + } else { + z = x; + A = w; + } + } else { + z = v; + A = u; + } + while (1) { + u = z + 20 | 0; + v = c[u >> 2] | 0; + if ((v | 0) != 0) { + z = v; + A = u; + continue; + } + u = z + 16 | 0; + v = c[u >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + z = v; + A = u; + } + } + if (A >>> 0 < j >>> 0) { + av(); + return 0; + } else { + c[A >> 2] = 0; + y = z; + break; + } + } else { + u = c[g + (f + 8) >> 2] | 0; + if (u >>> 0 < j >>> 0) { + av(); + return 0; + } + v = u + 12 | 0; + if ((c[v >> 2] | 0) != (o | 0)) { + av(); + return 0; + } + w = t + 8 | 0; + if ((c[w >> 2] | 0) == (o | 0)) { + c[v >> 2] = t; + c[w >> 2] = u; + y = t; + break; + } else { + av(); + return 0; + } + } + } while (0); + if ((s | 0) == 0) { + break; + } + t = g + (f + 28) | 0; + l = 112456 + (c[t >> 2] << 2) | 0; + do { + if ((o | 0) == (c[l >> 2] | 0)) { + c[l >> 2] = y; + if ((y | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[t >> 2]); + break L1042; + } else { + if (s >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + k = s + 16 | 0; + if ((c[k >> 2] | 0) == (o | 0)) { + c[k >> 2] = y; + } else { + c[s + 20 >> 2] = y; + } + if ((y | 0) == 0) { + break L1042; + } + } + } while (0); + if (y >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } + c[y + 24 >> 2] = s; + o = c[g + (f + 16) >> 2] | 0; + do { + if ((o | 0) != 0) { + if (o >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[y + 16 >> 2] = o; + c[o + 24 >> 2] = y; + break; + } + } + } while (0); + o = c[g + (f + 20) >> 2] | 0; + if ((o | 0) == 0) { + break; + } + if (o >>> 0 < (c[28042] | 0) >>> 0) { + av(); + return 0; + } else { + c[y + 20 >> 2] = o; + c[o + 24 >> 2] = y; + break; + } + } + } while (0); + if (q >>> 0 < 16) { + c[d >> 2] = p | c[d >> 2] & 1 | 2; + y = g + (p | 4) | 0; + c[y >> 2] = c[y >> 2] | 1; + n = a; + return n | 0; + } else { + c[d >> 2] = c[d >> 2] & 1 | b | 2; + c[g + (b + 4) >> 2] = q | 3; + d = g + (p | 4) | 0; + c[d >> 2] = c[d >> 2] | 1; + eN(g + b | 0, q); + n = a; + return n | 0; + } + return 0; +} +function ew() { + return c[28146] | 0; +} +function ex() { + return c[28147] | 0; +} +function ey() { + var a = 0; + a = c[28148] | 0; + return ((a | 0) == 0 ? -1 : a) | 0; +} +function ez(a) { + a = a | 0; + var b = 0, d = 0; + if ((a | 0) == -1) { + b = 0; + } else { + d = c[28016] | 0; + b = a - 1 + d & -d; + } + c[28148] = b; + return b | 0; +} +function eA(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + do { + if ((a | 0) == 0) { + b = 0; + } else { + d = c[a - 4 >> 2] | 0; + e = d & 3; + if ((e | 0) == 1) { + b = 0; + break; + } + b = (d & -8) - ((e | 0) == 0 ? 8 : 4) | 0; + } + } while (0); + return b | 0; +} +function eB(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + do { + if ((b | 0) == 8) { + e = en(d) | 0; + } else { + f = b >>> 2; + if ((b & 3 | 0) != 0 | (f | 0) == 0) { + g = 22; + return g | 0; + } + if ((f + 1073741823 & f | 0) != 0) { + g = 22; + return g | 0; + } + if ((-64 - b | 0) >>> 0 < d >>> 0) { + g = 12; + return g | 0; + } else { + e = et(b >>> 0 < 16 ? 16 : b, d) | 0; + break; + } + } + } while (0); + if ((e | 0) == 0) { + g = 12; + return g | 0; + } + c[a >> 2] = e; + g = 0; + return g | 0; +} +function eC(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 8 | 0; + f = e | 0; + c[f >> 2] = b; + b = eG(a, f, 3, d) | 0; + i = e; + return b | 0; +} +function eD(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return eG(a, b, 0, c) | 0; +} +function eE(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + if ((c[28014] | 0) != 0) { + b = c[28015] | 0; + d = es(b, a) | 0; + return d | 0; + } + e = ar(8) | 0; + if ((e - 1 & e | 0) != 0) { + av(); + return 0; + } + c[28016] = e; + c[28015] = e; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + b = c[28015] | 0; + d = es(b, a) | 0; + return d | 0; +} +function eF(a) { + a = a | 0; + var b = 0; + do { + if ((c[28014] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[28016] = b; + c[28015] = b; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + return 0; + } + } + } while (0); + b = c[28015] | 0; + return es(b, a - 1 + b & -b) | 0; +} +function eG(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + do { + if ((c[28014] | 0) == 0) { + f = ar(8) | 0; + if ((f - 1 & f | 0) == 0) { + c[28016] = f; + c[28015] = f; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + return 0; + } + } + } while (0); + f = (a | 0) == 0; + do { + if ((e | 0) == 0) { + if (f) { + g = en(0) | 0; + return g | 0; + } else { + h = a << 2; + if (h >>> 0 < 11) { + i = 0; + j = 16; + break; + } + i = 0; + j = h + 11 & -8; + break; + } + } else { + if (f) { + g = e; + } else { + i = e; + j = 0; + break; + } + return g | 0; + } + } while (0); + do { + if ((d & 1 | 0) == 0) { + if (f) { + k = 0; + l = 0; + break; + } else { + m = 0; + n = 0; + } + while (1) { + e = c[b + (n << 2) >> 2] | 0; + if (e >>> 0 < 11) { + o = 16; + } else { + o = e + 11 & -8; + } + e = o + m | 0; + h = n + 1 | 0; + if ((h | 0) == (a | 0)) { + k = 0; + l = e; + break; + } else { + m = e; + n = h; + } + } + } else { + h = c[b >> 2] | 0; + if (h >>> 0 < 11) { + p = 16; + } else { + p = h + 11 & -8; + } + k = p; + l = ad(p, a) | 0; + } + } while (0); + p = en(j - 4 + l | 0) | 0; + if ((p | 0) == 0) { + g = 0; + return g | 0; + } + n = p - 8 | 0; + m = c[p - 4 >> 2] & -8; + if ((d & 2 | 0) != 0) { + fm(p | 0, 0, -4 - j + m | 0); + } + if ((i | 0) == 0) { + c[p + (l - 4) >> 2] = m - l | 3; + q = p + l | 0; + r = l; + } else { + q = i; + r = m; + } + c[q >> 2] = p; + p = a - 1 | 0; + L1202 : do { + if ((p | 0) == 0) { + s = n; + t = r; + } else { + if ((k | 0) == 0) { + u = n; + v = r; + w = 0; + } else { + a = n; + m = r; + i = 0; + while (1) { + l = m - k | 0; + c[a + 4 >> 2] = k | 3; + j = a + k | 0; + d = i + 1 | 0; + c[q + (d << 2) >> 2] = a + (k + 8); + if ((d | 0) == (p | 0)) { + s = j; + t = l; + break L1202; + } else { + a = j; + m = l; + i = d; + } + } + } + while (1) { + i = c[b + (w << 2) >> 2] | 0; + if (i >>> 0 < 11) { + x = 16; + } else { + x = i + 11 & -8; + } + i = v - x | 0; + c[u + 4 >> 2] = x | 3; + m = u + x | 0; + a = w + 1 | 0; + c[q + (a << 2) >> 2] = u + (x + 8); + if ((a | 0) == (p | 0)) { + s = m; + t = i; + break; + } else { + u = m; + v = i; + w = a; + } + } + } + } while (0); + c[s + 4 >> 2] = t | 3; + g = q; + return g | 0; +} +function eH(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + d = a + (b << 2) | 0; + L1215 : do { + if ((b | 0) != 0) { + e = a; + L1216 : while (1) { + f = c[e >> 2] | 0; + L1218 : do { + if ((f | 0) == 0) { + g = e + 4 | 0; + } else { + h = f - 8 | 0; + i = h; + j = f - 4 | 0; + k = c[j >> 2] & -8; + c[e >> 2] = 0; + if (h >>> 0 < (c[28042] | 0) >>> 0) { + l = 932; + break L1216; + } + h = c[j >> 2] | 0; + if ((h & 3 | 0) == 1) { + l = 931; + break L1216; + } + m = e + 4 | 0; + n = h - 8 & -8; + do { + if ((m | 0) != (d | 0)) { + if ((c[m >> 2] | 0) != (f + (n + 8) | 0)) { + break; + } + o = (c[f + (n | 4) >> 2] & -8) + k | 0; + c[j >> 2] = h & 1 | o | 2; + p = f + (o - 4) | 0; + c[p >> 2] = c[p >> 2] | 1; + c[m >> 2] = f; + g = m; + break L1218; + } + } while (0); + eN(i, k); + g = m; + } + } while (0); + if ((g | 0) == (d | 0)) { + break L1215; + } else { + e = g; + } + } + if ((l | 0) == 932) { + av(); + return 0; + } else if ((l | 0) == 931) { + av(); + return 0; + } + } + } while (0); + if ((c[28041] | 0) >>> 0 <= (c[28045] | 0) >>> 0) { + return 0; + } + eu(0) | 0; + return 0; +} +function eI(a) { + a = a | 0; + var b = 0, d = 0; + if ((c[28014] | 0) != 0) { + b = eu(a) | 0; + return b | 0; + } + d = ar(8) | 0; + if ((d - 1 & d | 0) != 0) { + av(); + return 0; + } + c[28016] = d; + c[28015] = d; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + b = eu(a) | 0; + return b | 0; +} +function eJ(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0; + do { + if ((c[28014] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[28016] = b; + c[28015] = b; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + } + } + } while (0); + b = c[28044] | 0; + if ((b | 0) == 0) { + d = 0; + e = 0; + f = 0; + g = 0; + h = 0; + i = 0; + j = 0; + } else { + k = c[28041] | 0; + l = k + 40 | 0; + m = 1; + n = l; + o = l; + l = 112600; + while (1) { + p = c[l >> 2] | 0; + q = p + 8 | 0; + if ((q & 7 | 0) == 0) { + r = 0; + } else { + r = -q & 7; + } + q = p + (c[l + 4 >> 2] | 0) | 0; + s = m; + t = n; + u = o; + v = p + r | 0; + while (1) { + if (v >>> 0 >= q >>> 0 | (v | 0) == (b | 0)) { + w = s; + x = t; + y = u; + break; + } + z = c[v + 4 >> 2] | 0; + if ((z | 0) == 7) { + w = s; + x = t; + y = u; + break; + } + A = z & -8; + B = A + u | 0; + if ((z & 3 | 0) == 1) { + C = A + t | 0; + D = s + 1 | 0; + } else { + C = t; + D = s; + } + z = v + A | 0; + if (z >>> 0 < p >>> 0) { + w = D; + x = C; + y = B; + break; + } else { + s = D; + t = C; + u = B; + v = z; + } + } + v = c[l + 8 >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + m = w; + n = x; + o = y; + l = v; + } + } + l = c[28146] | 0; + d = k; + e = y; + f = w; + g = l - y | 0; + h = c[28147] | 0; + i = l - x | 0; + j = x; + } + c[a >> 2] = e; + c[a + 4 >> 2] = f; + f = a + 8 | 0; + c[f >> 2] = 0; + c[f + 4 >> 2] = 0; + c[a + 16 >> 2] = g; + c[a + 20 >> 2] = h; + c[a + 24 >> 2] = 0; + c[a + 28 >> 2] = i; + c[a + 32 >> 2] = j; + c[a + 36 >> 2] = d; + return; +} +function eK() { + var a = 0, b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, q = 0, r = 0, s = 0, t = 0, u = 0; + a = i; + do { + if ((c[28014] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[28016] = b; + c[28015] = b; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + } + } + } while (0); + b = c[28044] | 0; + if ((b | 0) == 0) { + d = 0; + e = 0; + f = 0; + } else { + g = c[28147] | 0; + h = c[28146] | 0; + j = h - 40 - (c[28041] | 0) | 0; + k = 112600; + while (1) { + l = c[k >> 2] | 0; + m = l + 8 | 0; + if ((m & 7 | 0) == 0) { + n = 0; + } else { + n = -m & 7; + } + m = l + (c[k + 4 >> 2] | 0) | 0; + o = j; + q = l + n | 0; + while (1) { + if (q >>> 0 >= m >>> 0 | (q | 0) == (b | 0)) { + r = o; + break; + } + s = c[q + 4 >> 2] | 0; + if ((s | 0) == 7) { + r = o; + break; + } + t = s & -8; + u = o - ((s & 3 | 0) == 1 ? t : 0) | 0; + s = q + t | 0; + if (s >>> 0 < l >>> 0) { + r = u; + break; + } else { + o = u; + q = s; + } + } + q = c[k + 8 >> 2] | 0; + if ((q | 0) == 0) { + d = r; + e = h; + f = g; + break; + } else { + j = r; + k = q; + } + } + } + aw(c[p >> 2] | 0, 111824, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + aw(c[p >> 2] | 0, 111792, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + aw(c[p >> 2] | 0, 111704, (y = i, i = i + 8 | 0, c[y >> 2] = d, y) | 0) | 0; + i = a; + return; +} +function eL(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + do { + if ((c[28014] | 0) == 0) { + d = ar(8) | 0; + if ((d - 1 & d | 0) == 0) { + c[28016] = d; + c[28015] = d; + c[28017] = -1; + c[28018] = 2097152; + c[28019] = 0; + c[28149] = 0; + c[28014] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + av(); + return 0; + } + } + } while (0); + if ((a | 0) == (-2 | 0)) { + if ((c[28015] | 0) >>> 0 > b >>> 0) { + e = 0; + return e | 0; + } + if ((b - 1 & b | 0) != 0) { + e = 0; + return e | 0; + } + c[28016] = b; + e = 1; + return e | 0; + } else if ((a | 0) == (-3 | 0)) { + c[28017] = b; + e = 1; + return e | 0; + } else if ((a | 0) == (-1 | 0)) { + c[28018] = b; + e = 1; + return e | 0; + } else { + e = 0; + return e | 0; + } + return 0; +} +function eM() { + return (F = c[28158] | 0, c[28158] = F + 0, F) | 0; +} +function eN(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0; + d = a; + e = d + b | 0; + f = e; + g = c[a + 4 >> 2] | 0; + L1311 : do { + if ((g & 1 | 0) == 0) { + h = c[a >> 2] | 0; + if ((g & 3 | 0) == 0) { + return; + } + i = d + (-h | 0) | 0; + j = i; + k = h + b | 0; + l = c[28042] | 0; + if (i >>> 0 < l >>> 0) { + av(); + } + if ((j | 0) == (c[28043] | 0)) { + m = d + (b + 4) | 0; + if ((c[m >> 2] & 3 | 0) != 3) { + n = j; + o = k; + break; + } + c[28040] = k; + c[m >> 2] = c[m >> 2] & -2; + c[d + (4 - h) >> 2] = k | 1; + c[e >> 2] = k; + return; + } + m = h >>> 3; + if (h >>> 0 < 256) { + p = c[d + (8 - h) >> 2] | 0; + q = c[d + (12 - h) >> 2] | 0; + r = 112192 + (m << 1 << 2) | 0; + do { + if ((p | 0) != (r | 0)) { + if (p >>> 0 < l >>> 0) { + av(); + } + if ((c[p + 12 >> 2] | 0) == (j | 0)) { + break; + } + av(); + } + } while (0); + if ((q | 0) == (p | 0)) { + c[28038] = c[28038] & ~(1 << m); + n = j; + o = k; + break; + } + do { + if ((q | 0) == (r | 0)) { + s = q + 8 | 0; + } else { + if (q >>> 0 < l >>> 0) { + av(); + } + t = q + 8 | 0; + if ((c[t >> 2] | 0) == (j | 0)) { + s = t; + break; + } + av(); + } + } while (0); + c[p + 12 >> 2] = q; + c[s >> 2] = p; + n = j; + o = k; + break; + } + r = i; + m = c[d + (24 - h) >> 2] | 0; + t = c[d + (12 - h) >> 2] | 0; + do { + if ((t | 0) == (r | 0)) { + u = 16 - h | 0; + v = d + (u + 4) | 0; + w = c[v >> 2] | 0; + if ((w | 0) == 0) { + x = d + u | 0; + u = c[x >> 2] | 0; + if ((u | 0) == 0) { + y = 0; + break; + } else { + z = u; + A = x; + } + } else { + z = w; + A = v; + } + while (1) { + v = z + 20 | 0; + w = c[v >> 2] | 0; + if ((w | 0) != 0) { + z = w; + A = v; + continue; + } + v = z + 16 | 0; + w = c[v >> 2] | 0; + if ((w | 0) == 0) { + break; + } else { + z = w; + A = v; + } + } + if (A >>> 0 < l >>> 0) { + av(); + } else { + c[A >> 2] = 0; + y = z; + break; + } + } else { + v = c[d + (8 - h) >> 2] | 0; + if (v >>> 0 < l >>> 0) { + av(); + } + w = v + 12 | 0; + if ((c[w >> 2] | 0) != (r | 0)) { + av(); + } + x = t + 8 | 0; + if ((c[x >> 2] | 0) == (r | 0)) { + c[w >> 2] = t; + c[x >> 2] = v; + y = t; + break; + } else { + av(); + } + } + } while (0); + if ((m | 0) == 0) { + n = j; + o = k; + break; + } + t = d + (28 - h) | 0; + l = 112456 + (c[t >> 2] << 2) | 0; + do { + if ((r | 0) == (c[l >> 2] | 0)) { + c[l >> 2] = y; + if ((y | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[t >> 2]); + n = j; + o = k; + break L1311; + } else { + if (m >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + i = m + 16 | 0; + if ((c[i >> 2] | 0) == (r | 0)) { + c[i >> 2] = y; + } else { + c[m + 20 >> 2] = y; + } + if ((y | 0) == 0) { + n = j; + o = k; + break L1311; + } + } + } while (0); + if (y >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + c[y + 24 >> 2] = m; + r = 16 - h | 0; + t = c[d + r >> 2] | 0; + do { + if ((t | 0) != 0) { + if (t >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[y + 16 >> 2] = t; + c[t + 24 >> 2] = y; + break; + } + } + } while (0); + t = c[d + (r + 4) >> 2] | 0; + if ((t | 0) == 0) { + n = j; + o = k; + break; + } + if (t >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[y + 20 >> 2] = t; + c[t + 24 >> 2] = y; + n = j; + o = k; + break; + } + } else { + n = a; + o = b; + } + } while (0); + a = c[28042] | 0; + if (e >>> 0 < a >>> 0) { + av(); + } + y = d + (b + 4) | 0; + z = c[y >> 2] | 0; + do { + if ((z & 2 | 0) == 0) { + if ((f | 0) == (c[28044] | 0)) { + A = (c[28041] | 0) + o | 0; + c[28041] = A; + c[28044] = n; + c[n + 4 >> 2] = A | 1; + if ((n | 0) != (c[28043] | 0)) { + return; + } + c[28043] = 0; + c[28040] = 0; + return; + } + if ((f | 0) == (c[28043] | 0)) { + A = (c[28040] | 0) + o | 0; + c[28040] = A; + c[28043] = n; + c[n + 4 >> 2] = A | 1; + c[n + A >> 2] = A; + return; + } + A = (z & -8) + o | 0; + s = z >>> 3; + L1410 : do { + if (z >>> 0 < 256) { + g = c[d + (b + 8) >> 2] | 0; + t = c[d + (b + 12) >> 2] | 0; + h = 112192 + (s << 1 << 2) | 0; + do { + if ((g | 0) != (h | 0)) { + if (g >>> 0 < a >>> 0) { + av(); + } + if ((c[g + 12 >> 2] | 0) == (f | 0)) { + break; + } + av(); + } + } while (0); + if ((t | 0) == (g | 0)) { + c[28038] = c[28038] & ~(1 << s); + break; + } + do { + if ((t | 0) == (h | 0)) { + B = t + 8 | 0; + } else { + if (t >>> 0 < a >>> 0) { + av(); + } + m = t + 8 | 0; + if ((c[m >> 2] | 0) == (f | 0)) { + B = m; + break; + } + av(); + } + } while (0); + c[g + 12 >> 2] = t; + c[B >> 2] = g; + } else { + h = e; + m = c[d + (b + 24) >> 2] | 0; + l = c[d + (b + 12) >> 2] | 0; + do { + if ((l | 0) == (h | 0)) { + i = d + (b + 20) | 0; + p = c[i >> 2] | 0; + if ((p | 0) == 0) { + q = d + (b + 16) | 0; + v = c[q >> 2] | 0; + if ((v | 0) == 0) { + C = 0; + break; + } else { + D = v; + E = q; + } + } else { + D = p; + E = i; + } + while (1) { + i = D + 20 | 0; + p = c[i >> 2] | 0; + if ((p | 0) != 0) { + D = p; + E = i; + continue; + } + i = D + 16 | 0; + p = c[i >> 2] | 0; + if ((p | 0) == 0) { + break; + } else { + D = p; + E = i; + } + } + if (E >>> 0 < a >>> 0) { + av(); + } else { + c[E >> 2] = 0; + C = D; + break; + } + } else { + i = c[d + (b + 8) >> 2] | 0; + if (i >>> 0 < a >>> 0) { + av(); + } + p = i + 12 | 0; + if ((c[p >> 2] | 0) != (h | 0)) { + av(); + } + q = l + 8 | 0; + if ((c[q >> 2] | 0) == (h | 0)) { + c[p >> 2] = l; + c[q >> 2] = i; + C = l; + break; + } else { + av(); + } + } + } while (0); + if ((m | 0) == 0) { + break; + } + l = d + (b + 28) | 0; + g = 112456 + (c[l >> 2] << 2) | 0; + do { + if ((h | 0) == (c[g >> 2] | 0)) { + c[g >> 2] = C; + if ((C | 0) != 0) { + break; + } + c[28039] = c[28039] & ~(1 << c[l >> 2]); + break L1410; + } else { + if (m >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + t = m + 16 | 0; + if ((c[t >> 2] | 0) == (h | 0)) { + c[t >> 2] = C; + } else { + c[m + 20 >> 2] = C; + } + if ((C | 0) == 0) { + break L1410; + } + } + } while (0); + if (C >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + c[C + 24 >> 2] = m; + h = c[d + (b + 16) >> 2] | 0; + do { + if ((h | 0) != 0) { + if (h >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[C + 16 >> 2] = h; + c[h + 24 >> 2] = C; + break; + } + } + } while (0); + h = c[d + (b + 20) >> 2] | 0; + if ((h | 0) == 0) { + break; + } + if (h >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } else { + c[C + 20 >> 2] = h; + c[h + 24 >> 2] = C; + break; + } + } + } while (0); + c[n + 4 >> 2] = A | 1; + c[n + A >> 2] = A; + if ((n | 0) != (c[28043] | 0)) { + F = A; + break; + } + c[28040] = A; + return; + } else { + c[y >> 2] = z & -2; + c[n + 4 >> 2] = o | 1; + c[n + o >> 2] = o; + F = o; + } + } while (0); + o = F >>> 3; + if (F >>> 0 < 256) { + z = o << 1; + y = 112192 + (z << 2) | 0; + C = c[28038] | 0; + b = 1 << o; + do { + if ((C & b | 0) == 0) { + c[28038] = C | b; + G = y; + H = 112192 + (z + 2 << 2) | 0; + } else { + o = 112192 + (z + 2 << 2) | 0; + d = c[o >> 2] | 0; + if (d >>> 0 >= (c[28042] | 0) >>> 0) { + G = d; + H = o; + break; + } + av(); + } + } while (0); + c[H >> 2] = n; + c[G + 12 >> 2] = n; + c[n + 8 >> 2] = G; + c[n + 12 >> 2] = y; + return; + } + y = n; + G = F >>> 8; + do { + if ((G | 0) == 0) { + I = 0; + } else { + if (F >>> 0 > 16777215) { + I = 31; + break; + } + H = (G + 1048320 | 0) >>> 16 & 8; + z = G << H; + b = (z + 520192 | 0) >>> 16 & 4; + C = z << b; + z = (C + 245760 | 0) >>> 16 & 2; + o = 14 - (b | H | z) + (C << z >>> 15) | 0; + I = F >>> ((o + 7 | 0) >>> 0) & 1 | o << 1; + } + } while (0); + G = 112456 + (I << 2) | 0; + c[n + 28 >> 2] = I; + c[n + 20 >> 2] = 0; + c[n + 16 >> 2] = 0; + o = c[28039] | 0; + z = 1 << I; + if ((o & z | 0) == 0) { + c[28039] = o | z; + c[G >> 2] = y; + c[n + 24 >> 2] = G; + c[n + 12 >> 2] = n; + c[n + 8 >> 2] = n; + return; + } + if ((I | 0) == 31) { + J = 0; + } else { + J = 25 - (I >>> 1) | 0; + } + I = F << J; + J = c[G >> 2] | 0; + while (1) { + if ((c[J + 4 >> 2] & -8 | 0) == (F | 0)) { + break; + } + K = J + 16 + (I >>> 31 << 2) | 0; + G = c[K >> 2] | 0; + if ((G | 0) == 0) { + L = 1116; + break; + } else { + I = I << 1; + J = G; + } + } + if ((L | 0) == 1116) { + if (K >>> 0 < (c[28042] | 0) >>> 0) { + av(); + } + c[K >> 2] = y; + c[n + 24 >> 2] = J; + c[n + 12 >> 2] = n; + c[n + 8 >> 2] = n; + return; + } + K = J + 8 | 0; + L = c[K >> 2] | 0; + I = c[28042] | 0; + if (J >>> 0 < I >>> 0) { + av(); + } + if (L >>> 0 < I >>> 0) { + av(); + } + c[L + 12 >> 2] = y; + c[K >> 2] = y; + c[n + 8 >> 2] = L; + c[n + 12 >> 2] = J; + c[n + 24 >> 2] = 0; + return; +} +function eO(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = (a | 0) == 0 ? 1 : a; + while (1) { + d = en(b) | 0; + if ((d | 0) != 0) { + e = 1160; + break; + } + a = (F = c[28158] | 0, c[28158] = F + 0, F); + if ((a | 0) == 0) { + break; + } + a5[a & 1](); + } + if ((e | 0) == 1160) { + return d | 0; + } + d = aK(4) | 0; + c[d >> 2] = 111864; + as(d | 0, 111992, 6); + return 0; +} +function eP(a, b) { + a = a | 0; + b = b | 0; + return eO(a) | 0; +} +function eQ(a) { + a = a | 0; + return; +} +function eR(a) { + a = a | 0; + return 111664 | 0; +} +function eS(a) { + a = a | 0; + return 111752 | 0; +} +function eT(a) { + a = a | 0; + return (F = c[28158] | 0, c[28158] = a, F) | 0; +} +function eU(a) { + a = a | 0; + c[a >> 2] = 111864; + return; +} +function eV(a) { + a = a | 0; + c[a >> 2] = 111896; + return; +} +function eW(a) { + a = a | 0; + if ((a | 0) != 0) { + eo(a); + } + return; +} +function eX(a, b) { + a = a | 0; + b = b | 0; + eW(a); + return; +} +function eY(a) { + a = a | 0; + eW(a); + return; +} +function eZ(a, b) { + a = a | 0; + b = b | 0; + eY(a); + return; +} +function e_(a) { + a = a | 0; + eW(a); + return; +} +function e$(a) { + a = a | 0; + eW(a); + return; +} +function e0(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return e1(a, b, c, 0, 0, 0) | 0; +} +function e1(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0; + j = i; + if ((e | 0) == 0) { + k = -1; + i = j; + return k | 0; + } + l = c[80] | 0; + if ((l | 0) == 0) { + c[28006] = 1; + c[80] = 1; + m = 1; + n = 1; + o = 1186; + } else { + p = c[28006] | 0; + q = c[348] | 0; + if ((q | 0) == -1 | (p | 0) != 0) { + m = p; + n = l; + o = 1186; + } else { + r = q; + s = p; + t = l; + } + } + if ((o | 0) == 1186) { + l = (aQ(111648) | 0) != 0 | 0; + c[348] = l; + r = l; + s = m; + t = n; + } + n = a[e] | 0; + if (n << 24 >> 24 == 45) { + u = h | 2; + o = 1190; + } else { + m = (r | 0) != 0 | n << 24 >> 24 == 43 ? h & -2 : h; + if (n << 24 >> 24 == 43) { + u = m; + o = 1190; + } else { + v = e; + w = m; + } + } + if ((o | 0) == 1190) { + v = e + 1 | 0; + w = u; + } + c[28008] = 0; + if ((s | 0) == 0) { + x = t; + o = 1194; + } else { + c[86] = -1; + c[84] = -1; + z = t; + A = s; + o = 1193; + } + while (1) { + if ((o | 0) == 1193) { + o = 0; + if ((A | 0) == 0) { + x = z; + o = 1194; + continue; + } else { + B = z; + } + } else if ((o | 0) == 1194) { + o = 0; + s = c[76] | 0; + if ((a[s] | 0) == 0) { + B = x; + } else { + C = s; + D = x; + break; + } + } + c[28006] = 0; + if ((B | 0) >= (b | 0)) { + o = 1196; + break; + } + E = d + (B << 2) | 0; + F = c[E >> 2] | 0; + c[76] = F; + if ((a[F] | 0) == 45) { + G = F + 1 | 0; + H = a[G] | 0; + if (H << 24 >> 24 != 0) { + o = 1228; + break; + } + if ((aC(v | 0, 45) | 0) != 0) { + o = 1228; + break; + } + } + c[76] = 112144; + if ((w & 2 | 0) != 0) { + o = 1213; + break; + } + if ((w & 1 | 0) == 0) { + k = -1; + o = 1299; + break; + } + s = c[84] | 0; + do { + if ((s | 0) == -1) { + c[84] = B; + I = B; + J = 0; + } else { + t = c[86] | 0; + if ((t | 0) == -1) { + I = B; + J = 0; + break; + } + u = t - s | 0; + e = B - t | 0; + m = (u | 0) % (e | 0) | 0; + if ((m | 0) == 0) { + K = e; + } else { + n = e; + h = m; + while (1) { + m = (n | 0) % (h | 0) | 0; + if ((m | 0) == 0) { + K = h; + break; + } else { + n = h; + h = m; + } + } + } + h = (B - s | 0) / (K | 0) | 0; + do { + if ((K | 0) > 0) { + n = -u | 0; + if ((h | 0) > 0) { + L = 0; + } else { + M = B; + N = t; + O = s; + P = 0; + break; + } + do { + m = L + t | 0; + r = d + (m << 2) | 0; + l = 0; + p = m; + m = c[r >> 2] | 0; + while (1) { + q = ((p | 0) < (t | 0) ? e : n) + p | 0; + Q = d + (q << 2) | 0; + R = c[Q >> 2] | 0; + c[Q >> 2] = m; + c[r >> 2] = R; + Q = l + 1 | 0; + if ((Q | 0) < (h | 0)) { + l = Q; + p = q; + m = R; + } else { + break; + } + } + L = L + 1 | 0; + } while ((L | 0) < (K | 0)); + M = c[80] | 0; + N = c[86] | 0; + O = c[84] | 0; + P = c[28006] | 0; + } else { + M = B; + N = t; + O = s; + P = 0; + } + } while (0); + c[84] = M - N + O; + c[86] = -1; + I = M; + J = P; + } + } while (0); + s = I + 1 | 0; + c[80] = s; + z = s; + A = J; + o = 1193; + } + do { + if ((o | 0) == 1299) { + i = j; + return k | 0; + } else if ((o | 0) == 1196) { + c[76] = 112144; + J = c[86] | 0; + A = c[84] | 0; + do { + if ((J | 0) == -1) { + if ((A | 0) == -1) { + break; + } + c[80] = A; + } else { + z = J - A | 0; + I = B - J | 0; + P = (z | 0) % (I | 0) | 0; + if ((P | 0) == 0) { + S = I; + } else { + M = I; + O = P; + while (1) { + P = (M | 0) % (O | 0) | 0; + if ((P | 0) == 0) { + S = O; + break; + } else { + M = O; + O = P; + } + } + } + O = (B - A | 0) / (S | 0) | 0; + do { + if ((S | 0) > 0) { + M = -z | 0; + if ((O | 0) > 0) { + T = 0; + } else { + U = J; + V = A; + W = B; + break; + } + do { + P = T + J | 0; + N = d + (P << 2) | 0; + K = 0; + L = P; + P = c[N >> 2] | 0; + while (1) { + x = ((L | 0) < (J | 0) ? I : M) + L | 0; + s = d + (x << 2) | 0; + t = c[s >> 2] | 0; + c[s >> 2] = P; + c[N >> 2] = t; + s = K + 1 | 0; + if ((s | 0) < (O | 0)) { + K = s; + L = x; + P = t; + } else { + break; + } + } + T = T + 1 | 0; + } while ((T | 0) < (S | 0)); + U = c[86] | 0; + V = c[84] | 0; + W = c[80] | 0; + } else { + U = J; + V = A; + W = B; + } + } while (0); + c[80] = V - U + W; + } + } while (0); + c[86] = -1; + c[84] = -1; + k = -1; + i = j; + return k | 0; + } else if ((o | 0) == 1213) { + c[80] = B + 1; + c[28008] = c[E >> 2]; + k = 1; + i = j; + return k | 0; + } else if ((o | 0) == 1228) { + A = c[84] | 0; + J = c[86] | 0; + if ((A | 0) != -1 & (J | 0) == -1) { + c[86] = B; + X = a[G] | 0; + Y = B; + } else { + X = H; + Y = J; + } + if (X << 24 >> 24 == 0) { + C = F; + D = B; + break; + } + c[76] = G; + if ((a[G] | 0) != 45) { + C = G; + D = B; + break; + } + if ((a[F + 2 | 0] | 0) != 0) { + C = G; + D = B; + break; + } + J = B + 1 | 0; + c[80] = J; + c[76] = 112144; + if ((Y | 0) != -1) { + O = Y - A | 0; + I = J - Y | 0; + z = (O | 0) % (I | 0) | 0; + if ((z | 0) == 0) { + Z = I; + } else { + M = I; + P = z; + while (1) { + z = (M | 0) % (P | 0) | 0; + if ((z | 0) == 0) { + Z = P; + break; + } else { + M = P; + P = z; + } + } + } + P = (J - A | 0) / (Z | 0) | 0; + do { + if ((Z | 0) > 0) { + M = -O | 0; + if ((P | 0) > 0) { + _ = 0; + } else { + $ = Y; + aa = A; + ab = J; + break; + } + do { + z = _ + Y | 0; + L = d + (z << 2) | 0; + K = 0; + N = z; + z = c[L >> 2] | 0; + while (1) { + t = ((N | 0) < (Y | 0) ? I : M) + N | 0; + x = d + (t << 2) | 0; + s = c[x >> 2] | 0; + c[x >> 2] = z; + c[L >> 2] = s; + x = K + 1 | 0; + if ((x | 0) < (P | 0)) { + K = x; + N = t; + z = s; + } else { + break; + } + } + _ = _ + 1 | 0; + } while ((_ | 0) < (Z | 0)); + $ = c[86] | 0; + aa = c[84] | 0; + ab = c[80] | 0; + } else { + $ = Y; + aa = A; + ab = J; + } + } while (0); + c[80] = aa - $ + ab; + } + c[86] = -1; + c[84] = -1; + k = -1; + i = j; + return k | 0; + } + } while (0); + ab = (f | 0) != 0; + L1645 : do { + if (ab) { + if ((C | 0) == (c[d + (D << 2) >> 2] | 0)) { + ac = C; + break; + } + $ = a[C] | 0; + do { + if ($ << 24 >> 24 == 45) { + c[76] = C + 1; + ad = 0; + } else { + if ((w & 4 | 0) == 0) { + ac = C; + break L1645; + } + if ($ << 24 >> 24 == 58) { + ad = 0; + break; + } + ad = (aC(v | 0, $ << 24 >> 24 | 0) | 0) != 0 | 0; + } + } while (0); + $ = e7(d, v, f, g, ad) | 0; + if (($ | 0) == -1) { + ac = c[76] | 0; + break; + } + c[76] = 112144; + k = $; + i = j; + return k | 0; + } else { + ac = C; + } + } while (0); + C = ac + 1 | 0; + c[76] = C; + ad = a[ac] | 0; + ac = ad << 24 >> 24; + if ((ad << 24 >> 24 | 0) == 58) { + o = 1259; + } else if ((ad << 24 >> 24 | 0) == 45) { + if ((a[C] | 0) == 0) { + o = 1256; + } + } else { + o = 1256; + } + do { + if ((o | 0) == 1256) { + w = aC(v | 0, ac | 0) | 0; + if ((w | 0) == 0) { + if (ad << 24 >> 24 != 45) { + o = 1259; + break; + } + if ((a[C] | 0) == 0) { + k = -1; + } else { + break; + } + i = j; + return k | 0; + } + D = a[w + 1 | 0] | 0; + if (ab & ad << 24 >> 24 == 87 & D << 24 >> 24 == 59) { + do { + if ((a[C] | 0) == 0) { + $ = (c[80] | 0) + 1 | 0; + c[80] = $; + if (($ | 0) < (b | 0)) { + c[76] = c[d + ($ << 2) >> 2]; + break; + } + c[76] = 112144; + do { + if ((c[82] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + e9(192, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[78] = ac; + k = (a[v] | 0) == 58 ? 58 : 63; + i = j; + return k | 0; + } + } while (0); + $ = e7(d, v, f, g, 0) | 0; + c[76] = 112144; + k = $; + i = j; + return k | 0; + } + if (D << 24 >> 24 != 58) { + if ((a[C] | 0) != 0) { + k = ac; + i = j; + return k | 0; + } + c[80] = (c[80] | 0) + 1; + k = ac; + i = j; + return k | 0; + } + c[28008] = 0; + do { + if ((a[C] | 0) == 0) { + if ((a[w + 2 | 0] | 0) == 58) { + break; + } + $ = (c[80] | 0) + 1 | 0; + c[80] = $; + if (($ | 0) < (b | 0)) { + c[28008] = c[d + ($ << 2) >> 2]; + break; + } + c[76] = 112144; + do { + if ((c[82] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + e9(192, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[78] = ac; + k = (a[v] | 0) == 58 ? 58 : 63; + i = j; + return k | 0; + } else { + c[28008] = C; + } + } while (0); + c[76] = 112144; + c[80] = (c[80] | 0) + 1; + k = ac; + i = j; + return k | 0; + } + } while (0); + do { + if ((o | 0) == 1259) { + if ((a[C] | 0) != 0) { + break; + } + c[80] = (c[80] | 0) + 1; + } + } while (0); + do { + if ((c[82] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + e9(1368, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[78] = ac; + k = 63; + i = j; + return k | 0; +} +function e2(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + return e1(a, b, c, d, e, 1) | 0; +} +function e3(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + return e1(a, b, c, d, e, 5) | 0; +} +function e4(a) { + a = a | 0; + return eO(a) | 0; +} +function e5(a, b) { + a = a | 0; + b = b | 0; + return e4(a) | 0; +} +function e6() { + var a = 0; + a = aK(4) | 0; + c[a >> 2] = 111864; + as(a | 0, 111992, 6); +} +function e7(b, d, e, f, g) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, z = 0; + h = i; + j = c[76] | 0; + k = c[80] | 0; + l = k + 1 | 0; + c[80] = l; + m = aC(j | 0, 61) | 0; + if ((m | 0) == 0) { + n = fo(j | 0) | 0; + o = 0; + } else { + n = m - j | 0; + o = m + 1 | 0; + } + m = c[e >> 2] | 0; + L1725 : do { + if ((m | 0) != 0) { + L1727 : do { + if ((g | 0) != 0 & (n | 0) == 1) { + p = 0; + q = m; + while (1) { + if ((a[j] | 0) == (a[q] | 0)) { + if ((fo(q | 0) | 0) == 1) { + r = p; + break L1727; + } + } + p = p + 1 | 0; + q = c[e + (p << 4) >> 2] | 0; + if ((q | 0) == 0) { + break L1725; + } + } + } else { + q = 0; + p = -1; + s = m; + while (1) { + if ((ap(j | 0, s | 0, n | 0) | 0) == 0) { + if ((fo(s | 0) | 0) == (n | 0)) { + r = q; + break L1727; + } + if ((p | 0) == -1) { + t = q; + } else { + break; + } + } else { + t = p; + } + u = q + 1 | 0; + v = c[e + (u << 4) >> 2] | 0; + if ((v | 0) == 0) { + r = t; + break L1727; + } else { + q = u; + p = t; + s = v; + } + } + do { + if ((c[82] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + e9(111608, (y = i, i = i + 16 | 0, c[y >> 2] = n, c[y + 8 >> 2] = j, y) | 0); + } + } while (0); + c[78] = 0; + w = 63; + i = h; + return w | 0; + } + } while (0); + if ((r | 0) == -1) { + break; + } + s = e + (r << 4) + 4 | 0; + p = c[s >> 2] | 0; + q = (o | 0) == 0; + if (!((p | 0) != 0 | q)) { + do { + if ((c[82] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + e9(352, (y = i, i = i + 16 | 0, c[y >> 2] = n, c[y + 8 >> 2] = j, y) | 0); + } + } while (0); + if ((c[e + (r << 4) + 8 >> 2] | 0) == 0) { + x = c[e + (r << 4) + 12 >> 2] | 0; + } else { + x = 0; + } + c[78] = x; + w = (a[d] | 0) == 58 ? 58 : 63; + i = h; + return w | 0; + } + do { + if ((p - 1 | 0) >>> 0 < 2) { + if (!q) { + c[28008] = o; + break; + } + if ((p | 0) != 1) { + break; + } + c[80] = k + 2; + c[28008] = c[b + (l << 2) >> 2]; + } + } while (0); + if (!((c[s >> 2] | 0) == 1 & (c[28008] | 0) == 0)) { + if ((f | 0) != 0) { + c[f >> 2] = r; + } + p = c[e + (r << 4) + 8 >> 2] | 0; + q = c[e + (r << 4) + 12 >> 2] | 0; + if ((p | 0) == 0) { + w = q; + i = h; + return w | 0; + } + c[p >> 2] = q; + w = 0; + i = h; + return w | 0; + } + do { + if ((c[82] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + e9(152, (y = i, i = i + 8 | 0, c[y >> 2] = j, y) | 0); + } + } while (0); + if ((c[e + (r << 4) + 8 >> 2] | 0) == 0) { + z = c[e + (r << 4) + 12 >> 2] | 0; + } else { + z = 0; + } + c[78] = z; + c[80] = (c[80] | 0) - 1; + w = (a[d] | 0) == 58 ? 58 : 63; + i = h; + return w | 0; + } + } while (0); + if ((g | 0) != 0) { + c[80] = k; + w = -1; + i = h; + return w | 0; + } + do { + if ((c[82] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + e9(1344, (y = i, i = i + 8 | 0, c[y >> 2] = j, y) | 0); + } + } while (0); + c[78] = 0; + w = 63; + i = h; + return w | 0; +} +function e8(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + i = i + 16 | 0; + e = d | 0; + f = e; + c[f >> 2] = b; + c[f + 4 >> 2] = 0; + fa(a, e | 0); + i = d; + return; +} +function e9(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + i = i + 16 | 0; + e = d | 0; + f = e; + c[f >> 2] = b; + c[f + 4 >> 2] = 0; + fb(a, e | 0); + i = d; + return; +} +function fa(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + e = c[(aY() | 0) >> 2] | 0; + f = c[r >> 2] | 0; + aw(c[p >> 2] | 0, 111736, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + if ((a | 0) != 0) { + f = c[p >> 2] | 0; + aR(f | 0, a | 0, b | 0) | 0; + b = c[p >> 2] | 0; + aF(111776, 2, 1, b | 0) | 0; + } + b = c[p >> 2] | 0; + a = au(e | 0) | 0; + aw(b | 0, 111688, (y = i, i = i + 8 | 0, c[y >> 2] = a, y) | 0) | 0; + i = d; + return; +} +function fb(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + d = i; + e = c[r >> 2] | 0; + aw(c[p >> 2] | 0, 111680, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + if ((a | 0) != 0) { + e = c[p >> 2] | 0; + aR(e | 0, a | 0, b | 0) | 0; + } + aD(10, c[p >> 2] | 0) | 0; + i = d; + return; +} +function fc(b, d) { + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0.0, r = 0, s = 0, t = 0, u = 0, v = 0.0, w = 0, x = 0, y = 0, z = 0.0, A = 0.0, B = 0, C = 0, D = 0, E = 0.0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0.0, O = 0, P = 0, Q = 0.0, R = 0.0, S = 0.0; + e = b; + while (1) { + f = e + 1 | 0; + if ((aL(a[e] | 0) | 0) == 0) { + break; + } else { + e = f; + } + } + g = a[e] | 0; + if ((g << 24 >> 24 | 0) == 45) { + i = f; + j = 1; + } else if ((g << 24 >> 24 | 0) == 43) { + i = f; + j = 0; + } else { + i = e; + j = 0; + } + e = -1; + f = 0; + g = i; + while (1) { + k = a[g] | 0; + if (((k << 24 >> 24) - 48 | 0) >>> 0 < 10) { + l = e; + } else { + if (k << 24 >> 24 != 46 | (e | 0) > -1) { + break; + } else { + l = f; + } + } + e = l; + f = f + 1 | 0; + g = g + 1 | 0; + } + l = g + (-f | 0) | 0; + i = (e | 0) < 0; + m = ((i ^ 1) << 31 >> 31) + f | 0; + n = (m | 0) > 18; + o = (n ? -18 : -m | 0) + (i ? f : e) | 0; + e = n ? 18 : m; + do { + if ((e | 0) == 0) { + p = b; + q = 0.0; + } else { + if ((e | 0) > 9) { + m = l; + n = e; + f = 0; + while (1) { + i = a[m] | 0; + r = m + 1 | 0; + if (i << 24 >> 24 == 46) { + s = a[r] | 0; + t = m + 2 | 0; + } else { + s = i; + t = r; + } + u = (f * 10 | 0) - 48 + (s << 24 >> 24) | 0; + r = n - 1 | 0; + if ((r | 0) > 9) { + m = t; + n = r; + f = u; + } else { + break; + } + } + v = +(u | 0) * 1.0e9; + w = 9; + x = t; + y = 1389; + } else { + if ((e | 0) > 0) { + v = 0.0; + w = e; + x = l; + y = 1389; + } else { + z = 0.0; + A = 0.0; + } + } + if ((y | 0) == 1389) { + f = x; + n = w; + m = 0; + while (1) { + r = a[f] | 0; + i = f + 1 | 0; + if (r << 24 >> 24 == 46) { + B = a[i] | 0; + C = f + 2 | 0; + } else { + B = r; + C = i; + } + D = (m * 10 | 0) - 48 + (B << 24 >> 24) | 0; + i = n - 1 | 0; + if ((i | 0) > 0) { + f = C; + n = i; + m = D; + } else { + break; + } + } + z = +(D | 0); + A = v; + } + E = A + z; + do { + if ((k << 24 >> 24 | 0) == 69 | (k << 24 >> 24 | 0) == 101) { + m = g + 1 | 0; + n = a[m] | 0; + if ((n << 24 >> 24 | 0) == 45) { + F = g + 2 | 0; + G = 1; + } else if ((n << 24 >> 24 | 0) == 43) { + F = g + 2 | 0; + G = 0; + } else { + F = m; + G = 0; + } + m = a[F] | 0; + if (((m << 24 >> 24) - 48 | 0) >>> 0 < 10) { + H = F; + I = 0; + J = m; + } else { + K = 0; + L = F; + M = G; + break; + } + while (1) { + m = (I * 10 | 0) - 48 + (J << 24 >> 24) | 0; + n = H + 1 | 0; + f = a[n] | 0; + if (((f << 24 >> 24) - 48 | 0) >>> 0 < 10) { + H = n; + I = m; + J = f; + } else { + K = m; + L = n; + M = G; + break; + } + } + } else { + K = 0; + L = g; + M = 0; + } + } while (0); + n = o + ((M | 0) == 0 ? K : -K | 0) | 0; + m = (n | 0) < 0 ? -n | 0 : n; + if ((m | 0) > 511) { + c[(aY() | 0) >> 2] = 34; + N = 1.0; + O = 232; + P = 511; + y = 1406; + } else { + if ((m | 0) == 0) { + Q = 1.0; + } else { + N = 1.0; + O = 232; + P = m; + y = 1406; + } + } + if ((y | 0) == 1406) { + while (1) { + y = 0; + if ((P & 1 | 0) == 0) { + R = N; + } else { + R = N * +h[O >> 3]; + } + m = P >> 1; + if ((m | 0) == 0) { + Q = R; + break; + } else { + N = R; + O = O + 8 | 0; + P = m; + y = 1406; + } + } + } + if ((n | 0) > -1) { + p = L; + q = E * Q; + break; + } else { + p = L; + q = E / Q; + break; + } + } + } while (0); + if ((d | 0) != 0) { + c[d >> 2] = p; + } + if ((j | 0) == 0) { + S = q; + return +S; + } + S = -0.0 - q; + return +S; +} +function fd(a, b) { + a = a | 0; + b = b | 0; + return +(+fc(a, b)); +} +function fe(a, b) { + a = a | 0; + b = b | 0; + return +(+fc(a, b)); +} +function ff(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return +(+fc(a, b)); +} +function fg(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return +(+fc(a, b)); +} +function fh(a) { + a = a | 0; + return +(+fc(a, 0)); +} +function fi(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + e = f; + c[e >> 2] = d; + c[e + 4 >> 2] = 0; + fk(a, b, f | 0); +} +function fj(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + e = f; + c[e >> 2] = d; + c[e + 4 >> 2] = 0; + fl(a, b, f | 0); +} +function fk(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = c[(aY() | 0) >> 2] | 0; + f = c[r >> 2] | 0; + aw(c[p >> 2] | 0, 111640, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + if ((b | 0) != 0) { + f = c[p >> 2] | 0; + aR(f | 0, b | 0, d | 0) | 0; + d = c[p >> 2] | 0; + aF(111784, 2, 1, d | 0) | 0; + } + d = c[p >> 2] | 0; + b = au(e | 0) | 0; + aw(d | 0, 111696, (y = i, i = i + 8 | 0, c[y >> 2] = b, y) | 0) | 0; + aI(a | 0); +} +function fl(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0; + e = c[r >> 2] | 0; + aw(c[p >> 2] | 0, 111744, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + if ((b | 0) != 0) { + e = c[p >> 2] | 0; + aR(e | 0, b | 0, d | 0) | 0; + } + aD(10, c[p >> 2] | 0) | 0; + aI(a | 0); +} +function fm(b, d, e) { + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0; + f = b + e | 0; + if ((e | 0) >= 20) { + d = d & 255; + e = b & 3; + g = d | d << 8 | d << 16 | d << 24; + h = f & ~3; + if (e) { + e = b + 4 - e | 0; + while ((b | 0) < (e | 0)) { + a[b] = d; + b = b + 1 | 0; + } + } + while ((b | 0) < (h | 0)) { + c[b >> 2] = g; + b = b + 4 | 0; + } + } + while ((b | 0) < (f | 0)) { + a[b] = d; + b = b + 1 | 0; + } +} +function fn(b, d, e) { + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0; + f = b | 0; + if ((b & 3) == (d & 3)) { + while (b & 3) { + if ((e | 0) == 0) return f | 0; + a[b] = a[d] | 0; + b = b + 1 | 0; + d = d + 1 | 0; + e = e - 1 | 0; + } + while ((e | 0) >= 4) { + c[b >> 2] = c[d >> 2]; + b = b + 4 | 0; + d = d + 4 | 0; + e = e - 4 | 0; + } + } + while ((e | 0) > 0) { + a[b] = a[d] | 0; + b = b + 1 | 0; + d = d + 1 | 0; + e = e - 1 | 0; + } + return f | 0; +} +function fo(b) { + b = b | 0; + var c = 0; + c = b; + while (a[c] | 0) { + c = c + 1 | 0; + } + return c - b | 0; +} +function fp(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = a + c >>> 0; + return (H = b + d + (e >>> 0 < a >>> 0 | 0) >>> 0, e | 0) | 0; +} +function fq(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = b - d >>> 0; + e = b - d - (c >>> 0 > a >>> 0 | 0) >>> 0; + return (H = e, a - c >>> 0 | 0) | 0; +} +function fr(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b << c | (a & (1 << c) - 1 << 32 - c) >>> 32 - c; + return a << c; + } + H = a << c - 32; + return 0; +} +function fs(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b >>> c; + return a >>> c | (b & (1 << c) - 1) << 32 - c; + } + H = 0; + return b >>> c - 32 | 0; +} +function ft(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b >> c; + return a >>> c | (b & (1 << c) - 1) << 32 - c; + } + H = (b | 0) < 0 ? -1 : 0; + return b >> c - 32 | 0; +} +function fu(b) { + b = b | 0; + var c = 0; + c = a[n + (b >>> 24) | 0] | 0; + if ((c | 0) < 8) return c | 0; + c = a[n + (b >> 16 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 8 | 0; + c = a[n + (b >> 8 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 16 | 0; + return (a[n + (b & 255) | 0] | 0) + 24 | 0; +} +function fv(b) { + b = b | 0; + var c = 0; + c = a[m + (b & 255) | 0] | 0; + if ((c | 0) < 8) return c | 0; + c = a[m + (b >> 8 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 8 | 0; + c = a[m + (b >> 16 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 16 | 0; + return (a[m + (b >>> 24) | 0] | 0) + 24 | 0; +} +function fw(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0; + c = a & 65535; + d = b & 65535; + e = ad(d, c) | 0; + f = a >>> 16; + a = (e >>> 16) + (ad(d, f) | 0) | 0; + d = b >>> 16; + b = ad(d, c) | 0; + return (H = (a >>> 16) + (ad(d, f) | 0) + (((a & 65535) + b | 0) >>> 16) | 0, a + b << 16 | e & 65535 | 0) | 0; +} +function fx(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0; + e = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + f = ((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + g = d >> 31 | ((d | 0) < 0 ? -1 : 0) << 1; + h = ((d | 0) < 0 ? -1 : 0) >> 31 | ((d | 0) < 0 ? -1 : 0) << 1; + i = fq(e ^ a, f ^ b, e, f) | 0; + b = H; + a = g ^ e; + e = h ^ f; + f = fq((fC(i, b, fq(g ^ c, h ^ d, g, h) | 0, H, 0) | 0) ^ a, H ^ e, a, e) | 0; + return (H = H, f) | 0; +} +function fy(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + f = i; + i = i + 8 | 0; + g = f | 0; + h = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + j = ((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + k = e >> 31 | ((e | 0) < 0 ? -1 : 0) << 1; + l = ((e | 0) < 0 ? -1 : 0) >> 31 | ((e | 0) < 0 ? -1 : 0) << 1; + m = fq(h ^ a, j ^ b, h, j) | 0; + b = H; + a = fq(k ^ d, l ^ e, k, l) | 0; + fC(m, b, a, H, g) | 0; + a = fq(c[g >> 2] ^ h, c[g + 4 >> 2] ^ j, h, j) | 0; + j = H; + i = f; + return (H = j, a) | 0; +} +function fz(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0; + e = a; + a = c; + c = fw(e, a) | 0; + f = H; + return (H = (ad(b, a) | 0) + (ad(d, e) | 0) + f | f & 0, c | 0 | 0) | 0; +} +function fA(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = fC(a, b, c, d, 0) | 0; + return (H = H, e) | 0; +} +function fB(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 8 | 0; + g = f | 0; + fC(a, b, d, e, g) | 0; + i = f; + return (H = c[g + 4 >> 2] | 0, c[g >> 2] | 0) | 0; +} +function fC(a, b, d, e, f) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0; + g = a; + h = b; + i = h; + j = d; + k = e; + l = k; + if ((i | 0) == 0) { + m = (f | 0) != 0; + if ((l | 0) == 0) { + if (m) { + c[f >> 2] = (g >>> 0) % (j >>> 0); + c[f + 4 >> 2] = 0; + } + n = 0; + o = (g >>> 0) / (j >>> 0) >>> 0; + return (H = n, o) | 0; + } else { + if (!m) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } + } + m = (l | 0) == 0; + do { + if ((j | 0) == 0) { + if (m) { + if ((f | 0) != 0) { + c[f >> 2] = (i >>> 0) % (j >>> 0); + c[f + 4 >> 2] = 0; + } + n = 0; + o = (i >>> 0) / (j >>> 0) >>> 0; + return (H = n, o) | 0; + } + if ((g | 0) == 0) { + if ((f | 0) != 0) { + c[f >> 2] = 0; + c[f + 4 >> 2] = (i >>> 0) % (l >>> 0); + } + n = 0; + o = (i >>> 0) / (l >>> 0) >>> 0; + return (H = n, o) | 0; + } + p = l - 1 | 0; + if ((p & l | 0) == 0) { + if ((f | 0) != 0) { + c[f >> 2] = a | 0; + c[f + 4 >> 2] = p & i | b & 0; + } + n = 0; + o = i >>> ((fv(l | 0) | 0) >>> 0); + return (H = n, o) | 0; + } + p = (fu(l | 0) | 0) - (fu(i | 0) | 0) | 0; + if (p >>> 0 <= 30) { + q = p + 1 | 0; + r = 31 - p | 0; + s = q; + t = i << r | g >>> (q >>> 0); + u = i >>> (q >>> 0); + v = 0; + w = g << r; + break; + } + if ((f | 0) == 0) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = h | b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } else { + if (!m) { + r = (fu(l | 0) | 0) - (fu(i | 0) | 0) | 0; + if (r >>> 0 <= 31) { + q = r + 1 | 0; + p = 31 - r | 0; + x = r - 31 >> 31; + s = q; + t = g >>> (q >>> 0) & x | i << p; + u = i >>> (q >>> 0) & x; + v = 0; + w = g << p; + break; + } + if ((f | 0) == 0) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = h | b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } + p = j - 1 | 0; + if ((p & j | 0) != 0) { + x = (fu(j | 0) | 0) + 33 - (fu(i | 0) | 0) | 0; + q = 64 - x | 0; + r = 32 - x | 0; + y = r >> 31; + z = x - 32 | 0; + A = z >> 31; + s = x; + t = r - 1 >> 31 & i >>> (z >>> 0) | (i << r | g >>> (x >>> 0)) & A; + u = A & i >>> (x >>> 0); + v = g << q & y; + w = (i << q | g >>> (z >>> 0)) & y | g << r & x - 33 >> 31; + break; + } + if ((f | 0) != 0) { + c[f >> 2] = p & g; + c[f + 4 >> 2] = 0; + } + if ((j | 0) == 1) { + n = h | b & 0; + o = a | 0 | 0; + return (H = n, o) | 0; + } else { + p = fv(j | 0) | 0; + n = i >>> (p >>> 0) | 0; + o = i << 32 - p | g >>> (p >>> 0) | 0; + return (H = n, o) | 0; + } + } + } while (0); + if ((s | 0) == 0) { + B = w; + C = v; + D = u; + E = t; + F = 0; + G = 0; + } else { + g = d | 0 | 0; + d = k | e & 0; + e = fp(g, d, -1, -1) | 0; + k = H; + i = w; + w = v; + v = u; + u = t; + t = s; + s = 0; + while (1) { + I = w >>> 31 | i << 1; + J = s | w << 1; + j = u << 1 | i >>> 31 | 0; + a = u >>> 31 | v << 1 | 0; + fq(e, k, j, a) | 0; + b = H; + h = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + K = h & 1; + L = fq(j, a, h & g, (((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1) & d) | 0; + M = H; + b = t - 1 | 0; + if ((b | 0) == 0) { + break; + } else { + i = I; + w = J; + v = M; + u = L; + t = b; + s = K; + } + } + B = I; + C = J; + D = M; + E = L; + F = 0; + G = K; + } + K = C; + C = 0; + if ((f | 0) != 0) { + c[f >> 2] = E; + c[f + 4 >> 2] = D; + } + n = (K | 0) >>> 31 | (B | C) << 1 | (C << 1 | K >>> 31) & 0 | F; + o = (K << 1 | 0 >>> 31) & -2 | G; + return (H = n, o) | 0; +} +function fD(a, b) { + a = a | 0; + b = b | 0; + a1[a & 15](b | 0); +} +function fE(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + a2[a & 15](b | 0, c | 0); +} +function fF(a, b) { + a = a | 0; + b = b | 0; + return a3[a & 7](b | 0) | 0; +} +function fG(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + a4[a & 15](b | 0, c | 0, d | 0); +} +function fH(a) { + a = a | 0; + a5[a & 1](); +} +function fI(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return a6[a & 1](b | 0, c | 0) | 0; +} +function fJ(a) { + a = a | 0; + ae(0); +} +function fK(a, b) { + a = a | 0; + b = b | 0; + ae(1); +} +function fL(a) { + a = a | 0; + ae(2); + return 0; +} +function fM(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + ae(3); +} +function fN() { + ae(4); +} +function fO(a, b) { + a = a | 0; + b = b | 0; + ae(5); + return 0; +} +// EMSCRIPTEN_END_FUNCS + var a1 = [ fJ, fJ, eV, fJ, e$, fJ, eQ, fJ, eU, fJ, e_, fJ, fJ, fJ, fJ, fJ ]; + var a2 = [ fK, fK, e8, fK, fa, fK, e9, fK, fb, fK, fK, fK, fK, fK, fK, fK ]; + var a3 = [ fL, fL, eR, fL, eS, fL, fL, fL ]; + var a4 = [ fM, fM, fl, fM, fk, fM, fi, fM, fj, fM, fM, fM, fM, fM, fM, fM ]; + var a5 = [ fN, fN ]; + var a6 = [ fO, fO ]; + return { + _strlen: fo, + _crypto_auth_hmacsha256: bw, + _crypto_sign_edwards25519sha512batch: dQ, + _crypto_core_salsa208: bP, + _crypto_box_curve25519xsalsa20poly1305_afternm: bA, + _crypto_secretbox_xsalsa20poly1305: ci, + _crypto_stream_salsa20_xor: ef, + _crypto_stream_aes128ctr_xor_afternm: ec, + _crypto_sign_edwards25519sha512batch_keypair: dP, + _crypto_hashblocks_sha512: bV, + _crypto_hashblocks_sha256: bS, + _crypto_scalarmult_curve25519_base: b2, + _realloc: eq, + _crypto_sign_ed25519_open: cn, + _crypto_sign_keypair_from_raw_sk: bu, + _calloc: ep, + _crypto_box_curve25519xsalsa20poly1305_keypair: bF, + _crypto_stream_salsa2012_xor: eh, + _memset: fm, + _crypto_stream_salsa20: ee, + _memcpy: fn, + _crypto_onetimeauth_poly1305: b_, + _crypto_sign_ed25519_keypair: ck, + _crypto_auth_hmacsha512256: by, + _crypto_sign_ed25519: cl, + _crypto_box_curve25519xsalsa20poly1305_open: bE, + _crypto_stream_aes128ctr_beforenm: dT, + _crypto_stream_salsa208: ei, + _crypto_stream_xsalsa20: ek, + _crypto_scalarmult_curve25519: b3, + _crypto_box_curve25519xsalsa20poly1305: bD, + _crypto_onetimeauth_poly1305_verify: b1, + _crypto_hash_sha512: bR, + _crypto_secretbox_xsalsa20poly1305_open: cj, + _crypto_sign_edwards25519sha512batch_open: dR, + _crypto_hash_sha256: bQ, + _crypto_auth_hmacsha256_verify: bx, + _crypto_verify_32: em, + _crypto_auth_hmacsha512256_verify: bz, + _free: eo, + _crypto_box_curve25519xsalsa20poly1305_beforenm: bC, + _crypto_stream_aes128ctr: ea, + _crypto_core_salsa2012: bO, + _crypto_verify_16: ed, + _crypto_core_salsa20: bH, + _crypto_stream_salsa208_xor: ej, + _malloc: en, + _crypto_stream_aes128ctr_xor: eb, + _crypto_box_curve25519xsalsa20poly1305_open_afternm: bB, + _crypto_stream_xsalsa20_xor: el, + _crypto_stream_aes128ctr_afternm: dS, + _crypto_stream_salsa2012: eg, + _crypto_core_hsalsa20: bG, + runPostSets: bn, + stackAlloc: a7, + stackSave: a8, + stackRestore: a9, + setThrew: ba, + setTempRet0: bd, + setTempRet1: be, + setTempRet2: bf, + setTempRet3: bg, + setTempRet4: bh, + setTempRet5: bi, + setTempRet6: bj, + setTempRet7: bk, + setTempRet8: bl, + setTempRet9: bm, + dynCall_vi: fD, + dynCall_vii: fE, + dynCall_ii: fF, + dynCall_viii: fG, + dynCall_v: fH, + dynCall_iii: fI + }; +// EMSCRIPTEN_END_ASM +})({Math:Math, Int8Array:Int8Array, Int16Array:Int16Array, Int32Array:Int32Array, Uint8Array:Uint8Array, Uint16Array:Uint16Array, Uint32Array:Uint32Array, Float32Array:Float32Array, Float64Array:Float64Array}, {abort:wa, assert:v, asmPrintInt:function(a, b) { + r.print("int " + a + "," + b) +}, asmPrintFloat:function(a, b) { + r.print("float " + a + "," + b) +}, min:Zc, invoke_vi:function(a, b) { + try { + r.dynCall_vi(a, b) + }catch(c) { + "number" !== typeof c && "longjmp" !== c && e(c), V.setThrew(1, 0) + } +}, invoke_vii:function(a, b, c) { + try { + r.dynCall_vii(a, b, c) + }catch(d) { + "number" !== typeof d && "longjmp" !== d && e(d), V.setThrew(1, 0) + } +}, invoke_ii:function(a, b) { + try { + return r.dynCall_ii(a, b) + }catch(c) { + "number" !== typeof c && "longjmp" !== c && e(c), V.setThrew(1, 0) + } +}, invoke_viii:function(a, b, c, d) { + try { + r.dynCall_viii(a, b, c, d) + }catch(f) { + "number" !== typeof f && "longjmp" !== f && e(f), V.setThrew(1, 0) + } +}, invoke_v:function(a) { + try { + r.dynCall_v(a) + }catch(b) { + "number" !== typeof b && "longjmp" !== b && e(b), V.setThrew(1, 0) + } +}, invoke_iii:function(a, b, c) { + try { + return r.dynCall_iii(a, b, c) + }catch(d) { + "number" !== typeof d && "longjmp" !== d && e(d), V.setThrew(1, 0) + } +}, _strncmp:function(a, b, c) { + for(var d = 0;d < c;) { + var f = G[a + d | 0], g = G[b + d | 0]; + if(f == g && 0 == f) { + break + } + if(0 == f) { + return-1 + } + if(0 == g) { + return 1 + } + if(f == g) { + d++ + }else { + return f > g ? 1 : -1 + } + } + return 0 +}, _llvm_va_end:aa(), _sysconf:function(a) { + switch(a) { + case 8: + return 4096; + case 54: + ; + case 56: + ; + case 21: + ; + case 61: + ; + case 63: + ; + case 22: + ; + case 67: + ; + case 23: + ; + case 24: + ; + case 25: + ; + case 26: + ; + case 27: + ; + case 69: + ; + case 28: + ; + case 101: + ; + case 70: + ; + case 71: + ; + case 29: + ; + case 30: + ; + case 199: + ; + case 75: + ; + case 76: + ; + case 32: + ; + case 43: + ; + case 44: + ; + case 80: + ; + case 46: + ; + case 47: + ; + case 45: + ; + case 48: + ; + case 49: + ; + case 42: + ; + case 82: + ; + case 33: + ; + case 7: + ; + case 108: + ; + case 109: + ; + case 107: + ; + case 112: + ; + case 119: + ; + case 121: + return 200809; + case 13: + ; + case 104: + ; + case 94: + ; + case 95: + ; + case 34: + ; + case 35: + ; + case 77: + ; + case 81: + ; + case 83: + ; + case 84: + ; + case 85: + ; + case 86: + ; + case 87: + ; + case 88: + ; + case 89: + ; + case 90: + ; + case 91: + ; + case 94: + ; + case 95: + ; + case 110: + ; + case 111: + ; + case 113: + ; + case 114: + ; + case 115: + ; + case 116: + ; + case 117: + ; + case 118: + ; + case 120: + ; + case 40: + ; + case 16: + ; + case 79: + ; + case 19: + return-1; + case 92: + ; + case 93: + ; + case 5: + ; + case 72: + ; + case 6: + ; + case 74: + ; + case 92: + ; + case 93: + ; + case 96: + ; + case 97: + ; + case 98: + ; + case 99: + ; + case 102: + ; + case 103: + ; + case 105: + return 1; + case 38: + ; + case 66: + ; + case 50: + ; + case 51: + ; + case 4: + return 1024; + case 15: + ; + case 64: + ; + case 41: + return 32; + case 55: + ; + case 37: + ; + case 17: + return 2147483647; + case 18: + ; + case 1: + return 47839; + case 59: + ; + case 57: + return 99; + case 68: + ; + case 58: + return 2048; + case 0: + return 2097152; + case 3: + return 65536; + case 14: + return 32768; + case 73: + return 32767; + case 39: + return 16384; + case 60: + return 1E3; + case 106: + return 700; + case 52: + return 256; + case 62: + return 255; + case 2: + return 100; + case 65: + return 64; + case 36: + return 20; + case 100: + return 16; + case 20: + return 6; + case 53: + return 4; + case 10: + return 1 + } + M(N.A); + return-1 +}, ___cxa_throw:tc, _randombytes:ub, _strerror:Bc, _abort:function() { + r.abort() +}, _fprintf:oc, _llvm_eh_exception:U, ___cxa_free_exception:uc, _fflush:aa(), ___buildEnvironment:yc, __reallyNegative:lc, _strchr:function(a, b) { + a--; + do { + a++; + var c = A[a]; + if(c == b) { + return a + } + }while(c); + return 0 +}, _fputc:Dc, ___setErrNo:M, _fwrite:jc, _send:hc, _write:ic, _exit:function(a) { + Cc(a) +}, ___cxa_find_matching_catch:function(a, b) { + -1 == a && (a = B[U.m >> 2]); + -1 == b && (b = B[U.m + 4 >> 2]); + var c = Array.prototype.slice.call(arguments, 2); + 0 != b && !rc(b) && 0 == B[B[b >> 2] - 8 >> 2] && (a = B[a >> 2]); + for(var d = 0;d < c.length;d++) { + if(sc(c[d], b, a)) { + return(V.setTempRet0(c[d]), a) | 0 + } + } + return(V.setTempRet0(b), a) | 0 +}, ___cxa_allocate_exception:function(a) { + return Oa(a) +}, _isspace:function(a) { + return 32 == a || 9 <= a && 13 >= a +}, ___cxa_is_number_type:rc, ___resumeException:function(a) { + 0 == B[U.m >> 2] && (B[U.m >> 2] = a); + e(a + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.") +}, __formatString:mc, ___cxa_does_inherit:sc, _getenv:zc, _vfprintf:function(a, b, c) { + return oc(a, b, B[c >> 2]) +}, ___cxa_begin_catch:function(a) { + qc.ta--; + return a +}, __ZSt18uncaught_exceptionv:qc, _pwrite:function(a, b, c, d) { + a = R[a]; + if(!a) { + return M(N.$), -1 + } + try { + return Kb(a, A, b, c, d) + }catch(f) { + return ac(f), -1 + } +}, ___cxa_call_unexpected:function(a) { + r.P("Unexpected exception thrown, this is not properly supported - aborting"); + za = l; + e(a) +}, _sbrk:pc, _strerror_r:Ac, ___errno_location:function() { + return vb +}, ___gxx_personality_v0:aa(), _time:function(a) { + var b = Math.floor(Date.now() / 1E3); + a && (B[a >> 2] = b); + return b +}, __exit:Cc, ___cxa_end_catch:wc, STACKTOP:u, STACK_MAX:Ta, tempDoublePtr:qb, ABORT:za, cttz_i8:Yc, ctlz_i8:Xc, NaN:NaN, Infinity:Infinity, __ZTVN10__cxxabiv120__si_class_type_infoE:ob, _stderr:nb, __ZTVN10__cxxabiv117__class_type_infoE:pb, ___progname:k}, I), kc = r._strlen = V._strlen; +r._crypto_auth_hmacsha256 = V._crypto_auth_hmacsha256; +r._crypto_sign_edwards25519sha512batch = V._crypto_sign_edwards25519sha512batch; +r._crypto_core_salsa208 = V._crypto_core_salsa208; +r._crypto_box_curve25519xsalsa20poly1305_afternm = V._crypto_box_curve25519xsalsa20poly1305_afternm; +r._crypto_secretbox_xsalsa20poly1305 = V._crypto_secretbox_xsalsa20poly1305; +r._crypto_stream_salsa20_xor = V._crypto_stream_salsa20_xor; +r._crypto_stream_aes128ctr_xor_afternm = V._crypto_stream_aes128ctr_xor_afternm; +r._crypto_sign_edwards25519sha512batch_keypair = V._crypto_sign_edwards25519sha512batch_keypair; +r._crypto_hashblocks_sha512 = V._crypto_hashblocks_sha512; +r._crypto_hashblocks_sha256 = V._crypto_hashblocks_sha256; +r._crypto_scalarmult_curve25519_base = V._crypto_scalarmult_curve25519_base; +r._realloc = V._realloc; +r._crypto_sign_ed25519_open = V._crypto_sign_ed25519_open; +r._crypto_sign_keypair_from_raw_sk = V._crypto_sign_keypair_from_raw_sk; +r._calloc = V._calloc; +r._crypto_box_curve25519xsalsa20poly1305_keypair = V._crypto_box_curve25519xsalsa20poly1305_keypair; +r._crypto_stream_salsa2012_xor = V._crypto_stream_salsa2012_xor; +var rb = r._memset = V._memset; +r._crypto_stream_salsa20 = V._crypto_stream_salsa20; +var sb = r._memcpy = V._memcpy; +r._crypto_onetimeauth_poly1305 = V._crypto_onetimeauth_poly1305; +r._crypto_sign_ed25519_keypair = V._crypto_sign_ed25519_keypair; +r._crypto_auth_hmacsha512256 = V._crypto_auth_hmacsha512256; +r._crypto_sign_ed25519 = V._crypto_sign_ed25519; +r._crypto_box_curve25519xsalsa20poly1305_open = V._crypto_box_curve25519xsalsa20poly1305_open; +r._crypto_stream_aes128ctr_beforenm = V._crypto_stream_aes128ctr_beforenm; +r._crypto_stream_salsa208 = V._crypto_stream_salsa208; +r._crypto_stream_xsalsa20 = V._crypto_stream_xsalsa20; +r._crypto_scalarmult_curve25519 = V._crypto_scalarmult_curve25519; +r._crypto_box_curve25519xsalsa20poly1305 = V._crypto_box_curve25519xsalsa20poly1305; +r._crypto_onetimeauth_poly1305_verify = V._crypto_onetimeauth_poly1305_verify; +r._crypto_hash_sha512 = V._crypto_hash_sha512; +r._crypto_secretbox_xsalsa20poly1305_open = V._crypto_secretbox_xsalsa20poly1305_open; +r._crypto_sign_edwards25519sha512batch_open = V._crypto_sign_edwards25519sha512batch_open; +r._crypto_hash_sha256 = V._crypto_hash_sha256; +r._crypto_auth_hmacsha256_verify = V._crypto_auth_hmacsha256_verify; +r._crypto_verify_32 = V._crypto_verify_32; +r._crypto_auth_hmacsha512256_verify = V._crypto_auth_hmacsha512256_verify; +var vc = r._free = V._free; +r._crypto_box_curve25519xsalsa20poly1305_beforenm = V._crypto_box_curve25519xsalsa20poly1305_beforenm; +r._crypto_stream_aes128ctr = V._crypto_stream_aes128ctr; +r._crypto_core_salsa2012 = V._crypto_core_salsa2012; +r._crypto_verify_16 = V._crypto_verify_16; +r._crypto_core_salsa20 = V._crypto_core_salsa20; +r._crypto_stream_salsa208_xor = V._crypto_stream_salsa208_xor; +var Oa = r._malloc = V._malloc; +r._crypto_stream_aes128ctr_xor = V._crypto_stream_aes128ctr_xor; +r._crypto_box_curve25519xsalsa20poly1305_open_afternm = V._crypto_box_curve25519xsalsa20poly1305_open_afternm; +r._crypto_stream_xsalsa20_xor = V._crypto_stream_xsalsa20_xor; +r._crypto_stream_aes128ctr_afternm = V._crypto_stream_aes128ctr_afternm; +r._crypto_stream_salsa2012 = V._crypto_stream_salsa2012; +r._crypto_core_hsalsa20 = V._crypto_core_hsalsa20; +var mb = r.runPostSets = V.runPostSets; +r.dynCall_vi = V.dynCall_vi; +r.dynCall_vii = V.dynCall_vii; +r.dynCall_ii = V.dynCall_ii; +r.dynCall_viii = V.dynCall_viii; +r.dynCall_v = V.dynCall_v; +r.dynCall_iii = V.dynCall_iii; +var qa = function(a) { + return V.stackAlloc(a) +}, ja = function() { + return V.stackSave() +}, ka = function(a) { + V.stackRestore(a) +}, nc; +function X(a, b) { + a != m && ("number" == typeof a ? this.p(a) : b == m && "string" != typeof a ? this.k(a, 256) : this.k(a, b)) +} +function $c() { + return new X(m) +} +function ad(a, b) { + var c = bd[a.charCodeAt(b)]; + return c == m ? -1 : c +} +function cd(a) { + var b = $c(); + b.D(a); + return b +} +function Y(a, b) { + this.h = a | 0; + this.j = b | 0 +} +Y.Ca = {}; +Y.D = function(a) { + if(-128 <= a && 128 > a) { + var b = Y.Ca[a]; + if(b) { + return b + } + } + b = new Y(a | 0, 0 > a ? -1 : 0); + -128 <= a && 128 > a && (Y.Ca[a] = b); + return b +}; +Y.p = function(a) { + return isNaN(a) || !isFinite(a) ? Y.ZERO : a <= -Y.Ea ? Y.MIN_VALUE : a + 1 >= Y.Ea ? Y.MAX_VALUE : 0 > a ? Y.p(-a).i() : new Y(a % Y.B | 0, a / Y.B | 0) +}; +Y.v = function(a, b) { + return new Y(a, b) +}; +Y.k = function(a, b) { + 0 == a.length && e(Error("number format error: empty string")); + var c = b || 10; + (2 > c || 36 < c) && e(Error("radix out of range: " + c)); + if("-" == a.charAt(0)) { + return Y.k(a.substring(1), c).i() + } + 0 <= a.indexOf("-") && e(Error('number format error: interior "-" character: ' + a)); + for(var d = Y.p(Math.pow(c, 8)), f = Y.ZERO, g = 0;g < a.length;g += 8) { + var h = Math.min(8, a.length - g), i = parseInt(a.substring(g, g + h), c); + 8 > h ? (h = Y.p(Math.pow(c, h)), f = f.multiply(h).add(Y.p(i))) : (f = f.multiply(d), f = f.add(Y.p(i))) + } + return f +}; +Y.ea = 65536; +Y.Od = 16777216; +Y.B = Y.ea * Y.ea; +Y.Pd = Y.B / 2; +Y.Qd = Y.B * Y.ea; +Y.eb = Y.B * Y.B; +Y.Ea = Y.eb / 2; +Y.ZERO = Y.D(0); +Y.ONE = Y.D(1); +Y.Da = Y.D(-1); +Y.MAX_VALUE = Y.v(-1, 2147483647); +Y.MIN_VALUE = Y.v(0, -2147483648); +Y.cb = Y.D(16777216); +q = Y.prototype; +q.Z = function() { + return this.j * Y.B + this.ob() +}; +q.toString = function(a) { + a = a || 10; + (2 > a || 36 < a) && e(Error("radix out of range: " + a)); + if(this.G()) { + return"0" + } + if(this.n()) { + if(this.o(Y.MIN_VALUE)) { + var b = Y.p(a), c = this.F(b), b = c.multiply(b).R(this); + return c.toString(a) + b.h.toString(a) + } + return"-" + this.i().toString(a) + } + for(var c = Y.p(Math.pow(a, 6)), b = this, d = "";;) { + var f = b.F(c), g = b.R(f.multiply(c)).h.toString(a), b = f; + if(b.G()) { + return g + d + } + for(;6 > g.length;) { + g = "0" + g + } + d = "" + g + d + } +}; +q.ob = function() { + return 0 <= this.h ? this.h : Y.B + this.h +}; +q.G = function() { + return 0 == this.j && 0 == this.h +}; +q.n = function() { + return 0 > this.j +}; +q.Pa = function() { + return 1 == (this.h & 1) +}; +q.o = function(a) { + return this.j == a.j && this.h == a.h +}; +q.Ra = function() { + return 0 > this.ja(Y.cb) +}; +q.qb = function(a) { + return 0 < this.ja(a) +}; +q.rb = function(a) { + return 0 <= this.ja(a) +}; +q.ja = function(a) { + if(this.o(a)) { + return 0 + } + var b = this.n(), c = a.n(); + return b && !c ? -1 : !b && c ? 1 : this.R(a).n() ? -1 : 1 +}; +q.i = function() { + return this.o(Y.MIN_VALUE) ? Y.MIN_VALUE : this.xb().add(Y.ONE) +}; +q.add = function(a) { + var b = this.j >>> 16, c = this.j & 65535, d = this.h >>> 16, f = a.j >>> 16, g = a.j & 65535, h = a.h >>> 16, i; + i = 0 + ((this.h & 65535) + (a.h & 65535)); + a = 0 + (i >>> 16); + a += d + h; + d = 0 + (a >>> 16); + d += c + g; + c = 0 + (d >>> 16); + c = c + (b + f) & 65535; + return Y.v((a & 65535) << 16 | i & 65535, c << 16 | d & 65535) +}; +q.R = function(a) { + return this.add(a.i()) +}; +q.multiply = function(a) { + if(this.G() || a.G()) { + return Y.ZERO + } + if(this.o(Y.MIN_VALUE)) { + return a.Pa() ? Y.MIN_VALUE : Y.ZERO + } + if(a.o(Y.MIN_VALUE)) { + return this.Pa() ? Y.MIN_VALUE : Y.ZERO + } + if(this.n()) { + return a.n() ? this.i().multiply(a.i()) : this.i().multiply(a).i() + } + if(a.n()) { + return this.multiply(a.i()).i() + } + if(this.Ra() && a.Ra()) { + return Y.p(this.Z() * a.Z()) + } + var b = this.j >>> 16, c = this.j & 65535, d = this.h >>> 16, f = this.h & 65535, g = a.j >>> 16, h = a.j & 65535, i = a.h >>> 16, a = a.h & 65535, j, p, z, w; + w = 0 + f * a; + z = 0 + (w >>> 16); + z += d * a; + p = 0 + (z >>> 16); + z = (z & 65535) + f * i; + p += z >>> 16; + z &= 65535; + p += c * a; + j = 0 + (p >>> 16); + p = (p & 65535) + d * i; + j += p >>> 16; + p &= 65535; + p += f * h; + j += p >>> 16; + p &= 65535; + j = j + (b * a + c * i + d * h + f * g) & 65535; + return Y.v(z << 16 | w & 65535, j << 16 | p) +}; +q.F = function(a) { + a.G() && e(Error("division by zero")); + if(this.G()) { + return Y.ZERO + } + if(this.o(Y.MIN_VALUE)) { + if(a.o(Y.ONE) || a.o(Y.Da)) { + return Y.MIN_VALUE + } + if(a.o(Y.MIN_VALUE)) { + return Y.ONE + } + var b = this.Db().F(a).shiftLeft(1); + if(b.o(Y.ZERO)) { + return a.n() ? Y.ONE : Y.Da + } + var c = this.R(a.multiply(b)); + return b.add(c.F(a)) + } + if(a.o(Y.MIN_VALUE)) { + return Y.ZERO + } + if(this.n()) { + return a.n() ? this.i().F(a.i()) : this.i().F(a).i() + } + if(a.n()) { + return this.F(a.i()).i() + } + for(var d = Y.ZERO, c = this;c.rb(a);) { + for(var b = Math.max(1, Math.floor(c.Z() / a.Z())), f = Math.ceil(Math.log(b) / Math.LN2), f = 48 >= f ? 1 : Math.pow(2, f - 48), g = Y.p(b), h = g.multiply(a);h.n() || h.qb(c);) { + b -= f, g = Y.p(b), h = g.multiply(a) + } + g.G() && (g = Y.ONE); + d = d.add(g); + c = c.R(h) + } + return d +}; +q.xb = function() { + return Y.v(~this.h, ~this.j) +}; +q.shiftLeft = function(a) { + a &= 63; + if(0 == a) { + return this + } + var b = this.h; + return 32 > a ? Y.v(b << a, this.j << a | b >>> 32 - a) : Y.v(0, b << a - 32) +}; +q.Db = function() { + var a; + a = 1; + if(0 == a) { + return this + } + var b = this.j; + return 32 > a ? Y.v(this.h >>> a | b << 32 - a, b >> a) : Y.v(b >> a - 32, 0 <= b ? 0 : -1) +}; +q = X.prototype; +q.ga = function(a, b, c, d) { + for(var f = 0, g = 0;0 <= --d;) { + var h = a * this[f++] + b[c] + g, g = Math.floor(h / 67108864); + b[c++] = h & 67108863 + } + return g +}; +q.f = 26; +q.u = 67108863; +q.K = 67108864; +q.bb = Math.pow(2, 52); +q.Aa = 26; +q.Ba = 0; +var bd = [], dd, Z; +dd = 48; +for(Z = 0;9 >= Z;++Z) { + bd[dd++] = Z +} +dd = 97; +for(Z = 10;36 > Z;++Z) { + bd[dd++] = Z +} +dd = 65; +for(Z = 10;36 > Z;++Z) { + bd[dd++] = Z +} +q = X.prototype; +q.copyTo = function(a) { + for(var b = this.b - 1;0 <= b;--b) { + a[b] = this[b] + } + a.b = this.b; + a.c = this.c +}; +q.D = function(a) { + this.b = 1; + this.c = 0 > a ? -1 : 0; + 0 < a ? this[0] = a : -1 > a ? this[0] = a + DV : this.b = 0 +}; +q.k = function(a, b) { + var c; + if(16 == b) { + c = 4 + }else { + if(8 == b) { + c = 3 + }else { + if(256 == b) { + c = 8 + }else { + if(2 == b) { + c = 1 + }else { + if(32 == b) { + c = 5 + }else { + if(4 == b) { + c = 2 + }else { + this.nb(a, b); + return + } + } + } + } + } + } + this.c = this.b = 0; + for(var d = a.length, f = n, g = 0;0 <= --d;) { + var h = 8 == c ? a[d] & 255 : ad(a, d); + 0 > h ? "-" == a.charAt(d) && (f = l) : (f = n, 0 == g ? this[this.b++] = h : g + c > this.f ? (this[this.b - 1] |= (h & (1 << this.f - g) - 1) << g, this[this.b++] = h >> this.f - g) : this[this.b - 1] |= h << g, g += c, g >= this.f && (g -= this.f)) + } + 8 == c && 0 != (a[0] & 128) && (this.c = -1, 0 < g && (this[this.b - 1] |= (1 << this.f - g) - 1 << g)); + this.C(); + f && X.ZERO.t(this, this) +}; +q.C = function() { + for(var a = this.c & this.u;0 < this.b && this[this.b - 1] == a;) { + --this.b + } +}; +q.la = function(a, b) { + var c; + for(c = this.b - 1;0 <= c;--c) { + b[c + a] = this[c] + } + for(c = a - 1;0 <= c;--c) { + b[c] = 0 + } + b.b = this.b + a; + b.c = this.c +}; +q.jb = function(a, b) { + for(var c = a;c < this.b;++c) { + b[c - a] = this[c] + } + b.b = Math.max(this.b - a, 0); + b.c = this.c +}; +q.Qa = function(a, b) { + var c = a % this.f, d = this.f - c, f = (1 << d) - 1, g = Math.floor(a / this.f), h = this.c << c & this.u, i; + for(i = this.b - 1;0 <= i;--i) { + b[i + g + 1] = this[i] >> d | h, h = (this[i] & f) << c + } + for(i = g - 1;0 <= i;--i) { + b[i] = 0 + } + b[g] = h; + b.b = this.b + g + 1; + b.c = this.c; + b.C() +}; +q.zb = function(a, b) { + b.c = this.c; + var c = Math.floor(a / this.f); + if(c >= this.b) { + b.b = 0 + }else { + var d = a % this.f, f = this.f - d, g = (1 << d) - 1; + b[0] = this[c] >> d; + for(var h = c + 1;h < this.b;++h) { + b[h - c - 1] |= (this[h] & g) << f, b[h - c] = this[h] >> d + } + 0 < d && (b[this.b - c - 1] |= (this.c & g) << f); + b.b = this.b - c; + b.C() + } +}; +q.t = function(a, b) { + for(var c = 0, d = 0, f = Math.min(a.b, this.b);c < f;) { + d += this[c] - a[c], b[c++] = d & this.u, d >>= this.f + } + if(a.b < this.b) { + for(d -= a.c;c < this.b;) { + d += this[c], b[c++] = d & this.u, d >>= this.f + } + d += this.c + }else { + for(d += this.c;c < a.b;) { + d -= a[c], b[c++] = d & this.u, d >>= this.f + } + d -= a.c + } + b.c = 0 > d ? -1 : 0; + -1 > d ? b[c++] = this.K + d : 0 < d && (b[c++] = d); + b.b = c; + b.C() +}; +q.vb = function(a) { + var b = $.Xa, c = this.abs(), d = b.abs(), f = c.b; + for(a.b = f + d.b;0 <= --f;) { + a[f] = 0 + } + for(f = 0;f < d.b;++f) { + a[f + c.b] = c.ga(d[f], a, f, c.b) + } + a.c = 0; + a.C(); + this.c != b.c && X.ZERO.t(a, a) +}; +q.Ja = function(a, b, c) { + var d = a.abs(); + if(!(0 >= d.b)) { + var f = this.abs(); + if(f.b < d.b) { + b != m && b.D(0), c != m && this.copyTo(c) + }else { + c == m && (c = $c()); + var g = $c(), h = this.c, a = a.c, i = d[d.b - 1], j = 1, p; + if(0 != (p = i >>> 16)) { + i = p, j += 16 + } + if(0 != (p = i >> 8)) { + i = p, j += 8 + } + if(0 != (p = i >> 4)) { + i = p, j += 4 + } + if(0 != (p = i >> 2)) { + i = p, j += 2 + } + 0 != i >> 1 && (j += 1); + i = this.f - j; + 0 < i ? (d.Qa(i, g), f.Qa(i, c)) : (d.copyTo(g), f.copyTo(c)); + d = g.b; + f = g[d - 1]; + if(0 != f) { + p = f * (1 << this.Aa) + (1 < d ? g[d - 2] >> this.Ba : 0); + j = this.bb / p; + p = (1 << this.Aa) / p; + var z = 1 << this.Ba, w = c.b, C = w - d, D = b == m ? $c() : b; + g.la(C, D); + 0 <= c.U(D) && (c[c.b++] = 1, c.t(D, c)); + X.ONE.la(d, D); + for(D.t(g, g);g.b < d;) { + g[g.b++] = 0 + } + for(;0 <= --C;) { + var L = c[--w] == f ? this.u : Math.floor(c[w] * j + (c[w - 1] + z) * p); + if((c[w] += g.ga(L, c, C, d)) < L) { + g.la(C, D); + for(c.t(D, c);c[w] < --L;) { + c.t(D, c) + } + } + } + b != m && (c.jb(d, b), h != a && X.ZERO.t(b, b)); + c.b = d; + c.C(); + 0 < i && c.zb(i, c); + 0 > h && X.ZERO.t(c, c) + } + } + } +}; +q.toString = function(a) { + if(0 > this.c) { + return"-" + this.i().toString(a) + } + if(16 == a) { + a = 4 + }else { + if(8 == a) { + a = 3 + }else { + if(2 == a) { + a = 1 + }else { + if(32 == a) { + a = 5 + }else { + if(4 == a) { + a = 2 + }else { + return this.Fb(a) + } + } + } + } + } + var b = (1 << a) - 1, c, d = n, f = "", g = this.b, h = this.f - g * this.f % a; + if(0 < g--) { + if(h < this.f && 0 < (c = this[g] >> h)) { + d = l, f = "0123456789abcdefghijklmnopqrstuvwxyz".charAt(c) + } + for(;0 <= g;) { + h < a ? (c = (this[g] & (1 << h) - 1) << a - h, c |= this[--g] >> (h += this.f - a)) : (c = this[g] >> (h -= a) & b, 0 >= h && (h += this.f, --g)), 0 < c && (d = l), d && (f += "0123456789abcdefghijklmnopqrstuvwxyz".charAt(c)) + } + } + return d ? f : "0" +}; +q.i = function() { + var a = $c(); + X.ZERO.t(this, a); + return a +}; +q.abs = function() { + return 0 > this.c ? this.i() : this +}; +q.U = function(a) { + var b = this.c - a.c; + if(0 != b) { + return b + } + var c = this.b, b = c - a.b; + if(0 != b) { + return 0 > this.c ? -b : b + } + for(;0 <= --c;) { + if(0 != (b = this[c] - a[c])) { + return b + } + } + return 0 +}; +X.ZERO = cd(0); +X.ONE = cd(1); +q = X.prototype; +q.nb = function(a, b) { + this.D(0); + b == m && (b = 10); + for(var c = this.S(b), d = Math.pow(b, c), f = n, g = 0, h = 0, i = 0;i < a.length;++i) { + var j = ad(a, i); + 0 > j ? "-" == a.charAt(i) && 0 == this.ra() && (f = l) : (h = b * h + j, ++g >= c && (this.Ia(d), this.Ha(h), h = g = 0)) + } + 0 < g && (this.Ia(Math.pow(b, g)), this.Ha(h)); + f && X.ZERO.t(this, this) +}; +q.S = function(a) { + return Math.floor(Math.LN2 * this.f / Math.log(a)) +}; +q.ra = function() { + return 0 > this.c ? -1 : 0 >= this.b || 1 == this.b && 0 >= this[0] ? 0 : 1 +}; +q.Ia = function(a) { + this[this.b] = this.ga(a - 1, this, 0, this.b); + ++this.b; + this.C() +}; +q.Ha = function(a) { + var b = 0; + if(0 != a) { + for(;this.b <= b;) { + this[this.b++] = 0 + } + for(this[b] += a;this[b] >= this.K;) { + this[b] -= this.K, ++b >= this.b && (this[this.b++] = 0), ++this[b] + } + } +}; +q.Fb = function(a) { + a == m && (a = 10); + if(0 == this.ra() || 2 > a || 36 < a) { + return"0" + } + var b = this.S(a), b = Math.pow(a, b), c = cd(b), d = $c(), f = $c(), g = ""; + for(this.Ja(c, d, f);0 < d.ra();) { + g = (b + f.Oa()).toString(a).substr(1) + g, d.Ja(c, d, f) + } + return f.Oa().toString(a) + g +}; +q.Oa = function() { + if(0 > this.c) { + if(1 == this.b) { + return this[0] - this.K + } + if(0 == this.b) { + return-1 + } + }else { + if(1 == this.b) { + return this[0] + } + if(0 == this.b) { + return 0 + } + } + return(this[1] & (1 << 32 - this.f) - 1) << this.f | this[0] +}; +q.fa = function(a, b) { + for(var c = 0, d = 0, f = Math.min(a.b, this.b);c < f;) { + d += this[c] + a[c], b[c++] = d & this.u, d >>= this.f + } + if(a.b < this.b) { + for(d += a.c;c < this.b;) { + d += this[c], b[c++] = d & this.u, d >>= this.f + } + d += this.c + }else { + for(d += this.c;c < a.b;) { + d += a[c], b[c++] = d & this.u, d >>= this.f + } + d += a.c + } + b.c = 0 > d ? -1 : 0; + 0 < d ? b[c++] = d : -1 > d && (b[c++] = this.K + d); + b.b = c; + b.C() +}; +var $ = {abs:function(a, b) { + var c = new Y(a, b), c = c.n() ? c.i() : c; + B[qb >> 2] = c.h; + B[qb + 4 >> 2] = c.j +}, Ka:function() { + $.kb || ($.kb = l, $.Xa = new X, $.Xa.k("4294967296", 10), $.sa = new X, $.sa.k("18446744073709551616", 10), $.xe = new X, $.ye = new X) +}, me:function(a, b) { + var c = new X; + c.k(b.toString(), 10); + var d = new X; + c.vb(d); + c = new X; + c.k(a.toString(), 10); + var f = new X; + c.fa(d, f); + return f +}, stringify:function(a, b, c) { + a = (new Y(a, b)).toString(); + c && "-" == a[0] && ($.Ka(), c = new X, c.k(a, 10), a = new X, $.sa.fa(c, a), a = a.toString(10)); + return a +}, k:function(a, b, c, d, f) { + $.Ka(); + var g = new X; + g.k(a, b); + a = new X; + a.k(c, 10); + c = new X; + c.k(d, 10); + f && 0 > g.U(X.ZERO) && (d = new X, g.fa($.sa, d), g = d); + d = n; + 0 > g.U(a) ? (g = a, d = l) : 0 < g.U(c) && (g = c, d = l); + g = Y.k(g.toString()); + B[qb >> 2] = g.h; + B[qb + 4 >> 2] = g.j; + d && e("range error") +}}; +nc = $; +var ed, fd; +r.callMain = r.$d = function(a) { + function b() { + for(var a = 0;3 > a;a++) { + d.push(0) + } + } + v(0 == K, "cannot call main when async dependencies remain! (listen on __ATMAIN__)"); + v(0 == Wa.length, "cannot call main when preRun functions remain to be called"); + a = a || []; + ab || (ab = l, Va(Xa)); + var c = a.length + 1, d = [F(J("/bin/this.program"), "i8", Ka)]; + b(); + for(var f = 0;f < c - 1;f += 1) { + d.push(F(J(a[f]), "i8", Ka)), b() + } + d.push(0); + d = F(d, "i32", Ka); + ed = u; + fd = l; + var g; + try { + g = r._main(c, d, 0) + }catch(h) { + if(h && "object" == typeof h && "ExitStatus" == h.type) { + return r.print("Exit Status: " + h.value), h.value + } + "SimulateInfiniteLoop" == h ? r.noExitRuntime = l : e(h) + }finally { + fd = n + } + r.noExitRuntime || gd(g) +}; +function lb(a) { + function b() { + ab || (ab = l, Va(Xa)); + Va(Ya); + gb = l; + r._main && kb && r.callMain(a); + if(r.postRun) { + for("function" == typeof r.postRun && (r.postRun = [r.postRun]);r.postRun.length;) { + cb(r.postRun.shift()) + } + } + Va($a) + } + a = a || r.arguments; + if(0 < K) { + r.P("run() called, but dependencies remain, so not running") + }else { + if(r.preRun) { + for("function" == typeof r.preRun && (r.preRun = [r.preRun]);r.preRun.length;) { + bb(r.preRun.shift()) + } + } + Va(Wa); + 0 < K || (r.setStatus ? (r.setStatus("Running..."), setTimeout(function() { + setTimeout(function() { + r.setStatus("") + }, 1); + za || b() + }, 1)) : b()) + } +} +r.run = r.we = lb; +function gd(a) { + za = l; + u = ed; + Va(Za); + fd && e({type:"ExitStatus", value:a}) +} +r.exit = r.de = gd; +function wa(a) { + a && r.print(a); + za = l; + e("abort() at " + Error().stack) +} +r.abort = r.abort = wa; +if(r.preInit) { + for("function" == typeof r.preInit && (r.preInit = [r.preInit]);0 < r.preInit.length;) { + r.preInit.pop()() + } +} +var kb = l; +r.noInitialRun && (kb = n); +lb(); +r._crypto_auth_hmacsha256_BYTES = 32; +r._crypto_core_salsa2012_INPUTBYTES = 16; +r._crypto_box_curve25519xsalsa20poly1305_ZEROBYTES = 32; +r._crypto_core_salsa20_KEYBYTES = 32; +r._crypto_core_hsalsa20_OUTPUTBYTES = 32; +r._crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES = 32; +r._crypto_secretbox_xsalsa20poly1305_ZEROBYTES = 32; +r._crypto_stream_salsa2012_NONCEBYTES = 8; +r._crypto_scalarmult_curve25519_SCALARBYTES = 32; +r._crypto_sign_edwards25519sha512batch_BYTES = 64; +r._crypto_auth_hmacsha512256_BYTES = 32; +r._crypto_core_salsa208_INPUTBYTES = 16; +r._crypto_stream_xsalsa20_KEYBYTES = 32; +r._crypto_sign_ed25519_BYTES = 64; +r._crypto_stream_salsa2012_KEYBYTES = 32; +r._crypto_stream_salsa20_KEYBYTES = 32; +r._crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES = 16; +r._crypto_core_salsa20_INPUTBYTES = 16; +r._crypto_hashblocks_sha256_BLOCKBYTES = 64; +r._crypto_onetimeauth_poly1305_KEYBYTES = 32; +r._crypto_auth_hmacsha512256_KEYBYTES = 32; +r._crypto_hash_sha256_BYTES = 32; +r._crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32; +r._crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32; +r._crypto_sign_ed25519_SECRETKEYBYTES = 64; +r._crypto_stream_salsa208_NONCEBYTES = 8; +r._crypto_scalarmult_curve25519_BYTES = 32; +r._crypto_hashblocks_sha512_STATEBYTES = 64; +r._crypto_stream_salsa20_NONCEBYTES = 8; +r._crypto_sign_ed25519_PUBLICKEYBYTES = 32; +r._crypto_core_salsa208_OUTPUTBYTES = 64; +r._crypto_core_hsalsa20_INPUTBYTES = 16; +r._crypto_stream_aes128ctr_BEFORENMBYTES = 1408; +r._crypto_auth_hmacsha256_KEYBYTES = 32; +r._crypto_verify_32_BYTES = 32; +r._crypto_verify_16_BYTES = 16; +r._crypto_box_curve25519xsalsa20poly1305_NONCEBYTES = 24; +r._crypto_core_salsa2012_KEYBYTES = 32; +r._crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES = 16; +r._crypto_hashblocks_sha256_STATEBYTES = 32; +r._crypto_secretbox_xsalsa20poly1305_KEYBYTES = 32; +r._crypto_stream_xsalsa20_NONCEBYTES = 24; +r._crypto_onetimeauth_poly1305_BYTES = 16; +r._crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32; +r._crypto_hash_sha512_BYTES = 64; +r._crypto_core_salsa20_CONSTBYTES = 16; +r._crypto_core_salsa2012_CONSTBYTES = 16; +r._crypto_core_salsa2012_OUTPUTBYTES = 64; +r._crypto_core_salsa20_OUTPUTBYTES = 64; +r._crypto_core_hsalsa20_CONSTBYTES = 16; +r._crypto_stream_salsa208_KEYBYTES = 32; +r._crypto_stream_aes128ctr_NONCEBYTES = 16; +r._crypto_core_salsa208_CONSTBYTES = 16; +r._crypto_stream_aes128ctr_KEYBYTES = 16; +r._crypto_core_hsalsa20_KEYBYTES = 32; +r._crypto_secretbox_xsalsa20poly1305_NONCEBYTES = 24; +r._crypto_sign_edwards25519sha512batch_SECRETKEYBYTES = 64; +r._crypto_core_salsa208_KEYBYTES = 32; +r._crypto_hashblocks_sha512_BLOCKBYTES = 128; +r._crypto_hash_BYTES = r._crypto_hash_sha512_BYTES; +r._crypto_sign = r._crypto_sign_ed25519; +r._crypto_stream_xor_afternm = r._crypto_stream_xsalsa20_xor_afternm; +r._crypto_box_PUBLICKEYBYTES = r._crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; +r._crypto_box_SECRETKEYBYTES = r._crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; +r._crypto_box_open_afternm = r._crypto_box_curve25519xsalsa20poly1305_open_afternm; +r._crypto_sign_SECRETKEYBYTES = r._crypto_sign_ed25519_SECRETKEYBYTES; +r._crypto_box_beforenm = r._crypto_box_curve25519xsalsa20poly1305_beforenm; +r._crypto_secretbox = r._crypto_secretbox_xsalsa20poly1305; +r._crypto_hash = r._crypto_hash_sha512; +r._crypto_sign_PUBLICKEYBYTES = r._crypto_sign_ed25519_PUBLICKEYBYTES; +r._crypto_stream_xor = r._crypto_stream_xsalsa20_xor; +r._crypto_box = r._crypto_box_curve25519xsalsa20poly1305; +r._crypto_secretbox_ZEROBYTES = r._crypto_secretbox_xsalsa20poly1305_ZEROBYTES; +r._crypto_box_ZEROBYTES = r._crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; +r._crypto_secretbox_KEYBYTES = r._crypto_secretbox_xsalsa20poly1305_KEYBYTES; +r._crypto_stream_beforenm = r._crypto_stream_xsalsa20_beforenm; +r._crypto_onetimeauth_verify = r._crypto_onetimeauth_poly1305_verify; +r._crypto_box_BOXZEROBYTES = r._crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; +r._crypto_hashblocks = r._crypto_hashblocks_sha512; +r._crypto_stream = r._crypto_stream_xsalsa20; +r._crypto_onetimeauth_KEYBYTES = r._crypto_onetimeauth_poly1305_KEYBYTES; +r._crypto_box_afternm = r._crypto_box_curve25519xsalsa20poly1305_afternm; +r._crypto_secretbox_BOXZEROBYTES = r._crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES; +r._crypto_hashblocks_BLOCKBYTES = r._crypto_hashblocks_sha512_BLOCKBYTES; +r._crypto_box_keypair = r._crypto_box_curve25519xsalsa20poly1305_keypair; +r._crypto_auth = r._crypto_auth_hmacsha512256; +r._crypto_box_BEFORENMBYTES = r._crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES; +r._crypto_secretbox_NONCEBYTES = r._crypto_secretbox_xsalsa20poly1305_NONCEBYTES; +r._crypto_stream_KEYBYTES = r._crypto_stream_xsalsa20_KEYBYTES; +r._crypto_box_NONCEBYTES = r._crypto_box_curve25519xsalsa20poly1305_NONCEBYTES; +r._crypto_auth_verify = r._crypto_auth_hmacsha512256_verify; +r._crypto_secretbox_open = r._crypto_secretbox_xsalsa20poly1305_open; +r._crypto_sign_BYTES = r._crypto_sign_ed25519_BYTES; +r._crypto_hashblocks_STATEBYTES = r._crypto_hashblocks_sha512_STATEBYTES; +r._crypto_auth_BYTES = r._crypto_auth_hmacsha512256_BYTES; +r._crypto_stream_BEFORENMBYTES = r._crypto_stream_xsalsa20_BEFORENMBYTES; +r._crypto_auth_KEYBYTES = r._crypto_auth_hmacsha512256_KEYBYTES; +r._crypto_stream_afternm = r._crypto_stream_xsalsa20_afternm; +r._crypto_sign_keypair = r._crypto_sign_ed25519_keypair; +r._crypto_sign_open = r._crypto_sign_ed25519_open; +r._crypto_onetimeauth_BYTES = r._crypto_onetimeauth_poly1305_BYTES; +r._crypto_box_open = r._crypto_box_curve25519xsalsa20poly1305_open; +r._crypto_stream_NONCEBYTES = r._crypto_stream_xsalsa20_NONCEBYTES; +r._crypto_onetimeauth = r._crypto_onetimeauth_poly1305; +var nacl = (function () { + 'use strict'; + var exports = {}; + + //--------------------------------------------------------------------------- + // Horrifying UTF-8 and hex codecs + + function encode_utf8(s) { + return encode_latin1(unescape(encodeURIComponent(s))); + } + + function encode_latin1(s) { + var result = new Uint8Array(s.length); + for (var i = 0; i < s.length; i++) { + var c = s.charCodeAt(i); + if ((c & 0xff) !== c) throw {message: "Cannot encode string in Latin1", str: s}; + result[i] = (c & 0xff); + } + return result; + } + + function decode_utf8(bs) { + return decodeURIComponent(escape(decode_latin1(bs))); + } + + function decode_latin1(bs) { + var encoded = []; + for (var i = 0; i < bs.length; i++) { + encoded.push(String.fromCharCode(bs[i])); + } + return encoded.join(''); + } + + function to_hex(bs) { + var encoded = []; + for (var i = 0; i < bs.length; i++) { + encoded.push("0123456789abcdef"[(bs[i] >> 4) & 15]); + encoded.push("0123456789abcdef"[bs[i] & 15]); + } + return encoded.join(''); + } + + function from_hex(s) { + var result = new Uint8Array(s.length / 2); + for (var i = 0; i < s.length / 2; i++) { + result[i] = parseInt(s.substr(2*i,2),16); + } + return result; + } + + //--------------------------------------------------------------------------- + // Allocation + + function MALLOC(nbytes) { + var result = nacl_raw._malloc(nbytes); + if (result === 0) { + throw {message: "malloc() failed", nbytes: nbytes}; + } + return result; + } + + function FREE(pointer) { + nacl_raw._free(pointer); + } + + //--------------------------------------------------------------------------- + + function injectBytes(bs, leftPadding) { + var p = leftPadding || 0; + var address = MALLOC(bs.length + p); + nacl_raw.HEAPU8.set(bs, address + p); + for (var i = address; i < address + p; i++) { + nacl_raw.HEAPU8[i] = 0; + } + return address; + } + + function check_injectBytes(function_name, what, thing, expected_length, leftPadding) { + check_length(function_name, what, thing, expected_length); + return injectBytes(thing, leftPadding); + } + + function extractBytes(address, length) { + var result = new Uint8Array(length); + result.set(nacl_raw.HEAPU8.subarray(address, address + length)); + return result; + } + + //--------------------------------------------------------------------------- + + function check(function_name, result) { + if (result !== 0) { + throw {message: "nacl_raw." + function_name + " signalled an error"}; + } + } + + function check_length(function_name, what, thing, expected_length) { + if (thing.length !== expected_length) { + throw {message: "nacl." + function_name + " expected " + + expected_length + "-byte " + what + " but got length " + thing.length}; + } + } + + function Target(length) { + this.length = length; + this.address = MALLOC(length); + } + + Target.prototype.extractBytes = function (offset) { + var result = extractBytes(this.address + (offset || 0), this.length - (offset || 0)); + FREE(this.address); + this.address = null; + return result; + }; + + function free_all(addresses) { + for (var i = 0; i < addresses.length; i++) { + FREE(addresses[i]); + } + } + + //--------------------------------------------------------------------------- + // Boxing + + function crypto_box_keypair() { + var pk = new Target(nacl_raw._crypto_box_PUBLICKEYBYTES); + var sk = new Target(nacl_raw._crypto_box_SECRETKEYBYTES); + check("_crypto_box_keypair", nacl_raw._crypto_box_keypair(pk.address, sk.address)); + return {boxPk: pk.extractBytes(), boxSk: sk.extractBytes()}; + } + + function crypto_box_random_nonce() { + return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_box_NONCEBYTES); + } + + function crypto_box(msg, nonce, pk, sk) { + var m = injectBytes(msg, nacl_raw._crypto_box_ZEROBYTES); + var na = check_injectBytes("crypto_box", "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); + var pka = check_injectBytes("crypto_box", "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); + var ska = check_injectBytes("crypto_box", "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); + var c = new Target(msg.length + nacl_raw._crypto_box_ZEROBYTES); + check("_crypto_box", nacl_raw._crypto_box(c.address, m, c.length, 0, na, pka, ska)); + free_all([m, na, pka, ska]); + return c.extractBytes(nacl_raw._crypto_box_BOXZEROBYTES); + } + + function crypto_box_open(ciphertext, nonce, pk, sk) { + var c = injectBytes(ciphertext, nacl_raw._crypto_box_BOXZEROBYTES); + var na = check_injectBytes("crypto_box_open", + "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); + var pka = check_injectBytes("crypto_box_open", + "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); + var ska = check_injectBytes("crypto_box_open", + "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); + var m = new Target(ciphertext.length + nacl_raw._crypto_box_BOXZEROBYTES); + check("_crypto_box_open", nacl_raw._crypto_box_open(m.address, c, m.length, 0, na, pka, ska)); + free_all([c, na, pka, ska]); + return m.extractBytes(nacl_raw._crypto_box_ZEROBYTES); + } + + function crypto_box_precompute(pk, sk) { + var pka = check_injectBytes("crypto_box_precompute", + "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); + var ska = check_injectBytes("crypto_box_precompute", + "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); + var k = new Target(nacl_raw._crypto_box_BEFORENMBYTES); + check("_crypto_box_beforenm", + nacl_raw._crypto_box_beforenm(k.address, pka, ska)); + free_all([pka, ska]); + return {boxK: k.extractBytes()}; + } + + function crypto_box_precomputed(msg, nonce, state) { + var m = injectBytes(msg, nacl_raw._crypto_box_ZEROBYTES); + var na = check_injectBytes("crypto_box_precomputed", + "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); + var ka = check_injectBytes("crypto_box_precomputed", + "boxK", state.boxK, nacl_raw._crypto_box_BEFORENMBYTES); + var c = new Target(msg.length + nacl_raw._crypto_box_ZEROBYTES); + check("_crypto_box_afternm", + nacl_raw._crypto_box_afternm(c.address, m, c.length, 0, na, ka)); + free_all([m, na, ka]); + return c.extractBytes(nacl_raw._crypto_box_BOXZEROBYTES); + } + + function crypto_box_open_precomputed(ciphertext, nonce, state) { + var c = injectBytes(ciphertext, nacl_raw._crypto_box_BOXZEROBYTES); + var na = check_injectBytes("crypto_box_open_precomputed", + "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); + var ka = check_injectBytes("crypto_box_open_precomputed", + "boxK", state.boxK, nacl_raw._crypto_box_BEFORENMBYTES); + var m = new Target(ciphertext.length + nacl_raw._crypto_box_BOXZEROBYTES); + check("_crypto_box_open_afternm", + nacl_raw._crypto_box_open_afternm(m.address, c, m.length, 0, na, ka)); + free_all([c, na, ka]); + return m.extractBytes(nacl_raw._crypto_box_ZEROBYTES); + } + + //--------------------------------------------------------------------------- + // Hashing + + function crypto_hash(bs) { + var address = injectBytes(bs); + var hash = new Target(nacl_raw._crypto_hash_BYTES); + check("_crypto_hash", nacl_raw._crypto_hash(hash.address, address, bs.length, 0)); + FREE(address); + return hash.extractBytes(); + } + + function crypto_hash_sha256(bs) { + var address = injectBytes(bs); + var hash = new Target(nacl_raw._crypto_hash_sha256_BYTES); + check("_crypto_hash_sha256", + nacl_raw._crypto_hash_sha256(hash.address, address, bs.length, 0)); + FREE(address); + return hash.extractBytes(); + } + + function crypto_hash_string(s) { + return crypto_hash(encode_utf8(s)); + } + + //--------------------------------------------------------------------------- + // Symmetric-key encryption + + function crypto_stream_random_nonce() { + return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_stream_NONCEBYTES); + } + + function crypto_stream(len, nonce, key) { + var na = check_injectBytes("crypto_stream", + "nonce", nonce, nacl_raw._crypto_stream_NONCEBYTES); + var ka = check_injectBytes("crypto_stream", + "key", key, nacl_raw._crypto_stream_KEYBYTES); + var out = new Target(len); + check("_crypto_stream", nacl_raw._crypto_stream(out.address, len, 0, na, ka)); + free_all([na, ka]); + return out.extractBytes(); + } + + function crypto_stream_xor(msg, nonce, key) { + var na = check_injectBytes("crypto_stream_xor", + "nonce", nonce, nacl_raw._crypto_stream_NONCEBYTES); + var ka = check_injectBytes("crypto_stream_xor", + "key", key, nacl_raw._crypto_stream_KEYBYTES); + var ma = injectBytes(msg); + var out = new Target(msg.length); + check("_crypto_stream_xor", + nacl_raw._crypto_stream_xor(out.address, ma, msg.length, 0, na, ka)); + free_all([na, ka, ma]); + return out.extractBytes(); + } + + //--------------------------------------------------------------------------- + // One-time authentication + + function crypto_onetimeauth(msg, key) { + var ka = check_injectBytes("crypto_onetimeauth", + "key", key, nacl_raw._crypto_onetimeauth_KEYBYTES); + var ma = injectBytes(msg); + var authenticator = new Target(nacl_raw._crypto_onetimeauth_BYTES); + check("_crypto_onetimeauth", + nacl_raw._crypto_onetimeauth(authenticator.address, ma, msg.length, 0, ka)); + free_all([ka, ma]); + return authenticator.extractBytes(); + } + + function crypto_onetimeauth_verify(authenticator, msg, key) { + if (authenticator.length != nacl_raw._crypto_onetimeauth_BYTES) return false; + var ka = check_injectBytes("crypto_onetimeauth_verify", + "key", key, nacl_raw._crypto_onetimeauth_KEYBYTES); + var ma = injectBytes(msg); + var aa = injectBytes(authenticator); + var result = nacl_raw._crypto_onetimeauth_verify(aa, ma, msg.length, 0, ka); + free_all([ka, ma, aa]); + return (result == 0); + } + + //--------------------------------------------------------------------------- + // Authentication + + function crypto_auth(msg, key) { + var ka = check_injectBytes("crypto_auth", "key", key, nacl_raw._crypto_auth_KEYBYTES); + var ma = injectBytes(msg); + var authenticator = new Target(nacl_raw._crypto_auth_BYTES); + check("_crypto_auth", nacl_raw._crypto_auth(authenticator.address, ma, msg.length, 0, ka)); + free_all([ka, ma]); + return authenticator.extractBytes(); + } + + function crypto_auth_verify(authenticator, msg, key) { + if (authenticator.length != nacl_raw._crypto_auth_BYTES) return false; + var ka = check_injectBytes("crypto_auth_verify", + "key", key, nacl_raw._crypto_auth_KEYBYTES); + var ma = injectBytes(msg); + var aa = injectBytes(authenticator); + var result = nacl_raw._crypto_auth_verify(aa, ma, msg.length, 0, ka); + free_all([ka, ma, aa]); + return (result == 0); + } + + //--------------------------------------------------------------------------- + // Authenticated symmetric-key encryption + + function crypto_secretbox_random_nonce() { + return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_secretbox_NONCEBYTES); + } + + function crypto_secretbox(msg, nonce, key) { + var m = injectBytes(msg, nacl_raw._crypto_secretbox_ZEROBYTES); + var na = check_injectBytes("crypto_secretbox", + "nonce", nonce, nacl_raw._crypto_secretbox_NONCEBYTES); + var ka = check_injectBytes("crypto_secretbox", + "key", key, nacl_raw._crypto_secretbox_KEYBYTES); + var c = new Target(msg.length + nacl_raw._crypto_secretbox_ZEROBYTES); + check("_crypto_secretbox", nacl_raw._crypto_secretbox(c.address, m, c.length, 0, na, ka)); + free_all([m, na, ka]); + return c.extractBytes(nacl_raw._crypto_secretbox_BOXZEROBYTES); + } + + function crypto_secretbox_open(ciphertext, nonce, key) { + var c = injectBytes(ciphertext, nacl_raw._crypto_secretbox_BOXZEROBYTES); + var na = check_injectBytes("crypto_secretbox_open", + "nonce", nonce, nacl_raw._crypto_secretbox_NONCEBYTES); + var ka = check_injectBytes("crypto_secretbox_open", + "key", key, nacl_raw._crypto_secretbox_KEYBYTES); + var m = new Target(ciphertext.length + nacl_raw._crypto_secretbox_BOXZEROBYTES); + check("_crypto_secretbox_open", + nacl_raw._crypto_secretbox_open(m.address, c, m.length, 0, na, ka)); + free_all([c, na, ka]); + return m.extractBytes(nacl_raw._crypto_secretbox_ZEROBYTES); + } + + //--------------------------------------------------------------------------- + // Signing + + function crypto_sign_keypair() { + var pk = new Target(nacl_raw._crypto_sign_PUBLICKEYBYTES); + var sk = new Target(nacl_raw._crypto_sign_SECRETKEYBYTES); + check("_crypto_sign_keypair", nacl_raw._crypto_sign_keypair(pk.address, sk.address)); + return {signPk: pk.extractBytes(), signSk: sk.extractBytes()}; + } + + function crypto_sign(msg, sk) { + var ma = injectBytes(msg); + var ska = check_injectBytes("crypto_sign", "sk", sk, nacl_raw._crypto_sign_SECRETKEYBYTES); + var sm = new Target(msg.length + nacl_raw._crypto_sign_BYTES); + var smlen = new Target(8); + check("_crypto_sign", + nacl_raw._crypto_sign(sm.address, smlen.address, ma, msg.length, 0, ska)); + free_all([ma, ska]); + sm.length = nacl_raw.HEAPU32[smlen.address >> 2]; + FREE(smlen.address); + return sm.extractBytes(); + } + + function crypto_sign_detached(msg, sk) { + // WARNING: Experimental. Works for ed25519 but not necessarily other implementations. + var signed_msg = crypto_sign(msg, sk); + return signed_msg.subarray(0, nacl_raw._crypto_sign_BYTES); + } + + function crypto_sign_open(sm, pk) { + var sma = injectBytes(sm); + var pka = check_injectBytes("crypto_sign_open", + "pk", pk, nacl_raw._crypto_sign_PUBLICKEYBYTES); + var m = new Target(sm.length); + var mlen = new Target(8); + if (nacl_raw._crypto_sign_open(m.address, mlen.address, sma, sm.length, 0, pka) === 0) { + free_all([sma, pka]); + m.length = nacl_raw.HEAPU32[mlen.address >> 2]; + FREE(mlen.address); + return m.extractBytes(); + } else { + free_all([sma, pka, m.address, mlen.address]); + return null; + } + } + + function crypto_sign_verify_detached(detached_signature, msg, pk) { + // WARNING: Experimental. Works for ed25519 but not necessarily other implementations. + var signed_msg = new Uint8Array(detached_signature.length + msg.length); + signed_msg.set(detached_signature, 0); + signed_msg.set(msg, detached_signature.length); + return crypto_sign_open(signed_msg, pk) !== null; + } + + //--------------------------------------------------------------------------- + // Keys + + function crypto_sign_keypair_from_seed(bs) { + var seeda = check_injectBytes("crypto_sign_keypair_from_seed", + "seed", bs, nacl_raw._crypto_sign_SECRETKEYBYTES / 2); + var pk = new Target(nacl_raw._crypto_sign_PUBLICKEYBYTES); + var sk = new Target(nacl_raw._crypto_sign_SECRETKEYBYTES); + check("_crypto_sign_keypair_from_raw_sk", + nacl_raw._crypto_sign_keypair_from_raw_sk(pk.address, sk.address, seeda)); + FREE(seeda); + return {signPk: pk.extractBytes(), signSk: sk.extractBytes()}; + } + + function crypto_box_keypair_from_seed(bs) { + var hash = new Uint8Array(crypto_hash(bs)); + return crypto_box_keypair_from_raw_sk(hash.subarray(0, + nacl_raw._crypto_box_SECRETKEYBYTES)); + } + + function crypto_box_keypair_from_raw_sk(sk) { + return {boxPk: crypto_scalarmult_base(sk), boxSk: sk}; + } + + //--------------------------------------------------------------------------- + // Scalarmult + + function crypto_scalarmult(n,p) { + var na = check_injectBytes("crypto_scalarmult", "n", n, + nacl_raw._crypto_scalarmult_curve25519_SCALARBYTES); + var pa = check_injectBytes("crypto_scalarmult", "p", p, + nacl_raw._crypto_scalarmult_curve25519_BYTES); + var q = new Target(nacl_raw._crypto_scalarmult_curve25519_BYTES); + check("_crypto_scalarmult_curve25519", + nacl_raw._crypto_scalarmult_curve25519(q.address, na, pa)); + FREE(na); + FREE(pa); + return q.extractBytes(); + } + + function crypto_scalarmult_base(n) { + var na = check_injectBytes("crypto_scalarmult_base", "n", n, + nacl_raw._crypto_scalarmult_curve25519_SCALARBYTES); + var q = new Target(nacl_raw._crypto_scalarmult_curve25519_BYTES); + check("_crypto_scalarmult_curve25519_base", + nacl_raw._crypto_scalarmult_curve25519_base(q.address, na)); + FREE(na); + return q.extractBytes(); + } + + //--------------------------------------------------------------------------- + + exports.crypto_auth_BYTES = nacl_raw._crypto_auth_BYTES; + exports.crypto_auth_KEYBYTES = nacl_raw._crypto_auth_KEYBYTES; + exports.crypto_box_BEFORENMBYTES = nacl_raw._crypto_box_BEFORENMBYTES; + exports.crypto_box_BOXZEROBYTES = nacl_raw._crypto_box_BOXZEROBYTES; + exports.crypto_box_NONCEBYTES = nacl_raw._crypto_box_NONCEBYTES; + exports.crypto_box_PUBLICKEYBYTES = nacl_raw._crypto_box_PUBLICKEYBYTES; + exports.crypto_box_SECRETKEYBYTES = nacl_raw._crypto_box_SECRETKEYBYTES; + exports.crypto_box_ZEROBYTES = nacl_raw._crypto_box_ZEROBYTES; + exports.crypto_hash_BYTES = nacl_raw._crypto_hash_BYTES; + exports.crypto_hash_sha256_BYTES = nacl_raw._crypto_hash_sha256_BYTES; + exports.crypto_hashblocks_BLOCKBYTES = nacl_raw._crypto_hashblocks_BLOCKBYTES; + exports.crypto_hashblocks_STATEBYTES = nacl_raw._crypto_hashblocks_STATEBYTES; + exports.crypto_onetimeauth_BYTES = nacl_raw._crypto_onetimeauth_BYTES; + exports.crypto_onetimeauth_KEYBYTES = nacl_raw._crypto_onetimeauth_KEYBYTES; + exports.crypto_secretbox_BOXZEROBYTES = nacl_raw._crypto_secretbox_BOXZEROBYTES; + exports.crypto_secretbox_KEYBYTES = nacl_raw._crypto_secretbox_KEYBYTES; + exports.crypto_secretbox_NONCEBYTES = nacl_raw._crypto_secretbox_NONCEBYTES; + exports.crypto_secretbox_ZEROBYTES = nacl_raw._crypto_secretbox_ZEROBYTES; + exports.crypto_sign_BYTES = nacl_raw._crypto_sign_BYTES; + exports.crypto_sign_PUBLICKEYBYTES = nacl_raw._crypto_sign_PUBLICKEYBYTES; + exports.crypto_sign_SECRETKEYBYTES = nacl_raw._crypto_sign_SECRETKEYBYTES; + exports.crypto_stream_BEFORENMBYTES = nacl_raw._crypto_stream_BEFORENMBYTES; + exports.crypto_stream_KEYBYTES = nacl_raw._crypto_stream_KEYBYTES; + exports.crypto_stream_NONCEBYTES = nacl_raw._crypto_stream_NONCEBYTES; + exports.crypto_scalarmult_SCALARBYTES = nacl_raw._crypto_scalarmult_curve25519_SCALARBYTES; + exports.crypto_scalarmult_BYTES = nacl_raw._crypto_scalarmult_curve25519_BYTES; + + exports.encode_utf8 = encode_utf8; + exports.encode_latin1 = encode_latin1; + exports.decode_utf8 = decode_utf8; + exports.decode_latin1 = decode_latin1; + exports.to_hex = to_hex; + exports.from_hex = from_hex; + + exports.crypto_box_keypair = crypto_box_keypair; + exports.crypto_box_random_nonce = crypto_box_random_nonce; + exports.crypto_box = crypto_box; + exports.crypto_box_open = crypto_box_open; + exports.crypto_box_precompute = crypto_box_precompute; + exports.crypto_box_precomputed = crypto_box_precomputed; + exports.crypto_box_open_precomputed = crypto_box_open_precomputed; + + exports.crypto_stream_random_nonce = crypto_stream_random_nonce; + exports.crypto_stream = crypto_stream; + exports.crypto_stream_xor = crypto_stream_xor; + + exports.crypto_onetimeauth = crypto_onetimeauth; + exports.crypto_onetimeauth_verify = crypto_onetimeauth_verify; + + exports.crypto_auth = crypto_auth; + exports.crypto_auth_verify = crypto_auth_verify; + + exports.crypto_secretbox_random_nonce = crypto_secretbox_random_nonce; + exports.crypto_secretbox = crypto_secretbox; + exports.crypto_secretbox_open = crypto_secretbox_open; + + exports.crypto_sign_keypair = crypto_sign_keypair; + exports.crypto_sign = crypto_sign; + exports.crypto_sign_detached = crypto_sign_detached; + exports.crypto_sign_open = crypto_sign_open; + exports.crypto_sign_verify_detached = crypto_sign_verify_detached; + + exports.crypto_hash = crypto_hash; + exports.crypto_hash_sha256 = crypto_hash_sha256; + exports.crypto_hash_string = crypto_hash_string; + + exports.crypto_sign_keypair_from_seed = crypto_sign_keypair_from_seed; + exports.crypto_box_keypair_from_seed = crypto_box_keypair_from_seed; + exports.crypto_box_keypair_from_raw_sk = crypto_box_keypair_from_raw_sk; + + exports.crypto_scalarmult = crypto_scalarmult; + exports.crypto_scalarmult_base = crypto_scalarmult_base; + + return exports; +})(); + var randomBytes; + if (typeof module !== 'undefined' && module.exports) { + // add node.js implementations + var crypto = require('crypto'); + randomBytes = crypto.randomBytes; + } else if (window && window.crypto && window.crypto.getRandomValues) { + // add in-browser implementation + randomBytes = function (count) { + var bs = new Uint8Array(count); + window.crypto.getRandomValues(bs); + return bs; + }; + } else { + randomBytes = function (count) { + throw { name: "No cryptographic random number generator", + message: "Your browser does not support cryptographic random number generation." }; + }; + } + + nacl_raw.RandomBytes.crypto = { "randomBytes": randomBytes }; + nacl.random_bytes = randomBytes; + nacl.nacl_raw = nacl_raw; + return nacl; + })((typeof window !== 'undefined') ? window : null, (typeof document !== 'undefined') ? document : null); + } +}; + +// export common.js module to allow one js file for browser and node.js +if (typeof module !== 'undefined' && module.exports) { + module.exports = nacl_factory; +} diff --git a/ucoinj-ui-wicket/src/main/webapp/js/scrypt-em.js b/ucoinj-ui-wicket/src/main/webapp/js/scrypt-em.js new file mode 100644 index 0000000000000000000000000000000000000000..70c570e5792825314824d2f1b48be4cc10477429 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/scrypt-em.js @@ -0,0 +1,10285 @@ + + +var scrypt_module_factory = (function (requested_total_memory) { + var Module = {TOTAL_MEMORY: (requested_total_memory || 33554432)}; + var scrypt_raw = Module; +function g(a) { + throw a; +} +var k = void 0, l = !0, m = null, p = !1; +function aa() { + return function() { + } +} +var q, s; +s || (s = eval("(function() { try { return Module || {} } catch(e) { return {} } })()")); +var ba = {}, t; +for(t in s) { + s.hasOwnProperty(t) && (ba[t] = s[t]) +} +var ca = "object" === typeof process && "function" === typeof require, da = "object" === typeof window, ea = "function" === typeof importScripts, fa = !da && !ca && !ea; +if(ca) { + s.print = function(a) { + process.stdout.write(a + "\n") + }; + s.printErr = function(a) { + process.stderr.write(a + "\n") + }; + var ga = require("fs"), ha = require("path"); + s.read = function(a, b) { + var a = ha.normalize(a), c = ga.readFileSync(a); + !c && a != ha.resolve(a) && (a = path.join(__dirname, "..", "src", a), c = ga.readFileSync(a)); + c && !b && (c = c.toString()); + return c + }; + s.readBinary = function(a) { + return s.read(a, l) + }; + s.load = function(a) { + ia(read(a)) + }; + s.arguments = process.argv.slice(2); + module.ee = s +}else { + fa ? (s.print = print, "undefined" != typeof printErr && (s.printErr = printErr), s.read = read, s.readBinary = function(a) { + return read(a, "binary") + }, "undefined" != typeof scriptArgs ? s.arguments = scriptArgs : "undefined" != typeof arguments && (s.arguments = arguments), this.Module = s) : da || ea ? (s.read = function(a) { + var b = new XMLHttpRequest; + b.open("GET", a, p); + b.send(m); + return b.responseText + }, "undefined" != typeof arguments && (s.arguments = arguments), da ? (s.print = function(a) { + console.log(a) + }, s.printErr = function(a) { + console.log(a) + }, this.Module = s) : ea && (s.print = aa(), s.load = importScripts)) : g("Unknown runtime environment. Where are we?") +} +function ia(a) { + eval.call(m, a) +} +"undefined" == !s.load && s.read && (s.load = function(a) { + ia(s.read(a)) +}); +s.print || (s.print = aa()); +s.printErr || (s.printErr = s.print); +s.arguments || (s.arguments = []); +s.print = s.print; +s.P = s.printErr; +s.preRun = []; +s.postRun = []; +for(t in ba) { + ba.hasOwnProperty(t) && (s[t] = ba[t]) +} +function ja() { + return u +} +function ka(a) { + u = a +} +function la(a) { + if(1 == ma) { + return 1 + } + var b = {"%i1":1, "%i8":1, "%i16":2, "%i32":4, "%i64":8, "%float":4, "%double":8}["%" + a]; + b || ("*" == a.charAt(a.length - 1) ? b = ma : "i" == a[0] && (a = parseInt(a.substr(1)), w(0 == a % 8), b = a / 8)); + return b +} +function na(a, b, c) { + c && c.length ? (c.splice || (c = Array.prototype.slice.call(c)), c.splice(0, 0, b), s["dynCall_" + a].apply(m, c)) : s["dynCall_" + a].call(m, b) +} +var oa; +function pa() { + var a = [], b = 0; + this.oa = function(c) { + c &= 255; + b && (a.push(c), b--); + if(0 == a.length) { + if(128 > c) { + return String.fromCharCode(c) + } + a.push(c); + b = 191 < c && 224 > c ? 1 : 2; + return"" + } + if(0 < b) { + return"" + } + var c = a[0], d = a[1], e = a[2], c = 191 < c && 224 > c ? String.fromCharCode((c & 31) << 6 | d & 63) : String.fromCharCode((c & 15) << 12 | (d & 63) << 6 | e & 63); + a.length = 0; + return c + }; + this.yb = function(a) { + for(var a = unescape(encodeURIComponent(a)), b = [], e = 0;e < a.length;e++) { + b.push(a.charCodeAt(e)) + } + return b + } +} +function qa(a) { + var b = u; + u = u + a | 0; + u = u + 7 >> 3 << 3; + return b +} +function ra(a) { + var b = sa; + sa = sa + a | 0; + sa = sa + 7 >> 3 << 3; + return b +} +function ua(a) { + var b = z; + z = z + a | 0; + z = z + 7 >> 3 << 3; + z >= va && wa("Cannot enlarge memory arrays in asm.js. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value, or (2) set Module.TOTAL_MEMORY before the program runs."); + return b +} +function xa(a, b) { + return Math.ceil(a / (b ? b : 8)) * (b ? b : 8) +} +var ma = 4, ya = {}, za = p, Aa; +function w(a, b) { + a || wa("Assertion failed: " + b) +} +s.ccall = function(a, b, c, d) { + return Ba(Ca(a), b, c, d) +}; +function Ca(a) { + try { + var b = s["_" + a]; + b || (b = eval("_" + a)) + }catch(c) { + } + w(b, "Cannot call unknown function " + a + " (perhaps LLVM optimizations or closure removed it?)"); + return b +} +function Ba(a, b, c, d) { + function e(a, b) { + if("string" == b) { + if(a === m || a === k || 0 === a) { + return 0 + } + f || (f = ja()); + var c = qa(a.length + 1); + Da(a, c); + return c + } + return"array" == b ? (f || (f = ja()), c = qa(a.length), Ea(a, c), c) : a + } + var f = 0, h = 0, d = d ? d.map(function(a) { + return e(a, c[h++]) + }) : []; + a = a.apply(m, d); + "string" == b ? b = Fa(a) : (w("array" != b), b = a); + f && ka(f); + return b +} +s.cwrap = function(a, b, c) { + var d = Ca(a); + return function() { + return Ba(d, b, c, Array.prototype.slice.call(arguments)) + } +}; +function Ga(a, b, c) { + c = c || "i8"; + "*" === c.charAt(c.length - 1) && (c = "i32"); + switch(c) { + case "i1": + A[a] = b; + break; + case "i8": + A[a] = b; + break; + case "i16": + Ha[a >> 1] = b; + break; + case "i32": + B[a >> 2] = b; + break; + case "i64": + Aa = [b >>> 0, (Math.min(+Math.floor(b / 4294967296), 4294967295) | 0) >>> 0]; + B[a >> 2] = Aa[0]; + B[a + 4 >> 2] = Aa[1]; + break; + case "float": + Ia[a >> 2] = b; + break; + case "double": + Ja[a >> 3] = b; + break; + default: + wa("invalid type for setValue: " + c) + } +} +s.setValue = Ga; +s.getValue = function(a, b) { + b = b || "i8"; + "*" === b.charAt(b.length - 1) && (b = "i32"); + switch(b) { + case "i1": + return A[a]; + case "i8": + return A[a]; + case "i16": + return Ha[a >> 1]; + case "i32": + return B[a >> 2]; + case "i64": + return B[a >> 2]; + case "float": + return Ia[a >> 2]; + case "double": + return Ja[a >> 3]; + default: + wa("invalid type for setValue: " + b) + } + return m +}; +var Ka = 0, La = 1, E = 2, Na = 4; +s.ALLOC_NORMAL = Ka; +s.ALLOC_STACK = La; +s.ALLOC_STATIC = E; +s.ALLOC_DYNAMIC = 3; +s.ALLOC_NONE = Na; +function F(a, b, c, d) { + var e, f; + "number" === typeof a ? (e = l, f = a) : (e = p, f = a.length); + var h = "string" === typeof b ? b : m, c = c == Na ? d : [Oa, qa, ra, ua][c === k ? E : c](Math.max(f, h ? 1 : b.length)); + if(e) { + d = c; + w(0 == (c & 3)); + for(a = c + (f & -4);d < a;d += 4) { + B[d >> 2] = 0 + } + for(a = c + f;d < a;) { + A[d++ | 0] = 0 + } + return c + } + if("i8" === h) { + return a.subarray || a.slice ? G.set(a, c) : G.set(new Uint8Array(a), c), c + } + for(var d = 0, i, j;d < f;) { + var n = a[d]; + "function" === typeof n && (n = ya.fe(n)); + e = h || b[d]; + 0 === e ? d++ : ("i64" == e && (e = "i32"), Ga(c + d, n, e), j !== e && (i = la(e), j = e), d += i) + } + return c +} +s.allocate = F; +function Fa(a, b) { + for(var c = p, d, e = 0;;) { + d = G[a + e | 0]; + if(128 <= d) { + c = l + }else { + if(0 == d && !b) { + break + } + } + e++; + if(b && e == b) { + break + } + } + b || (b = e); + var f = ""; + if(!c) { + for(;0 < b;) { + d = String.fromCharCode.apply(String, G.subarray(a, a + Math.min(b, 1024))), f = f ? f + d : d, a += 1024, b -= 1024 + } + return f + } + c = new pa; + for(e = 0;e < b;e++) { + d = G[a + e | 0], f += c.oa(d) + } + return f +} +s.Pointer_stringify = Fa; +var A, G, Ha, Pa, B, Qa, Ia, Ja, Ra = 0, sa = 0, Sa = 0, u = 0, Ta = 0, Ua = 0, z = 0, va = s.TOTAL_MEMORY || 33554432; +w(!!Int32Array && !!Float64Array && !!(new Int32Array(1)).subarray && !!(new Int32Array(1)).set, "Cannot fallback to non-typed array case: Code is too specialized"); +var I = new ArrayBuffer(va); +A = new Int8Array(I); +Ha = new Int16Array(I); +B = new Int32Array(I); +G = new Uint8Array(I); +Pa = new Uint16Array(I); +Qa = new Uint32Array(I); +Ia = new Float32Array(I); +Ja = new Float64Array(I); +B[0] = 255; +w(255 === G[0] && 0 === G[3], "Typed arrays 2 must be run on a little-endian system"); +s.HEAP = k; +s.HEAP8 = A; +s.HEAP16 = Ha; +s.HEAP32 = B; +s.HEAPU8 = G; +s.HEAPU16 = Pa; +s.HEAPU32 = Qa; +s.HEAPF32 = Ia; +s.HEAPF64 = Ja; +function Va(a) { + for(;0 < a.length;) { + var b = a.shift(); + if("function" == typeof b) { + b() + }else { + var c = b.V; + "number" === typeof c ? b.ha === k ? na("v", c) : na("vi", c, [b.ha]) : c(b.ha === k ? m : b.ha) + } + } +} +var Wa = [], Xa = [], Ya = [], Za = [], $a = [], ab = p; +function bb(a) { + Wa.unshift(a) +} +s.addOnPreRun = s.Vd = bb; +s.addOnInit = s.Sd = function(a) { + Xa.unshift(a) +}; +s.addOnPreMain = s.Ud = function(a) { + Ya.unshift(a) +}; +s.addOnExit = s.Rd = function(a) { + Za.unshift(a) +}; +function cb(a) { + $a.unshift(a) +} +s.addOnPostRun = s.Td = cb; +function J(a, b, c) { + a = (new pa).yb(a); + c && (a.length = c); + b || a.push(0); + return a +} +s.intArrayFromString = J; +s.intArrayToString = function(a) { + for(var b = [], c = 0;c < a.length;c++) { + var d = a[c]; + 255 < d && (d &= 255); + b.push(String.fromCharCode(d)) + } + return b.join("") +}; +function Da(a, b, c) { + a = J(a, c); + for(c = 0;c < a.length;) { + A[b + c | 0] = a[c], c += 1 + } +} +s.writeStringToMemory = Da; +function Ea(a, b) { + for(var c = 0;c < a.length;c++) { + A[b + c | 0] = a[c] + } +} +s.writeArrayToMemory = Ea; +function db(a, b) { + return 0 <= a ? a : 32 >= b ? 2 * Math.abs(1 << b - 1) + a : Math.pow(2, b) + a +} +function eb(a, b) { + if(0 >= a) { + return a + } + var c = 32 >= b ? Math.abs(1 << b - 1) : Math.pow(2, b - 1); + if(a >= c && (32 >= b || a > c)) { + a = -2 * c + a + } + return a +} +Math.imul || (Math.imul = function(a, b) { + var c = a & 65535, d = b & 65535; + return c * d + ((a >>> 16) * d + c * (b >>> 16) << 16) | 0 +}); +Math.ie = Math.imul; +var L = 0, fb = {}, gb = p, hb = m; +function ib(a) { + L++; + s.monitorRunDependencies && s.monitorRunDependencies(L); + a ? (w(!fb[a]), fb[a] = 1) : s.P("warning: run dependency added without ID") +} +s.addRunDependency = ib; +function jb(a) { + L--; + s.monitorRunDependencies && s.monitorRunDependencies(L); + a ? (w(fb[a]), delete fb[a]) : s.P("warning: run dependency removed without ID"); + 0 == L && (hb !== m && (clearInterval(hb), hb = m), !gb && kb && lb()) +} +s.removeRunDependency = jb; +s.preloadedImages = {}; +s.preloadedAudios = {}; +Ra = 8; +sa = Ra + 1312; +Xa.push({V:function() { + mb() +}}); +var nb, ob, pb; +nb = nb = F([0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +ob = ob = F([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +pb = pb = F([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", E); +F([111, 112, 116, 105, 111, 110, 32, 114, 101, 113, 117, 105, 114, 101, 115, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 115, 0, 0, 0, 0, 0, 0, 0, 111, 112, 116, 105, 111, 110, 32, 114, 101, 113, 117, 105, 114, 101, 115, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 64, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 136, 195, 64, 0, 0, 0, 0, 132, 215, 151, 65, 0, 128, 224, 55, 121, 195, 65, 67, +23, 110, 5, 181, 181, 184, 147, 70, 245, 249, 63, 233, 3, 79, 56, 77, 50, 29, 48, 249, 72, 119, 130, 90, 60, 191, 115, 127, 221, 79, 21, 117, 56, 3, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 111, 112, 116, 105, 111, 110, 32, 100, 111, 101, 115, 110, 39, 116, 32, 116, 97, 107, 101, 32, 97, 110, 32, 97, 114, 103, 117, 109, 101, 110, 116, 32, 45, 45, 32, 37, 46, 42, 115, 0, 117, 110, 107, +110, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 115, 0, 0, 0, 0, 117, 110, 107, 110, 111, 119, 110, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 99, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 97, 109, 98, 105, 103, 117, 111, 117, 115, 32, 111, 112, 116, 105, 111, 110, 32, 45, 45, 32, 37, 46, 42, 115, 0, 0, 0, 0, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 80, 79, 83, 73, 88, 76, 89, 95, 67, 79, 82, 82, 69, 67, 84, 0, 115, 116, 100, 58, 58, 98, 97, 100, 95, 97, 108, +108, 111, 99, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 37, 115, 10, 0, 0, 0, 0, 0, 37, 115, 10, 0, 0, 0, 0, 0, 105, 110, 32, 117, 115, 101, 32, 98, 121, 116, 101, 115, 32, 32, 32, 32, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, 0, 0, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 37, 115, 58, 32, 0, 0, 0, 0, 98, 97, 100, 95, 97, 114, 114, 97, 121, 95, 110, 101, 119, 95, 108, 101, 110, 103, 116, 104, 0, 0, 0, 0, 58, 32, 0, 0, 0, 0, 0, 0, 58, 32, 0, 0, 0, 0, 0, 0, 115, 121, 115, 116, 101, 109, 32, 98, 121, 116, 101, +115, 32, 32, 32, 32, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, 0, 0, 0, 0, 0, 0, 109, 97, 120, 32, 115, 121, 115, 116, 101, 109, 32, 98, 121, 116, 101, 115, 32, 61, 32, 37, 49, 48, 108, 117, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176, 2, 0, 0, 6, 0, 0, 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 116, 57, 101, 120, 99, 101, 112, 116, 105, 111, 110, 0, 0, 0, 0, 83, 116, 57, 98, 97, +100, 95, 97, 108, 108, 111, 99, 0, 0, 0, 0, 83, 116, 50, 48, 98, 97, 100, 95, 97, 114, 114, 97, 121, 95, 110, 101, 119, 95, 108, 101, 110, 103, 116, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 2, 0, 0, 0, 0, 0, 0, 120, 2, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 2, 0, 0, 176, 2, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], +"i8", Na, 8); +var qb = xa(F(12, "i8", E), 8); +w(0 == qb % 8); +var rb = 0; +function M(a) { + return B[rb >> 2] = a +} +s._memcpy = sb; +s._memset = tb; +var N = {L:1, ca:2, Bd:3, sc:4, I:5, za:6, Jb:7, Sc:8, $:9, Zb:10, ua:11, Ld:11, $a:12, Ya:13, kc:14, ed:15, Wb:16, va:17, Md:18, wa:19, gd:20, aa:21, A:22, Mc:23, Za:24, ld:25, Id:26, lc:27, ad:28, da:29, yd:30, Fc:31, rd:32, hc:33, ab:34, Wc:35, pc:36, $b:37, vc:38, wc:39, xc:40, Ec:41, Jd:42, Qc:43, uc:44, ec:45, Tc:46, Pb:50, Sb:51, Nd:52, Oc:53, Tb:54, Ub:55, fc:56, Vb:57, cd:60, Rc:61, Fd:62, bd:63, Xc:64, Yc:65, xd:66, Uc:67, Mb:68, Cd:69, ac:70, td:71, Hc:74, yc:75, ic:76, Rb:77, mc:79, md:80, +Qb:81, wd:82, zc:83, Ac:84, Dc:85, Cc:86, Bc:87, dd:88, Nc:89, ya:90, Ic:91, ba:92, nd:95, qd:96, dc:104, Pc:105, Nb:106, vd:107, jd:108, Zc:109, zd:110, cc:111, Kb:112, bc:113, Lc:114, Jc:115, Gd:116, nc:117, oc:118, rc:119, Ob:120, gc:121, Gc:122, ud:123, Ad:124, Lb:125, Kc:126, tc:127, fd:128, Hd:129, sd:130, Kd:131, jc:132, Dd:133, kd:134, Vc:135, $c:136, Yb:137, qc:138, od:139, Xb:140, hd:141, pd:142, Ed:143}, ub = {"0":"Success", 1:"Not super-user", 2:"No such file or directory", 3:"No such process", +4:"Interrupted system call", 5:"I/O error", 6:"No such device or address", 7:"Arg list too long", 8:"Exec format error", 9:"Bad file number", 10:"No children", 11:"No more processes", 12:"Not enough core", 13:"Permission denied", 14:"Bad address", 15:"Block device required", 16:"Mount device busy", 17:"File exists", 18:"Cross-device link", 19:"No such device", 20:"Not a directory", 21:"Is a directory", 22:"Invalid argument", 23:"Too many open files in system", 24:"Too many open files", 25:"Not a typewriter", +26:"Text file busy", 27:"File too large", 28:"No space left on device", 29:"Illegal seek", 30:"Read only file system", 31:"Too many links", 32:"Broken pipe", 33:"Math arg out of domain of func", 34:"Math result not representable", 35:"No message of desired type", 36:"Identifier removed", 37:"Channel number out of range", 38:"Level 2 not synchronized", 39:"Level 3 halted", 40:"Level 3 reset", 41:"Link number out of range", 42:"Protocol driver not attached", 43:"No CSI structure available", 44:"Level 2 halted", +45:"Deadlock condition", 46:"No record locks available", 50:"Invalid exchange", 51:"Invalid request descriptor", 52:"Exchange full", 53:"No anode", 54:"Invalid request code", 55:"Invalid slot", 56:"File locking deadlock error", 57:"Bad font file fmt", 60:"Device not a stream", 61:"No data (for no delay io)", 62:"Timer expired", 63:"Out of streams resources", 64:"Machine is not on the network", 65:"Package not installed", 66:"The object is remote", 67:"The link has been severed", 68:"Advertise error", +69:"Srmount error", 70:"Communication error on send", 71:"Protocol error", 74:"Multihop attempted", 75:"Inode is remote (not really error)", 76:"Cross mount point (not really error)", 77:"Trying to read unreadable message", 79:"Inappropriate file type or format", 80:"Given log. name not unique", 81:"f.d. invalid for this operation", 82:"Remote address changed", 83:"Can\t access a needed shared lib", 84:"Accessing a corrupted shared lib", 85:".lib section in a.out corrupted", 86:"Attempting to link in too many libs", +87:"Attempting to exec a shared library", 88:"Function not implemented", 89:"No more files", 90:"Directory not empty", 91:"File or path name too long", 92:"Too many symbolic links", 95:"Operation not supported on transport endpoint", 96:"Protocol family not supported", 104:"Connection reset by peer", 105:"No buffer space available", 106:"Address family not supported by protocol family", 107:"Protocol wrong type for socket", 108:"Socket operation on non-socket", 109:"Protocol not available", 110:"Can't send after socket shutdown", +111:"Connection refused", 112:"Address already in use", 113:"Connection aborted", 114:"Network is unreachable", 115:"Network interface is not configured", 116:"Connection timed out", 117:"Host is down", 118:"Host is unreachable", 119:"Connection already in progress", 120:"Socket already connected", 121:"Destination address required", 122:"Message too long", 123:"Unknown protocol", 124:"Socket type not supported", 125:"Address not available", 126:"ENETRESET", 127:"Socket is already connected", 128:"Socket is not connected", +129:"TOOMANYREFS", 130:"EPROCLIM", 131:"EUSERS", 132:"EDQUOT", 133:"ESTALE", 134:"Not supported", 135:"No medium (in tape drive)", 136:"No such host or network path", 137:"Filename exists with different case", 138:"EILSEQ", 139:"Value too large for defined data type", 140:"Operation canceled", 141:"State not recoverable", 142:"Previous owner died", 143:"Streams pipe error"}; +function vb(a, b, c) { + var d = O(a, {parent:l}).d, a = "/" === a ? "/" : wb(a)[2], e = xb(d, a); + e && g(new Q(e)); + d.l.Ta || g(new Q(N.L)); + return d.l.Ta(d, a, b, c) +} +function yb(a, b) { + b = b & 4095 | 32768; + return vb(a, b, 0) +} +function zb(a, b) { + b = b & 1023 | 16384; + return vb(a, b, 0) +} +function Ab(a, b, c) { + return vb(a, b | 8192, c) +} +function Bb(a, b) { + var c = O(b, {parent:l}).d, d = "/" === b ? "/" : wb(b)[2], e = xb(c, d); + e && g(new Q(e)); + c.l.Wa || g(new Q(N.L)); + return c.l.Wa(c, d, a) +} +function Cb(a, b) { + var c; + c = "string" === typeof a ? O(a, {N:l}).d : a; + c.l.Y || g(new Q(N.L)); + c.l.Y(c, {mode:b & 4095 | c.mode & -4096, timestamp:Date.now()}) +} +function Db(a, b) { + var c, a = Eb(a), d; + "string" === typeof b ? (d = Fb[b], "undefined" === typeof d && g(Error("Unknown file open mode: " + b))) : d = b; + b = d; + c = b & 512 ? c & 4095 | 32768 : 0; + var e; + try { + var f = O(a, {N:!(b & 65536)}); + e = f.d; + a = f.path + }catch(h) { + } + b & 512 && (e ? b & 2048 && g(new Q(N.va)) : e = vb(a, c, 0)); + e || g(new Q(N.ca)); + 8192 === (e.mode & 61440) && (b &= -1025); + e ? 40960 === (e.mode & 61440) ? c = N.ba : 16384 === (e.mode & 61440) && (0 !== (b & 3) || b & 1024) ? c = N.aa : (c = ["r", "w", "rw"][b & 3], b & 1024 && (c += "w"), c = Gb(e, c)) : c = N.ca; + c && g(new Q(c)); + b & 1024 && (c = e, c = "string" === typeof c ? O(c, {N:l}).d : c, c.l.Y || g(new Q(N.L)), 16384 === (c.mode & 61440) && g(new Q(N.aa)), 32768 !== (c.mode & 61440) && g(new Q(N.A)), (f = Gb(c, "w")) && g(new Q(f)), c.l.Y(c, {size:0, timestamp:Date.now()})); + var i = {path:a, d:e, M:b, seekable:l, position:0, e:e.e, Gb:[], error:p}, j; + a: { + e = k || 4096; + for(c = k || 1;c <= e;c++) { + if(!R[c]) { + j = c; + break a + } + } + g(new Q(N.Za)) + } + i.s = j; + Object.defineProperty(i, "object", {get:function() { + return i.d + }, set:function(a) { + i.d = a + }}); + Object.defineProperty(i, "isRead", {get:function() { + return 1 !== (i.M & 3) + }}); + Object.defineProperty(i, "isWrite", {get:function() { + return 0 !== (i.M & 3) + }}); + Object.defineProperty(i, "isAppend", {get:function() { + return i.M & 8 + }}); + R[j] = i; + i.e.open && i.e.open(i); + return i +} +function Hb(a) { + try { + a.e.close && a.e.close(a) + }catch(b) { + g(b) + }finally { + R[a.s] = m + } +} +function Ib(a, b, c, d, e) { + (0 > d || 0 > e) && g(new Q(N.A)); + 0 === (a.M & 3) && g(new Q(N.$)); + 16384 === (a.d.mode & 61440) && g(new Q(N.aa)); + a.e.write || g(new Q(N.A)); + var f = l; + "undefined" === typeof e ? (e = a.position, f = p) : a.seekable || g(new Q(N.da)); + a.M & 8 && ((!a.seekable || !a.e.na) && g(new Q(N.da)), a.e.na(a, 0, 2)); + b = a.e.write(a, b, c, d, e); + f || (a.position += b); + return b +} +function wb(a) { + return/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(a).slice(1) +} +function Jb(a, b) { + for(var c = 0, d = a.length - 1;0 <= d;d--) { + var e = a[d]; + "." === e ? a.splice(d, 1) : ".." === e ? (a.splice(d, 1), c++) : c && (a.splice(d, 1), c--) + } + if(b) { + for(;c--;c) { + a.unshift("..") + } + } + return a +} +function Eb(a) { + var b = "/" === a.charAt(0), c = "/" === a.substr(-1), a = Jb(a.split("/").filter(function(a) { + return!!a + }), !b).join("/"); + !a && !b && (a = "."); + a && c && (a += "/"); + return(b ? "/" : "") + a +} +function S() { + var a = Array.prototype.slice.call(arguments, 0); + return Eb(a.filter(function(a) { + "string" !== typeof a && g(new TypeError("Arguments to path.join must be strings")); + return a + }).join("/")) +} +function Kb() { + for(var a = "", b = p, c = arguments.length - 1;-1 <= c && !b;c--) { + var d = 0 <= c ? arguments[c] : "/"; + "string" !== typeof d && g(new TypeError("Arguments to path.resolve must be strings")); + d && (a = d + "/" + a, b = "/" === d.charAt(0)) + } + a = Jb(a.split("/").filter(function(a) { + return!!a + }), !b).join("/"); + return(b ? "/" : "") + a || "." +} +var Lb = []; +function Mb(a, b) { + Lb[a] = {input:[], H:[], O:b}; + Nb[a] = {e:Ob} +} +var Ob = {open:function(a) { + Pb || (Pb = new pa); + var b = Lb[a.d.X]; + b || g(new Q(N.wa)); + a.q = b; + a.seekable = p +}, close:function(a) { + a.q.H.length && a.q.O.W(a.q, 10) +}, Q:function(a, b, c, d) { + (!a.q || !a.q.O.Na) && g(new Q(N.za)); + for(var e = 0, f = 0;f < d;f++) { + var h; + try { + h = a.q.O.Na(a.q) + }catch(i) { + g(new Q(N.I)) + } + h === k && 0 === e && g(new Q(N.ua)); + if(h === m || h === k) { + break + } + e++; + b[c + f] = h + } + e && (a.d.timestamp = Date.now()); + return e +}, write:function(a, b, c, d) { + (!a.q || !a.q.O.W) && g(new Q(N.za)); + for(var e = 0;e < d;e++) { + try { + a.q.O.W(a.q, b[c + e]) + }catch(f) { + g(new Q(N.I)) + } + } + d && (a.d.timestamp = Date.now()); + return e +}}, Pb, T = {z:function() { + return T.ka(m, "/", 16895, 0) +}, ka:function(a, b, c, d) { + (24576 === (c & 61440) || 4096 === (c & 61440)) && g(new Q(N.L)); + c = Qb(a, b, c, d); + c.l = T.l; + 16384 === (c.mode & 61440) ? (c.e = T.e, c.g = {}) : 32768 === (c.mode & 61440) ? (c.e = T.e, c.g = []) : 40960 === (c.mode & 61440) ? c.e = T.e : 8192 === (c.mode & 61440) && (c.e = Rb); + c.timestamp = Date.now(); + a && (a.g[b] = c); + return c +}, l:{ge:function(a) { + var b = {}; + b.ce = 8192 === (a.mode & 61440) ? a.id : 1; + b.je = a.id; + b.mode = a.mode; + b.pe = 1; + b.uid = 0; + b.he = 0; + b.X = a.X; + b.size = 16384 === (a.mode & 61440) ? 4096 : 32768 === (a.mode & 61440) ? a.g.length : 40960 === (a.mode & 61440) ? a.link.length : 0; + b.Yd = new Date(a.timestamp); + b.oe = new Date(a.timestamp); + b.ae = new Date(a.timestamp); + b.ib = 4096; + b.Zd = Math.ceil(b.size / b.ib); + return b +}, Y:function(a, b) { + b.mode !== k && (a.mode = b.mode); + b.timestamp !== k && (a.timestamp = b.timestamp); + if(b.size !== k) { + var c = a.g; + if(b.size < c.length) { + c.length = b.size + }else { + for(;b.size > c.length;) { + c.push(0) + } + } + } +}, tb:function() { + g(new Q(N.ca)) +}, Ta:function(a, b, c, d) { + return T.ka(a, b, c, d) +}, rename:function(a, b, c) { + if(16384 === (a.mode & 61440)) { + var d; + try { + d = Sb(b, c) + }catch(e) { + } + if(d) { + for(var f in d.g) { + g(new Q(N.ya)) + } + } + } + delete a.parent.g[a.name]; + a.name = c; + b.g[c] = a +}, ze:function(a, b) { + delete a.g[b] +}, ve:function(a, b) { + var c = Sb(a, b), d; + for(d in c.g) { + g(new Q(N.ya)) + } + delete a.g[b] +}, Wa:function(a, b, c) { + a = T.ka(a, b, 41471, 0); + a.link = c; + return a +}, Va:function(a) { + 40960 !== (a.mode & 61440) && g(new Q(N.A)); + return a.link +}}, e:{open:function(a) { + if(16384 === (a.d.mode & 61440)) { + var b = [".", ".."], c; + for(c in a.d.g) { + a.d.g.hasOwnProperty(c) && b.push(c) + } + a.lb = b + } +}, Q:function(a, b, c, d, e) { + a = a.d.g; + d = Math.min(a.length - e, d); + if(a.subarray) { + b.set(a.subarray(e, e + d), c) + }else { + for(var f = 0;f < d;f++) { + b[c + f] = a[e + f] + } + } + return d +}, write:function(a, b, c, d, e) { + for(var f = a.d.g;f.length < e;) { + f.push(0) + } + for(var h = 0;h < d;h++) { + f[e + h] = b[c + h] + } + a.d.timestamp = Date.now(); + return d +}, na:function(a, b, c) { + 1 === c ? b += a.position : 2 === c && 32768 === (a.d.mode & 61440) && (b += a.d.g.length); + 0 > b && g(new Q(N.A)); + a.Gb = []; + return a.position = b +}, ue:function(a) { + return a.lb +}, Wd:function(a, b, c) { + a = a.d.g; + for(b += c;b > a.length;) { + a.push(0) + } +}, ne:function(a, b, c, d, e, f, h) { + 32768 !== (a.d.mode & 61440) && g(new Q(N.wa)); + a = a.d.g; + if(h & 2) { + if(0 < e || e + d < a.length) { + a = a.subarray ? a.subarray(e, e + d) : Array.prototype.slice.call(a, e, e + d) + } + e = l; + (d = Oa(d)) || g(new Q(N.$a)); + b.set(a, d) + }else { + w(a.buffer === b || a.buffer === b.buffer), e = p, d = a.byteOffset + } + return{te:d, Xd:e} +}}}, Tb = F(1, "i32*", E), Ub = F(1, "i32*", E); +nb = F(1, "i32*", E); +var Vb = m, Nb = [m], R = [m], Wb = 1, Xb = [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ], Yb = l; +function Q(a) { + this.mb = a; + for(var b in N) { + if(N[b] === a) { + this.code = b; + break + } + } + this.message = ub[a] +} +function Zb(a) { + a instanceof Q || g(a + " : " + Error().stack); + M(a.mb) +} +function $b(a, b) { + for(var c = 0, d = 0;d < b.length;d++) { + c = (c << 5) - c + b.charCodeAt(d) | 0 + } + return(a + c) % Xb.length +} +function Sb(a, b) { + var c = Gb(a, "x"); + c && g(new Q(c)); + for(c = Xb[$b(a.id, b)];c;c = c.wb) { + if(c.parent.id === a.id && c.name === b) { + return c + } + } + return a.l.tb(a, b) +} +function Qb(a, b, c, d) { + var e = {id:Wb++, name:b, mode:c, l:{}, e:{}, X:d, parent:m, z:m}; + a || (a = e); + e.parent = a; + e.z = a.z; + Object.defineProperty(e, "read", {get:function() { + return 365 === (e.mode & 365) + }, set:function(a) { + a ? e.mode |= 365 : e.mode &= -366 + }}); + Object.defineProperty(e, "write", {get:function() { + return 146 === (e.mode & 146) + }, set:function(a) { + a ? e.mode |= 146 : e.mode &= -147 + }}); + a = $b(e.parent.id, e.name); + e.wb = Xb[a]; + return Xb[a] = e +} +function O(a, b) { + a = Kb("/", a); + b = b || {pa:0}; + 8 < b.pa && g(new Q(N.ba)); + for(var c = Jb(a.split("/").filter(function(a) { + return!!a + }), p), d = Vb, e = "/", f = 0;f < c.length;f++) { + var h = f === c.length - 1; + if(h && b.parent) { + break + } + d = Sb(d, c[f]); + e = S(e, c[f]); + d.ub && (d = d.z.root); + if(!h || b.N) { + for(h = 0;40960 === (d.mode & 61440);) { + d = O(e, {N:p}).d; + d.l.Va || g(new Q(N.A)); + var d = d.l.Va(d), i = Kb; + var j = wb(e), e = j[0], j = j[1]; + !e && !j ? e = "." : (j && (j = j.substr(0, j.length - 1)), e += j); + e = i(e, d); + d = O(e, {pa:b.pa}).d; + 40 < h++ && g(new Q(N.ba)) + } + } + } + return{path:e, d:d} +} +function ac(a) { + for(var b;;) { + if(a === a.parent) { + return b ? S(a.z.Ua, b) : a.z.Ua + } + b = b ? S(a.name, b) : a.name; + a = a.parent + } +} +var Fb = {r:0, rs:8192, "r+":2, w:1537, wx:3585, xw:3585, "w+":1538, "wx+":3586, "xw+":3586, a:521, ax:2569, xa:2569, "a+":522, "ax+":2570, "xa+":2570}; +function Gb(a, b) { + return Yb ? 0 : -1 !== b.indexOf("r") && !(a.mode & 292) || -1 !== b.indexOf("w") && !(a.mode & 146) || -1 !== b.indexOf("x") && !(a.mode & 73) ? N.Ya : 0 +} +function xb(a, b) { + try { + return Sb(a, b), N.va + }catch(c) { + } + return Gb(a, "wx") +} +var Rb = {open:function(a) { + a.e = Nb[a.d.X].e; + a.e.open && a.e.open(a) +}, na:function() { + g(new Q(N.da)) +}}, bc; +function cc(a, b) { + var c = 0; + a && (c |= 365); + b && (c |= 146); + return c +} +function dc(a, b, c, d, e) { + a = S("string" === typeof a ? a : ac(a), b); + d = cc(d, e); + e = yb(a, d); + if(c) { + if("string" === typeof c) { + for(var b = Array(c.length), f = 0, h = c.length;f < h;++f) { + b[f] = c.charCodeAt(f) + } + c = b + } + Cb(a, d | 146); + b = Db(a, "w"); + Ib(b, c, 0, c.length, 0); + Hb(b); + Cb(a, d) + } + return e +} +function ec(a, b, c, d) { + a = S("string" === typeof a ? a : ac(a), b); + ec.Sa || (ec.Sa = 64); + b = ec.Sa++ << 8 | 0; + Nb[b] = {e:{open:function(a) { + a.seekable = p + }, close:function() { + d && (d.buffer && d.buffer.length) && d(10) + }, Q:function(a, b, d, i) { + for(var j = 0, n = 0;n < i;n++) { + var y; + try { + y = c() + }catch(v) { + g(new Q(N.I)) + } + y === k && 0 === j && g(new Q(N.ua)); + if(y === m || y === k) { + break + } + j++; + b[d + n] = y + } + j && (a.d.timestamp = Date.now()); + return j + }, write:function(a, b, c, i) { + for(var j = 0;j < i;j++) { + try { + d(b[c + j]) + }catch(n) { + g(new Q(N.I)) + } + } + i && (a.d.timestamp = Date.now()); + return j + }}}; + return Ab(a, c && d ? 511 : c ? 219 : 365, b) +} +function fc(a, b, c) { + a = R[a]; + if(!a) { + return-1 + } + a.sender(G.subarray(b, b + c)); + return c +} +function gc(a, b, c) { + var d = R[a]; + if(!d) { + return M(N.$), -1 + } + if(d && "socket" in d) { + return fc(a, b, c) + } + try { + return Ib(d, A, b, c) + }catch(e) { + return Zb(e), -1 + } +} +function hc(a, b, c, d) { + c *= b; + if(0 == c) { + return 0 + } + a = gc(d, a, c); + if(-1 == a) { + if(b = R[d]) { + b.error = l + } + return 0 + } + return Math.floor(a / b) +} +s._strlen = ic; +function jc(a) { + return 0 > a || 0 === a && -Infinity === 1 / a +} +function kc(a, b) { + function c(a) { + var c; + "double" === a ? c = Ja[b + e >> 3] : "i64" == a ? (c = [B[b + e >> 2], B[b + (e + 8) >> 2]], e += 8) : (a = "i32", c = B[b + e >> 2]); + e += Math.max(Math.max(la(a), ma), 8); + return c + } + for(var d = a, e = 0, f = [], h, i;;) { + var j = d; + h = A[d]; + if(0 === h) { + break + } + i = A[d + 1 | 0]; + if(37 == h) { + var n = p, y = p, v = p, C = p; + a:for(;;) { + switch(i) { + case 43: + n = l; + break; + case 45: + y = l; + break; + case 35: + v = l; + break; + case 48: + if(C) { + break a + }else { + C = l; + break + } + ; + default: + break a + } + d++; + i = A[d + 1 | 0] + } + var D = 0; + if(42 == i) { + D = c("i32"), d++, i = A[d + 1 | 0] + }else { + for(;48 <= i && 57 >= i;) { + D = 10 * D + (i - 48), d++, i = A[d + 1 | 0] + } + } + var K = p; + if(46 == i) { + var H = 0, K = l; + d++; + i = A[d + 1 | 0]; + if(42 == i) { + H = c("i32"), d++ + }else { + for(;;) { + i = A[d + 1 | 0]; + if(48 > i || 57 < i) { + break + } + H = 10 * H + (i - 48); + d++ + } + } + i = A[d + 1 | 0] + }else { + H = 6 + } + var x; + switch(String.fromCharCode(i)) { + case "h": + i = A[d + 2 | 0]; + 104 == i ? (d++, x = 1) : x = 2; + break; + case "l": + i = A[d + 2 | 0]; + 108 == i ? (d++, x = 8) : x = 4; + break; + case "L": + ; + case "q": + ; + case "j": + x = 8; + break; + case "z": + ; + case "t": + ; + case "I": + x = 4; + break; + default: + x = m + } + x && d++; + i = A[d + 1 | 0]; + switch(String.fromCharCode(i)) { + case "d": + ; + case "i": + ; + case "u": + ; + case "o": + ; + case "x": + ; + case "X": + ; + case "p": + j = 100 == i || 105 == i; + x = x || 4; + var P = h = c("i" + 8 * x), r; + 8 == x && (h = 117 == i ? +(h[0] >>> 0) + 4294967296 * +(h[1] >>> 0) : +(h[0] >>> 0) + 4294967296 * +(h[1] | 0)); + 4 >= x && (h = (j ? eb : db)(h & Math.pow(256, x) - 1, 8 * x)); + var ta = Math.abs(h), j = ""; + if(100 == i || 105 == i) { + r = 8 == x && lc ? lc.stringify(P[0], P[1], m) : eb(h, 8 * x).toString(10) + }else { + if(117 == i) { + r = 8 == x && lc ? lc.stringify(P[0], P[1], l) : db(h, 8 * x).toString(10), h = Math.abs(h) + }else { + if(111 == i) { + r = (v ? "0" : "") + ta.toString(8) + }else { + if(120 == i || 88 == i) { + j = v && 0 != h ? "0x" : ""; + if(8 == x && lc) { + if(P[1]) { + r = (P[1] >>> 0).toString(16); + for(v = (P[0] >>> 0).toString(16);8 > v.length;) { + v = "0" + v + } + r += v + }else { + r = (P[0] >>> 0).toString(16) + } + }else { + if(0 > h) { + h = -h; + r = (ta - 1).toString(16); + P = []; + for(v = 0;v < r.length;v++) { + P.push((15 - parseInt(r[v], 16)).toString(16)) + } + for(r = P.join("");r.length < 2 * x;) { + r = "f" + r + } + }else { + r = ta.toString(16) + } + } + 88 == i && (j = j.toUpperCase(), r = r.toUpperCase()) + }else { + 112 == i && (0 === ta ? r = "(nil)" : (j = "0x", r = ta.toString(16))) + } + } + } + } + if(K) { + for(;r.length < H;) { + r = "0" + r + } + } + for(n && (j = 0 > h ? "-" + j : "+" + j);j.length + r.length < D;) { + y ? r += " " : C ? r = "0" + r : j = " " + j + } + r = j + r; + r.split("").forEach(function(a) { + f.push(a.charCodeAt(0)) + }); + break; + case "f": + ; + case "F": + ; + case "e": + ; + case "E": + ; + case "g": + ; + case "G": + h = c("double"); + if(isNaN(h)) { + r = "nan", C = p + }else { + if(isFinite(h)) { + K = p; + x = Math.min(H, 20); + if(103 == i || 71 == i) { + K = l, H = H || 1, x = parseInt(h.toExponential(x).split("e")[1], 10), H > x && -4 <= x ? (i = (103 == i ? "f" : "F").charCodeAt(0), H -= x + 1) : (i = (103 == i ? "e" : "E").charCodeAt(0), H--), x = Math.min(H, 20) + } + if(101 == i || 69 == i) { + r = h.toExponential(x), /[eE][-+]\d$/.test(r) && (r = r.slice(0, -1) + "0" + r.slice(-1)) + }else { + if(102 == i || 70 == i) { + r = h.toFixed(x), 0 === h && jc(h) && (r = "-" + r) + } + } + j = r.split("e"); + if(K && !v) { + for(;1 < j[0].length && -1 != j[0].indexOf(".") && ("0" == j[0].slice(-1) || "." == j[0].slice(-1));) { + j[0] = j[0].slice(0, -1) + } + }else { + for(v && -1 == r.indexOf(".") && (j[0] += ".");H > x++;) { + j[0] += "0" + } + } + r = j[0] + (1 < j.length ? "e" + j[1] : ""); + 69 == i && (r = r.toUpperCase()); + n && 0 <= h && (r = "+" + r) + }else { + r = (0 > h ? "-" : "") + "inf", C = p + } + } + for(;r.length < D;) { + r = y ? r + " " : C && ("-" == r[0] || "+" == r[0]) ? r[0] + "0" + r.slice(1) : (C ? "0" : " ") + r + } + 97 > i && (r = r.toUpperCase()); + r.split("").forEach(function(a) { + f.push(a.charCodeAt(0)) + }); + break; + case "s": + C = (n = c("i8*")) ? ic(n) : 6; + K && (C = Math.min(C, H)); + if(!y) { + for(;C < D--;) { + f.push(32) + } + } + if(n) { + for(v = 0;v < C;v++) { + f.push(G[n++ | 0]) + } + }else { + f = f.concat(J("(null)".substr(0, C), l)) + } + if(y) { + for(;C < D--;) { + f.push(32) + } + } + break; + case "c": + for(y && f.push(c("i8"));0 < --D;) { + f.push(32) + } + y || f.push(c("i8")); + break; + case "n": + y = c("i32*"); + B[y >> 2] = f.length; + break; + case "%": + f.push(h); + break; + default: + for(v = j;v < d + 2;v++) { + f.push(A[v]) + } + } + d += 2 + }else { + f.push(h), d += 1 + } + } + return f +} +function mc(a, b, c) { + c = kc(b, c); + b = ja(); + a = hc(F(c, "i8", La), 1, c.length, a); + ka(b); + return a +} +function nc(a) { + nc.ia || (z = z + 4095 >> 12 << 12, nc.ia = l, w(ua), nc.hb = ua, ua = function() { + wa("cannot dynamically allocate, sbrk now has control") + }); + var b = z; + 0 != a && nc.hb(a); + return b +} +function U() { + return B[U.m >> 2] +} +function oc() { + return!!oc.ta +} +function pc(a) { + var b = p; + try { + a == __ZTIi && (b = l) + }catch(c) { + } + try { + a == __ZTIj && (b = l) + }catch(d) { + } + try { + a == __ZTIl && (b = l) + }catch(e) { + } + try { + a == __ZTIm && (b = l) + }catch(f) { + } + try { + a == __ZTIx && (b = l) + }catch(h) { + } + try { + a == __ZTIy && (b = l) + }catch(i) { + } + try { + a == __ZTIf && (b = l) + }catch(j) { + } + try { + a == __ZTId && (b = l) + }catch(n) { + } + try { + a == __ZTIe && (b = l) + }catch(y) { + } + try { + a == __ZTIc && (b = l) + }catch(v) { + } + try { + a == __ZTIa && (b = l) + }catch(C) { + } + try { + a == __ZTIh && (b = l) + }catch(D) { + } + try { + a == __ZTIs && (b = l) + }catch(K) { + } + try { + a == __ZTIt && (b = l) + }catch(H) { + } + return b +} +function qc(a, b, c) { + if(0 == c) { + return p + } + if(0 == b || b == a) { + return l + } + switch(pc(b) ? b : B[B[b >> 2] - 8 >> 2]) { + case 0: + return 0 == B[B[a >> 2] - 8 >> 2] ? qc(B[a + 8 >> 2], B[b + 8 >> 2], c) : p; + case 1: + return p; + case 2: + return qc(a, B[b + 8 >> 2], c); + default: + return p + } +} +function rc(a, b, c) { + if(!rc.sb) { + try { + B[__ZTVN10__cxxabiv119__pointer_type_infoE >> 2] = 0 + }catch(d) { + } + try { + B[pb >> 2] = 1 + }catch(e) { + } + try { + B[ob >> 2] = 2 + }catch(f) { + } + rc.sb = l + } + B[U.m >> 2] = a; + B[U.m + 4 >> 2] = b; + B[U.m + 8 >> 2] = c; + "uncaught_exception" in oc ? oc.ta++ : oc.ta = 1; + g(a + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.") +} +function sc(a) { + try { + return tc(a) + }catch(b) { + } +} +function uc() { + if(uc.Bb) { + uc.Bb = p + }else { + V.setThrew(0); + B[U.m + 4 >> 2] = 0; + var a = B[U.m >> 2], b = B[U.m + 8 >> 2]; + b && (na("vi", b, [a]), B[U.m + 8 >> 2] = 0); + a && (sc(a), B[U.m >> 2] = 0) + } +} +var vc = F(1, "i32*", E); +function wc(a) { + var b, c; + wc.ia ? (c = B[vc >> 2], b = B[c >> 2]) : (wc.ia = l, W.USER = "root", W.PATH = "/", W.PWD = "/", W.HOME = "/home/emscripten", W.LANG = "en_US.UTF-8", W._ = "./this.program", b = F(1024, "i8", E), c = F(256, "i8*", E), B[c >> 2] = b, B[vc >> 2] = c); + var d = [], e = 0, f; + for(f in a) { + if("string" === typeof a[f]) { + var h = f + "=" + a[f]; + d.push(h); + e += h.length + } + } + 1024 < e && g(Error("Environment size exceeded TOTAL_ENV_SIZE!")); + for(a = 0;a < d.length;a++) { + h = d[a]; + for(e = 0;e < h.length;e++) { + A[b + e | 0] = h.charCodeAt(e) + } + A[b + e | 0] = 0; + B[c + 4 * a >> 2] = b; + b += h.length + 1 + } + B[c + 4 * d.length >> 2] = 0 +} +var W = {}; +function xc(a) { + if(0 === a) { + return 0 + } + a = Fa(a); + if(!W.hasOwnProperty(a)) { + return 0 + } + xc.J && tc(xc.J); + xc.J = F(J(W[a]), "i8", Ka); + return xc.J +} +function yc(a, b, c) { + if(a in ub) { + if(ub[a].length > c - 1) { + return M(N.ab) + } + a = ub[a]; + for(c = 0;c < a.length;c++) { + A[b + c | 0] = a.charCodeAt(c) + } + return A[b + c | 0] = 0 + } + return M(N.A) +} +function zc(a) { + zc.buffer || (zc.buffer = Oa(256)); + yc(a, zc.buffer, 256); + return zc.buffer +} +function Ac(a) { + s.exit(a) +} +function Bc(a, b) { + var c = db(a & 255); + A[Bc.J | 0] = c; + if(-1 == gc(b, Bc.J, 1)) { + if(c = R[b]) { + c.error = l + } + return-1 + } + return c +} +var Cc = p, Dc = p, Ec = p, Fc = p, Gc = k, Hc = k; +function Ic(a) { + return{jpg:"image/jpeg", jpeg:"image/jpeg", png:"image/png", bmp:"image/bmp", ogg:"audio/ogg", wav:"audio/wav", mp3:"audio/mpeg"}[a.substr(a.lastIndexOf(".") + 1)] +} +var Jc = []; +function Kc() { + var a = s.canvas; + Jc.forEach(function(b) { + b(a.width, a.height) + }) +} +function Lc() { + var a = s.canvas; + this.Ib = a.width; + this.Hb = a.height; + a.width = screen.width; + a.height = screen.height; + "undefined" != typeof SDL && (a = Qa[SDL.screen + 0 * ma >> 2], B[SDL.screen + 0 * ma >> 2] = a | 8388608); + Kc() +} +function Mc() { + var a = s.canvas; + a.width = this.Ib; + a.height = this.Hb; + "undefined" != typeof SDL && (a = Qa[SDL.screen + 0 * ma >> 2], B[SDL.screen + 0 * ma >> 2] = a & -8388609); + Kc() +} +var Nc, Oc, Pc, Qc, rb = ra(4); +B[rb >> 2] = 0; +var Vb = Qb(m, "/", 16895, 0), Rc = T, Sc = {type:Rc, se:{}, Ua:"/", root:m}, Tc; +Tc = O("/", {N:p}); +var Uc = Rc.z(Sc); +Uc.z = Sc; +Sc.root = Uc; +Tc && (Tc.d.z = Sc, Tc.d.ub = l, Vb = Sc.root); +zb("/tmp", 511); +zb("/dev", 511); +Nb[259] = {e:{Q:function() { + return 0 +}, write:function() { + return 0 +}}}; +Ab("/dev/null", 438, 259); +Mb(1280, {Na:function(a) { + if(!a.input.length) { + var b = m; + if(ca) { + if(process.Eb.be) { + return + } + b = process.Eb.Q() + }else { + "undefined" != typeof window && "function" == typeof window.prompt ? (b = window.prompt("Input: "), b !== m && (b += "\n")) : "function" == typeof readline && (b = readline(), b !== m && (b += "\n")) + } + if(!b) { + return m + } + a.input = J(b, l) + } + return a.input.shift() +}, W:function(a, b) { + b === m || 10 === b ? (s.print(a.H.join("")), a.H = []) : a.H.push(Pb.oa(b)) +}}); +Mb(1536, {W:function(a, b) { + b === m || 10 === b ? (s.printErr(a.H.join("")), a.H = []) : a.H.push(Pb.oa(b)) +}}); +Ab("/dev/tty", 438, 1280); +Ab("/dev/tty1", 438, 1536); +zb("/dev/shm", 511); +zb("/dev/shm/tmp", 511); +Xa.unshift({V:function() { + if(!s.noFSInit && !bc) { + w(!bc, "FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)"); + bc = l; + s.stdin = s.stdin; + s.stdout = s.stdout; + s.stderr = s.stderr; + s.stdin ? ec("/dev", "stdin", s.stdin) : Bb("/dev/tty", "/dev/stdin"); + s.stdout ? ec("/dev", "stdout", m, s.stdout) : Bb("/dev/tty", "/dev/stdout"); + s.stderr ? ec("/dev", "stderr", m, s.stderr) : Bb("/dev/tty1", "/dev/stderr"); + var a = Db("/dev/stdin", "r"); + B[Tb >> 2] = a.s; + w(1 === a.s, "invalid handle for stdin (" + a.s + ")"); + a = Db("/dev/stdout", "w"); + B[Ub >> 2] = a.s; + w(2 === a.s, "invalid handle for stdout (" + a.s + ")"); + a = Db("/dev/stderr", "w"); + B[nb >> 2] = a.s; + w(3 === a.s, "invalid handle for stderr (" + a.s + ")") + } +}}); +Ya.push({V:function() { + Yb = p +}}); +Za.push({V:function() { + bc = p; + for(var a = 0;a < R.length;a++) { + var b = R[a]; + b && Hb(b) + } +}}); +s.FS_createFolder = function(a, b, c, d) { + a = S("string" === typeof a ? a : ac(a), b); + return zb(a, cc(c, d)) +}; +s.FS_createPath = function(a, b) { + for(var a = "string" === typeof a ? a : ac(a), c = b.split("/").reverse();c.length;) { + var d = c.pop(); + if(d) { + var e = S(a, d); + try { + zb(e, 511) + }catch(f) { + } + a = e + } + } + return e +}; +s.FS_createDataFile = dc; +s.FS_createPreloadedFile = function(a, b, c, d, e, f, h, i) { + function j() { + Ec = document.pointerLockElement === v || document.mozPointerLockElement === v || document.webkitPointerLockElement === v + } + function n(c) { + function j(c) { + i || dc(a, b, c, d, e); + f && f(); + jb("cp " + C) + } + var n = p; + s.preloadPlugins.forEach(function(a) { + !n && a.canHandle(C) && (a.handle(c, C, j, function() { + h && h(); + jb("cp " + C) + }), n = l) + }); + n || j(c) + } + s.preloadPlugins || (s.preloadPlugins = []); + if(!Nc && !ea) { + Nc = l; + try { + new Blob, Oc = l + }catch(y) { + Oc = p, console.log("warning: no blob constructor, cannot create blobs with mimetypes") + } + Pc = "undefined" != typeof MozBlobBuilder ? MozBlobBuilder : "undefined" != typeof WebKitBlobBuilder ? WebKitBlobBuilder : !Oc ? console.log("warning: no BlobBuilder") : m; + Qc = "undefined" != typeof window ? window.URL ? window.URL : window.webkitURL : console.log("warning: cannot create object URLs"); + s.preloadPlugins.push({canHandle:function(a) { + return!s.re && /\.(jpg|jpeg|png|bmp)$/i.test(a) + }, handle:function(a, b, c, d) { + var e = m; + if(Oc) { + try { + e = new Blob([a], {type:Ic(b)}), e.size !== a.length && (e = new Blob([(new Uint8Array(a)).buffer], {type:Ic(b)})) + }catch(f) { + var h = "Blob constructor present but fails: " + f + "; falling back to blob builder"; + oa || (oa = {}); + oa[h] || (oa[h] = 1, s.P(h)) + } + } + e || (e = new Pc, e.append((new Uint8Array(a)).buffer), e = e.getBlob()); + var i = Qc.createObjectURL(e), j = new Image; + j.onload = function() { + w(j.complete, "Image " + b + " could not be decoded"); + var d = document.createElement("canvas"); + d.width = j.width; + d.height = j.height; + d.getContext("2d").drawImage(j, 0, 0); + s.preloadedImages[b] = d; + Qc.revokeObjectURL(i); + c && c(a) + }; + j.onerror = function() { + console.log("Image " + i + " could not be decoded"); + d && d() + }; + j.src = i + }}); + s.preloadPlugins.push({canHandle:function(a) { + return!s.qe && a.substr(-4) in {".ogg":1, ".wav":1, ".mp3":1} + }, handle:function(a, b, c, d) { + function e(d) { + h || (h = l, s.preloadedAudios[b] = d, c && c(a)) + } + function f() { + h || (h = l, s.preloadedAudios[b] = new Audio, d && d()) + } + var h = p; + if(Oc) { + try { + var i = new Blob([a], {type:Ic(b)}) + }catch(j) { + return f() + } + var i = Qc.createObjectURL(i), n = new Audio; + n.addEventListener("canplaythrough", function() { + e(n) + }, p); + n.onerror = function() { + if(!h) { + console.log("warning: browser could not fully decode audio " + b + ", trying slower base64 approach"); + for(var c = "", d = 0, f = 0, i = 0;i < a.length;i++) { + d = d << 8 | a[i]; + for(f += 8;6 <= f;) { + var j = d >> f - 6 & 63, f = f - 6, c = c + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[j] + } + } + 2 == f ? (c += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(d & 3) << 4], c += "==") : 4 == f && (c += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(d & 15) << 2], c += "="); + n.src = "data:audio/x-" + b.substr(-3) + ";base64," + c; + e(n) + } + }; + n.src = i; + setTimeout(function() { + za || e(n) + }, 1E4) + }else { + return f() + } + }}); + var v = s.canvas; + v.qa = v.requestPointerLock || v.mozRequestPointerLock || v.webkitRequestPointerLock; + v.La = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock || aa(); + v.La = v.La.bind(document); + document.addEventListener("pointerlockchange", j, p); + document.addEventListener("mozpointerlockchange", j, p); + document.addEventListener("webkitpointerlockchange", j, p); + s.elementPointerLock && v.addEventListener("click", function(a) { + !Ec && v.qa && (v.qa(), a.preventDefault()) + }, p) + } + var C, D = S.apply(m, [a, b]); + "/" == D[0] && (D = D.substr(1)); + C = D; + ib("cp " + C); + if("string" == typeof c) { + var K = h, H = function() { + K ? K() : g('Loading data file "' + c + '" failed.') + }, x = new XMLHttpRequest; + x.open("GET", c, l); + x.responseType = "arraybuffer"; + x.onload = function() { + if(200 == x.status || 0 == x.status && x.response) { + var a = x.response; + w(a, 'Loading data file "' + c + '" failed (no arrayBuffer).'); + a = new Uint8Array(a); + n(a); + jb("al " + c) + }else { + H() + } + }; + x.onerror = H; + x.send(m); + ib("al " + c) + }else { + n(c) + } +}; +s.FS_createLazyFile = function(a, b, c, d, e) { + var f, h; + "undefined" !== typeof XMLHttpRequest ? (ea || g("Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc"), f = function() { + this.ma = p; + this.T = [] + }, f.prototype.get = function(a) { + if(!(a > this.length - 1 || 0 > a)) { + var b = a % this.S; + return this.pb(Math.floor(a / this.S))[b] + } + }, f.prototype.Cb = function(a) { + this.pb = a + }, f.prototype.Fa = function() { + var a = new XMLHttpRequest; + a.open("HEAD", c, p); + a.send(m); + 200 <= a.status && 300 > a.status || 304 === a.status || g(Error("Couldn't load " + c + ". Status: " + a.status)); + var b = Number(a.getResponseHeader("Content-length")), d, e = 1048576; + if(!((d = a.getResponseHeader("Accept-Ranges")) && "bytes" === d)) { + e = b + } + var f = this; + f.Cb(function(a) { + var d = a * e, h = (a + 1) * e - 1, h = Math.min(h, b - 1); + if("undefined" === typeof f.T[a]) { + var i = f.T; + d > h && g(Error("invalid range (" + d + ", " + h + ") or no bytes requested!")); + h > b - 1 && g(Error("only " + b + " bytes available! programmer error!")); + var j = new XMLHttpRequest; + j.open("GET", c, p); + b !== e && j.setRequestHeader("Range", "bytes=" + d + "-" + h); + "undefined" != typeof Uint8Array && (j.responseType = "arraybuffer"); + j.overrideMimeType && j.overrideMimeType("text/plain; charset=x-user-defined"); + j.send(m); + 200 <= j.status && 300 > j.status || 304 === j.status || g(Error("Couldn't load " + c + ". Status: " + j.status)); + d = j.response !== k ? new Uint8Array(j.response || []) : J(j.responseText || "", l); + i[a] = d + } + "undefined" === typeof f.T[a] && g(Error("doXHR failed!")); + return f.T[a] + }); + this.gb = b; + this.fb = e; + this.ma = l + }, f = new f, Object.defineProperty(f, "length", {get:function() { + this.ma || this.Fa(); + return this.gb + }}), Object.defineProperty(f, "chunkSize", {get:function() { + this.ma || this.Fa(); + return this.fb + }}), h = k) : (h = c, f = k); + var i, a = S("string" === typeof a ? a : ac(a), b); + i = yb(a, cc(d, e)); + f ? i.g = f : h && (i.g = m, i.url = h); + var j = {}; + Object.keys(i.e).forEach(function(a) { + var b = i.e[a]; + j[a] = function() { + var a; + if(i.ke || i.le || i.link || i.g) { + a = l + }else { + a = l; + "undefined" !== typeof XMLHttpRequest && g(Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")); + if(s.read) { + try { + i.g = J(s.read(i.url), l) + }catch(c) { + a = p + } + }else { + g(Error("Cannot load without read() or XMLHttpRequest.")) + } + a || M(N.I) + } + a || g(new Q(N.I)); + return b.apply(m, arguments) + } + }); + j.Q = function(a, b, c, d, e) { + a = a.d.g; + d = Math.min(a.length - e, d); + if(a.slice) { + for(var f = 0;f < d;f++) { + b[c + f] = a[e + f] + } + }else { + for(f = 0;f < d;f++) { + b[c + f] = a.get(e + f) + } + } + return d + }; + i.e = j; + return i +}; +s.FS_createLink = function(a, b, c) { + a = S("string" === typeof a ? a : ac(a), b); + return Bb(c, a) +}; +s.FS_createDevice = ec; +U.m = F(12, "void*", E); +wc(W); +Bc.J = F([0], "i8", E); +s.requestFullScreen = function(a, b) { + function c() { + Dc = p; + (document.webkitFullScreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.mozFullscreenElement || document.fullScreenElement || document.fullscreenElement) === d ? (d.Ga = document.cancelFullScreen || document.mozCancelFullScreen || document.webkitCancelFullScreen, d.Ga = d.Ga.bind(document), Gc && d.qa(), Dc = l, Hc && Lc()) : Hc && Mc(); + if(s.onFullScreen) { + s.onFullScreen(Dc) + } + } + Gc = a; + Hc = b; + "undefined" === typeof Gc && (Gc = l); + "undefined" === typeof Hc && (Hc = p); + var d = s.canvas; + Fc || (Fc = l, document.addEventListener("fullscreenchange", c, p), document.addEventListener("mozfullscreenchange", c, p), document.addEventListener("webkitfullscreenchange", c, p)); + d.Ab = d.requestFullScreen || d.mozRequestFullScreen || (d.webkitRequestFullScreen ? function() { + d.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT) + } : m); + d.Ab() +}; +s.requestAnimationFrame = function(a) { + window.requestAnimationFrame || (window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || window.setTimeout); + window.requestAnimationFrame(a) +}; +s.pauseMainLoop = aa(); +s.resumeMainLoop = function() { + Cc && (Cc = p, m()) +}; +s.getUserMedia = function() { + window.Ma || (window.Ma = navigator.getUserMedia || navigator.mozGetUserMedia); + window.Ma(k) +}; +Sa = u = xa(sa); +Ta = Sa + 5242880; +Ua = z = xa(Ta); +w(Ua < va); +var Vc = F([8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "i8", 3), Wc = F([8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, +2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, +0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0], "i8", 3), Xc = Math.min; +var V = (function(global,env,buffer) { +// EMSCRIPTEN_START_ASM + "use asm"; + var a = new global.Int8Array(buffer); + var b = new global.Int16Array(buffer); + var c = new global.Int32Array(buffer); + var d = new global.Uint8Array(buffer); + var e = new global.Uint16Array(buffer); + var f = new global.Uint32Array(buffer); + var g = new global.Float32Array(buffer); + var h = new global.Float64Array(buffer); + var i = env.STACKTOP | 0; + var j = env.STACK_MAX | 0; + var k = env.tempDoublePtr | 0; + var l = env.ABORT | 0; + var m = env.cttz_i8 | 0; + var n = env.ctlz_i8 | 0; + var o = env._stderr | 0; + var p = env.__ZTVN10__cxxabiv120__si_class_type_infoE | 0; + var q = env.__ZTVN10__cxxabiv117__class_type_infoE | 0; + var r = env.___progname | 0; + var s = +env.NaN; + var t = +env.Infinity; + var u = 0; + var v = 0; + var w = 0; + var x = 0; + var y = 0, z = 0, A = 0, B = 0, C = 0.0, D = 0, E = 0, F = 0, G = 0.0; + var H = 0; + var I = 0; + var J = 0; + var K = 0; + var L = 0; + var M = 0; + var N = 0; + var O = 0; + var P = 0; + var Q = 0; + var R = global.Math.floor; + var S = global.Math.abs; + var T = global.Math.sqrt; + var U = global.Math.pow; + var V = global.Math.cos; + var W = global.Math.sin; + var X = global.Math.tan; + var Y = global.Math.acos; + var Z = global.Math.asin; + var _ = global.Math.atan; + var $ = global.Math.atan2; + var aa = global.Math.exp; + var ab = global.Math.log; + var ac = global.Math.ceil; + var ad = global.Math.imul; + var ae = env.abort; + var af = env.assert; + var ag = env.asmPrintInt; + var ah = env.asmPrintFloat; + var ai = env.min; + var aj = env.invoke_vi; + var ak = env.invoke_vii; + var al = env.invoke_ii; + var am = env.invoke_viii; + var an = env.invoke_v; + var ao = env.invoke_iii; + var ap = env._strncmp; + var aq = env._llvm_va_end; + var ar = env._sysconf; + var as = env.___cxa_throw; + var at = env._strerror; + var au = env._abort; + var av = env._fprintf; + var aw = env._llvm_eh_exception; + var ax = env.___cxa_free_exception; + var ay = env._fflush; + var az = env.___buildEnvironment; + var aA = env.__reallyNegative; + var aB = env._strchr; + var aC = env._fputc; + var aD = env.___setErrNo; + var aE = env._fwrite; + var aF = env._send; + var aG = env._write; + var aH = env._exit; + var aI = env.___cxa_find_matching_catch; + var aJ = env.___cxa_allocate_exception; + var aK = env._isspace; + var aL = env.__formatString; + var aM = env.___resumeException; + var aN = env._llvm_uadd_with_overflow_i32; + var aO = env.___cxa_does_inherit; + var aP = env._getenv; + var aQ = env._vfprintf; + var aR = env.___cxa_begin_catch; + var aS = env.__ZSt18uncaught_exceptionv; + var aT = env._pwrite; + var aU = env.___cxa_call_unexpected; + var aV = env._sbrk; + var aW = env._strerror_r; + var aX = env.___errno_location; + var aY = env.___gxx_personality_v0; + var aZ = env.___cxa_is_number_type; + var a_ = env._time; + var a$ = env.__exit; + var a0 = env.___cxa_end_catch; +// EMSCRIPTEN_START_FUNCS +function a7(a) { + a = a | 0; + var b = 0; + b = i; + i = i + a | 0; + i = i + 7 >> 3 << 3; + return b | 0; +} +function a8() { + return i | 0; +} +function a9(a) { + a = a | 0; + i = a; +} +function ba(a, b) { + a = a | 0; + b = b | 0; + if ((u | 0) == 0) { + u = a; + v = b; + } +} +function bb(b) { + b = b | 0; + a[k] = a[b]; + a[k + 1 | 0] = a[b + 1 | 0]; + a[k + 2 | 0] = a[b + 2 | 0]; + a[k + 3 | 0] = a[b + 3 | 0]; +} +function bc(b) { + b = b | 0; + a[k] = a[b]; + a[k + 1 | 0] = a[b + 1 | 0]; + a[k + 2 | 0] = a[b + 2 | 0]; + a[k + 3 | 0] = a[b + 3 | 0]; + a[k + 4 | 0] = a[b + 4 | 0]; + a[k + 5 | 0] = a[b + 5 | 0]; + a[k + 6 | 0] = a[b + 6 | 0]; + a[k + 7 | 0] = a[b + 7 | 0]; +} +function bd(a) { + a = a | 0; + H = a; +} +function be(a) { + a = a | 0; + I = a; +} +function bf(a) { + a = a | 0; + J = a; +} +function bg(a) { + a = a | 0; + K = a; +} +function bh(a) { + a = a | 0; + L = a; +} +function bi(a) { + a = a | 0; + M = a; +} +function bj(a) { + a = a | 0; + N = a; +} +function bk(a) { + a = a | 0; + O = a; +} +function bl(a) { + a = a | 0; + P = a; +} +function bm(a) { + a = a | 0; + Q = a; +} +function bn() { + c[170] = q + 8; + c[172] = p + 8; + c[176] = p + 8; +} +function bo(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + if ((d | 0) == 0) { + return; + } else { + e = 0; + } + do { + a[b + e | 0] = a[c + e | 0] | 0; + e = e + 1 | 0; + } while (e >>> 0 < d >>> 0); + return; +} +function bp(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0; + if ((d | 0) == 0) { + return; + } else { + e = 0; + } + do { + f = b + e | 0; + a[f] = a[f] ^ a[c + e | 0]; + e = e + 1 | 0; + } while (e >>> 0 < d >>> 0); + return; +} +function bq(a) { + a = a | 0; + var b = 0, c = 0, e = 0, f = 0; + b = d[a + 1 | 0] | 0; + c = d[a + 2 | 0] | 0; + e = d[a + 3 | 0] | 0; + f = cN(b << 8 | 0 >>> 24 | (d[a] | 0) | (c << 16 | 0 >>> 16) | (e << 24 | 0 >>> 8) | (0 << 8 | 0 >>> 24), 0 << 8 | b >>> 24 | (0 << 16 | c >>> 16) | (0 << 24 | e >>> 8) | (d[a + 4 | 0] | 0) | ((d[a + 5 | 0] | 0) << 8 | 0 >>> 24), 0 << 16 | 0 >>> 16, (d[a + 6 | 0] | 0) << 16 | 0 >>> 16) | 0; + e = cN(f, H, 0 << 24 | 0 >>> 8, (d[a + 7 | 0] | 0) << 24 | 0 >>> 8) | 0; + return (H = H, e) | 0; +} +function br(a) { + a = a | 0; + return (d[a + 1 | 0] | 0) << 8 | (d[a] | 0) | (d[a + 2 | 0] | 0) << 16 | (d[a + 3 | 0] | 0) << 24 | 0; +} +function bs(b, c) { + b = b | 0; + c = c | 0; + a[b] = c & 255; + a[b + 1 | 0] = c >>> 8 & 255; + a[b + 2 | 0] = c >>> 16 & 255; + a[b + 3 | 0] = c >>> 24 & 255; + return; +} +function bt(a) { + a = a | 0; + c[a + 36 >> 2] = 0; + c[a + 32 >> 2] = 0; + c[a >> 2] = 1779033703; + c[a + 4 >> 2] = -1150833019; + c[a + 8 >> 2] = 1013904242; + c[a + 12 >> 2] = -1521486534; + c[a + 16 >> 2] = 1359893119; + c[a + 20 >> 2] = -1694144372; + c[a + 24 >> 2] = 528734635; + c[a + 28 >> 2] = 1541459225; + return; +} +function bu(a, b, d, e, f, g, h, i, j, k) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + i = i | 0; + j = j | 0; + k = k | 0; + var l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0; + l = cX(i, 0, h, 0) | 0; + m = H; + n = 0; + if (m >>> 0 > n >>> 0 | m >>> 0 == n >>> 0 & l >>> 0 > 1073741823 >>> 0) { + c[(aX() | 0) >> 2] = 27; + o = -1; + return o | 0; + } + l = cN(f, g, -1, -1) | 0; + if ((l & f | 0) != 0 | (H & g | 0) != 0 | (f | 0) == 0 & (g | 0) == 0) { + c[(aX() | 0) >> 2] = 22; + o = -1; + return o | 0; + } + do { + if (!((33554431 / (i >>> 0) | 0) >>> 0 < h >>> 0 | h >>> 0 > 16777215)) { + l = 0; + if (l >>> 0 < g >>> 0 | l >>> 0 == g >>> 0 & (33554431 / (h >>> 0) | 0) >>> 0 < f >>> 0) { + break; + } + l = h << 7; + n = bL(ad(l, i) | 0) | 0; + if ((n | 0) == 0) { + o = -1; + return o | 0; + } + m = bL(h << 8) | 0; + do { + if ((m | 0) != 0) { + p = cX(l, 0, f, g) | 0; + q = bL(p) | 0; + if ((q | 0) == 0) { + bM(m); + break; + } + p = ad(i << 7, h) | 0; + bJ(a, b, d, e, 1, 0, n, p); + if ((i | 0) != 0) { + r = h << 7; + s = 0; + do { + bv(n + (ad(r, s) | 0) | 0, h, f, g, q, m); + s = s + 1 | 0; + } while (s >>> 0 < i >>> 0); + } + bJ(a, b, n, p, 1, 0, j, k); + bM(q); + bM(m); + bM(n); + o = 0; + return o | 0; + } + } while (0); + bM(n); + o = -1; + return o | 0; + } + } while (0); + c[(aX() | 0) >> 2] = 12; + o = -1; + return o | 0; +} +function bv(a, b, c, d, e, f) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + g = b << 7; + h = f + g | 0; + bo(f, a, g); + if ((c | 0) == 0 & (d | 0) == 0) { + bo(a, f, g); + return; + } + i = g; + j = 0; + k = 0; + l = 0; + do { + m = cX(l, k, i, j) | 0; + bo(e + m | 0, f, g); + bw(f, h, b); + l = cN(l, k, 1, 0) | 0; + k = H; + } while (k >>> 0 < d >>> 0 | k >>> 0 == d >>> 0 & l >>> 0 < c >>> 0); + if ((c | 0) == 0 & (d | 0) == 0) { + bo(a, f, g); + return; + } + l = cN(c, d, -1, -1) | 0; + k = H; + j = g; + i = 0; + m = 0; + n = 0; + do { + o = bx(f, b) | 0; + p = cX(o & l, H & k, j, i) | 0; + bp(f, e + p | 0, g); + bw(f, h, b); + n = cN(n, m, 1, 0) | 0; + m = H; + } while (m >>> 0 < d >>> 0 | m >>> 0 == d >>> 0 & n >>> 0 < c >>> 0); + bo(a, f, g); + return; +} +function bw(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0; + d = i; + i = i + 64 | 0; + e = d | 0; + f = c << 1; + bo(e, a + ((c << 7) - 64) | 0, 64); + if ((f | 0) != 0) { + g = 0; + do { + h = g << 6; + bp(e, a + h | 0, 64); + by(e); + bo(b + h | 0, e, 64); + g = g + 1 | 0; + } while (g >>> 0 < f >>> 0); + } + if ((c | 0) == 0) { + i = d; + return; + } else { + j = 0; + } + do { + bo(a + (j << 6) | 0, b + (j << 7) | 0, 64); + j = j + 1 | 0; + } while (j >>> 0 < c >>> 0); + if ((c | 0) == 0) { + i = d; + return; + } else { + k = 0; + } + do { + bo(a + (k + c << 6) | 0, b + (k << 7 | 64) | 0, 64); + k = k + 1 | 0; + } while (k >>> 0 < c >>> 0); + i = d; + return; +} +function bx(a, b) { + a = a | 0; + b = b | 0; + var c = 0; + c = bq(a + ((b << 7) - 64) | 0) | 0; + return (H = H, c) | 0; +} +function by(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0; + b = i; + i = i + 128 | 0; + d = b | 0; + e = b + 64 | 0; + f = 0; + do { + c[d + (f << 2) >> 2] = br(a + (f << 2) | 0) | 0; + f = f + 1 | 0; + } while (f >>> 0 < 16); + f = d; + g = e; + cK(g | 0, f | 0, 64) | 0; + f = e | 0; + g = e + 48 | 0; + h = e + 16 | 0; + j = e + 32 | 0; + k = e + 20 | 0; + l = e + 4 | 0; + m = e + 36 | 0; + n = e + 52 | 0; + o = e + 40 | 0; + p = e + 24 | 0; + q = e + 56 | 0; + r = e + 8 | 0; + s = e + 60 | 0; + t = e + 44 | 0; + u = e + 12 | 0; + v = e + 28 | 0; + w = 0; + x = c[f >> 2] | 0; + y = c[g >> 2] | 0; + z = c[h >> 2] | 0; + A = c[j >> 2] | 0; + B = c[k >> 2] | 0; + C = c[l >> 2] | 0; + D = c[m >> 2] | 0; + E = c[n >> 2] | 0; + F = c[o >> 2] | 0; + G = c[p >> 2] | 0; + H = c[q >> 2] | 0; + I = c[r >> 2] | 0; + J = c[s >> 2] | 0; + K = c[t >> 2] | 0; + L = c[u >> 2] | 0; + M = c[v >> 2] | 0; + do { + N = y + x | 0; + O = (N << 7 | N >>> 25) ^ z; + N = O + x | 0; + P = (N << 9 | N >>> 23) ^ A; + N = P + O | 0; + Q = (N << 13 | N >>> 19) ^ y; + N = Q + P | 0; + R = (N << 18 | N >>> 14) ^ x; + N = C + B | 0; + S = (N << 7 | N >>> 25) ^ D; + N = S + B | 0; + T = (N << 9 | N >>> 23) ^ E; + N = T + S | 0; + U = (N << 13 | N >>> 19) ^ C; + N = U + T | 0; + V = (N << 18 | N >>> 14) ^ B; + N = G + F | 0; + W = (N << 7 | N >>> 25) ^ H; + N = W + F | 0; + X = (N << 9 | N >>> 23) ^ I; + N = X + W | 0; + Y = (N << 13 | N >>> 19) ^ G; + N = Y + X | 0; + Z = (N << 18 | N >>> 14) ^ F; + N = K + J | 0; + _ = (N << 7 | N >>> 25) ^ L; + N = _ + J | 0; + $ = (N << 9 | N >>> 23) ^ M; + N = $ + _ | 0; + aa = (N << 13 | N >>> 19) ^ K; + N = aa + $ | 0; + ab = (N << 18 | N >>> 14) ^ J; + N = _ + R | 0; + C = (N << 7 | N >>> 25) ^ U; + U = C + R | 0; + I = (U << 9 | U >>> 23) ^ X; + X = I + C | 0; + L = (X << 13 | X >>> 19) ^ _; + _ = L + I | 0; + x = (_ << 18 | _ >>> 14) ^ R; + R = O + V | 0; + G = (R << 7 | R >>> 25) ^ Y; + Y = G + V | 0; + M = (Y << 9 | Y >>> 23) ^ $; + $ = M + G | 0; + z = ($ << 13 | $ >>> 19) ^ O; + O = z + M | 0; + B = (O << 18 | O >>> 14) ^ V; + V = S + Z | 0; + K = (V << 7 | V >>> 25) ^ aa; + aa = K + Z | 0; + A = (aa << 9 | aa >>> 23) ^ P; + P = A + K | 0; + D = (P << 13 | P >>> 19) ^ S; + S = D + A | 0; + F = (S << 18 | S >>> 14) ^ Z; + Z = W + ab | 0; + y = (Z << 7 | Z >>> 25) ^ Q; + Q = y + ab | 0; + E = (Q << 9 | Q >>> 23) ^ T; + T = E + y | 0; + H = (T << 13 | T >>> 19) ^ W; + W = H + E | 0; + J = (W << 18 | W >>> 14) ^ ab; + w = w + 2 | 0; + } while (w >>> 0 < 8); + c[f >> 2] = x; + c[g >> 2] = y; + c[h >> 2] = z; + c[j >> 2] = A; + c[k >> 2] = B; + c[l >> 2] = C; + c[m >> 2] = D; + c[n >> 2] = E; + c[o >> 2] = F; + c[p >> 2] = G; + c[q >> 2] = H; + c[r >> 2] = I; + c[s >> 2] = J; + c[t >> 2] = K; + c[u >> 2] = L; + c[v >> 2] = M; + M = d | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e >> 2] | 0); + M = d + 4 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 4 >> 2] | 0); + M = d + 8 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 8 >> 2] | 0); + M = d + 12 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 12 >> 2] | 0); + M = d + 16 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 16 >> 2] | 0); + M = d + 20 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 20 >> 2] | 0); + M = d + 24 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 24 >> 2] | 0); + M = d + 28 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 28 >> 2] | 0); + M = d + 32 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 32 >> 2] | 0); + M = d + 36 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 36 >> 2] | 0); + M = d + 40 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 40 >> 2] | 0); + M = d + 44 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 44 >> 2] | 0); + M = d + 48 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 48 >> 2] | 0); + M = d + 52 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 52 >> 2] | 0); + M = d + 56 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 56 >> 2] | 0); + M = d + 60 | 0; + c[M >> 2] = (c[M >> 2] | 0) + (c[e + 60 >> 2] | 0); + e = 0; + do { + bs(a + (e << 2) | 0, c[d + (e << 2) >> 2] | 0); + e = e + 1 | 0; + } while (e >>> 0 < 16); + i = b; + return; +} +function bz(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0; + e = a + 32 | 0; + f = a + 36 | 0; + g = c[f >> 2] | 0; + h = g >>> 3 & 63; + i = aN(g | 0, d << 3 | 0) | 0; + c[f >> 2] = i; + if (H) { + i = e | 0; + c[i >> 2] = (c[i >> 2] | 0) + 1; + } + i = e | 0; + c[i >> 2] = (c[i >> 2] | 0) + (d >>> 29); + i = 64 - h | 0; + e = a + 40 + h | 0; + if (i >>> 0 > d >>> 0) { + cK(e | 0, b | 0, d) | 0; + return; + } + cK(e | 0, b | 0, i) | 0; + e = a | 0; + h = a + 40 | 0; + bA(e, h); + a = b + i | 0; + b = d - i | 0; + if (b >>> 0 > 63) { + i = b; + d = a; + while (1) { + bA(e, d); + f = d + 64 | 0; + g = i - 64 | 0; + if (g >>> 0 > 63) { + i = g; + d = f; + } else { + j = g; + k = f; + break; + } + } + } else { + j = b; + k = a; + } + cK(h | 0, k | 0, j) | 0; + return; +} +function bA(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0; + d = i; + i = i + 288 | 0; + e = d | 0; + f = d + 256 | 0; + g = e | 0; + bK(g, b); + b = 16; + do { + h = c[e + (b - 2 << 2) >> 2] | 0; + j = c[e + (b - 15 << 2) >> 2] | 0; + c[e + (b << 2) >> 2] = (c[e + (b - 16 << 2) >> 2] | 0) + (c[e + (b - 7 << 2) >> 2] | 0) + ((h >>> 19 | h << 13) ^ h >>> 10 ^ (h >>> 17 | h << 15)) + ((j >>> 18 | j << 14) ^ j >>> 3 ^ (j >>> 7 | j << 25)); + b = b + 1 | 0; + } while ((b | 0) < 64); + b = f; + j = a; + cK(b | 0, j | 0, 32) | 0; + j = f + 28 | 0; + b = f + 16 | 0; + h = c[b >> 2] | 0; + k = f + 20 | 0; + l = f + 24 | 0; + m = c[l >> 2] | 0; + n = (c[j >> 2] | 0) + 1116352408 + (c[g >> 2] | 0) + ((h >>> 6 | h << 26) ^ (h >>> 11 | h << 21) ^ (h >>> 25 | h << 7)) + ((m ^ c[k >> 2]) & h ^ m) | 0; + m = f | 0; + h = c[m >> 2] | 0; + g = f + 4 | 0; + o = c[g >> 2] | 0; + p = f + 8 | 0; + q = c[p >> 2] | 0; + r = f + 12 | 0; + c[r >> 2] = (c[r >> 2] | 0) + n; + s = ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + n + ((q | o) & h | q & o) | 0; + c[j >> 2] = s; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + h = (c[l >> 2] | 0) + 1899447441 + (c[e + 4 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[l >> 2] = n; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + s = (c[k >> 2] | 0) - 1245643825 + (c[e + 8 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[k >> 2] = h; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + n = (c[b >> 2] | 0) - 373957723 + (c[e + 12 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[b >> 2] = s; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + h = (c[r >> 2] | 0) + 961987163 + (c[e + 16 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[r >> 2] = n; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + s = (c[p >> 2] | 0) + 1508970993 + (c[e + 20 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[p >> 2] = h; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + n = (c[g >> 2] | 0) - 1841331548 + (c[e + 24 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[g >> 2] = s; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + h = (c[m >> 2] | 0) - 1424204075 + (c[e + 28 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[m >> 2] = n; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + s = (c[j >> 2] | 0) - 670586216 + (c[e + 32 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[j >> 2] = h; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + n = (c[l >> 2] | 0) + 310598401 + (c[e + 36 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[l >> 2] = s; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + h = (c[k >> 2] | 0) + 607225278 + (c[e + 40 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[k >> 2] = n; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + s = (c[b >> 2] | 0) + 1426881987 + (c[e + 44 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[b >> 2] = h; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + n = (c[r >> 2] | 0) + 1925078388 + (c[e + 48 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[r >> 2] = s; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + h = (c[p >> 2] | 0) - 2132889090 + (c[e + 52 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[p >> 2] = n; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + s = (c[g >> 2] | 0) - 1680079193 + (c[e + 56 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[g >> 2] = h; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + n = (c[m >> 2] | 0) - 1046744716 + (c[e + 60 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[m >> 2] = s; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + h = (c[j >> 2] | 0) - 459576895 + (c[e + 64 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[j >> 2] = n; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + s = (c[l >> 2] | 0) - 272742522 + (c[e + 68 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[l >> 2] = h; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + n = (c[k >> 2] | 0) + 264347078 + (c[e + 72 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[k >> 2] = s; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + h = (c[b >> 2] | 0) + 604807628 + (c[e + 76 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[b >> 2] = n; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + s = (c[r >> 2] | 0) + 770255983 + (c[e + 80 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[r >> 2] = h; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + n = (c[p >> 2] | 0) + 1249150122 + (c[e + 84 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[p >> 2] = s; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + h = (c[g >> 2] | 0) + 1555081692 + (c[e + 88 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[g >> 2] = n; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + s = (c[m >> 2] | 0) + 1996064986 + (c[e + 92 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[m >> 2] = h; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + n = (c[j >> 2] | 0) - 1740746414 + (c[e + 96 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[j >> 2] = s; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + h = (c[l >> 2] | 0) - 1473132947 + (c[e + 100 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[l >> 2] = n; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + s = (c[k >> 2] | 0) - 1341970488 + (c[e + 104 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[k >> 2] = h; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + n = (c[b >> 2] | 0) - 1084653625 + (c[e + 108 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[b >> 2] = s; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + h = (c[r >> 2] | 0) - 958395405 + (c[e + 112 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[r >> 2] = n; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + s = (c[p >> 2] | 0) - 710438585 + (c[e + 116 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[p >> 2] = h; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + n = (c[g >> 2] | 0) + 113926993 + (c[e + 120 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[g >> 2] = s; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + h = (c[m >> 2] | 0) + 338241895 + (c[e + 124 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[m >> 2] = n; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + s = (c[j >> 2] | 0) + 666307205 + (c[e + 128 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[j >> 2] = h; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + n = (c[l >> 2] | 0) + 773529912 + (c[e + 132 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[l >> 2] = s; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + h = (c[k >> 2] | 0) + 1294757372 + (c[e + 136 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[k >> 2] = n; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + s = (c[b >> 2] | 0) + 1396182291 + (c[e + 140 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[b >> 2] = h; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + n = (c[r >> 2] | 0) + 1695183700 + (c[e + 144 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[r >> 2] = s; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + h = (c[p >> 2] | 0) + 1986661051 + (c[e + 148 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[p >> 2] = n; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + s = (c[g >> 2] | 0) - 2117940946 + (c[e + 152 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[g >> 2] = h; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + n = (c[m >> 2] | 0) - 1838011259 + (c[e + 156 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[m >> 2] = s; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + h = (c[j >> 2] | 0) - 1564481375 + (c[e + 160 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[j >> 2] = n; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + s = (c[l >> 2] | 0) - 1474664885 + (c[e + 164 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[l >> 2] = h; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + n = (c[k >> 2] | 0) - 1035236496 + (c[e + 168 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[k >> 2] = s; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + h = (c[b >> 2] | 0) - 949202525 + (c[e + 172 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[b >> 2] = n; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + s = (c[r >> 2] | 0) - 778901479 + (c[e + 176 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[r >> 2] = h; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + n = (c[p >> 2] | 0) - 694614492 + (c[e + 180 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[p >> 2] = s; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + h = (c[g >> 2] | 0) - 200395387 + (c[e + 184 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[g >> 2] = n; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + s = (c[m >> 2] | 0) + 275423344 + (c[e + 188 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[m >> 2] = h; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + n = (c[j >> 2] | 0) + 430227734 + (c[e + 192 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[j >> 2] = s; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + h = (c[l >> 2] | 0) + 506948616 + (c[e + 196 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[l >> 2] = n; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + s = (c[k >> 2] | 0) + 659060556 + (c[e + 200 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[k >> 2] = h; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + n = (c[b >> 2] | 0) + 883997877 + (c[e + 204 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[b >> 2] = s; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + h = (c[r >> 2] | 0) + 958139571 + (c[e + 208 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[r >> 2] = n; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + s = (c[p >> 2] | 0) + 1322822218 + (c[e + 212 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[p >> 2] = h; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + n = (c[g >> 2] | 0) + 1537002063 + (c[e + 216 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[g >> 2] = s; + o = c[k >> 2] | 0; + q = c[j >> 2] | 0; + h = (c[m >> 2] | 0) + 1747873779 + (c[e + 220 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[l >> 2]) & o ^ q) | 0; + q = c[p >> 2] | 0; + o = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[m >> 2] = n; + q = c[b >> 2] | 0; + o = c[l >> 2] | 0; + s = (c[j >> 2] | 0) + 1955562222 + (c[e + 224 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[k >> 2]) & q ^ o) | 0; + o = c[g >> 2] | 0; + q = c[p >> 2] | 0; + c[r >> 2] = (c[r >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[j >> 2] = h; + o = c[r >> 2] | 0; + q = c[k >> 2] | 0; + n = (c[l >> 2] | 0) + 2024104815 + (c[e + 228 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[b >> 2]) & o ^ q) | 0; + q = c[m >> 2] | 0; + o = c[g >> 2] | 0; + c[p >> 2] = (c[p >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((o | q) & h | o & q) | 0; + c[l >> 2] = s; + q = c[p >> 2] | 0; + o = c[b >> 2] | 0; + h = (c[k >> 2] | 0) - 2067236844 + (c[e + 232 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[r >> 2]) & q ^ o) | 0; + o = c[j >> 2] | 0; + q = c[m >> 2] | 0; + c[g >> 2] = (c[g >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((q | o) & s | q & o) | 0; + c[k >> 2] = n; + o = c[g >> 2] | 0; + q = c[r >> 2] | 0; + s = (c[b >> 2] | 0) - 1933114872 + (c[e + 236 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[p >> 2]) & o ^ q) | 0; + q = c[l >> 2] | 0; + o = c[j >> 2] | 0; + c[m >> 2] = (c[m >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((o | q) & n | o & q) | 0; + c[b >> 2] = h; + q = c[m >> 2] | 0; + o = c[p >> 2] | 0; + n = (c[r >> 2] | 0) - 1866530822 + (c[e + 240 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[g >> 2]) & q ^ o) | 0; + o = c[k >> 2] | 0; + q = c[l >> 2] | 0; + c[j >> 2] = (c[j >> 2] | 0) + n; + s = n + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((q | o) & h | q & o) | 0; + c[r >> 2] = s; + o = c[j >> 2] | 0; + q = c[g >> 2] | 0; + h = (c[p >> 2] | 0) - 1538233109 + (c[e + 244 >> 2] | 0) + ((o >>> 6 | o << 26) ^ (o >>> 11 | o << 21) ^ (o >>> 25 | o << 7)) + ((q ^ c[m >> 2]) & o ^ q) | 0; + q = c[b >> 2] | 0; + o = c[k >> 2] | 0; + c[l >> 2] = (c[l >> 2] | 0) + h; + n = h + ((s >>> 2 | s << 30) ^ (s >>> 13 | s << 19) ^ (s >>> 22 | s << 10)) + ((o | q) & s | o & q) | 0; + c[p >> 2] = n; + q = c[l >> 2] | 0; + o = c[m >> 2] | 0; + s = (c[g >> 2] | 0) - 1090935817 + (c[e + 248 >> 2] | 0) + ((q >>> 6 | q << 26) ^ (q >>> 11 | q << 21) ^ (q >>> 25 | q << 7)) + ((o ^ c[j >> 2]) & q ^ o) | 0; + o = c[r >> 2] | 0; + q = c[b >> 2] | 0; + c[k >> 2] = (c[k >> 2] | 0) + s; + h = s + ((n >>> 2 | n << 30) ^ (n >>> 13 | n << 19) ^ (n >>> 22 | n << 10)) + ((q | o) & n | q & o) | 0; + c[g >> 2] = h; + g = c[k >> 2] | 0; + k = c[j >> 2] | 0; + j = (c[m >> 2] | 0) - 965641998 + (c[e + 252 >> 2] | 0) + ((g >>> 6 | g << 26) ^ (g >>> 11 | g << 21) ^ (g >>> 25 | g << 7)) + ((k ^ c[l >> 2]) & g ^ k) | 0; + k = c[p >> 2] | 0; + p = c[r >> 2] | 0; + c[b >> 2] = (c[b >> 2] | 0) + j; + b = j + ((h >>> 2 | h << 30) ^ (h >>> 13 | h << 19) ^ (h >>> 22 | h << 10)) + ((p | k) & h | p & k) | 0; + c[m >> 2] = b; + c[a >> 2] = (c[a >> 2] | 0) + b; + b = a + 4 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 4 >> 2] | 0); + b = a + 8 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 8 >> 2] | 0); + b = a + 12 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 12 >> 2] | 0); + b = a + 16 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 16 >> 2] | 0); + b = a + 20 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 20 >> 2] | 0); + b = a + 24 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 24 >> 2] | 0); + b = a + 28 | 0; + c[b >> 2] = (c[b >> 2] | 0) + (c[f + 28 >> 2] | 0); + i = d; + return; +} +function bB(b, c) { + b = b | 0; + c = c | 0; + a[b + 3 | 0] = c & 255; + a[b + 2 | 0] = c >>> 8 & 255; + a[b + 1 | 0] = c >>> 16 & 255; + a[b] = c >>> 24 & 255; + return; +} +function bC(a) { + a = a | 0; + return (d[a + 2 | 0] | 0) << 8 | (d[a + 3 | 0] | 0) | (d[a + 1 | 0] | 0) << 16 | (d[a] | 0) << 24 | 0; +} +function bD(a, b) { + a = a | 0; + b = b | 0; + bE(b); + bF(a, b | 0, 32); + cL(b | 0, 0, 104); + return; +} +function bE(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = i; + i = i + 8 | 0; + d = b | 0; + bF(d, a + 32 | 0, 8); + e = (c[a + 36 >> 2] | 0) >>> 3 & 63; + bz(a, 720, (e >>> 0 < 56 ? 56 : 120) - e | 0); + bz(a, d, 8); + i = b; + return; +} +function bF(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = d >>> 2; + if ((e | 0) == 0) { + return; + } else { + f = 0; + } + do { + bB(a + (f << 2) | 0, c[b + (f << 2) >> 2] | 0); + f = f + 1 | 0; + } while (f >>> 0 < e >>> 0); + return; +} +function bG(b, c, d) { + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0; + e = i; + i = i + 96 | 0; + f = e | 0; + if (d >>> 0 > 64) { + g = b | 0; + bt(g); + bz(g, c, d); + h = e + 64 | 0; + bD(h, g); + j = h; + k = 32; + } else { + j = c; + k = d; + } + d = b | 0; + bt(d); + c = f | 0; + cL(c | 0, 54, 64); + if ((k | 0) != 0) { + h = 0; + do { + g = f + h | 0; + a[g] = a[g] ^ a[j + h | 0]; + h = h + 1 | 0; + } while (h >>> 0 < k >>> 0); + } + bz(d, c, 64); + d = b + 104 | 0; + bt(d); + cL(c | 0, 92, 64); + if ((k | 0) == 0) { + bz(d, c, 64); + i = e; + return; + } else { + l = 0; + } + do { + b = f + l | 0; + a[b] = a[b] ^ a[j + l | 0]; + l = l + 1 | 0; + } while (l >>> 0 < k >>> 0); + bz(d, c, 64); + i = e; + return; +} +function bH(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + bz(a | 0, b, c); + return; +} +function bI(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0; + c = i; + i = i + 32 | 0; + d = c | 0; + bD(d, b | 0); + e = b + 104 | 0; + bz(e, d, 32); + bD(a, e); + i = c; + return; +} +function bJ(b, c, d, e, f, g, h, j) { + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + j = j | 0; + var k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + k = i; + i = i + 488 | 0; + l = k | 0; + m = k + 208 | 0; + n = k + 424 | 0; + o = k + 456 | 0; + bG(l, b, c); + bH(l, d, e); + if ((j | 0) == 0) { + i = k; + return; + } + e = k + 416 | 0; + d = m; + p = l; + l = n | 0; + q = o | 0; + r = 0; + s = g >>> 0 < r >>> 0 | g >>> 0 == r >>> 0 & f >>> 0 < 2 >>> 0; + r = 0; + t = 0; + do { + r = r + 1 | 0; + bB(e, r); + cK(d | 0, p | 0, 208) | 0; + bH(m, e, 4); + bI(l, m); + cK(q | 0, l | 0, 32) | 0; + if (!s) { + u = 0; + v = 2; + do { + bG(m, b, c); + bH(m, l, 32); + bI(l, m); + w = 0; + do { + x = o + w | 0; + a[x] = a[x] ^ a[n + w | 0]; + w = w + 1 | 0; + } while ((w | 0) < 32); + v = cN(v, u, 1, 0) | 0; + u = H; + } while (!(u >>> 0 > g >>> 0 | u >>> 0 == g >>> 0 & v >>> 0 > f >>> 0)); + } + v = j - t | 0; + u = v >>> 0 > 32 ? 32 : v; + v = h + t | 0; + cK(v | 0, q | 0, u) | 0; + t = r << 5; + } while (t >>> 0 < j >>> 0); + i = k; + return; +} +function bK(a, b) { + a = a | 0; + b = b | 0; + var d = 0; + d = 0; + do { + c[a + (d << 2) >> 2] = bC(b + (d << 2) | 0) | 0; + d = d + 1 | 0; + } while (d >>> 0 < 16); + return; +} +function bL(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0, ae = 0, af = 0, ag = 0, ah = 0, ai = 0, aj = 0, ak = 0, al = 0, am = 0, an = 0, ao = 0, ap = 0, aq = 0, as = 0, at = 0, av = 0, aw = 0, ax = 0, ay = 0, az = 0, aA = 0, aB = 0, aC = 0, aD = 0, aE = 0, aF = 0, aG = 0, aH = 0, aI = 0; + do { + if (a >>> 0 < 245) { + if (a >>> 0 < 11) { + b = 16; + } else { + b = a + 11 & -8; + } + d = b >>> 3; + e = c[208] | 0; + f = e >>> (d >>> 0); + if ((f & 3 | 0) != 0) { + g = (f & 1 ^ 1) + d | 0; + h = g << 1; + i = 872 + (h << 2) | 0; + j = 872 + (h + 2 << 2) | 0; + h = c[j >> 2] | 0; + k = h + 8 | 0; + l = c[k >> 2] | 0; + do { + if ((i | 0) == (l | 0)) { + c[208] = e & ~(1 << g); + } else { + if (l >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + m = l + 12 | 0; + if ((c[m >> 2] | 0) == (h | 0)) { + c[m >> 2] = i; + c[j >> 2] = l; + break; + } else { + au(); + return 0; + } + } + } while (0); + l = g << 3; + c[h + 4 >> 2] = l | 3; + j = h + (l | 4) | 0; + c[j >> 2] = c[j >> 2] | 1; + n = k; + return n | 0; + } + if (b >>> 0 <= (c[210] | 0) >>> 0) { + o = b; + break; + } + if ((f | 0) != 0) { + j = 2 << d; + l = f << d & (j | -j); + j = (l & -l) - 1 | 0; + l = j >>> 12 & 16; + i = j >>> (l >>> 0); + j = i >>> 5 & 8; + m = i >>> (j >>> 0); + i = m >>> 2 & 4; + p = m >>> (i >>> 0); + m = p >>> 1 & 2; + q = p >>> (m >>> 0); + p = q >>> 1 & 1; + r = (j | l | i | m | p) + (q >>> (p >>> 0)) | 0; + p = r << 1; + q = 872 + (p << 2) | 0; + m = 872 + (p + 2 << 2) | 0; + p = c[m >> 2] | 0; + i = p + 8 | 0; + l = c[i >> 2] | 0; + do { + if ((q | 0) == (l | 0)) { + c[208] = e & ~(1 << r); + } else { + if (l >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + j = l + 12 | 0; + if ((c[j >> 2] | 0) == (p | 0)) { + c[j >> 2] = q; + c[m >> 2] = l; + break; + } else { + au(); + return 0; + } + } + } while (0); + l = r << 3; + m = l - b | 0; + c[p + 4 >> 2] = b | 3; + q = p; + e = q + b | 0; + c[q + (b | 4) >> 2] = m | 1; + c[q + l >> 2] = m; + l = c[210] | 0; + if ((l | 0) != 0) { + q = c[213] | 0; + d = l >>> 3; + l = d << 1; + f = 872 + (l << 2) | 0; + k = c[208] | 0; + h = 1 << d; + do { + if ((k & h | 0) == 0) { + c[208] = k | h; + s = f; + t = 872 + (l + 2 << 2) | 0; + } else { + d = 872 + (l + 2 << 2) | 0; + g = c[d >> 2] | 0; + if (g >>> 0 >= (c[212] | 0) >>> 0) { + s = g; + t = d; + break; + } + au(); + return 0; + } + } while (0); + c[t >> 2] = q; + c[s + 12 >> 2] = q; + c[q + 8 >> 2] = s; + c[q + 12 >> 2] = f; + } + c[210] = m; + c[213] = e; + n = i; + return n | 0; + } + l = c[209] | 0; + if ((l | 0) == 0) { + o = b; + break; + } + h = (l & -l) - 1 | 0; + l = h >>> 12 & 16; + k = h >>> (l >>> 0); + h = k >>> 5 & 8; + p = k >>> (h >>> 0); + k = p >>> 2 & 4; + r = p >>> (k >>> 0); + p = r >>> 1 & 2; + d = r >>> (p >>> 0); + r = d >>> 1 & 1; + g = c[1136 + ((h | l | k | p | r) + (d >>> (r >>> 0)) << 2) >> 2] | 0; + r = g; + d = g; + p = (c[g + 4 >> 2] & -8) - b | 0; + while (1) { + g = c[r + 16 >> 2] | 0; + if ((g | 0) == 0) { + k = c[r + 20 >> 2] | 0; + if ((k | 0) == 0) { + break; + } else { + u = k; + } + } else { + u = g; + } + g = (c[u + 4 >> 2] & -8) - b | 0; + k = g >>> 0 < p >>> 0; + r = u; + d = k ? u : d; + p = k ? g : p; + } + r = d; + i = c[212] | 0; + if (r >>> 0 < i >>> 0) { + au(); + return 0; + } + e = r + b | 0; + m = e; + if (r >>> 0 >= e >>> 0) { + au(); + return 0; + } + e = c[d + 24 >> 2] | 0; + f = c[d + 12 >> 2] | 0; + do { + if ((f | 0) == (d | 0)) { + q = d + 20 | 0; + g = c[q >> 2] | 0; + if ((g | 0) == 0) { + k = d + 16 | 0; + l = c[k >> 2] | 0; + if ((l | 0) == 0) { + v = 0; + break; + } else { + w = l; + x = k; + } + } else { + w = g; + x = q; + } + while (1) { + q = w + 20 | 0; + g = c[q >> 2] | 0; + if ((g | 0) != 0) { + w = g; + x = q; + continue; + } + q = w + 16 | 0; + g = c[q >> 2] | 0; + if ((g | 0) == 0) { + break; + } else { + w = g; + x = q; + } + } + if (x >>> 0 < i >>> 0) { + au(); + return 0; + } else { + c[x >> 2] = 0; + v = w; + break; + } + } else { + q = c[d + 8 >> 2] | 0; + if (q >>> 0 < i >>> 0) { + au(); + return 0; + } + g = q + 12 | 0; + if ((c[g >> 2] | 0) != (d | 0)) { + au(); + return 0; + } + k = f + 8 | 0; + if ((c[k >> 2] | 0) == (d | 0)) { + c[g >> 2] = f; + c[k >> 2] = q; + v = f; + break; + } else { + au(); + return 0; + } + } + } while (0); + L223 : do { + if ((e | 0) != 0) { + f = d + 28 | 0; + i = 1136 + (c[f >> 2] << 2) | 0; + do { + if ((d | 0) == (c[i >> 2] | 0)) { + c[i >> 2] = v; + if ((v | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[f >> 2]); + break L223; + } else { + if (e >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + q = e + 16 | 0; + if ((c[q >> 2] | 0) == (d | 0)) { + c[q >> 2] = v; + } else { + c[e + 20 >> 2] = v; + } + if ((v | 0) == 0) { + break L223; + } + } + } while (0); + if (v >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + c[v + 24 >> 2] = e; + f = c[d + 16 >> 2] | 0; + do { + if ((f | 0) != 0) { + if (f >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[v + 16 >> 2] = f; + c[f + 24 >> 2] = v; + break; + } + } + } while (0); + f = c[d + 20 >> 2] | 0; + if ((f | 0) == 0) { + break; + } + if (f >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[v + 20 >> 2] = f; + c[f + 24 >> 2] = v; + break; + } + } + } while (0); + if (p >>> 0 < 16) { + e = p + b | 0; + c[d + 4 >> 2] = e | 3; + f = r + (e + 4) | 0; + c[f >> 2] = c[f >> 2] | 1; + } else { + c[d + 4 >> 2] = b | 3; + c[r + (b | 4) >> 2] = p | 1; + c[r + (p + b) >> 2] = p; + f = c[210] | 0; + if ((f | 0) != 0) { + e = c[213] | 0; + i = f >>> 3; + f = i << 1; + q = 872 + (f << 2) | 0; + k = c[208] | 0; + g = 1 << i; + do { + if ((k & g | 0) == 0) { + c[208] = k | g; + y = q; + z = 872 + (f + 2 << 2) | 0; + } else { + i = 872 + (f + 2 << 2) | 0; + l = c[i >> 2] | 0; + if (l >>> 0 >= (c[212] | 0) >>> 0) { + y = l; + z = i; + break; + } + au(); + return 0; + } + } while (0); + c[z >> 2] = e; + c[y + 12 >> 2] = e; + c[e + 8 >> 2] = y; + c[e + 12 >> 2] = q; + } + c[210] = p; + c[213] = m; + } + f = d + 8 | 0; + if ((f | 0) == 0) { + o = b; + break; + } else { + n = f; + } + return n | 0; + } else { + if (a >>> 0 > 4294967231) { + o = -1; + break; + } + f = a + 11 | 0; + g = f & -8; + k = c[209] | 0; + if ((k | 0) == 0) { + o = g; + break; + } + r = -g | 0; + i = f >>> 8; + do { + if ((i | 0) == 0) { + A = 0; + } else { + if (g >>> 0 > 16777215) { + A = 31; + break; + } + f = (i + 1048320 | 0) >>> 16 & 8; + l = i << f; + h = (l + 520192 | 0) >>> 16 & 4; + j = l << h; + l = (j + 245760 | 0) >>> 16 & 2; + B = 14 - (h | f | l) + (j << l >>> 15) | 0; + A = g >>> ((B + 7 | 0) >>> 0) & 1 | B << 1; + } + } while (0); + i = c[1136 + (A << 2) >> 2] | 0; + L271 : do { + if ((i | 0) == 0) { + C = 0; + D = r; + E = 0; + } else { + if ((A | 0) == 31) { + F = 0; + } else { + F = 25 - (A >>> 1) | 0; + } + d = 0; + m = r; + p = i; + q = g << F; + e = 0; + while (1) { + B = c[p + 4 >> 2] & -8; + l = B - g | 0; + if (l >>> 0 < m >>> 0) { + if ((B | 0) == (g | 0)) { + C = p; + D = l; + E = p; + break L271; + } else { + G = p; + H = l; + } + } else { + G = d; + H = m; + } + l = c[p + 20 >> 2] | 0; + B = c[p + 16 + (q >>> 31 << 2) >> 2] | 0; + j = (l | 0) == 0 | (l | 0) == (B | 0) ? e : l; + if ((B | 0) == 0) { + C = G; + D = H; + E = j; + break; + } else { + d = G; + m = H; + p = B; + q = q << 1; + e = j; + } + } + } + } while (0); + if ((E | 0) == 0 & (C | 0) == 0) { + i = 2 << A; + r = k & (i | -i); + if ((r | 0) == 0) { + o = g; + break; + } + i = (r & -r) - 1 | 0; + r = i >>> 12 & 16; + e = i >>> (r >>> 0); + i = e >>> 5 & 8; + q = e >>> (i >>> 0); + e = q >>> 2 & 4; + p = q >>> (e >>> 0); + q = p >>> 1 & 2; + m = p >>> (q >>> 0); + p = m >>> 1 & 1; + I = c[1136 + ((i | r | e | q | p) + (m >>> (p >>> 0)) << 2) >> 2] | 0; + } else { + I = E; + } + if ((I | 0) == 0) { + J = D; + K = C; + } else { + p = I; + m = D; + q = C; + while (1) { + e = (c[p + 4 >> 2] & -8) - g | 0; + r = e >>> 0 < m >>> 0; + i = r ? e : m; + e = r ? p : q; + r = c[p + 16 >> 2] | 0; + if ((r | 0) != 0) { + p = r; + m = i; + q = e; + continue; + } + r = c[p + 20 >> 2] | 0; + if ((r | 0) == 0) { + J = i; + K = e; + break; + } else { + p = r; + m = i; + q = e; + } + } + } + if ((K | 0) == 0) { + o = g; + break; + } + if (J >>> 0 >= ((c[210] | 0) - g | 0) >>> 0) { + o = g; + break; + } + q = K; + m = c[212] | 0; + if (q >>> 0 < m >>> 0) { + au(); + return 0; + } + p = q + g | 0; + k = p; + if (q >>> 0 >= p >>> 0) { + au(); + return 0; + } + e = c[K + 24 >> 2] | 0; + i = c[K + 12 >> 2] | 0; + do { + if ((i | 0) == (K | 0)) { + r = K + 20 | 0; + d = c[r >> 2] | 0; + if ((d | 0) == 0) { + j = K + 16 | 0; + B = c[j >> 2] | 0; + if ((B | 0) == 0) { + L = 0; + break; + } else { + M = B; + N = j; + } + } else { + M = d; + N = r; + } + while (1) { + r = M + 20 | 0; + d = c[r >> 2] | 0; + if ((d | 0) != 0) { + M = d; + N = r; + continue; + } + r = M + 16 | 0; + d = c[r >> 2] | 0; + if ((d | 0) == 0) { + break; + } else { + M = d; + N = r; + } + } + if (N >>> 0 < m >>> 0) { + au(); + return 0; + } else { + c[N >> 2] = 0; + L = M; + break; + } + } else { + r = c[K + 8 >> 2] | 0; + if (r >>> 0 < m >>> 0) { + au(); + return 0; + } + d = r + 12 | 0; + if ((c[d >> 2] | 0) != (K | 0)) { + au(); + return 0; + } + j = i + 8 | 0; + if ((c[j >> 2] | 0) == (K | 0)) { + c[d >> 2] = i; + c[j >> 2] = r; + L = i; + break; + } else { + au(); + return 0; + } + } + } while (0); + L321 : do { + if ((e | 0) != 0) { + i = K + 28 | 0; + m = 1136 + (c[i >> 2] << 2) | 0; + do { + if ((K | 0) == (c[m >> 2] | 0)) { + c[m >> 2] = L; + if ((L | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[i >> 2]); + break L321; + } else { + if (e >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + r = e + 16 | 0; + if ((c[r >> 2] | 0) == (K | 0)) { + c[r >> 2] = L; + } else { + c[e + 20 >> 2] = L; + } + if ((L | 0) == 0) { + break L321; + } + } + } while (0); + if (L >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + c[L + 24 >> 2] = e; + i = c[K + 16 >> 2] | 0; + do { + if ((i | 0) != 0) { + if (i >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[L + 16 >> 2] = i; + c[i + 24 >> 2] = L; + break; + } + } + } while (0); + i = c[K + 20 >> 2] | 0; + if ((i | 0) == 0) { + break; + } + if (i >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[L + 20 >> 2] = i; + c[i + 24 >> 2] = L; + break; + } + } + } while (0); + do { + if (J >>> 0 < 16) { + e = J + g | 0; + c[K + 4 >> 2] = e | 3; + i = q + (e + 4) | 0; + c[i >> 2] = c[i >> 2] | 1; + } else { + c[K + 4 >> 2] = g | 3; + c[q + (g | 4) >> 2] = J | 1; + c[q + (J + g) >> 2] = J; + i = J >>> 3; + if (J >>> 0 < 256) { + e = i << 1; + m = 872 + (e << 2) | 0; + r = c[208] | 0; + j = 1 << i; + do { + if ((r & j | 0) == 0) { + c[208] = r | j; + O = m; + P = 872 + (e + 2 << 2) | 0; + } else { + i = 872 + (e + 2 << 2) | 0; + d = c[i >> 2] | 0; + if (d >>> 0 >= (c[212] | 0) >>> 0) { + O = d; + P = i; + break; + } + au(); + return 0; + } + } while (0); + c[P >> 2] = k; + c[O + 12 >> 2] = k; + c[q + (g + 8) >> 2] = O; + c[q + (g + 12) >> 2] = m; + break; + } + e = p; + j = J >>> 8; + do { + if ((j | 0) == 0) { + Q = 0; + } else { + if (J >>> 0 > 16777215) { + Q = 31; + break; + } + r = (j + 1048320 | 0) >>> 16 & 8; + i = j << r; + d = (i + 520192 | 0) >>> 16 & 4; + B = i << d; + i = (B + 245760 | 0) >>> 16 & 2; + l = 14 - (d | r | i) + (B << i >>> 15) | 0; + Q = J >>> ((l + 7 | 0) >>> 0) & 1 | l << 1; + } + } while (0); + j = 1136 + (Q << 2) | 0; + c[q + (g + 28) >> 2] = Q; + c[q + (g + 20) >> 2] = 0; + c[q + (g + 16) >> 2] = 0; + m = c[209] | 0; + l = 1 << Q; + if ((m & l | 0) == 0) { + c[209] = m | l; + c[j >> 2] = e; + c[q + (g + 24) >> 2] = j; + c[q + (g + 12) >> 2] = e; + c[q + (g + 8) >> 2] = e; + break; + } + if ((Q | 0) == 31) { + R = 0; + } else { + R = 25 - (Q >>> 1) | 0; + } + l = J << R; + m = c[j >> 2] | 0; + while (1) { + if ((c[m + 4 >> 2] & -8 | 0) == (J | 0)) { + break; + } + S = m + 16 + (l >>> 31 << 2) | 0; + j = c[S >> 2] | 0; + if ((j | 0) == 0) { + T = 262; + break; + } else { + l = l << 1; + m = j; + } + } + if ((T | 0) == 262) { + if (S >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[S >> 2] = e; + c[q + (g + 24) >> 2] = m; + c[q + (g + 12) >> 2] = e; + c[q + (g + 8) >> 2] = e; + break; + } + } + l = m + 8 | 0; + j = c[l >> 2] | 0; + i = c[212] | 0; + if (m >>> 0 < i >>> 0) { + au(); + return 0; + } + if (j >>> 0 < i >>> 0) { + au(); + return 0; + } else { + c[j + 12 >> 2] = e; + c[l >> 2] = e; + c[q + (g + 8) >> 2] = j; + c[q + (g + 12) >> 2] = m; + c[q + (g + 24) >> 2] = 0; + break; + } + } + } while (0); + q = K + 8 | 0; + if ((q | 0) == 0) { + o = g; + break; + } else { + n = q; + } + return n | 0; + } + } while (0); + K = c[210] | 0; + if (o >>> 0 <= K >>> 0) { + S = K - o | 0; + J = c[213] | 0; + if (S >>> 0 > 15) { + R = J; + c[213] = R + o; + c[210] = S; + c[R + (o + 4) >> 2] = S | 1; + c[R + K >> 2] = S; + c[J + 4 >> 2] = o | 3; + } else { + c[210] = 0; + c[213] = 0; + c[J + 4 >> 2] = K | 3; + S = J + (K + 4) | 0; + c[S >> 2] = c[S >> 2] | 1; + } + n = J + 8 | 0; + return n | 0; + } + J = c[211] | 0; + if (o >>> 0 < J >>> 0) { + S = J - o | 0; + c[211] = S; + J = c[214] | 0; + K = J; + c[214] = K + o; + c[K + (o + 4) >> 2] = S | 1; + c[J + 4 >> 2] = o | 3; + n = J + 8 | 0; + return n | 0; + } + do { + if ((c[200] | 0) == 0) { + J = ar(8) | 0; + if ((J - 1 & J | 0) == 0) { + c[202] = J; + c[201] = J; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + return 0; + } + } + } while (0); + J = o + 48 | 0; + S = c[202] | 0; + K = o + 47 | 0; + R = S + K | 0; + Q = -S | 0; + S = R & Q; + if (S >>> 0 <= o >>> 0) { + n = 0; + return n | 0; + } + O = c[318] | 0; + do { + if ((O | 0) != 0) { + P = c[316] | 0; + L = P + S | 0; + if (L >>> 0 <= P >>> 0 | L >>> 0 > O >>> 0) { + n = 0; + } else { + break; + } + return n | 0; + } + } while (0); + L413 : do { + if ((c[319] & 4 | 0) == 0) { + O = c[214] | 0; + L415 : do { + if ((O | 0) == 0) { + T = 292; + } else { + L = O; + P = 1280; + while (1) { + U = P | 0; + M = c[U >> 2] | 0; + if (M >>> 0 <= L >>> 0) { + V = P + 4 | 0; + if ((M + (c[V >> 2] | 0) | 0) >>> 0 > L >>> 0) { + break; + } + } + M = c[P + 8 >> 2] | 0; + if ((M | 0) == 0) { + T = 292; + break L415; + } else { + P = M; + } + } + if ((P | 0) == 0) { + T = 292; + break; + } + L = R - (c[211] | 0) & Q; + if (L >>> 0 >= 2147483647) { + W = 0; + break; + } + m = aV(L | 0) | 0; + e = (m | 0) == ((c[U >> 2] | 0) + (c[V >> 2] | 0) | 0); + X = e ? m : -1; + Y = e ? L : 0; + Z = m; + _ = L; + T = 301; + } + } while (0); + do { + if ((T | 0) == 292) { + O = aV(0) | 0; + if ((O | 0) == -1) { + W = 0; + break; + } + g = O; + L = c[201] | 0; + m = L - 1 | 0; + if ((m & g | 0) == 0) { + $ = S; + } else { + $ = S - g + (m + g & -L) | 0; + } + L = c[316] | 0; + g = L + $ | 0; + if (!($ >>> 0 > o >>> 0 & $ >>> 0 < 2147483647)) { + W = 0; + break; + } + m = c[318] | 0; + if ((m | 0) != 0) { + if (g >>> 0 <= L >>> 0 | g >>> 0 > m >>> 0) { + W = 0; + break; + } + } + m = aV($ | 0) | 0; + g = (m | 0) == (O | 0); + X = g ? O : -1; + Y = g ? $ : 0; + Z = m; + _ = $; + T = 301; + } + } while (0); + L435 : do { + if ((T | 0) == 301) { + m = -_ | 0; + if ((X | 0) != -1) { + aa = Y; + ab = X; + T = 312; + break L413; + } + do { + if ((Z | 0) != -1 & _ >>> 0 < 2147483647 & _ >>> 0 < J >>> 0) { + g = c[202] | 0; + O = K - _ + g & -g; + if (O >>> 0 >= 2147483647) { + ac = _; + break; + } + if ((aV(O | 0) | 0) == -1) { + aV(m | 0) | 0; + W = Y; + break L435; + } else { + ac = O + _ | 0; + break; + } + } else { + ac = _; + } + } while (0); + if ((Z | 0) == -1) { + W = Y; + } else { + aa = ac; + ab = Z; + T = 312; + break L413; + } + } + } while (0); + c[319] = c[319] | 4; + ad = W; + T = 309; + } else { + ad = 0; + T = 309; + } + } while (0); + do { + if ((T | 0) == 309) { + if (S >>> 0 >= 2147483647) { + break; + } + W = aV(S | 0) | 0; + Z = aV(0) | 0; + if (!((Z | 0) != -1 & (W | 0) != -1 & W >>> 0 < Z >>> 0)) { + break; + } + ac = Z - W | 0; + Z = ac >>> 0 > (o + 40 | 0) >>> 0; + Y = Z ? W : -1; + if ((Y | 0) != -1) { + aa = Z ? ac : ad; + ab = Y; + T = 312; + } + } + } while (0); + do { + if ((T | 0) == 312) { + ad = (c[316] | 0) + aa | 0; + c[316] = ad; + if (ad >>> 0 > (c[317] | 0) >>> 0) { + c[317] = ad; + } + ad = c[214] | 0; + L455 : do { + if ((ad | 0) == 0) { + S = c[212] | 0; + if ((S | 0) == 0 | ab >>> 0 < S >>> 0) { + c[212] = ab; + } + c[320] = ab; + c[321] = aa; + c[323] = 0; + c[217] = c[200]; + c[216] = -1; + S = 0; + do { + Y = S << 1; + ac = 872 + (Y << 2) | 0; + c[872 + (Y + 3 << 2) >> 2] = ac; + c[872 + (Y + 2 << 2) >> 2] = ac; + S = S + 1 | 0; + } while (S >>> 0 < 32); + S = ab + 8 | 0; + if ((S & 7 | 0) == 0) { + ae = 0; + } else { + ae = -S & 7; + } + S = aa - 40 - ae | 0; + c[214] = ab + ae; + c[211] = S; + c[ab + (ae + 4) >> 2] = S | 1; + c[ab + (aa - 36) >> 2] = 40; + c[215] = c[204]; + } else { + S = 1280; + while (1) { + af = c[S >> 2] | 0; + ag = S + 4 | 0; + ah = c[ag >> 2] | 0; + if ((ab | 0) == (af + ah | 0)) { + T = 324; + break; + } + ac = c[S + 8 >> 2] | 0; + if ((ac | 0) == 0) { + break; + } else { + S = ac; + } + } + do { + if ((T | 0) == 324) { + if ((c[S + 12 >> 2] & 8 | 0) != 0) { + break; + } + ac = ad; + if (!(ac >>> 0 >= af >>> 0 & ac >>> 0 < ab >>> 0)) { + break; + } + c[ag >> 2] = ah + aa; + ac = c[214] | 0; + Y = (c[211] | 0) + aa | 0; + Z = ac; + W = ac + 8 | 0; + if ((W & 7 | 0) == 0) { + ai = 0; + } else { + ai = -W & 7; + } + W = Y - ai | 0; + c[214] = Z + ai; + c[211] = W; + c[Z + (ai + 4) >> 2] = W | 1; + c[Z + (Y + 4) >> 2] = 40; + c[215] = c[204]; + break L455; + } + } while (0); + if (ab >>> 0 < (c[212] | 0) >>> 0) { + c[212] = ab; + } + S = ab + aa | 0; + Y = 1280; + while (1) { + aj = Y | 0; + if ((c[aj >> 2] | 0) == (S | 0)) { + T = 334; + break; + } + Z = c[Y + 8 >> 2] | 0; + if ((Z | 0) == 0) { + break; + } else { + Y = Z; + } + } + do { + if ((T | 0) == 334) { + if ((c[Y + 12 >> 2] & 8 | 0) != 0) { + break; + } + c[aj >> 2] = ab; + S = Y + 4 | 0; + c[S >> 2] = (c[S >> 2] | 0) + aa; + S = ab + 8 | 0; + if ((S & 7 | 0) == 0) { + ak = 0; + } else { + ak = -S & 7; + } + S = ab + (aa + 8) | 0; + if ((S & 7 | 0) == 0) { + al = 0; + } else { + al = -S & 7; + } + S = ab + (al + aa) | 0; + Z = S; + W = ak + o | 0; + ac = ab + W | 0; + _ = ac; + K = S - (ab + ak) - o | 0; + c[ab + (ak + 4) >> 2] = o | 3; + do { + if ((Z | 0) == (c[214] | 0)) { + J = (c[211] | 0) + K | 0; + c[211] = J; + c[214] = _; + c[ab + (W + 4) >> 2] = J | 1; + } else { + if ((Z | 0) == (c[213] | 0)) { + J = (c[210] | 0) + K | 0; + c[210] = J; + c[213] = _; + c[ab + (W + 4) >> 2] = J | 1; + c[ab + (J + W) >> 2] = J; + break; + } + J = aa + 4 | 0; + X = c[ab + (J + al) >> 2] | 0; + if ((X & 3 | 0) == 1) { + $ = X & -8; + V = X >>> 3; + L500 : do { + if (X >>> 0 < 256) { + U = c[ab + ((al | 8) + aa) >> 2] | 0; + Q = c[ab + (aa + 12 + al) >> 2] | 0; + R = 872 + (V << 1 << 2) | 0; + do { + if ((U | 0) != (R | 0)) { + if (U >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + if ((c[U + 12 >> 2] | 0) == (Z | 0)) { + break; + } + au(); + return 0; + } + } while (0); + if ((Q | 0) == (U | 0)) { + c[208] = c[208] & ~(1 << V); + break; + } + do { + if ((Q | 0) == (R | 0)) { + am = Q + 8 | 0; + } else { + if (Q >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + m = Q + 8 | 0; + if ((c[m >> 2] | 0) == (Z | 0)) { + am = m; + break; + } + au(); + return 0; + } + } while (0); + c[U + 12 >> 2] = Q; + c[am >> 2] = U; + } else { + R = S; + m = c[ab + ((al | 24) + aa) >> 2] | 0; + P = c[ab + (aa + 12 + al) >> 2] | 0; + do { + if ((P | 0) == (R | 0)) { + O = al | 16; + g = ab + (J + O) | 0; + L = c[g >> 2] | 0; + if ((L | 0) == 0) { + e = ab + (O + aa) | 0; + O = c[e >> 2] | 0; + if ((O | 0) == 0) { + an = 0; + break; + } else { + ao = O; + ap = e; + } + } else { + ao = L; + ap = g; + } + while (1) { + g = ao + 20 | 0; + L = c[g >> 2] | 0; + if ((L | 0) != 0) { + ao = L; + ap = g; + continue; + } + g = ao + 16 | 0; + L = c[g >> 2] | 0; + if ((L | 0) == 0) { + break; + } else { + ao = L; + ap = g; + } + } + if (ap >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[ap >> 2] = 0; + an = ao; + break; + } + } else { + g = c[ab + ((al | 8) + aa) >> 2] | 0; + if (g >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + L = g + 12 | 0; + if ((c[L >> 2] | 0) != (R | 0)) { + au(); + return 0; + } + e = P + 8 | 0; + if ((c[e >> 2] | 0) == (R | 0)) { + c[L >> 2] = P; + c[e >> 2] = g; + an = P; + break; + } else { + au(); + return 0; + } + } + } while (0); + if ((m | 0) == 0) { + break; + } + P = ab + (aa + 28 + al) | 0; + U = 1136 + (c[P >> 2] << 2) | 0; + do { + if ((R | 0) == (c[U >> 2] | 0)) { + c[U >> 2] = an; + if ((an | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[P >> 2]); + break L500; + } else { + if (m >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + Q = m + 16 | 0; + if ((c[Q >> 2] | 0) == (R | 0)) { + c[Q >> 2] = an; + } else { + c[m + 20 >> 2] = an; + } + if ((an | 0) == 0) { + break L500; + } + } + } while (0); + if (an >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + c[an + 24 >> 2] = m; + R = al | 16; + P = c[ab + (R + aa) >> 2] | 0; + do { + if ((P | 0) != 0) { + if (P >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[an + 16 >> 2] = P; + c[P + 24 >> 2] = an; + break; + } + } + } while (0); + P = c[ab + (J + R) >> 2] | 0; + if ((P | 0) == 0) { + break; + } + if (P >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[an + 20 >> 2] = P; + c[P + 24 >> 2] = an; + break; + } + } + } while (0); + aq = ab + (($ | al) + aa) | 0; + as = $ + K | 0; + } else { + aq = Z; + as = K; + } + J = aq + 4 | 0; + c[J >> 2] = c[J >> 2] & -2; + c[ab + (W + 4) >> 2] = as | 1; + c[ab + (as + W) >> 2] = as; + J = as >>> 3; + if (as >>> 0 < 256) { + V = J << 1; + X = 872 + (V << 2) | 0; + P = c[208] | 0; + m = 1 << J; + do { + if ((P & m | 0) == 0) { + c[208] = P | m; + at = X; + av = 872 + (V + 2 << 2) | 0; + } else { + J = 872 + (V + 2 << 2) | 0; + U = c[J >> 2] | 0; + if (U >>> 0 >= (c[212] | 0) >>> 0) { + at = U; + av = J; + break; + } + au(); + return 0; + } + } while (0); + c[av >> 2] = _; + c[at + 12 >> 2] = _; + c[ab + (W + 8) >> 2] = at; + c[ab + (W + 12) >> 2] = X; + break; + } + V = ac; + m = as >>> 8; + do { + if ((m | 0) == 0) { + aw = 0; + } else { + if (as >>> 0 > 16777215) { + aw = 31; + break; + } + P = (m + 1048320 | 0) >>> 16 & 8; + $ = m << P; + J = ($ + 520192 | 0) >>> 16 & 4; + U = $ << J; + $ = (U + 245760 | 0) >>> 16 & 2; + Q = 14 - (J | P | $) + (U << $ >>> 15) | 0; + aw = as >>> ((Q + 7 | 0) >>> 0) & 1 | Q << 1; + } + } while (0); + m = 1136 + (aw << 2) | 0; + c[ab + (W + 28) >> 2] = aw; + c[ab + (W + 20) >> 2] = 0; + c[ab + (W + 16) >> 2] = 0; + X = c[209] | 0; + Q = 1 << aw; + if ((X & Q | 0) == 0) { + c[209] = X | Q; + c[m >> 2] = V; + c[ab + (W + 24) >> 2] = m; + c[ab + (W + 12) >> 2] = V; + c[ab + (W + 8) >> 2] = V; + break; + } + if ((aw | 0) == 31) { + ax = 0; + } else { + ax = 25 - (aw >>> 1) | 0; + } + Q = as << ax; + X = c[m >> 2] | 0; + while (1) { + if ((c[X + 4 >> 2] & -8 | 0) == (as | 0)) { + break; + } + ay = X + 16 + (Q >>> 31 << 2) | 0; + m = c[ay >> 2] | 0; + if ((m | 0) == 0) { + T = 407; + break; + } else { + Q = Q << 1; + X = m; + } + } + if ((T | 0) == 407) { + if (ay >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[ay >> 2] = V; + c[ab + (W + 24) >> 2] = X; + c[ab + (W + 12) >> 2] = V; + c[ab + (W + 8) >> 2] = V; + break; + } + } + Q = X + 8 | 0; + m = c[Q >> 2] | 0; + $ = c[212] | 0; + if (X >>> 0 < $ >>> 0) { + au(); + return 0; + } + if (m >>> 0 < $ >>> 0) { + au(); + return 0; + } else { + c[m + 12 >> 2] = V; + c[Q >> 2] = V; + c[ab + (W + 8) >> 2] = m; + c[ab + (W + 12) >> 2] = X; + c[ab + (W + 24) >> 2] = 0; + break; + } + } + } while (0); + n = ab + (ak | 8) | 0; + return n | 0; + } + } while (0); + Y = ad; + W = 1280; + while (1) { + az = c[W >> 2] | 0; + if (az >>> 0 <= Y >>> 0) { + aA = c[W + 4 >> 2] | 0; + aB = az + aA | 0; + if (aB >>> 0 > Y >>> 0) { + break; + } + } + W = c[W + 8 >> 2] | 0; + } + W = az + (aA - 39) | 0; + if ((W & 7 | 0) == 0) { + aC = 0; + } else { + aC = -W & 7; + } + W = az + (aA - 47 + aC) | 0; + ac = W >>> 0 < (ad + 16 | 0) >>> 0 ? Y : W; + W = ac + 8 | 0; + _ = ab + 8 | 0; + if ((_ & 7 | 0) == 0) { + aD = 0; + } else { + aD = -_ & 7; + } + _ = aa - 40 - aD | 0; + c[214] = ab + aD; + c[211] = _; + c[ab + (aD + 4) >> 2] = _ | 1; + c[ab + (aa - 36) >> 2] = 40; + c[215] = c[204]; + c[ac + 4 >> 2] = 27; + c[W >> 2] = c[320]; + c[W + 4 >> 2] = c[1284 >> 2]; + c[W + 8 >> 2] = c[1288 >> 2]; + c[W + 12 >> 2] = c[1292 >> 2]; + c[320] = ab; + c[321] = aa; + c[323] = 0; + c[322] = W; + W = ac + 28 | 0; + c[W >> 2] = 7; + if ((ac + 32 | 0) >>> 0 < aB >>> 0) { + _ = W; + while (1) { + W = _ + 4 | 0; + c[W >> 2] = 7; + if ((_ + 8 | 0) >>> 0 < aB >>> 0) { + _ = W; + } else { + break; + } + } + } + if ((ac | 0) == (Y | 0)) { + break; + } + _ = ac - ad | 0; + W = Y + (_ + 4) | 0; + c[W >> 2] = c[W >> 2] & -2; + c[ad + 4 >> 2] = _ | 1; + c[Y + _ >> 2] = _; + W = _ >>> 3; + if (_ >>> 0 < 256) { + K = W << 1; + Z = 872 + (K << 2) | 0; + S = c[208] | 0; + m = 1 << W; + do { + if ((S & m | 0) == 0) { + c[208] = S | m; + aE = Z; + aF = 872 + (K + 2 << 2) | 0; + } else { + W = 872 + (K + 2 << 2) | 0; + Q = c[W >> 2] | 0; + if (Q >>> 0 >= (c[212] | 0) >>> 0) { + aE = Q; + aF = W; + break; + } + au(); + return 0; + } + } while (0); + c[aF >> 2] = ad; + c[aE + 12 >> 2] = ad; + c[ad + 8 >> 2] = aE; + c[ad + 12 >> 2] = Z; + break; + } + K = ad; + m = _ >>> 8; + do { + if ((m | 0) == 0) { + aG = 0; + } else { + if (_ >>> 0 > 16777215) { + aG = 31; + break; + } + S = (m + 1048320 | 0) >>> 16 & 8; + Y = m << S; + ac = (Y + 520192 | 0) >>> 16 & 4; + W = Y << ac; + Y = (W + 245760 | 0) >>> 16 & 2; + Q = 14 - (ac | S | Y) + (W << Y >>> 15) | 0; + aG = _ >>> ((Q + 7 | 0) >>> 0) & 1 | Q << 1; + } + } while (0); + m = 1136 + (aG << 2) | 0; + c[ad + 28 >> 2] = aG; + c[ad + 20 >> 2] = 0; + c[ad + 16 >> 2] = 0; + Z = c[209] | 0; + Q = 1 << aG; + if ((Z & Q | 0) == 0) { + c[209] = Z | Q; + c[m >> 2] = K; + c[ad + 24 >> 2] = m; + c[ad + 12 >> 2] = ad; + c[ad + 8 >> 2] = ad; + break; + } + if ((aG | 0) == 31) { + aH = 0; + } else { + aH = 25 - (aG >>> 1) | 0; + } + Q = _ << aH; + Z = c[m >> 2] | 0; + while (1) { + if ((c[Z + 4 >> 2] & -8 | 0) == (_ | 0)) { + break; + } + aI = Z + 16 + (Q >>> 31 << 2) | 0; + m = c[aI >> 2] | 0; + if ((m | 0) == 0) { + T = 442; + break; + } else { + Q = Q << 1; + Z = m; + } + } + if ((T | 0) == 442) { + if (aI >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[aI >> 2] = K; + c[ad + 24 >> 2] = Z; + c[ad + 12 >> 2] = ad; + c[ad + 8 >> 2] = ad; + break; + } + } + Q = Z + 8 | 0; + _ = c[Q >> 2] | 0; + m = c[212] | 0; + if (Z >>> 0 < m >>> 0) { + au(); + return 0; + } + if (_ >>> 0 < m >>> 0) { + au(); + return 0; + } else { + c[_ + 12 >> 2] = K; + c[Q >> 2] = K; + c[ad + 8 >> 2] = _; + c[ad + 12 >> 2] = Z; + c[ad + 24 >> 2] = 0; + break; + } + } + } while (0); + ad = c[211] | 0; + if (ad >>> 0 <= o >>> 0) { + break; + } + _ = ad - o | 0; + c[211] = _; + ad = c[214] | 0; + Q = ad; + c[214] = Q + o; + c[Q + (o + 4) >> 2] = _ | 1; + c[ad + 4 >> 2] = o | 3; + n = ad + 8 | 0; + return n | 0; + } + } while (0); + c[(aX() | 0) >> 2] = 12; + n = 0; + return n | 0; +} +function bM(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0; + if ((a | 0) == 0) { + return; + } + b = a - 8 | 0; + d = b; + e = c[212] | 0; + if (b >>> 0 < e >>> 0) { + au(); + } + f = c[a - 4 >> 2] | 0; + g = f & 3; + if ((g | 0) == 1) { + au(); + } + h = f & -8; + i = a + (h - 8) | 0; + j = i; + L672 : do { + if ((f & 1 | 0) == 0) { + k = c[b >> 2] | 0; + if ((g | 0) == 0) { + return; + } + l = -8 - k | 0; + m = a + l | 0; + n = m; + o = k + h | 0; + if (m >>> 0 < e >>> 0) { + au(); + } + if ((n | 0) == (c[213] | 0)) { + p = a + (h - 4) | 0; + if ((c[p >> 2] & 3 | 0) != 3) { + q = n; + r = o; + break; + } + c[210] = o; + c[p >> 2] = c[p >> 2] & -2; + c[a + (l + 4) >> 2] = o | 1; + c[i >> 2] = o; + return; + } + p = k >>> 3; + if (k >>> 0 < 256) { + k = c[a + (l + 8) >> 2] | 0; + s = c[a + (l + 12) >> 2] | 0; + t = 872 + (p << 1 << 2) | 0; + do { + if ((k | 0) != (t | 0)) { + if (k >>> 0 < e >>> 0) { + au(); + } + if ((c[k + 12 >> 2] | 0) == (n | 0)) { + break; + } + au(); + } + } while (0); + if ((s | 0) == (k | 0)) { + c[208] = c[208] & ~(1 << p); + q = n; + r = o; + break; + } + do { + if ((s | 0) == (t | 0)) { + u = s + 8 | 0; + } else { + if (s >>> 0 < e >>> 0) { + au(); + } + v = s + 8 | 0; + if ((c[v >> 2] | 0) == (n | 0)) { + u = v; + break; + } + au(); + } + } while (0); + c[k + 12 >> 2] = s; + c[u >> 2] = k; + q = n; + r = o; + break; + } + t = m; + p = c[a + (l + 24) >> 2] | 0; + v = c[a + (l + 12) >> 2] | 0; + do { + if ((v | 0) == (t | 0)) { + w = a + (l + 20) | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + y = a + (l + 16) | 0; + z = c[y >> 2] | 0; + if ((z | 0) == 0) { + A = 0; + break; + } else { + B = z; + C = y; + } + } else { + B = x; + C = w; + } + while (1) { + w = B + 20 | 0; + x = c[w >> 2] | 0; + if ((x | 0) != 0) { + B = x; + C = w; + continue; + } + w = B + 16 | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + break; + } else { + B = x; + C = w; + } + } + if (C >>> 0 < e >>> 0) { + au(); + } else { + c[C >> 2] = 0; + A = B; + break; + } + } else { + w = c[a + (l + 8) >> 2] | 0; + if (w >>> 0 < e >>> 0) { + au(); + } + x = w + 12 | 0; + if ((c[x >> 2] | 0) != (t | 0)) { + au(); + } + y = v + 8 | 0; + if ((c[y >> 2] | 0) == (t | 0)) { + c[x >> 2] = v; + c[y >> 2] = w; + A = v; + break; + } else { + au(); + } + } + } while (0); + if ((p | 0) == 0) { + q = n; + r = o; + break; + } + v = a + (l + 28) | 0; + m = 1136 + (c[v >> 2] << 2) | 0; + do { + if ((t | 0) == (c[m >> 2] | 0)) { + c[m >> 2] = A; + if ((A | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[v >> 2]); + q = n; + r = o; + break L672; + } else { + if (p >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + k = p + 16 | 0; + if ((c[k >> 2] | 0) == (t | 0)) { + c[k >> 2] = A; + } else { + c[p + 20 >> 2] = A; + } + if ((A | 0) == 0) { + q = n; + r = o; + break L672; + } + } + } while (0); + if (A >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + c[A + 24 >> 2] = p; + t = c[a + (l + 16) >> 2] | 0; + do { + if ((t | 0) != 0) { + if (t >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[A + 16 >> 2] = t; + c[t + 24 >> 2] = A; + break; + } + } + } while (0); + t = c[a + (l + 20) >> 2] | 0; + if ((t | 0) == 0) { + q = n; + r = o; + break; + } + if (t >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[A + 20 >> 2] = t; + c[t + 24 >> 2] = A; + q = n; + r = o; + break; + } + } else { + q = d; + r = h; + } + } while (0); + d = q; + if (d >>> 0 >= i >>> 0) { + au(); + } + A = a + (h - 4) | 0; + e = c[A >> 2] | 0; + if ((e & 1 | 0) == 0) { + au(); + } + do { + if ((e & 2 | 0) == 0) { + if ((j | 0) == (c[214] | 0)) { + B = (c[211] | 0) + r | 0; + c[211] = B; + c[214] = q; + c[q + 4 >> 2] = B | 1; + if ((q | 0) == (c[213] | 0)) { + c[213] = 0; + c[210] = 0; + } + if (B >>> 0 <= (c[215] | 0) >>> 0) { + return; + } + bS(0) | 0; + return; + } + if ((j | 0) == (c[213] | 0)) { + B = (c[210] | 0) + r | 0; + c[210] = B; + c[213] = q; + c[q + 4 >> 2] = B | 1; + c[d + B >> 2] = B; + return; + } + B = (e & -8) + r | 0; + C = e >>> 3; + L777 : do { + if (e >>> 0 < 256) { + u = c[a + h >> 2] | 0; + g = c[a + (h | 4) >> 2] | 0; + b = 872 + (C << 1 << 2) | 0; + do { + if ((u | 0) != (b | 0)) { + if (u >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + if ((c[u + 12 >> 2] | 0) == (j | 0)) { + break; + } + au(); + } + } while (0); + if ((g | 0) == (u | 0)) { + c[208] = c[208] & ~(1 << C); + break; + } + do { + if ((g | 0) == (b | 0)) { + D = g + 8 | 0; + } else { + if (g >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + f = g + 8 | 0; + if ((c[f >> 2] | 0) == (j | 0)) { + D = f; + break; + } + au(); + } + } while (0); + c[u + 12 >> 2] = g; + c[D >> 2] = u; + } else { + b = i; + f = c[a + (h + 16) >> 2] | 0; + t = c[a + (h | 4) >> 2] | 0; + do { + if ((t | 0) == (b | 0)) { + p = a + (h + 12) | 0; + v = c[p >> 2] | 0; + if ((v | 0) == 0) { + m = a + (h + 8) | 0; + k = c[m >> 2] | 0; + if ((k | 0) == 0) { + E = 0; + break; + } else { + F = k; + G = m; + } + } else { + F = v; + G = p; + } + while (1) { + p = F + 20 | 0; + v = c[p >> 2] | 0; + if ((v | 0) != 0) { + F = v; + G = p; + continue; + } + p = F + 16 | 0; + v = c[p >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + F = v; + G = p; + } + } + if (G >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[G >> 2] = 0; + E = F; + break; + } + } else { + p = c[a + h >> 2] | 0; + if (p >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + v = p + 12 | 0; + if ((c[v >> 2] | 0) != (b | 0)) { + au(); + } + m = t + 8 | 0; + if ((c[m >> 2] | 0) == (b | 0)) { + c[v >> 2] = t; + c[m >> 2] = p; + E = t; + break; + } else { + au(); + } + } + } while (0); + if ((f | 0) == 0) { + break; + } + t = a + (h + 20) | 0; + u = 1136 + (c[t >> 2] << 2) | 0; + do { + if ((b | 0) == (c[u >> 2] | 0)) { + c[u >> 2] = E; + if ((E | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[t >> 2]); + break L777; + } else { + if (f >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + g = f + 16 | 0; + if ((c[g >> 2] | 0) == (b | 0)) { + c[g >> 2] = E; + } else { + c[f + 20 >> 2] = E; + } + if ((E | 0) == 0) { + break L777; + } + } + } while (0); + if (E >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + c[E + 24 >> 2] = f; + b = c[a + (h + 8) >> 2] | 0; + do { + if ((b | 0) != 0) { + if (b >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[E + 16 >> 2] = b; + c[b + 24 >> 2] = E; + break; + } + } + } while (0); + b = c[a + (h + 12) >> 2] | 0; + if ((b | 0) == 0) { + break; + } + if (b >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[E + 20 >> 2] = b; + c[b + 24 >> 2] = E; + break; + } + } + } while (0); + c[q + 4 >> 2] = B | 1; + c[d + B >> 2] = B; + if ((q | 0) != (c[213] | 0)) { + H = B; + break; + } + c[210] = B; + return; + } else { + c[A >> 2] = e & -2; + c[q + 4 >> 2] = r | 1; + c[d + r >> 2] = r; + H = r; + } + } while (0); + r = H >>> 3; + if (H >>> 0 < 256) { + d = r << 1; + e = 872 + (d << 2) | 0; + A = c[208] | 0; + E = 1 << r; + do { + if ((A & E | 0) == 0) { + c[208] = A | E; + I = e; + J = 872 + (d + 2 << 2) | 0; + } else { + r = 872 + (d + 2 << 2) | 0; + h = c[r >> 2] | 0; + if (h >>> 0 >= (c[212] | 0) >>> 0) { + I = h; + J = r; + break; + } + au(); + } + } while (0); + c[J >> 2] = q; + c[I + 12 >> 2] = q; + c[q + 8 >> 2] = I; + c[q + 12 >> 2] = e; + return; + } + e = q; + I = H >>> 8; + do { + if ((I | 0) == 0) { + K = 0; + } else { + if (H >>> 0 > 16777215) { + K = 31; + break; + } + J = (I + 1048320 | 0) >>> 16 & 8; + d = I << J; + E = (d + 520192 | 0) >>> 16 & 4; + A = d << E; + d = (A + 245760 | 0) >>> 16 & 2; + r = 14 - (E | J | d) + (A << d >>> 15) | 0; + K = H >>> ((r + 7 | 0) >>> 0) & 1 | r << 1; + } + } while (0); + I = 1136 + (K << 2) | 0; + c[q + 28 >> 2] = K; + c[q + 20 >> 2] = 0; + c[q + 16 >> 2] = 0; + r = c[209] | 0; + d = 1 << K; + do { + if ((r & d | 0) == 0) { + c[209] = r | d; + c[I >> 2] = e; + c[q + 24 >> 2] = I; + c[q + 12 >> 2] = q; + c[q + 8 >> 2] = q; + } else { + if ((K | 0) == 31) { + L = 0; + } else { + L = 25 - (K >>> 1) | 0; + } + A = H << L; + J = c[I >> 2] | 0; + while (1) { + if ((c[J + 4 >> 2] & -8 | 0) == (H | 0)) { + break; + } + M = J + 16 + (A >>> 31 << 2) | 0; + E = c[M >> 2] | 0; + if ((E | 0) == 0) { + N = 621; + break; + } else { + A = A << 1; + J = E; + } + } + if ((N | 0) == 621) { + if (M >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[M >> 2] = e; + c[q + 24 >> 2] = J; + c[q + 12 >> 2] = q; + c[q + 8 >> 2] = q; + break; + } + } + A = J + 8 | 0; + B = c[A >> 2] | 0; + E = c[212] | 0; + if (J >>> 0 < E >>> 0) { + au(); + } + if (B >>> 0 < E >>> 0) { + au(); + } else { + c[B + 12 >> 2] = e; + c[A >> 2] = e; + c[q + 8 >> 2] = B; + c[q + 12 >> 2] = J; + c[q + 24 >> 2] = 0; + break; + } + } + } while (0); + q = (c[216] | 0) - 1 | 0; + c[216] = q; + if ((q | 0) == 0) { + O = 1288; + } else { + return; + } + while (1) { + q = c[O >> 2] | 0; + if ((q | 0) == 0) { + break; + } else { + O = q + 8 | 0; + } + } + c[216] = -1; + return; +} +function bN(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + do { + if ((a | 0) == 0) { + d = 0; + } else { + e = ad(b, a) | 0; + if ((b | a) >>> 0 <= 65535) { + d = e; + break; + } + d = ((e >>> 0) / (a >>> 0) | 0 | 0) == (b | 0) ? e : -1; + } + } while (0); + b = bL(d) | 0; + if ((b | 0) == 0) { + return b | 0; + } + if ((c[b - 4 >> 2] & 3 | 0) == 0) { + return b | 0; + } + cL(b | 0, 0, d | 0); + return b | 0; +} +function bO(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0; + if ((a | 0) == 0) { + d = bL(b) | 0; + return d | 0; + } + if (b >>> 0 > 4294967231) { + c[(aX() | 0) >> 2] = 12; + d = 0; + return d | 0; + } + if (b >>> 0 < 11) { + e = 16; + } else { + e = b + 11 & -8; + } + f = bT(a - 8 | 0, e) | 0; + if ((f | 0) != 0) { + d = f + 8 | 0; + return d | 0; + } + f = bL(b) | 0; + if ((f | 0) == 0) { + d = 0; + return d | 0; + } + e = c[a - 4 >> 2] | 0; + g = (e & -8) - ((e & 3 | 0) == 0 ? 8 : 4) | 0; + e = g >>> 0 < b >>> 0 ? g : b; + cK(f | 0, a | 0, e) | 0; + bM(a); + d = f; + return d | 0; +} +function bP(a, b) { + a = a | 0; + b = b | 0; + var d = 0; + if ((a | 0) == 0) { + return 0; + } + if (b >>> 0 > 4294967231) { + c[(aX() | 0) >> 2] = 12; + return 0; + } + if (b >>> 0 < 11) { + d = 16; + } else { + d = b + 11 & -8; + } + b = a - 8 | 0; + return ((bT(b, d) | 0) == (b | 0) ? a : 0) | 0; +} +function bQ(a, b) { + a = a | 0; + b = b | 0; + var c = 0; + if (a >>> 0 < 9) { + c = bL(b) | 0; + return c | 0; + } else { + c = bR(a, b) | 0; + return c | 0; + } + return 0; +} +function bR(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + d = a >>> 0 < 16 ? 16 : a; + if ((d - 1 & d | 0) == 0) { + e = d; + } else { + a = 16; + while (1) { + if (a >>> 0 < d >>> 0) { + a = a << 1; + } else { + e = a; + break; + } + } + } + if ((-64 - e | 0) >>> 0 <= b >>> 0) { + c[(aX() | 0) >> 2] = 12; + f = 0; + return f | 0; + } + if (b >>> 0 < 11) { + g = 16; + } else { + g = b + 11 & -8; + } + b = bL(e + 12 + g | 0) | 0; + if ((b | 0) == 0) { + f = 0; + return f | 0; + } + a = b - 8 | 0; + d = a; + h = e - 1 | 0; + do { + if ((b & h | 0) == 0) { + i = d; + } else { + j = b + h & -e; + k = j - 8 | 0; + l = a; + if ((k - l | 0) >>> 0 > 15) { + m = k; + } else { + m = j + (e - 8) | 0; + } + j = m; + k = m - l | 0; + l = b - 4 | 0; + n = c[l >> 2] | 0; + o = (n & -8) - k | 0; + if ((n & 3 | 0) == 0) { + c[m >> 2] = (c[a >> 2] | 0) + k; + c[m + 4 >> 2] = o; + i = j; + break; + } else { + n = m + 4 | 0; + c[n >> 2] = o | c[n >> 2] & 1 | 2; + n = m + (o + 4) | 0; + c[n >> 2] = c[n >> 2] | 1; + c[l >> 2] = k | c[l >> 2] & 1 | 2; + l = b + (k - 4) | 0; + c[l >> 2] = c[l >> 2] | 1; + b9(d, k); + i = j; + break; + } + } + } while (0); + d = i + 4 | 0; + b = c[d >> 2] | 0; + do { + if ((b & 3 | 0) != 0) { + m = b & -8; + if (m >>> 0 <= (g + 16 | 0) >>> 0) { + break; + } + a = m - g | 0; + e = i; + c[d >> 2] = g | b & 1 | 2; + c[e + (g | 4) >> 2] = a | 3; + h = e + (m | 4) | 0; + c[h >> 2] = c[h >> 2] | 1; + b9(e + g | 0, a); + } + } while (0); + f = i + 8 | 0; + return f | 0; +} +function bS(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0; + do { + if ((c[200] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[202] = b; + c[201] = b; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + return 0; + } + } + } while (0); + if (a >>> 0 >= 4294967232) { + d = 0; + return d | 0; + } + b = c[214] | 0; + if ((b | 0) == 0) { + d = 0; + return d | 0; + } + e = c[211] | 0; + do { + if (e >>> 0 > (a + 40 | 0) >>> 0) { + f = c[202] | 0; + g = ad((((-40 - a - 1 + e + f | 0) >>> 0) / (f >>> 0) | 0) - 1 | 0, f) | 0; + h = b; + i = 1280; + while (1) { + j = c[i >> 2] | 0; + if (j >>> 0 <= h >>> 0) { + if ((j + (c[i + 4 >> 2] | 0) | 0) >>> 0 > h >>> 0) { + k = i; + break; + } + } + j = c[i + 8 >> 2] | 0; + if ((j | 0) == 0) { + k = 0; + break; + } else { + i = j; + } + } + if ((c[k + 12 >> 2] & 8 | 0) != 0) { + break; + } + i = aV(0) | 0; + h = k + 4 | 0; + if ((i | 0) != ((c[k >> 2] | 0) + (c[h >> 2] | 0) | 0)) { + break; + } + j = aV(-(g >>> 0 > 2147483646 ? -2147483648 - f | 0 : g) | 0) | 0; + l = aV(0) | 0; + if (!((j | 0) != -1 & l >>> 0 < i >>> 0)) { + break; + } + j = i - l | 0; + if ((i | 0) == (l | 0)) { + break; + } + c[h >> 2] = (c[h >> 2] | 0) - j; + c[316] = (c[316] | 0) - j; + h = c[214] | 0; + m = (c[211] | 0) - j | 0; + j = h; + n = h + 8 | 0; + if ((n & 7 | 0) == 0) { + o = 0; + } else { + o = -n & 7; + } + n = m - o | 0; + c[214] = j + o; + c[211] = n; + c[j + (o + 4) >> 2] = n | 1; + c[j + (m + 4) >> 2] = 40; + c[215] = c[204]; + d = (i | 0) != (l | 0) | 0; + return d | 0; + } + } while (0); + if ((c[211] | 0) >>> 0 <= (c[215] | 0) >>> 0) { + d = 0; + return d | 0; + } + c[215] = -1; + d = 0; + return d | 0; +} +function bT(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0; + d = a + 4 | 0; + e = c[d >> 2] | 0; + f = e & -8; + g = a; + h = g + f | 0; + i = h; + j = c[212] | 0; + if (g >>> 0 < j >>> 0) { + au(); + return 0; + } + k = e & 3; + if (!((k | 0) != 1 & g >>> 0 < h >>> 0)) { + au(); + return 0; + } + l = g + (f | 4) | 0; + m = c[l >> 2] | 0; + if ((m & 1 | 0) == 0) { + au(); + return 0; + } + if ((k | 0) == 0) { + if (b >>> 0 < 256) { + n = 0; + return n | 0; + } + do { + if (f >>> 0 >= (b + 4 | 0) >>> 0) { + if ((f - b | 0) >>> 0 > c[202] << 1 >>> 0) { + break; + } else { + n = a; + } + return n | 0; + } + } while (0); + n = 0; + return n | 0; + } + if (f >>> 0 >= b >>> 0) { + k = f - b | 0; + if (k >>> 0 <= 15) { + n = a; + return n | 0; + } + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = k | 3; + c[l >> 2] = c[l >> 2] | 1; + b9(g + b | 0, k); + n = a; + return n | 0; + } + if ((i | 0) == (c[214] | 0)) { + k = (c[211] | 0) + f | 0; + if (k >>> 0 <= b >>> 0) { + n = 0; + return n | 0; + } + l = k - b | 0; + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = l | 1; + c[214] = g + b; + c[211] = l; + n = a; + return n | 0; + } + if ((i | 0) == (c[213] | 0)) { + l = (c[210] | 0) + f | 0; + if (l >>> 0 < b >>> 0) { + n = 0; + return n | 0; + } + k = l - b | 0; + if (k >>> 0 > 15) { + c[d >> 2] = e & 1 | b | 2; + c[g + (b + 4) >> 2] = k | 1; + c[g + l >> 2] = k; + o = g + (l + 4) | 0; + c[o >> 2] = c[o >> 2] & -2; + p = g + b | 0; + q = k; + } else { + c[d >> 2] = e & 1 | l | 2; + e = g + (l + 4) | 0; + c[e >> 2] = c[e >> 2] | 1; + p = 0; + q = 0; + } + c[210] = q; + c[213] = p; + n = a; + return n | 0; + } + if ((m & 2 | 0) != 0) { + n = 0; + return n | 0; + } + p = (m & -8) + f | 0; + if (p >>> 0 < b >>> 0) { + n = 0; + return n | 0; + } + q = p - b | 0; + e = m >>> 3; + L1056 : do { + if (m >>> 0 < 256) { + l = c[g + (f + 8) >> 2] | 0; + k = c[g + (f + 12) >> 2] | 0; + o = 872 + (e << 1 << 2) | 0; + do { + if ((l | 0) != (o | 0)) { + if (l >>> 0 < j >>> 0) { + au(); + return 0; + } + if ((c[l + 12 >> 2] | 0) == (i | 0)) { + break; + } + au(); + return 0; + } + } while (0); + if ((k | 0) == (l | 0)) { + c[208] = c[208] & ~(1 << e); + break; + } + do { + if ((k | 0) == (o | 0)) { + r = k + 8 | 0; + } else { + if (k >>> 0 < j >>> 0) { + au(); + return 0; + } + s = k + 8 | 0; + if ((c[s >> 2] | 0) == (i | 0)) { + r = s; + break; + } + au(); + return 0; + } + } while (0); + c[l + 12 >> 2] = k; + c[r >> 2] = l; + } else { + o = h; + s = c[g + (f + 24) >> 2] | 0; + t = c[g + (f + 12) >> 2] | 0; + do { + if ((t | 0) == (o | 0)) { + u = g + (f + 20) | 0; + v = c[u >> 2] | 0; + if ((v | 0) == 0) { + w = g + (f + 16) | 0; + x = c[w >> 2] | 0; + if ((x | 0) == 0) { + y = 0; + break; + } else { + z = x; + A = w; + } + } else { + z = v; + A = u; + } + while (1) { + u = z + 20 | 0; + v = c[u >> 2] | 0; + if ((v | 0) != 0) { + z = v; + A = u; + continue; + } + u = z + 16 | 0; + v = c[u >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + z = v; + A = u; + } + } + if (A >>> 0 < j >>> 0) { + au(); + return 0; + } else { + c[A >> 2] = 0; + y = z; + break; + } + } else { + u = c[g + (f + 8) >> 2] | 0; + if (u >>> 0 < j >>> 0) { + au(); + return 0; + } + v = u + 12 | 0; + if ((c[v >> 2] | 0) != (o | 0)) { + au(); + return 0; + } + w = t + 8 | 0; + if ((c[w >> 2] | 0) == (o | 0)) { + c[v >> 2] = t; + c[w >> 2] = u; + y = t; + break; + } else { + au(); + return 0; + } + } + } while (0); + if ((s | 0) == 0) { + break; + } + t = g + (f + 28) | 0; + l = 1136 + (c[t >> 2] << 2) | 0; + do { + if ((o | 0) == (c[l >> 2] | 0)) { + c[l >> 2] = y; + if ((y | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[t >> 2]); + break L1056; + } else { + if (s >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + k = s + 16 | 0; + if ((c[k >> 2] | 0) == (o | 0)) { + c[k >> 2] = y; + } else { + c[s + 20 >> 2] = y; + } + if ((y | 0) == 0) { + break L1056; + } + } + } while (0); + if (y >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } + c[y + 24 >> 2] = s; + o = c[g + (f + 16) >> 2] | 0; + do { + if ((o | 0) != 0) { + if (o >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[y + 16 >> 2] = o; + c[o + 24 >> 2] = y; + break; + } + } + } while (0); + o = c[g + (f + 20) >> 2] | 0; + if ((o | 0) == 0) { + break; + } + if (o >>> 0 < (c[212] | 0) >>> 0) { + au(); + return 0; + } else { + c[y + 20 >> 2] = o; + c[o + 24 >> 2] = y; + break; + } + } + } while (0); + if (q >>> 0 < 16) { + c[d >> 2] = p | c[d >> 2] & 1 | 2; + y = g + (p | 4) | 0; + c[y >> 2] = c[y >> 2] | 1; + n = a; + return n | 0; + } else { + c[d >> 2] = c[d >> 2] & 1 | b | 2; + c[g + (b + 4) >> 2] = q | 3; + d = g + (p | 4) | 0; + c[d >> 2] = c[d >> 2] | 1; + b9(g + b | 0, q); + n = a; + return n | 0; + } + return 0; +} +function bU() { + return c[316] | 0; +} +function bV() { + return c[317] | 0; +} +function bW() { + var a = 0; + a = c[318] | 0; + return ((a | 0) == 0 ? -1 : a) | 0; +} +function bX(a) { + a = a | 0; + var b = 0, d = 0; + if ((a | 0) == -1) { + b = 0; + } else { + d = c[202] | 0; + b = a - 1 + d & -d; + } + c[318] = b; + return b | 0; +} +function bY(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + do { + if ((a | 0) == 0) { + b = 0; + } else { + d = c[a - 4 >> 2] | 0; + e = d & 3; + if ((e | 0) == 1) { + b = 0; + break; + } + b = (d & -8) - ((e | 0) == 0 ? 8 : 4) | 0; + } + } while (0); + return b | 0; +} +function bZ(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0; + do { + if ((b | 0) == 8) { + e = bL(d) | 0; + } else { + f = b >>> 2; + if ((b & 3 | 0) != 0 | (f | 0) == 0) { + g = 22; + return g | 0; + } + if ((f + 1073741823 & f | 0) != 0) { + g = 22; + return g | 0; + } + if ((-64 - b | 0) >>> 0 < d >>> 0) { + g = 12; + return g | 0; + } else { + e = bR(b >>> 0 < 16 ? 16 : b, d) | 0; + break; + } + } + } while (0); + if ((e | 0) == 0) { + g = 12; + return g | 0; + } + c[a >> 2] = e; + g = 0; + return g | 0; +} +function b_(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 8 | 0; + f = e | 0; + c[f >> 2] = b; + b = b2(a, f, 3, d) | 0; + i = e; + return b | 0; +} +function b$(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return b2(a, b, 0, c) | 0; +} +function b0(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + if ((c[200] | 0) != 0) { + b = c[201] | 0; + d = bQ(b, a) | 0; + return d | 0; + } + e = ar(8) | 0; + if ((e - 1 & e | 0) != 0) { + au(); + return 0; + } + c[202] = e; + c[201] = e; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + b = c[201] | 0; + d = bQ(b, a) | 0; + return d | 0; +} +function b1(a) { + a = a | 0; + var b = 0; + do { + if ((c[200] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[202] = b; + c[201] = b; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + return 0; + } + } + } while (0); + b = c[201] | 0; + return bQ(b, a - 1 + b & -b) | 0; +} +function b2(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0; + do { + if ((c[200] | 0) == 0) { + f = ar(8) | 0; + if ((f - 1 & f | 0) == 0) { + c[202] = f; + c[201] = f; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + return 0; + } + } + } while (0); + f = (a | 0) == 0; + do { + if ((e | 0) == 0) { + if (f) { + g = bL(0) | 0; + return g | 0; + } else { + h = a << 2; + if (h >>> 0 < 11) { + i = 0; + j = 16; + break; + } + i = 0; + j = h + 11 & -8; + break; + } + } else { + if (f) { + g = e; + } else { + i = e; + j = 0; + break; + } + return g | 0; + } + } while (0); + do { + if ((d & 1 | 0) == 0) { + if (f) { + k = 0; + l = 0; + break; + } else { + m = 0; + n = 0; + } + while (1) { + e = c[b + (n << 2) >> 2] | 0; + if (e >>> 0 < 11) { + o = 16; + } else { + o = e + 11 & -8; + } + e = o + m | 0; + h = n + 1 | 0; + if ((h | 0) == (a | 0)) { + k = 0; + l = e; + break; + } else { + m = e; + n = h; + } + } + } else { + h = c[b >> 2] | 0; + if (h >>> 0 < 11) { + p = 16; + } else { + p = h + 11 & -8; + } + k = p; + l = ad(p, a) | 0; + } + } while (0); + p = bL(j - 4 + l | 0) | 0; + if ((p | 0) == 0) { + g = 0; + return g | 0; + } + n = p - 8 | 0; + m = c[p - 4 >> 2] & -8; + if ((d & 2 | 0) != 0) { + cL(p | 0, 0, -4 - j + m | 0); + } + if ((i | 0) == 0) { + c[p + (l - 4) >> 2] = m - l | 3; + q = p + l | 0; + r = l; + } else { + q = i; + r = m; + } + c[q >> 2] = p; + p = a - 1 | 0; + L1216 : do { + if ((p | 0) == 0) { + s = n; + t = r; + } else { + if ((k | 0) == 0) { + u = n; + v = r; + w = 0; + } else { + a = n; + m = r; + i = 0; + while (1) { + l = m - k | 0; + c[a + 4 >> 2] = k | 3; + j = a + k | 0; + d = i + 1 | 0; + c[q + (d << 2) >> 2] = a + (k + 8); + if ((d | 0) == (p | 0)) { + s = j; + t = l; + break L1216; + } else { + a = j; + m = l; + i = d; + } + } + } + while (1) { + i = c[b + (w << 2) >> 2] | 0; + if (i >>> 0 < 11) { + x = 16; + } else { + x = i + 11 & -8; + } + i = v - x | 0; + c[u + 4 >> 2] = x | 3; + m = u + x | 0; + a = w + 1 | 0; + c[q + (a << 2) >> 2] = u + (x + 8); + if ((a | 0) == (p | 0)) { + s = m; + t = i; + break; + } else { + u = m; + v = i; + w = a; + } + } + } + } while (0); + c[s + 4 >> 2] = t | 3; + g = q; + return g | 0; +} +function b3(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0; + d = a + (b << 2) | 0; + L1229 : do { + if ((b | 0) != 0) { + e = a; + L1230 : while (1) { + f = c[e >> 2] | 0; + L1232 : do { + if ((f | 0) == 0) { + g = e + 4 | 0; + } else { + h = f - 8 | 0; + i = h; + j = f - 4 | 0; + k = c[j >> 2] & -8; + c[e >> 2] = 0; + if (h >>> 0 < (c[212] | 0) >>> 0) { + l = 935; + break L1230; + } + h = c[j >> 2] | 0; + if ((h & 3 | 0) == 1) { + l = 936; + break L1230; + } + m = e + 4 | 0; + n = h - 8 & -8; + do { + if ((m | 0) != (d | 0)) { + if ((c[m >> 2] | 0) != (f + (n + 8) | 0)) { + break; + } + o = (c[f + (n | 4) >> 2] & -8) + k | 0; + c[j >> 2] = h & 1 | o | 2; + p = f + (o - 4) | 0; + c[p >> 2] = c[p >> 2] | 1; + c[m >> 2] = f; + g = m; + break L1232; + } + } while (0); + b9(i, k); + g = m; + } + } while (0); + if ((g | 0) == (d | 0)) { + break L1229; + } else { + e = g; + } + } + if ((l | 0) == 935) { + au(); + return 0; + } else if ((l | 0) == 936) { + au(); + return 0; + } + } + } while (0); + if ((c[211] | 0) >>> 0 <= (c[215] | 0) >>> 0) { + return 0; + } + bS(0) | 0; + return 0; +} +function b4(a) { + a = a | 0; + var b = 0, d = 0; + if ((c[200] | 0) != 0) { + b = bS(a) | 0; + return b | 0; + } + d = ar(8) | 0; + if ((d - 1 & d | 0) != 0) { + au(); + return 0; + } + c[202] = d; + c[201] = d; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + b = bS(a) | 0; + return b | 0; +} +function b5(a) { + a = a | 0; + var b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0; + do { + if ((c[200] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[202] = b; + c[201] = b; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + } + } + } while (0); + b = c[214] | 0; + if ((b | 0) == 0) { + d = 0; + e = 0; + f = 0; + g = 0; + h = 0; + i = 0; + j = 0; + } else { + k = c[211] | 0; + l = k + 40 | 0; + m = 1; + n = l; + o = l; + l = 1280; + while (1) { + p = c[l >> 2] | 0; + q = p + 8 | 0; + if ((q & 7 | 0) == 0) { + r = 0; + } else { + r = -q & 7; + } + q = p + (c[l + 4 >> 2] | 0) | 0; + s = m; + t = n; + u = o; + v = p + r | 0; + while (1) { + if (v >>> 0 >= q >>> 0 | (v | 0) == (b | 0)) { + w = s; + x = t; + y = u; + break; + } + z = c[v + 4 >> 2] | 0; + if ((z | 0) == 7) { + w = s; + x = t; + y = u; + break; + } + A = z & -8; + B = A + u | 0; + if ((z & 3 | 0) == 1) { + C = A + t | 0; + D = s + 1 | 0; + } else { + C = t; + D = s; + } + z = v + A | 0; + if (z >>> 0 < p >>> 0) { + w = D; + x = C; + y = B; + break; + } else { + s = D; + t = C; + u = B; + v = z; + } + } + v = c[l + 8 >> 2] | 0; + if ((v | 0) == 0) { + break; + } else { + m = w; + n = x; + o = y; + l = v; + } + } + l = c[316] | 0; + d = k; + e = y; + f = w; + g = l - y | 0; + h = c[317] | 0; + i = l - x | 0; + j = x; + } + c[a >> 2] = e; + c[a + 4 >> 2] = f; + f = a + 8 | 0; + c[f >> 2] = 0; + c[f + 4 >> 2] = 0; + c[a + 16 >> 2] = g; + c[a + 20 >> 2] = h; + c[a + 24 >> 2] = 0; + c[a + 28 >> 2] = i; + c[a + 32 >> 2] = j; + c[a + 36 >> 2] = d; + return; +} +function b6() { + var a = 0, b = 0, d = 0, e = 0, f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0; + a = i; + do { + if ((c[200] | 0) == 0) { + b = ar(8) | 0; + if ((b - 1 & b | 0) == 0) { + c[202] = b; + c[201] = b; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + } + } + } while (0); + b = c[214] | 0; + if ((b | 0) == 0) { + d = 0; + e = 0; + f = 0; + } else { + g = c[317] | 0; + h = c[316] | 0; + j = h - 40 - (c[211] | 0) | 0; + k = 1280; + while (1) { + l = c[k >> 2] | 0; + m = l + 8 | 0; + if ((m & 7 | 0) == 0) { + n = 0; + } else { + n = -m & 7; + } + m = l + (c[k + 4 >> 2] | 0) | 0; + p = j; + q = l + n | 0; + while (1) { + if (q >>> 0 >= m >>> 0 | (q | 0) == (b | 0)) { + r = p; + break; + } + s = c[q + 4 >> 2] | 0; + if ((s | 0) == 7) { + r = p; + break; + } + t = s & -8; + u = p - ((s & 3 | 0) == 1 ? t : 0) | 0; + s = q + t | 0; + if (s >>> 0 < l >>> 0) { + r = u; + break; + } else { + p = u; + q = s; + } + } + q = c[k + 8 >> 2] | 0; + if ((q | 0) == 0) { + d = r; + e = h; + f = g; + break; + } else { + j = r; + k = q; + } + } + } + av(c[o >> 2] | 0, 520, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + av(c[o >> 2] | 0, 488, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + av(c[o >> 2] | 0, 400, (y = i, i = i + 8 | 0, c[y >> 2] = d, y) | 0) | 0; + i = a; + return; +} +function b7(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + do { + if ((c[200] | 0) == 0) { + d = ar(8) | 0; + if ((d - 1 & d | 0) == 0) { + c[202] = d; + c[201] = d; + c[203] = -1; + c[204] = 2097152; + c[205] = 0; + c[319] = 0; + c[200] = (a_(0) | 0) & -16 ^ 1431655768; + break; + } else { + au(); + return 0; + } + } + } while (0); + if ((a | 0) == (-1 | 0)) { + c[204] = b; + e = 1; + return e | 0; + } else if ((a | 0) == (-2 | 0)) { + if ((c[201] | 0) >>> 0 > b >>> 0) { + e = 0; + return e | 0; + } + if ((b - 1 & b | 0) != 0) { + e = 0; + return e | 0; + } + c[202] = b; + e = 1; + return e | 0; + } else if ((a | 0) == (-3 | 0)) { + c[203] = b; + e = 1; + return e | 0; + } else { + e = 0; + return e | 0; + } + return 0; +} +function b8() { + return (F = c[328] | 0, c[328] = F + 0, F) | 0; +} +function b9(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0; + d = a; + e = d + b | 0; + f = e; + g = c[a + 4 >> 2] | 0; + L1325 : do { + if ((g & 1 | 0) == 0) { + h = c[a >> 2] | 0; + if ((g & 3 | 0) == 0) { + return; + } + i = d + (-h | 0) | 0; + j = i; + k = h + b | 0; + l = c[212] | 0; + if (i >>> 0 < l >>> 0) { + au(); + } + if ((j | 0) == (c[213] | 0)) { + m = d + (b + 4) | 0; + if ((c[m >> 2] & 3 | 0) != 3) { + n = j; + o = k; + break; + } + c[210] = k; + c[m >> 2] = c[m >> 2] & -2; + c[d + (4 - h) >> 2] = k | 1; + c[e >> 2] = k; + return; + } + m = h >>> 3; + if (h >>> 0 < 256) { + p = c[d + (8 - h) >> 2] | 0; + q = c[d + (12 - h) >> 2] | 0; + r = 872 + (m << 1 << 2) | 0; + do { + if ((p | 0) != (r | 0)) { + if (p >>> 0 < l >>> 0) { + au(); + } + if ((c[p + 12 >> 2] | 0) == (j | 0)) { + break; + } + au(); + } + } while (0); + if ((q | 0) == (p | 0)) { + c[208] = c[208] & ~(1 << m); + n = j; + o = k; + break; + } + do { + if ((q | 0) == (r | 0)) { + s = q + 8 | 0; + } else { + if (q >>> 0 < l >>> 0) { + au(); + } + t = q + 8 | 0; + if ((c[t >> 2] | 0) == (j | 0)) { + s = t; + break; + } + au(); + } + } while (0); + c[p + 12 >> 2] = q; + c[s >> 2] = p; + n = j; + o = k; + break; + } + r = i; + m = c[d + (24 - h) >> 2] | 0; + t = c[d + (12 - h) >> 2] | 0; + do { + if ((t | 0) == (r | 0)) { + u = 16 - h | 0; + v = d + (u + 4) | 0; + w = c[v >> 2] | 0; + if ((w | 0) == 0) { + x = d + u | 0; + u = c[x >> 2] | 0; + if ((u | 0) == 0) { + y = 0; + break; + } else { + z = u; + A = x; + } + } else { + z = w; + A = v; + } + while (1) { + v = z + 20 | 0; + w = c[v >> 2] | 0; + if ((w | 0) != 0) { + z = w; + A = v; + continue; + } + v = z + 16 | 0; + w = c[v >> 2] | 0; + if ((w | 0) == 0) { + break; + } else { + z = w; + A = v; + } + } + if (A >>> 0 < l >>> 0) { + au(); + } else { + c[A >> 2] = 0; + y = z; + break; + } + } else { + v = c[d + (8 - h) >> 2] | 0; + if (v >>> 0 < l >>> 0) { + au(); + } + w = v + 12 | 0; + if ((c[w >> 2] | 0) != (r | 0)) { + au(); + } + x = t + 8 | 0; + if ((c[x >> 2] | 0) == (r | 0)) { + c[w >> 2] = t; + c[x >> 2] = v; + y = t; + break; + } else { + au(); + } + } + } while (0); + if ((m | 0) == 0) { + n = j; + o = k; + break; + } + t = d + (28 - h) | 0; + l = 1136 + (c[t >> 2] << 2) | 0; + do { + if ((r | 0) == (c[l >> 2] | 0)) { + c[l >> 2] = y; + if ((y | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[t >> 2]); + n = j; + o = k; + break L1325; + } else { + if (m >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + i = m + 16 | 0; + if ((c[i >> 2] | 0) == (r | 0)) { + c[i >> 2] = y; + } else { + c[m + 20 >> 2] = y; + } + if ((y | 0) == 0) { + n = j; + o = k; + break L1325; + } + } + } while (0); + if (y >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + c[y + 24 >> 2] = m; + r = 16 - h | 0; + t = c[d + r >> 2] | 0; + do { + if ((t | 0) != 0) { + if (t >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[y + 16 >> 2] = t; + c[t + 24 >> 2] = y; + break; + } + } + } while (0); + t = c[d + (r + 4) >> 2] | 0; + if ((t | 0) == 0) { + n = j; + o = k; + break; + } + if (t >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[y + 20 >> 2] = t; + c[t + 24 >> 2] = y; + n = j; + o = k; + break; + } + } else { + n = a; + o = b; + } + } while (0); + a = c[212] | 0; + if (e >>> 0 < a >>> 0) { + au(); + } + y = d + (b + 4) | 0; + z = c[y >> 2] | 0; + do { + if ((z & 2 | 0) == 0) { + if ((f | 0) == (c[214] | 0)) { + A = (c[211] | 0) + o | 0; + c[211] = A; + c[214] = n; + c[n + 4 >> 2] = A | 1; + if ((n | 0) != (c[213] | 0)) { + return; + } + c[213] = 0; + c[210] = 0; + return; + } + if ((f | 0) == (c[213] | 0)) { + A = (c[210] | 0) + o | 0; + c[210] = A; + c[213] = n; + c[n + 4 >> 2] = A | 1; + c[n + A >> 2] = A; + return; + } + A = (z & -8) + o | 0; + s = z >>> 3; + L1424 : do { + if (z >>> 0 < 256) { + g = c[d + (b + 8) >> 2] | 0; + t = c[d + (b + 12) >> 2] | 0; + h = 872 + (s << 1 << 2) | 0; + do { + if ((g | 0) != (h | 0)) { + if (g >>> 0 < a >>> 0) { + au(); + } + if ((c[g + 12 >> 2] | 0) == (f | 0)) { + break; + } + au(); + } + } while (0); + if ((t | 0) == (g | 0)) { + c[208] = c[208] & ~(1 << s); + break; + } + do { + if ((t | 0) == (h | 0)) { + B = t + 8 | 0; + } else { + if (t >>> 0 < a >>> 0) { + au(); + } + m = t + 8 | 0; + if ((c[m >> 2] | 0) == (f | 0)) { + B = m; + break; + } + au(); + } + } while (0); + c[g + 12 >> 2] = t; + c[B >> 2] = g; + } else { + h = e; + m = c[d + (b + 24) >> 2] | 0; + l = c[d + (b + 12) >> 2] | 0; + do { + if ((l | 0) == (h | 0)) { + i = d + (b + 20) | 0; + p = c[i >> 2] | 0; + if ((p | 0) == 0) { + q = d + (b + 16) | 0; + v = c[q >> 2] | 0; + if ((v | 0) == 0) { + C = 0; + break; + } else { + D = v; + E = q; + } + } else { + D = p; + E = i; + } + while (1) { + i = D + 20 | 0; + p = c[i >> 2] | 0; + if ((p | 0) != 0) { + D = p; + E = i; + continue; + } + i = D + 16 | 0; + p = c[i >> 2] | 0; + if ((p | 0) == 0) { + break; + } else { + D = p; + E = i; + } + } + if (E >>> 0 < a >>> 0) { + au(); + } else { + c[E >> 2] = 0; + C = D; + break; + } + } else { + i = c[d + (b + 8) >> 2] | 0; + if (i >>> 0 < a >>> 0) { + au(); + } + p = i + 12 | 0; + if ((c[p >> 2] | 0) != (h | 0)) { + au(); + } + q = l + 8 | 0; + if ((c[q >> 2] | 0) == (h | 0)) { + c[p >> 2] = l; + c[q >> 2] = i; + C = l; + break; + } else { + au(); + } + } + } while (0); + if ((m | 0) == 0) { + break; + } + l = d + (b + 28) | 0; + g = 1136 + (c[l >> 2] << 2) | 0; + do { + if ((h | 0) == (c[g >> 2] | 0)) { + c[g >> 2] = C; + if ((C | 0) != 0) { + break; + } + c[209] = c[209] & ~(1 << c[l >> 2]); + break L1424; + } else { + if (m >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + t = m + 16 | 0; + if ((c[t >> 2] | 0) == (h | 0)) { + c[t >> 2] = C; + } else { + c[m + 20 >> 2] = C; + } + if ((C | 0) == 0) { + break L1424; + } + } + } while (0); + if (C >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + c[C + 24 >> 2] = m; + h = c[d + (b + 16) >> 2] | 0; + do { + if ((h | 0) != 0) { + if (h >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[C + 16 >> 2] = h; + c[h + 24 >> 2] = C; + break; + } + } + } while (0); + h = c[d + (b + 20) >> 2] | 0; + if ((h | 0) == 0) { + break; + } + if (h >>> 0 < (c[212] | 0) >>> 0) { + au(); + } else { + c[C + 20 >> 2] = h; + c[h + 24 >> 2] = C; + break; + } + } + } while (0); + c[n + 4 >> 2] = A | 1; + c[n + A >> 2] = A; + if ((n | 0) != (c[213] | 0)) { + F = A; + break; + } + c[210] = A; + return; + } else { + c[y >> 2] = z & -2; + c[n + 4 >> 2] = o | 1; + c[n + o >> 2] = o; + F = o; + } + } while (0); + o = F >>> 3; + if (F >>> 0 < 256) { + z = o << 1; + y = 872 + (z << 2) | 0; + C = c[208] | 0; + b = 1 << o; + do { + if ((C & b | 0) == 0) { + c[208] = C | b; + G = y; + H = 872 + (z + 2 << 2) | 0; + } else { + o = 872 + (z + 2 << 2) | 0; + d = c[o >> 2] | 0; + if (d >>> 0 >= (c[212] | 0) >>> 0) { + G = d; + H = o; + break; + } + au(); + } + } while (0); + c[H >> 2] = n; + c[G + 12 >> 2] = n; + c[n + 8 >> 2] = G; + c[n + 12 >> 2] = y; + return; + } + y = n; + G = F >>> 8; + do { + if ((G | 0) == 0) { + I = 0; + } else { + if (F >>> 0 > 16777215) { + I = 31; + break; + } + H = (G + 1048320 | 0) >>> 16 & 8; + z = G << H; + b = (z + 520192 | 0) >>> 16 & 4; + C = z << b; + z = (C + 245760 | 0) >>> 16 & 2; + o = 14 - (b | H | z) + (C << z >>> 15) | 0; + I = F >>> ((o + 7 | 0) >>> 0) & 1 | o << 1; + } + } while (0); + G = 1136 + (I << 2) | 0; + c[n + 28 >> 2] = I; + c[n + 20 >> 2] = 0; + c[n + 16 >> 2] = 0; + o = c[209] | 0; + z = 1 << I; + if ((o & z | 0) == 0) { + c[209] = o | z; + c[G >> 2] = y; + c[n + 24 >> 2] = G; + c[n + 12 >> 2] = n; + c[n + 8 >> 2] = n; + return; + } + if ((I | 0) == 31) { + J = 0; + } else { + J = 25 - (I >>> 1) | 0; + } + I = F << J; + J = c[G >> 2] | 0; + while (1) { + if ((c[J + 4 >> 2] & -8 | 0) == (F | 0)) { + break; + } + K = J + 16 + (I >>> 31 << 2) | 0; + G = c[K >> 2] | 0; + if ((G | 0) == 0) { + L = 1120; + break; + } else { + I = I << 1; + J = G; + } + } + if ((L | 0) == 1120) { + if (K >>> 0 < (c[212] | 0) >>> 0) { + au(); + } + c[K >> 2] = y; + c[n + 24 >> 2] = J; + c[n + 12 >> 2] = n; + c[n + 8 >> 2] = n; + return; + } + K = J + 8 | 0; + L = c[K >> 2] | 0; + I = c[212] | 0; + if (J >>> 0 < I >>> 0) { + au(); + } + if (L >>> 0 < I >>> 0) { + au(); + } + c[L + 12 >> 2] = y; + c[K >> 2] = y; + c[n + 8 >> 2] = L; + c[n + 12 >> 2] = J; + c[n + 24 >> 2] = 0; + return; +} +function ca(a) { + a = a | 0; + var b = 0, d = 0, e = 0; + b = (a | 0) == 0 ? 1 : a; + while (1) { + d = bL(b) | 0; + if ((d | 0) != 0) { + e = 1164; + break; + } + a = (F = c[328] | 0, c[328] = F + 0, F); + if ((a | 0) == 0) { + break; + } + a5[a & 1](); + } + if ((e | 0) == 1164) { + return d | 0; + } + d = aJ(4) | 0; + c[d >> 2] = 560; + as(d | 0, 688, 6); + return 0; +} +function cb(a, b) { + a = a | 0; + b = b | 0; + return ca(a) | 0; +} +function cc(a) { + a = a | 0; + return; +} +function cd(a) { + a = a | 0; + return 360 | 0; +} +function ce(a) { + a = a | 0; + return 448 | 0; +} +function cf(a) { + a = a | 0; + return (F = c[328] | 0, c[328] = a, F) | 0; +} +function cg(a) { + a = a | 0; + c[a >> 2] = 560; + return; +} +function ch(a) { + a = a | 0; + c[a >> 2] = 592; + return; +} +function ci(a) { + a = a | 0; + if ((a | 0) != 0) { + bM(a); + } + return; +} +function cj(a, b) { + a = a | 0; + b = b | 0; + ci(a); + return; +} +function ck(a) { + a = a | 0; + ci(a); + return; +} +function cl(a, b) { + a = a | 0; + b = b | 0; + ck(a); + return; +} +function cm(a) { + a = a | 0; + ci(a); + return; +} +function cn(a) { + a = a | 0; + ci(a); + return; +} +function co(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return cp(a, b, c, 0, 0, 0) | 0; +} +function cp(b, d, e, f, g, h) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + h = h | 0; + var j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0, O = 0, P = 0, Q = 0, R = 0, S = 0, T = 0, U = 0, V = 0, W = 0, X = 0, Y = 0, Z = 0, _ = 0, $ = 0, aa = 0, ab = 0, ac = 0, ad = 0; + j = i; + if ((e | 0) == 0) { + k = -1; + i = j; + return k | 0; + } + l = c[44] | 0; + if ((l | 0) == 0) { + c[196] = 1; + c[44] = 1; + m = 1; + n = 1; + o = 1190; + } else { + p = c[196] | 0; + q = c[74] | 0; + if ((q | 0) == -1 | (p | 0) != 0) { + m = p; + n = l; + o = 1190; + } else { + r = q; + s = p; + t = l; + } + } + if ((o | 0) == 1190) { + l = (aP(344) | 0) != 0 | 0; + c[74] = l; + r = l; + s = m; + t = n; + } + n = a[e] | 0; + if (n << 24 >> 24 == 45) { + u = h | 2; + o = 1194; + } else { + m = (r | 0) != 0 | n << 24 >> 24 == 43 ? h & -2 : h; + if (n << 24 >> 24 == 43) { + u = m; + o = 1194; + } else { + v = e; + w = m; + } + } + if ((o | 0) == 1194) { + v = e + 1 | 0; + w = u; + } + c[198] = 0; + if ((s | 0) == 0) { + x = t; + o = 1198; + } else { + c[50] = -1; + c[48] = -1; + z = t; + A = s; + o = 1197; + } + while (1) { + if ((o | 0) == 1197) { + o = 0; + if ((A | 0) == 0) { + x = z; + o = 1198; + continue; + } else { + B = z; + } + } else if ((o | 0) == 1198) { + o = 0; + s = c[40] | 0; + if ((a[s] | 0) == 0) { + B = x; + } else { + C = s; + D = x; + break; + } + } + c[196] = 0; + if ((B | 0) >= (b | 0)) { + o = 1200; + break; + } + E = d + (B << 2) | 0; + F = c[E >> 2] | 0; + c[40] = F; + if ((a[F] | 0) == 45) { + G = F + 1 | 0; + H = a[G] | 0; + if (H << 24 >> 24 != 0) { + o = 1232; + break; + } + if ((aB(v | 0, 45) | 0) != 0) { + o = 1232; + break; + } + } + c[40] = 824; + if ((w & 2 | 0) != 0) { + o = 1217; + break; + } + if ((w & 1 | 0) == 0) { + k = -1; + o = 1298; + break; + } + s = c[48] | 0; + do { + if ((s | 0) == -1) { + c[48] = B; + I = B; + J = 0; + } else { + t = c[50] | 0; + if ((t | 0) == -1) { + I = B; + J = 0; + break; + } + u = t - s | 0; + e = B - t | 0; + m = (u | 0) % (e | 0) | 0; + if ((m | 0) == 0) { + K = e; + } else { + n = e; + h = m; + while (1) { + m = (n | 0) % (h | 0) | 0; + if ((m | 0) == 0) { + K = h; + break; + } else { + n = h; + h = m; + } + } + } + h = (B - s | 0) / (K | 0) | 0; + do { + if ((K | 0) > 0) { + n = -u | 0; + if ((h | 0) > 0) { + L = 0; + } else { + M = B; + N = t; + O = s; + P = 0; + break; + } + do { + m = L + t | 0; + r = d + (m << 2) | 0; + l = 0; + p = m; + m = c[r >> 2] | 0; + while (1) { + q = ((p | 0) < (t | 0) ? e : n) + p | 0; + Q = d + (q << 2) | 0; + R = c[Q >> 2] | 0; + c[Q >> 2] = m; + c[r >> 2] = R; + Q = l + 1 | 0; + if ((Q | 0) < (h | 0)) { + l = Q; + p = q; + m = R; + } else { + break; + } + } + L = L + 1 | 0; + } while ((L | 0) < (K | 0)); + M = c[44] | 0; + N = c[50] | 0; + O = c[48] | 0; + P = c[196] | 0; + } else { + M = B; + N = t; + O = s; + P = 0; + } + } while (0); + c[48] = M - N + O; + c[50] = -1; + I = M; + J = P; + } + } while (0); + s = I + 1 | 0; + c[44] = s; + z = s; + A = J; + o = 1197; + } + do { + if ((o | 0) == 1298) { + i = j; + return k | 0; + } else if ((o | 0) == 1232) { + J = c[48] | 0; + A = c[50] | 0; + if ((J | 0) != -1 & (A | 0) == -1) { + c[50] = B; + S = a[G] | 0; + T = B; + } else { + S = H; + T = A; + } + if (S << 24 >> 24 == 0) { + C = F; + D = B; + break; + } + c[40] = G; + if ((a[G] | 0) != 45) { + C = G; + D = B; + break; + } + if ((a[F + 2 | 0] | 0) != 0) { + C = G; + D = B; + break; + } + A = B + 1 | 0; + c[44] = A; + c[40] = 824; + if ((T | 0) != -1) { + z = T - J | 0; + I = A - T | 0; + P = (z | 0) % (I | 0) | 0; + if ((P | 0) == 0) { + U = I; + } else { + M = I; + O = P; + while (1) { + P = (M | 0) % (O | 0) | 0; + if ((P | 0) == 0) { + U = O; + break; + } else { + M = O; + O = P; + } + } + } + O = (A - J | 0) / (U | 0) | 0; + do { + if ((U | 0) > 0) { + M = -z | 0; + if ((O | 0) > 0) { + V = 0; + } else { + W = T; + X = J; + Y = A; + break; + } + do { + P = V + T | 0; + N = d + (P << 2) | 0; + K = 0; + L = P; + P = c[N >> 2] | 0; + while (1) { + x = ((L | 0) < (T | 0) ? I : M) + L | 0; + s = d + (x << 2) | 0; + t = c[s >> 2] | 0; + c[s >> 2] = P; + c[N >> 2] = t; + s = K + 1 | 0; + if ((s | 0) < (O | 0)) { + K = s; + L = x; + P = t; + } else { + break; + } + } + V = V + 1 | 0; + } while ((V | 0) < (U | 0)); + W = c[50] | 0; + X = c[48] | 0; + Y = c[44] | 0; + } else { + W = T; + X = J; + Y = A; + } + } while (0); + c[44] = X - W + Y; + } + c[50] = -1; + c[48] = -1; + k = -1; + i = j; + return k | 0; + } else if ((o | 0) == 1200) { + c[40] = 824; + A = c[50] | 0; + J = c[48] | 0; + do { + if ((A | 0) == -1) { + if ((J | 0) == -1) { + break; + } + c[44] = J; + } else { + O = A - J | 0; + I = B - A | 0; + z = (O | 0) % (I | 0) | 0; + if ((z | 0) == 0) { + Z = I; + } else { + M = I; + P = z; + while (1) { + z = (M | 0) % (P | 0) | 0; + if ((z | 0) == 0) { + Z = P; + break; + } else { + M = P; + P = z; + } + } + } + P = (B - J | 0) / (Z | 0) | 0; + do { + if ((Z | 0) > 0) { + M = -O | 0; + if ((P | 0) > 0) { + _ = 0; + } else { + $ = A; + aa = J; + ab = B; + break; + } + do { + z = _ + A | 0; + L = d + (z << 2) | 0; + K = 0; + N = z; + z = c[L >> 2] | 0; + while (1) { + t = ((N | 0) < (A | 0) ? I : M) + N | 0; + x = d + (t << 2) | 0; + s = c[x >> 2] | 0; + c[x >> 2] = z; + c[L >> 2] = s; + x = K + 1 | 0; + if ((x | 0) < (P | 0)) { + K = x; + N = t; + z = s; + } else { + break; + } + } + _ = _ + 1 | 0; + } while ((_ | 0) < (Z | 0)); + $ = c[50] | 0; + aa = c[48] | 0; + ab = c[44] | 0; + } else { + $ = A; + aa = J; + ab = B; + } + } while (0); + c[44] = aa - $ + ab; + } + } while (0); + c[50] = -1; + c[48] = -1; + k = -1; + i = j; + return k | 0; + } else if ((o | 0) == 1217) { + c[44] = B + 1; + c[198] = c[E >> 2]; + k = 1; + i = j; + return k | 0; + } + } while (0); + E = (f | 0) != 0; + L1659 : do { + if (E) { + if ((C | 0) == (c[d + (D << 2) >> 2] | 0)) { + ac = C; + break; + } + B = a[C] | 0; + do { + if (B << 24 >> 24 == 45) { + c[40] = C + 1; + ad = 0; + } else { + if ((w & 4 | 0) == 0) { + ac = C; + break L1659; + } + if (B << 24 >> 24 == 58) { + ad = 0; + break; + } + ad = (aB(v | 0, B << 24 >> 24 | 0) | 0) != 0 | 0; + } + } while (0); + B = cv(d, v, f, g, ad) | 0; + if ((B | 0) == -1) { + ac = c[40] | 0; + break; + } + c[40] = 824; + k = B; + i = j; + return k | 0; + } else { + ac = C; + } + } while (0); + C = ac + 1 | 0; + c[40] = C; + ad = a[ac] | 0; + ac = ad << 24 >> 24; + if ((ad << 24 >> 24 | 0) == 45) { + if ((a[C] | 0) == 0) { + o = 1260; + } + } else if ((ad << 24 >> 24 | 0) == 58) { + o = 1263; + } else { + o = 1260; + } + do { + if ((o | 0) == 1260) { + w = aB(v | 0, ac | 0) | 0; + if ((w | 0) == 0) { + if (ad << 24 >> 24 != 45) { + o = 1263; + break; + } + if ((a[C] | 0) == 0) { + k = -1; + } else { + break; + } + i = j; + return k | 0; + } + D = a[w + 1 | 0] | 0; + if (E & ad << 24 >> 24 == 87 & D << 24 >> 24 == 59) { + do { + if ((a[C] | 0) == 0) { + B = (c[44] | 0) + 1 | 0; + c[44] = B; + if ((B | 0) < (b | 0)) { + c[40] = c[d + (B << 2) >> 2]; + break; + } + c[40] = 824; + do { + if ((c[46] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + cx(48, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[42] = ac; + k = (a[v] | 0) == 58 ? 58 : 63; + i = j; + return k | 0; + } + } while (0); + B = cv(d, v, f, g, 0) | 0; + c[40] = 824; + k = B; + i = j; + return k | 0; + } + if (D << 24 >> 24 != 58) { + if ((a[C] | 0) != 0) { + k = ac; + i = j; + return k | 0; + } + c[44] = (c[44] | 0) + 1; + k = ac; + i = j; + return k | 0; + } + c[198] = 0; + do { + if ((a[C] | 0) == 0) { + if ((a[w + 2 | 0] | 0) == 58) { + break; + } + B = (c[44] | 0) + 1 | 0; + c[44] = B; + if ((B | 0) < (b | 0)) { + c[198] = c[d + (B << 2) >> 2]; + break; + } + c[40] = 824; + do { + if ((c[46] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + cx(48, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[42] = ac; + k = (a[v] | 0) == 58 ? 58 : 63; + i = j; + return k | 0; + } else { + c[198] = C; + } + } while (0); + c[40] = 824; + c[44] = (c[44] | 0) + 1; + k = ac; + i = j; + return k | 0; + } + } while (0); + do { + if ((o | 0) == 1263) { + if ((a[C] | 0) != 0) { + break; + } + c[44] = (c[44] | 0) + 1; + } + } while (0); + do { + if ((c[46] | 0) != 0) { + if ((a[v] | 0) == 58) { + break; + } + cx(272, (y = i, i = i + 8 | 0, c[y >> 2] = ac, y) | 0); + } + } while (0); + c[42] = ac; + k = 63; + i = j; + return k | 0; +} +function cq(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + return cp(a, b, c, d, e, 1) | 0; +} +function cr(a, b, c, d, e) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + e = e | 0; + return cp(a, b, c, d, e, 5) | 0; +} +function cs(a) { + a = a | 0; + return ca(a) | 0; +} +function ct(a, b) { + a = a | 0; + b = b | 0; + return cs(a) | 0; +} +function cu() { + var a = 0; + a = aJ(4) | 0; + c[a >> 2] = 560; + as(a | 0, 688, 6); +} +function cv(b, d, e, f, g) { + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + g = g | 0; + var h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, z = 0; + h = i; + j = c[40] | 0; + k = c[44] | 0; + l = k + 1 | 0; + c[44] = l; + m = aB(j | 0, 61) | 0; + if ((m | 0) == 0) { + n = cM(j | 0) | 0; + o = 0; + } else { + n = m - j | 0; + o = m + 1 | 0; + } + m = c[e >> 2] | 0; + L1739 : do { + if ((m | 0) != 0) { + L1741 : do { + if ((g | 0) != 0 & (n | 0) == 1) { + p = 0; + q = m; + while (1) { + if ((a[j] | 0) == (a[q] | 0)) { + if ((cM(q | 0) | 0) == 1) { + r = p; + break L1741; + } + } + p = p + 1 | 0; + q = c[e + (p << 4) >> 2] | 0; + if ((q | 0) == 0) { + break L1739; + } + } + } else { + q = 0; + p = -1; + s = m; + while (1) { + if ((ap(j | 0, s | 0, n | 0) | 0) == 0) { + if ((cM(s | 0) | 0) == (n | 0)) { + r = q; + break L1741; + } + if ((p | 0) == -1) { + t = q; + } else { + break; + } + } else { + t = p; + } + u = q + 1 | 0; + v = c[e + (u << 4) >> 2] | 0; + if ((v | 0) == 0) { + r = t; + break L1741; + } else { + q = u; + p = t; + s = v; + } + } + do { + if ((c[46] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + cx(304, (y = i, i = i + 16 | 0, c[y >> 2] = n, c[y + 8 >> 2] = j, y) | 0); + } + } while (0); + c[42] = 0; + w = 63; + i = h; + return w | 0; + } + } while (0); + if ((r | 0) == -1) { + break; + } + s = e + (r << 4) + 4 | 0; + p = c[s >> 2] | 0; + q = (o | 0) == 0; + if (!((p | 0) != 0 | q)) { + do { + if ((c[46] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + cx(208, (y = i, i = i + 16 | 0, c[y >> 2] = n, c[y + 8 >> 2] = j, y) | 0); + } + } while (0); + if ((c[e + (r << 4) + 8 >> 2] | 0) == 0) { + x = c[e + (r << 4) + 12 >> 2] | 0; + } else { + x = 0; + } + c[42] = x; + w = (a[d] | 0) == 58 ? 58 : 63; + i = h; + return w | 0; + } + do { + if ((p - 1 | 0) >>> 0 < 2) { + if (!q) { + c[198] = o; + break; + } + if ((p | 0) != 1) { + break; + } + c[44] = k + 2; + c[198] = c[b + (l << 2) >> 2]; + } + } while (0); + if (!((c[s >> 2] | 0) == 1 & (c[198] | 0) == 0)) { + if ((f | 0) != 0) { + c[f >> 2] = r; + } + p = c[e + (r << 4) + 8 >> 2] | 0; + q = c[e + (r << 4) + 12 >> 2] | 0; + if ((p | 0) == 0) { + w = q; + i = h; + return w | 0; + } + c[p >> 2] = q; + w = 0; + i = h; + return w | 0; + } + do { + if ((c[46] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + cx(8, (y = i, i = i + 8 | 0, c[y >> 2] = j, y) | 0); + } + } while (0); + if ((c[e + (r << 4) + 8 >> 2] | 0) == 0) { + z = c[e + (r << 4) + 12 >> 2] | 0; + } else { + z = 0; + } + c[42] = z; + c[44] = (c[44] | 0) - 1; + w = (a[d] | 0) == 58 ? 58 : 63; + i = h; + return w | 0; + } + } while (0); + if ((g | 0) != 0) { + c[44] = k; + w = -1; + i = h; + return w | 0; + } + do { + if ((c[46] | 0) != 0) { + if ((a[d] | 0) == 58) { + break; + } + cx(248, (y = i, i = i + 8 | 0, c[y >> 2] = j, y) | 0); + } + } while (0); + c[42] = 0; + w = 63; + i = h; + return w | 0; +} +function cw(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + i = i + 16 | 0; + e = d | 0; + f = e; + c[f >> 2] = b; + c[f + 4 >> 2] = 0; + cy(a, e | 0); + i = d; + return; +} +function cx(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + i = i + 16 | 0; + e = d | 0; + f = e; + c[f >> 2] = b; + c[f + 4 >> 2] = 0; + cz(a, e | 0); + i = d; + return; +} +function cy(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0, f = 0; + d = i; + e = c[(aX() | 0) >> 2] | 0; + f = c[r >> 2] | 0; + av(c[o >> 2] | 0, 432, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + if ((a | 0) != 0) { + f = c[o >> 2] | 0; + aQ(f | 0, a | 0, b | 0) | 0; + b = c[o >> 2] | 0; + aE(472, 2, 1, b | 0) | 0; + } + b = c[o >> 2] | 0; + a = at(e | 0) | 0; + av(b | 0, 384, (y = i, i = i + 8 | 0, c[y >> 2] = a, y) | 0) | 0; + i = d; + return; +} +function cz(a, b) { + a = a | 0; + b = b | 0; + var d = 0, e = 0; + d = i; + e = c[r >> 2] | 0; + av(c[o >> 2] | 0, 376, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + if ((a | 0) != 0) { + e = c[o >> 2] | 0; + aQ(e | 0, a | 0, b | 0) | 0; + } + aC(10, c[o >> 2] | 0) | 0; + i = d; + return; +} +function cA(b, d) { + b = b | 0; + d = d | 0; + var e = 0, f = 0, g = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0.0, r = 0, s = 0, t = 0, u = 0, v = 0.0, w = 0, x = 0, y = 0, z = 0.0, A = 0.0, B = 0, C = 0, D = 0, E = 0.0, F = 0, G = 0, H = 0, I = 0, J = 0, K = 0, L = 0, M = 0, N = 0.0, O = 0, P = 0, Q = 0.0, R = 0.0, S = 0.0; + e = b; + while (1) { + f = e + 1 | 0; + if ((aK(a[e] | 0) | 0) == 0) { + break; + } else { + e = f; + } + } + g = a[e] | 0; + if ((g << 24 >> 24 | 0) == 45) { + i = f; + j = 1; + } else if ((g << 24 >> 24 | 0) == 43) { + i = f; + j = 0; + } else { + i = e; + j = 0; + } + e = -1; + f = 0; + g = i; + while (1) { + k = a[g] | 0; + if (((k << 24 >> 24) - 48 | 0) >>> 0 < 10) { + l = e; + } else { + if (k << 24 >> 24 != 46 | (e | 0) > -1) { + break; + } else { + l = f; + } + } + e = l; + f = f + 1 | 0; + g = g + 1 | 0; + } + l = g + (-f | 0) | 0; + i = (e | 0) < 0; + m = ((i ^ 1) << 31 >> 31) + f | 0; + n = (m | 0) > 18; + o = (n ? -18 : -m | 0) + (i ? f : e) | 0; + e = n ? 18 : m; + do { + if ((e | 0) == 0) { + p = b; + q = 0.0; + } else { + if ((e | 0) > 9) { + m = l; + n = e; + f = 0; + while (1) { + i = a[m] | 0; + r = m + 1 | 0; + if (i << 24 >> 24 == 46) { + s = a[r] | 0; + t = m + 2 | 0; + } else { + s = i; + t = r; + } + u = (f * 10 | 0) - 48 + (s << 24 >> 24) | 0; + r = n - 1 | 0; + if ((r | 0) > 9) { + m = t; + n = r; + f = u; + } else { + break; + } + } + v = +(u | 0) * 1.0e9; + w = 9; + x = t; + y = 1393; + } else { + if ((e | 0) > 0) { + v = 0.0; + w = e; + x = l; + y = 1393; + } else { + z = 0.0; + A = 0.0; + } + } + if ((y | 0) == 1393) { + f = x; + n = w; + m = 0; + while (1) { + r = a[f] | 0; + i = f + 1 | 0; + if (r << 24 >> 24 == 46) { + B = a[i] | 0; + C = f + 2 | 0; + } else { + B = r; + C = i; + } + D = (m * 10 | 0) - 48 + (B << 24 >> 24) | 0; + i = n - 1 | 0; + if ((i | 0) > 0) { + f = C; + n = i; + m = D; + } else { + break; + } + } + z = +(D | 0); + A = v; + } + E = A + z; + do { + if ((k << 24 >> 24 | 0) == 69 | (k << 24 >> 24 | 0) == 101) { + m = g + 1 | 0; + n = a[m] | 0; + if ((n << 24 >> 24 | 0) == 43) { + F = g + 2 | 0; + G = 0; + } else if ((n << 24 >> 24 | 0) == 45) { + F = g + 2 | 0; + G = 1; + } else { + F = m; + G = 0; + } + m = a[F] | 0; + if (((m << 24 >> 24) - 48 | 0) >>> 0 < 10) { + H = F; + I = 0; + J = m; + } else { + K = 0; + L = F; + M = G; + break; + } + while (1) { + m = (I * 10 | 0) - 48 + (J << 24 >> 24) | 0; + n = H + 1 | 0; + f = a[n] | 0; + if (((f << 24 >> 24) - 48 | 0) >>> 0 < 10) { + H = n; + I = m; + J = f; + } else { + K = m; + L = n; + M = G; + break; + } + } + } else { + K = 0; + L = g; + M = 0; + } + } while (0); + n = o + ((M | 0) == 0 ? K : -K | 0) | 0; + m = (n | 0) < 0 ? -n | 0 : n; + if ((m | 0) > 511) { + c[(aX() | 0) >> 2] = 34; + N = 1.0; + O = 88; + P = 511; + y = 1410; + } else { + if ((m | 0) == 0) { + Q = 1.0; + } else { + N = 1.0; + O = 88; + P = m; + y = 1410; + } + } + if ((y | 0) == 1410) { + while (1) { + y = 0; + if ((P & 1 | 0) == 0) { + R = N; + } else { + R = N * +h[O >> 3]; + } + m = P >> 1; + if ((m | 0) == 0) { + Q = R; + break; + } else { + N = R; + O = O + 8 | 0; + P = m; + y = 1410; + } + } + } + if ((n | 0) > -1) { + p = L; + q = E * Q; + break; + } else { + p = L; + q = E / Q; + break; + } + } + } while (0); + if ((d | 0) != 0) { + c[d >> 2] = p; + } + if ((j | 0) == 0) { + S = q; + return +S; + } + S = -0.0 - q; + return +S; +} +function cB(a, b) { + a = a | 0; + b = b | 0; + return +(+cA(a, b)); +} +function cC(a, b) { + a = a | 0; + b = b | 0; + return +(+cA(a, b)); +} +function cD(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return +(+cA(a, b)); +} +function cE(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return +(+cA(a, b)); +} +function cF(a) { + a = a | 0; + return +(+cA(a, 0)); +} +function cG(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + e = f; + c[e >> 2] = d; + c[e + 4 >> 2] = 0; + cI(a, b, f | 0); +} +function cH(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = i; + i = i + 16 | 0; + f = e | 0; + e = f; + c[e >> 2] = d; + c[e + 4 >> 2] = 0; + cJ(a, b, f | 0); +} +function cI(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0, f = 0; + e = c[(aX() | 0) >> 2] | 0; + f = c[r >> 2] | 0; + av(c[o >> 2] | 0, 336, (y = i, i = i + 8 | 0, c[y >> 2] = f, y) | 0) | 0; + if ((b | 0) != 0) { + f = c[o >> 2] | 0; + aQ(f | 0, b | 0, d | 0) | 0; + d = c[o >> 2] | 0; + aE(480, 2, 1, d | 0) | 0; + } + d = c[o >> 2] | 0; + b = at(e | 0) | 0; + av(d | 0, 392, (y = i, i = i + 8 | 0, c[y >> 2] = b, y) | 0) | 0; + aH(a | 0); +} +function cJ(a, b, d) { + a = a | 0; + b = b | 0; + d = d | 0; + var e = 0; + e = c[r >> 2] | 0; + av(c[o >> 2] | 0, 440, (y = i, i = i + 8 | 0, c[y >> 2] = e, y) | 0) | 0; + if ((b | 0) != 0) { + e = c[o >> 2] | 0; + aQ(e | 0, b | 0, d | 0) | 0; + } + aC(10, c[o >> 2] | 0) | 0; + aH(a | 0); +} +function cK(b, d, e) { + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0; + f = b | 0; + if ((b & 3) == (d & 3)) { + while (b & 3) { + if ((e | 0) == 0) return f | 0; + a[b] = a[d] | 0; + b = b + 1 | 0; + d = d + 1 | 0; + e = e - 1 | 0; + } + while ((e | 0) >= 4) { + c[b >> 2] = c[d >> 2]; + b = b + 4 | 0; + d = d + 4 | 0; + e = e - 4 | 0; + } + } + while ((e | 0) > 0) { + a[b] = a[d] | 0; + b = b + 1 | 0; + d = d + 1 | 0; + e = e - 1 | 0; + } + return f | 0; +} +function cL(b, d, e) { + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0; + f = b + e | 0; + if ((e | 0) >= 20) { + d = d & 255; + e = b & 3; + g = d | d << 8 | d << 16 | d << 24; + h = f & ~3; + if (e) { + e = b + 4 - e | 0; + while ((b | 0) < (e | 0)) { + a[b] = d; + b = b + 1 | 0; + } + } + while ((b | 0) < (h | 0)) { + c[b >> 2] = g; + b = b + 4 | 0; + } + } + while ((b | 0) < (f | 0)) { + a[b] = d; + b = b + 1 | 0; + } +} +function cM(b) { + b = b | 0; + var c = 0; + c = b; + while (a[c] | 0) { + c = c + 1 | 0; + } + return c - b | 0; +} +function cN(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = a + c >>> 0; + return (H = b + d + (e >>> 0 < a >>> 0 | 0) >>> 0, e | 0) | 0; +} +function cO(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = b - d >>> 0; + e = b - d - (c >>> 0 > a >>> 0 | 0) >>> 0; + return (H = e, a - c >>> 0 | 0) | 0; +} +function cP(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b << c | (a & (1 << c) - 1 << 32 - c) >>> 32 - c; + return a << c; + } + H = a << c - 32; + return 0; +} +function cQ(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b >>> c; + return a >>> c | (b & (1 << c) - 1) << 32 - c; + } + H = 0; + return b >>> c - 32 | 0; +} +function cR(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + if ((c | 0) < 32) { + H = b >> c; + return a >>> c | (b & (1 << c) - 1) << 32 - c; + } + H = (b | 0) < 0 ? -1 : 0; + return b >> c - 32 | 0; +} +function cS(b) { + b = b | 0; + var c = 0; + c = a[n + (b >>> 24) | 0] | 0; + if ((c | 0) < 8) return c | 0; + c = a[n + (b >> 16 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 8 | 0; + c = a[n + (b >> 8 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 16 | 0; + return (a[n + (b & 255) | 0] | 0) + 24 | 0; +} +function cT(b) { + b = b | 0; + var c = 0; + c = a[m + (b & 255) | 0] | 0; + if ((c | 0) < 8) return c | 0; + c = a[m + (b >> 8 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 8 | 0; + c = a[m + (b >> 16 & 255) | 0] | 0; + if ((c | 0) < 8) return c + 16 | 0; + return (a[m + (b >>> 24) | 0] | 0) + 24 | 0; +} +function cU(a, b) { + a = a | 0; + b = b | 0; + var c = 0, d = 0, e = 0, f = 0; + c = a & 65535; + d = b & 65535; + e = ad(d, c) | 0; + f = a >>> 16; + a = (e >>> 16) + (ad(d, f) | 0) | 0; + d = b >>> 16; + b = ad(d, c) | 0; + return (H = (a >>> 16) + (ad(d, f) | 0) + (((a & 65535) + b | 0) >>> 16) | 0, a + b << 16 | e & 65535 | 0) | 0; +} +function cV(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0, g = 0, h = 0, i = 0; + e = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + f = ((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + g = d >> 31 | ((d | 0) < 0 ? -1 : 0) << 1; + h = ((d | 0) < 0 ? -1 : 0) >> 31 | ((d | 0) < 0 ? -1 : 0) << 1; + i = cO(e ^ a, f ^ b, e, f) | 0; + b = H; + a = g ^ e; + e = h ^ f; + f = cO((c_(i, b, cO(g ^ c, h ^ d, g, h) | 0, H, 0) | 0) ^ a, H ^ e, a, e) | 0; + return (H = H, f) | 0; +} +function cW(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0, h = 0, j = 0, k = 0, l = 0, m = 0; + f = i; + i = i + 8 | 0; + g = f | 0; + h = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + j = ((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + k = e >> 31 | ((e | 0) < 0 ? -1 : 0) << 1; + l = ((e | 0) < 0 ? -1 : 0) >> 31 | ((e | 0) < 0 ? -1 : 0) << 1; + m = cO(h ^ a, j ^ b, h, j) | 0; + b = H; + a = cO(k ^ d, l ^ e, k, l) | 0; + c_(m, b, a, H, g) | 0; + a = cO(c[g >> 2] ^ h, c[g + 4 >> 2] ^ j, h, j) | 0; + j = H; + i = f; + return (H = j, a) | 0; +} +function cX(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0, f = 0; + e = a; + a = c; + c = cU(e, a) | 0; + f = H; + return (H = (ad(b, a) | 0) + (ad(d, e) | 0) + f | f & 0, c | 0 | 0) | 0; +} +function cY(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + var e = 0; + e = c_(a, b, c, d, 0) | 0; + return (H = H, e) | 0; +} +function cZ(a, b, d, e) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + var f = 0, g = 0; + f = i; + i = i + 8 | 0; + g = f | 0; + c_(a, b, d, e, g) | 0; + i = f; + return (H = c[g + 4 >> 2] | 0, c[g >> 2] | 0) | 0; +} +function c_(a, b, d, e, f) { + a = a | 0; + b = b | 0; + d = d | 0; + e = e | 0; + f = f | 0; + var g = 0, h = 0, i = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0, t = 0, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0, A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, I = 0, J = 0, K = 0, L = 0, M = 0; + g = a; + h = b; + i = h; + j = d; + k = e; + l = k; + if ((i | 0) == 0) { + m = (f | 0) != 0; + if ((l | 0) == 0) { + if (m) { + c[f >> 2] = (g >>> 0) % (j >>> 0); + c[f + 4 >> 2] = 0; + } + n = 0; + o = (g >>> 0) / (j >>> 0) >>> 0; + return (H = n, o) | 0; + } else { + if (!m) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } + } + m = (l | 0) == 0; + do { + if ((j | 0) == 0) { + if (m) { + if ((f | 0) != 0) { + c[f >> 2] = (i >>> 0) % (j >>> 0); + c[f + 4 >> 2] = 0; + } + n = 0; + o = (i >>> 0) / (j >>> 0) >>> 0; + return (H = n, o) | 0; + } + if ((g | 0) == 0) { + if ((f | 0) != 0) { + c[f >> 2] = 0; + c[f + 4 >> 2] = (i >>> 0) % (l >>> 0); + } + n = 0; + o = (i >>> 0) / (l >>> 0) >>> 0; + return (H = n, o) | 0; + } + p = l - 1 | 0; + if ((p & l | 0) == 0) { + if ((f | 0) != 0) { + c[f >> 2] = a | 0; + c[f + 4 >> 2] = p & i | b & 0; + } + n = 0; + o = i >>> ((cT(l | 0) | 0) >>> 0); + return (H = n, o) | 0; + } + p = (cS(l | 0) | 0) - (cS(i | 0) | 0) | 0; + if (p >>> 0 <= 30) { + q = p + 1 | 0; + r = 31 - p | 0; + s = q; + t = i << r | g >>> (q >>> 0); + u = i >>> (q >>> 0); + v = 0; + w = g << r; + break; + } + if ((f | 0) == 0) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = h | b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } else { + if (!m) { + r = (cS(l | 0) | 0) - (cS(i | 0) | 0) | 0; + if (r >>> 0 <= 31) { + q = r + 1 | 0; + p = 31 - r | 0; + x = r - 31 >> 31; + s = q; + t = g >>> (q >>> 0) & x | i << p; + u = i >>> (q >>> 0) & x; + v = 0; + w = g << p; + break; + } + if ((f | 0) == 0) { + n = 0; + o = 0; + return (H = n, o) | 0; + } + c[f >> 2] = a | 0; + c[f + 4 >> 2] = h | b & 0; + n = 0; + o = 0; + return (H = n, o) | 0; + } + p = j - 1 | 0; + if ((p & j | 0) != 0) { + x = (cS(j | 0) | 0) + 33 - (cS(i | 0) | 0) | 0; + q = 64 - x | 0; + r = 32 - x | 0; + y = r >> 31; + z = x - 32 | 0; + A = z >> 31; + s = x; + t = r - 1 >> 31 & i >>> (z >>> 0) | (i << r | g >>> (x >>> 0)) & A; + u = A & i >>> (x >>> 0); + v = g << q & y; + w = (i << q | g >>> (z >>> 0)) & y | g << r & x - 33 >> 31; + break; + } + if ((f | 0) != 0) { + c[f >> 2] = p & g; + c[f + 4 >> 2] = 0; + } + if ((j | 0) == 1) { + n = h | b & 0; + o = a | 0 | 0; + return (H = n, o) | 0; + } else { + p = cT(j | 0) | 0; + n = i >>> (p >>> 0) | 0; + o = i << 32 - p | g >>> (p >>> 0) | 0; + return (H = n, o) | 0; + } + } + } while (0); + if ((s | 0) == 0) { + B = w; + C = v; + D = u; + E = t; + F = 0; + G = 0; + } else { + g = d | 0 | 0; + d = k | e & 0; + e = cN(g, d, -1, -1) | 0; + k = H; + i = w; + w = v; + v = u; + u = t; + t = s; + s = 0; + while (1) { + I = w >>> 31 | i << 1; + J = s | w << 1; + j = u << 1 | i >>> 31 | 0; + a = u >>> 31 | v << 1 | 0; + cO(e, k, j, a) | 0; + b = H; + h = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1; + K = h & 1; + L = cO(j, a, h & g, (((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1) & d) | 0; + M = H; + b = t - 1 | 0; + if ((b | 0) == 0) { + break; + } else { + i = I; + w = J; + v = M; + u = L; + t = b; + s = K; + } + } + B = I; + C = J; + D = M; + E = L; + F = 0; + G = K; + } + K = C; + C = 0; + if ((f | 0) != 0) { + c[f >> 2] = E; + c[f + 4 >> 2] = D; + } + n = (K | 0) >>> 31 | (B | C) << 1 | (C << 1 | K >>> 31) & 0 | F; + o = (K << 1 | 0 >>> 31) & -2 | G; + return (H = n, o) | 0; +} +function c$(a, b) { + a = a | 0; + b = b | 0; + a1[a & 15](b | 0); +} +function c0(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + a2[a & 15](b | 0, c | 0); +} +function c1(a, b) { + a = a | 0; + b = b | 0; + return a3[a & 7](b | 0) | 0; +} +function c2(a, b, c, d) { + a = a | 0; + b = b | 0; + c = c | 0; + d = d | 0; + a4[a & 15](b | 0, c | 0, d | 0); +} +function c3(a) { + a = a | 0; + a5[a & 1](); +} +function c4(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + return a6[a & 1](b | 0, c | 0) | 0; +} +function c5(a) { + a = a | 0; + ae(0); +} +function c6(a, b) { + a = a | 0; + b = b | 0; + ae(1); +} +function c7(a) { + a = a | 0; + ae(2); + return 0; +} +function c8(a, b, c) { + a = a | 0; + b = b | 0; + c = c | 0; + ae(3); +} +function c9() { + ae(4); +} +function da(a, b) { + a = a | 0; + b = b | 0; + ae(5); + return 0; +} +// EMSCRIPTEN_END_FUNCS + var a1 = [ c5, c5, ch, c5, cn, c5, cc, c5, cg, c5, cm, c5, c5, c5, c5, c5 ]; + var a2 = [ c6, c6, cw, c6, cy, c6, cx, c6, cz, c6, c6, c6, c6, c6, c6, c6 ]; + var a3 = [ c7, c7, cd, c7, ce, c7, c7, c7 ]; + var a4 = [ c8, c8, cJ, c8, cI, c8, cG, c8, cH, c8, c8, c8, c8, c8, c8, c8 ]; + var a5 = [ c9, c9 ]; + var a6 = [ da, da ]; + return { + _crypto_scrypt: bu, + _strlen: cM, + _free: bM, + _realloc: bO, + _memset: cL, + _malloc: bL, + _memcpy: cK, + _calloc: bN, + runPostSets: bn, + stackAlloc: a7, + stackSave: a8, + stackRestore: a9, + setThrew: ba, + setTempRet0: bd, + setTempRet1: be, + setTempRet2: bf, + setTempRet3: bg, + setTempRet4: bh, + setTempRet5: bi, + setTempRet6: bj, + setTempRet7: bk, + setTempRet8: bl, + setTempRet9: bm, + dynCall_vi: c$, + dynCall_vii: c0, + dynCall_ii: c1, + dynCall_viii: c2, + dynCall_v: c3, + dynCall_iii: c4 + }; +// EMSCRIPTEN_END_ASM +})({Math:Math, Int8Array:Int8Array, Int16Array:Int16Array, Int32Array:Int32Array, Uint8Array:Uint8Array, Uint16Array:Uint16Array, Uint32Array:Uint32Array, Float32Array:Float32Array, Float64Array:Float64Array}, {abort:wa, assert:w, asmPrintInt:function(a, b) { + s.print("int " + a + "," + b) +}, asmPrintFloat:function(a, b) { + s.print("float " + a + "," + b) +}, min:Xc, invoke_vi:function(a, b) { + try { + s.dynCall_vi(a, b) + }catch(c) { + "number" !== typeof c && "longjmp" !== c && g(c), V.setThrew(1, 0) + } +}, invoke_vii:function(a, b, c) { + try { + s.dynCall_vii(a, b, c) + }catch(d) { + "number" !== typeof d && "longjmp" !== d && g(d), V.setThrew(1, 0) + } +}, invoke_ii:function(a, b) { + try { + return s.dynCall_ii(a, b) + }catch(c) { + "number" !== typeof c && "longjmp" !== c && g(c), V.setThrew(1, 0) + } +}, invoke_viii:function(a, b, c, d) { + try { + s.dynCall_viii(a, b, c, d) + }catch(e) { + "number" !== typeof e && "longjmp" !== e && g(e), V.setThrew(1, 0) + } +}, invoke_v:function(a) { + try { + s.dynCall_v(a) + }catch(b) { + "number" !== typeof b && "longjmp" !== b && g(b), V.setThrew(1, 0) + } +}, invoke_iii:function(a, b, c) { + try { + return s.dynCall_iii(a, b, c) + }catch(d) { + "number" !== typeof d && "longjmp" !== d && g(d), V.setThrew(1, 0) + } +}, _strncmp:function(a, b, c) { + for(var d = 0;d < c;) { + var e = G[a + d | 0], f = G[b + d | 0]; + if(e == f && 0 == e) { + break + } + if(0 == e) { + return-1 + } + if(0 == f) { + return 1 + } + if(e == f) { + d++ + }else { + return e > f ? 1 : -1 + } + } + return 0 +}, _llvm_va_end:aa(), _sysconf:function(a) { + switch(a) { + case 8: + return 4096; + case 54: + ; + case 56: + ; + case 21: + ; + case 61: + ; + case 63: + ; + case 22: + ; + case 67: + ; + case 23: + ; + case 24: + ; + case 25: + ; + case 26: + ; + case 27: + ; + case 69: + ; + case 28: + ; + case 101: + ; + case 70: + ; + case 71: + ; + case 29: + ; + case 30: + ; + case 199: + ; + case 75: + ; + case 76: + ; + case 32: + ; + case 43: + ; + case 44: + ; + case 80: + ; + case 46: + ; + case 47: + ; + case 45: + ; + case 48: + ; + case 49: + ; + case 42: + ; + case 82: + ; + case 33: + ; + case 7: + ; + case 108: + ; + case 109: + ; + case 107: + ; + case 112: + ; + case 119: + ; + case 121: + return 200809; + case 13: + ; + case 104: + ; + case 94: + ; + case 95: + ; + case 34: + ; + case 35: + ; + case 77: + ; + case 81: + ; + case 83: + ; + case 84: + ; + case 85: + ; + case 86: + ; + case 87: + ; + case 88: + ; + case 89: + ; + case 90: + ; + case 91: + ; + case 94: + ; + case 95: + ; + case 110: + ; + case 111: + ; + case 113: + ; + case 114: + ; + case 115: + ; + case 116: + ; + case 117: + ; + case 118: + ; + case 120: + ; + case 40: + ; + case 16: + ; + case 79: + ; + case 19: + return-1; + case 92: + ; + case 93: + ; + case 5: + ; + case 72: + ; + case 6: + ; + case 74: + ; + case 92: + ; + case 93: + ; + case 96: + ; + case 97: + ; + case 98: + ; + case 99: + ; + case 102: + ; + case 103: + ; + case 105: + return 1; + case 38: + ; + case 66: + ; + case 50: + ; + case 51: + ; + case 4: + return 1024; + case 15: + ; + case 64: + ; + case 41: + return 32; + case 55: + ; + case 37: + ; + case 17: + return 2147483647; + case 18: + ; + case 1: + return 47839; + case 59: + ; + case 57: + return 99; + case 68: + ; + case 58: + return 2048; + case 0: + return 2097152; + case 3: + return 65536; + case 14: + return 32768; + case 73: + return 32767; + case 39: + return 16384; + case 60: + return 1E3; + case 106: + return 700; + case 52: + return 256; + case 62: + return 255; + case 2: + return 100; + case 65: + return 64; + case 36: + return 20; + case 100: + return 16; + case 20: + return 6; + case 53: + return 4; + case 10: + return 1 + } + M(N.A); + return-1 +}, ___cxa_throw:rc, _strerror:zc, _abort:function() { + s.abort() +}, _fprintf:mc, _llvm_eh_exception:U, ___cxa_free_exception:sc, _fflush:aa(), ___buildEnvironment:wc, __reallyNegative:jc, _strchr:function(a, b) { + a--; + do { + a++; + var c = A[a]; + if(c == b) { + return a + } + }while(c); + return 0 +}, _fputc:Bc, ___setErrNo:M, _fwrite:hc, _send:fc, _write:gc, _exit:function(a) { + Ac(a) +}, ___cxa_find_matching_catch:function(a, b) { + -1 == a && (a = B[U.m >> 2]); + -1 == b && (b = B[U.m + 4 >> 2]); + var c = Array.prototype.slice.call(arguments, 2); + 0 != b && !pc(b) && 0 == B[B[b >> 2] - 8 >> 2] && (a = B[a >> 2]); + for(var d = 0;d < c.length;d++) { + if(qc(c[d], b, a)) { + return(V.setTempRet0(c[d]), a) | 0 + } + } + return(V.setTempRet0(b), a) | 0 +}, ___cxa_allocate_exception:function(a) { + return Oa(a) +}, _isspace:function(a) { + return 32 == a || 9 <= a && 13 >= a +}, __formatString:kc, ___resumeException:function(a) { + 0 == B[U.m >> 2] && (B[U.m >> 2] = a); + g(a + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.") +}, _llvm_uadd_with_overflow_i32:function(a, b) { + a >>>= 0; + b >>>= 0; + return(V.setTempRet0(4294967295 < a + b), a + b >>> 0) | 0 +}, ___cxa_does_inherit:qc, _getenv:xc, _vfprintf:function(a, b, c) { + return mc(a, b, B[c >> 2]) +}, ___cxa_begin_catch:function(a) { + oc.ta--; + return a +}, __ZSt18uncaught_exceptionv:oc, _pwrite:function(a, b, c, d) { + a = R[a]; + if(!a) { + return M(N.$), -1 + } + try { + return Ib(a, A, b, c, d) + }catch(e) { + return Zb(e), -1 + } +}, ___cxa_call_unexpected:function(a) { + s.P("Unexpected exception thrown, this is not properly supported - aborting"); + za = l; + g(a) +}, _sbrk:nc, _strerror_r:yc, ___errno_location:function() { + return rb +}, ___gxx_personality_v0:aa(), ___cxa_is_number_type:pc, _time:function(a) { + var b = Math.floor(Date.now() / 1E3); + a && (B[a >> 2] = b); + return b +}, __exit:Ac, ___cxa_end_catch:uc, STACKTOP:u, STACK_MAX:Ta, tempDoublePtr:qb, ABORT:za, cttz_i8:Wc, ctlz_i8:Vc, NaN:NaN, Infinity:Infinity, _stderr:nb, __ZTVN10__cxxabiv120__si_class_type_infoE:ob, __ZTVN10__cxxabiv117__class_type_infoE:pb, ___progname:k}, I); +s._crypto_scrypt = V._crypto_scrypt; +var ic = s._strlen = V._strlen, tc = s._free = V._free; +s._realloc = V._realloc; +var tb = s._memset = V._memset, Oa = s._malloc = V._malloc, sb = s._memcpy = V._memcpy; +s._calloc = V._calloc; +var mb = s.runPostSets = V.runPostSets; +s.dynCall_vi = V.dynCall_vi; +s.dynCall_vii = V.dynCall_vii; +s.dynCall_ii = V.dynCall_ii; +s.dynCall_viii = V.dynCall_viii; +s.dynCall_v = V.dynCall_v; +s.dynCall_iii = V.dynCall_iii; +var qa = function(a) { + return V.stackAlloc(a) +}, ja = function() { + return V.stackSave() +}, ka = function(a) { + V.stackRestore(a) +}, lc; +function X(a, b) { + a != m && ("number" == typeof a ? this.p(a) : b == m && "string" != typeof a ? this.k(a, 256) : this.k(a, b)) +} +function Yc() { + return new X(m) +} +function Zc(a, b) { + var c = $c[a.charCodeAt(b)]; + return c == m ? -1 : c +} +function ad(a) { + var b = Yc(); + b.D(a); + return b +} +function Y(a, b) { + this.h = a | 0; + this.j = b | 0 +} +Y.Ca = {}; +Y.D = function(a) { + if(-128 <= a && 128 > a) { + var b = Y.Ca[a]; + if(b) { + return b + } + } + b = new Y(a | 0, 0 > a ? -1 : 0); + -128 <= a && 128 > a && (Y.Ca[a] = b); + return b +}; +Y.p = function(a) { + return isNaN(a) || !isFinite(a) ? Y.ZERO : a <= -Y.Ea ? Y.MIN_VALUE : a + 1 >= Y.Ea ? Y.MAX_VALUE : 0 > a ? Y.p(-a).i() : new Y(a % Y.B | 0, a / Y.B | 0) +}; +Y.v = function(a, b) { + return new Y(a, b) +}; +Y.k = function(a, b) { + 0 == a.length && g(Error("number format error: empty string")); + var c = b || 10; + (2 > c || 36 < c) && g(Error("radix out of range: " + c)); + if("-" == a.charAt(0)) { + return Y.k(a.substring(1), c).i() + } + 0 <= a.indexOf("-") && g(Error('number format error: interior "-" character: ' + a)); + for(var d = Y.p(Math.pow(c, 8)), e = Y.ZERO, f = 0;f < a.length;f += 8) { + var h = Math.min(8, a.length - f), i = parseInt(a.substring(f, f + h), c); + 8 > h ? (h = Y.p(Math.pow(c, h)), e = e.multiply(h).add(Y.p(i))) : (e = e.multiply(d), e = e.add(Y.p(i))) + } + return e +}; +Y.ea = 65536; +Y.Od = 16777216; +Y.B = Y.ea * Y.ea; +Y.Pd = Y.B / 2; +Y.Qd = Y.B * Y.ea; +Y.eb = Y.B * Y.B; +Y.Ea = Y.eb / 2; +Y.ZERO = Y.D(0); +Y.ONE = Y.D(1); +Y.Da = Y.D(-1); +Y.MAX_VALUE = Y.v(-1, 2147483647); +Y.MIN_VALUE = Y.v(0, -2147483648); +Y.cb = Y.D(16777216); +q = Y.prototype; +q.Z = function() { + return this.j * Y.B + this.ob() +}; +q.toString = function(a) { + a = a || 10; + (2 > a || 36 < a) && g(Error("radix out of range: " + a)); + if(this.G()) { + return"0" + } + if(this.n()) { + if(this.o(Y.MIN_VALUE)) { + var b = Y.p(a), c = this.F(b), b = c.multiply(b).R(this); + return c.toString(a) + b.h.toString(a) + } + return"-" + this.i().toString(a) + } + for(var c = Y.p(Math.pow(a, 6)), b = this, d = "";;) { + var e = b.F(c), f = b.R(e.multiply(c)).h.toString(a), b = e; + if(b.G()) { + return f + d + } + for(;6 > f.length;) { + f = "0" + f + } + d = "" + f + d + } +}; +q.ob = function() { + return 0 <= this.h ? this.h : Y.B + this.h +}; +q.G = function() { + return 0 == this.j && 0 == this.h +}; +q.n = function() { + return 0 > this.j +}; +q.Pa = function() { + return 1 == (this.h & 1) +}; +q.o = function(a) { + return this.j == a.j && this.h == a.h +}; +q.Ra = function() { + return 0 > this.ja(Y.cb) +}; +q.qb = function(a) { + return 0 < this.ja(a) +}; +q.rb = function(a) { + return 0 <= this.ja(a) +}; +q.ja = function(a) { + if(this.o(a)) { + return 0 + } + var b = this.n(), c = a.n(); + return b && !c ? -1 : !b && c ? 1 : this.R(a).n() ? -1 : 1 +}; +q.i = function() { + return this.o(Y.MIN_VALUE) ? Y.MIN_VALUE : this.xb().add(Y.ONE) +}; +q.add = function(a) { + var b = this.j >>> 16, c = this.j & 65535, d = this.h >>> 16, e = a.j >>> 16, f = a.j & 65535, h = a.h >>> 16, i; + i = 0 + ((this.h & 65535) + (a.h & 65535)); + a = 0 + (i >>> 16); + a += d + h; + d = 0 + (a >>> 16); + d += c + f; + c = 0 + (d >>> 16); + c = c + (b + e) & 65535; + return Y.v((a & 65535) << 16 | i & 65535, c << 16 | d & 65535) +}; +q.R = function(a) { + return this.add(a.i()) +}; +q.multiply = function(a) { + if(this.G() || a.G()) { + return Y.ZERO + } + if(this.o(Y.MIN_VALUE)) { + return a.Pa() ? Y.MIN_VALUE : Y.ZERO + } + if(a.o(Y.MIN_VALUE)) { + return this.Pa() ? Y.MIN_VALUE : Y.ZERO + } + if(this.n()) { + return a.n() ? this.i().multiply(a.i()) : this.i().multiply(a).i() + } + if(a.n()) { + return this.multiply(a.i()).i() + } + if(this.Ra() && a.Ra()) { + return Y.p(this.Z() * a.Z()) + } + var b = this.j >>> 16, c = this.j & 65535, d = this.h >>> 16, e = this.h & 65535, f = a.j >>> 16, h = a.j & 65535, i = a.h >>> 16, a = a.h & 65535, j, n, y, v; + v = 0 + e * a; + y = 0 + (v >>> 16); + y += d * a; + n = 0 + (y >>> 16); + y = (y & 65535) + e * i; + n += y >>> 16; + y &= 65535; + n += c * a; + j = 0 + (n >>> 16); + n = (n & 65535) + d * i; + j += n >>> 16; + n &= 65535; + n += e * h; + j += n >>> 16; + n &= 65535; + j = j + (b * a + c * i + d * h + e * f) & 65535; + return Y.v(y << 16 | v & 65535, j << 16 | n) +}; +q.F = function(a) { + a.G() && g(Error("division by zero")); + if(this.G()) { + return Y.ZERO + } + if(this.o(Y.MIN_VALUE)) { + if(a.o(Y.ONE) || a.o(Y.Da)) { + return Y.MIN_VALUE + } + if(a.o(Y.MIN_VALUE)) { + return Y.ONE + } + var b = this.Db().F(a).shiftLeft(1); + if(b.o(Y.ZERO)) { + return a.n() ? Y.ONE : Y.Da + } + var c = this.R(a.multiply(b)); + return b.add(c.F(a)) + } + if(a.o(Y.MIN_VALUE)) { + return Y.ZERO + } + if(this.n()) { + return a.n() ? this.i().F(a.i()) : this.i().F(a).i() + } + if(a.n()) { + return this.F(a.i()).i() + } + for(var d = Y.ZERO, c = this;c.rb(a);) { + for(var b = Math.max(1, Math.floor(c.Z() / a.Z())), e = Math.ceil(Math.log(b) / Math.LN2), e = 48 >= e ? 1 : Math.pow(2, e - 48), f = Y.p(b), h = f.multiply(a);h.n() || h.qb(c);) { + b -= e, f = Y.p(b), h = f.multiply(a) + } + f.G() && (f = Y.ONE); + d = d.add(f); + c = c.R(h) + } + return d +}; +q.xb = function() { + return Y.v(~this.h, ~this.j) +}; +q.shiftLeft = function(a) { + a &= 63; + if(0 == a) { + return this + } + var b = this.h; + return 32 > a ? Y.v(b << a, this.j << a | b >>> 32 - a) : Y.v(0, b << a - 32) +}; +q.Db = function() { + var a; + a = 1; + if(0 == a) { + return this + } + var b = this.j; + return 32 > a ? Y.v(this.h >>> a | b << 32 - a, b >> a) : Y.v(b >> a - 32, 0 <= b ? 0 : -1) +}; +q = X.prototype; +q.ga = function(a, b, c, d) { + for(var e = 0, f = 0;0 <= --d;) { + var h = a * this[e++] + b[c] + f, f = Math.floor(h / 67108864); + b[c++] = h & 67108863 + } + return f +}; +q.f = 26; +q.u = 67108863; +q.K = 67108864; +q.bb = Math.pow(2, 52); +q.Aa = 26; +q.Ba = 0; +var $c = [], bd, Z; +bd = 48; +for(Z = 0;9 >= Z;++Z) { + $c[bd++] = Z +} +bd = 97; +for(Z = 10;36 > Z;++Z) { + $c[bd++] = Z +} +bd = 65; +for(Z = 10;36 > Z;++Z) { + $c[bd++] = Z +} +q = X.prototype; +q.copyTo = function(a) { + for(var b = this.b - 1;0 <= b;--b) { + a[b] = this[b] + } + a.b = this.b; + a.c = this.c +}; +q.D = function(a) { + this.b = 1; + this.c = 0 > a ? -1 : 0; + 0 < a ? this[0] = a : -1 > a ? this[0] = a + DV : this.b = 0 +}; +q.k = function(a, b) { + var c; + if(16 == b) { + c = 4 + }else { + if(8 == b) { + c = 3 + }else { + if(256 == b) { + c = 8 + }else { + if(2 == b) { + c = 1 + }else { + if(32 == b) { + c = 5 + }else { + if(4 == b) { + c = 2 + }else { + this.nb(a, b); + return + } + } + } + } + } + } + this.c = this.b = 0; + for(var d = a.length, e = p, f = 0;0 <= --d;) { + var h = 8 == c ? a[d] & 255 : Zc(a, d); + 0 > h ? "-" == a.charAt(d) && (e = l) : (e = p, 0 == f ? this[this.b++] = h : f + c > this.f ? (this[this.b - 1] |= (h & (1 << this.f - f) - 1) << f, this[this.b++] = h >> this.f - f) : this[this.b - 1] |= h << f, f += c, f >= this.f && (f -= this.f)) + } + 8 == c && 0 != (a[0] & 128) && (this.c = -1, 0 < f && (this[this.b - 1] |= (1 << this.f - f) - 1 << f)); + this.C(); + e && X.ZERO.t(this, this) +}; +q.C = function() { + for(var a = this.c & this.u;0 < this.b && this[this.b - 1] == a;) { + --this.b + } +}; +q.la = function(a, b) { + var c; + for(c = this.b - 1;0 <= c;--c) { + b[c + a] = this[c] + } + for(c = a - 1;0 <= c;--c) { + b[c] = 0 + } + b.b = this.b + a; + b.c = this.c +}; +q.jb = function(a, b) { + for(var c = a;c < this.b;++c) { + b[c - a] = this[c] + } + b.b = Math.max(this.b - a, 0); + b.c = this.c +}; +q.Qa = function(a, b) { + var c = a % this.f, d = this.f - c, e = (1 << d) - 1, f = Math.floor(a / this.f), h = this.c << c & this.u, i; + for(i = this.b - 1;0 <= i;--i) { + b[i + f + 1] = this[i] >> d | h, h = (this[i] & e) << c + } + for(i = f - 1;0 <= i;--i) { + b[i] = 0 + } + b[f] = h; + b.b = this.b + f + 1; + b.c = this.c; + b.C() +}; +q.zb = function(a, b) { + b.c = this.c; + var c = Math.floor(a / this.f); + if(c >= this.b) { + b.b = 0 + }else { + var d = a % this.f, e = this.f - d, f = (1 << d) - 1; + b[0] = this[c] >> d; + for(var h = c + 1;h < this.b;++h) { + b[h - c - 1] |= (this[h] & f) << e, b[h - c] = this[h] >> d + } + 0 < d && (b[this.b - c - 1] |= (this.c & f) << e); + b.b = this.b - c; + b.C() + } +}; +q.t = function(a, b) { + for(var c = 0, d = 0, e = Math.min(a.b, this.b);c < e;) { + d += this[c] - a[c], b[c++] = d & this.u, d >>= this.f + } + if(a.b < this.b) { + for(d -= a.c;c < this.b;) { + d += this[c], b[c++] = d & this.u, d >>= this.f + } + d += this.c + }else { + for(d += this.c;c < a.b;) { + d -= a[c], b[c++] = d & this.u, d >>= this.f + } + d -= a.c + } + b.c = 0 > d ? -1 : 0; + -1 > d ? b[c++] = this.K + d : 0 < d && (b[c++] = d); + b.b = c; + b.C() +}; +q.vb = function(a) { + var b = $.Xa, c = this.abs(), d = b.abs(), e = c.b; + for(a.b = e + d.b;0 <= --e;) { + a[e] = 0 + } + for(e = 0;e < d.b;++e) { + a[e + c.b] = c.ga(d[e], a, e, c.b) + } + a.c = 0; + a.C(); + this.c != b.c && X.ZERO.t(a, a) +}; +q.Ja = function(a, b, c) { + var d = a.abs(); + if(!(0 >= d.b)) { + var e = this.abs(); + if(e.b < d.b) { + b != m && b.D(0), c != m && this.copyTo(c) + }else { + c == m && (c = Yc()); + var f = Yc(), h = this.c, a = a.c, i = d[d.b - 1], j = 1, n; + if(0 != (n = i >>> 16)) { + i = n, j += 16 + } + if(0 != (n = i >> 8)) { + i = n, j += 8 + } + if(0 != (n = i >> 4)) { + i = n, j += 4 + } + if(0 != (n = i >> 2)) { + i = n, j += 2 + } + 0 != i >> 1 && (j += 1); + i = this.f - j; + 0 < i ? (d.Qa(i, f), e.Qa(i, c)) : (d.copyTo(f), e.copyTo(c)); + d = f.b; + e = f[d - 1]; + if(0 != e) { + n = e * (1 << this.Aa) + (1 < d ? f[d - 2] >> this.Ba : 0); + j = this.bb / n; + n = (1 << this.Aa) / n; + var y = 1 << this.Ba, v = c.b, C = v - d, D = b == m ? Yc() : b; + f.la(C, D); + 0 <= c.U(D) && (c[c.b++] = 1, c.t(D, c)); + X.ONE.la(d, D); + for(D.t(f, f);f.b < d;) { + f[f.b++] = 0 + } + for(;0 <= --C;) { + var K = c[--v] == e ? this.u : Math.floor(c[v] * j + (c[v - 1] + y) * n); + if((c[v] += f.ga(K, c, C, d)) < K) { + f.la(C, D); + for(c.t(D, c);c[v] < --K;) { + c.t(D, c) + } + } + } + b != m && (c.jb(d, b), h != a && X.ZERO.t(b, b)); + c.b = d; + c.C(); + 0 < i && c.zb(i, c); + 0 > h && X.ZERO.t(c, c) + } + } + } +}; +q.toString = function(a) { + if(0 > this.c) { + return"-" + this.i().toString(a) + } + if(16 == a) { + a = 4 + }else { + if(8 == a) { + a = 3 + }else { + if(2 == a) { + a = 1 + }else { + if(32 == a) { + a = 5 + }else { + if(4 == a) { + a = 2 + }else { + return this.Fb(a) + } + } + } + } + } + var b = (1 << a) - 1, c, d = p, e = "", f = this.b, h = this.f - f * this.f % a; + if(0 < f--) { + if(h < this.f && 0 < (c = this[f] >> h)) { + d = l, e = "0123456789abcdefghijklmnopqrstuvwxyz".charAt(c) + } + for(;0 <= f;) { + h < a ? (c = (this[f] & (1 << h) - 1) << a - h, c |= this[--f] >> (h += this.f - a)) : (c = this[f] >> (h -= a) & b, 0 >= h && (h += this.f, --f)), 0 < c && (d = l), d && (e += "0123456789abcdefghijklmnopqrstuvwxyz".charAt(c)) + } + } + return d ? e : "0" +}; +q.i = function() { + var a = Yc(); + X.ZERO.t(this, a); + return a +}; +q.abs = function() { + return 0 > this.c ? this.i() : this +}; +q.U = function(a) { + var b = this.c - a.c; + if(0 != b) { + return b + } + var c = this.b, b = c - a.b; + if(0 != b) { + return 0 > this.c ? -b : b + } + for(;0 <= --c;) { + if(0 != (b = this[c] - a[c])) { + return b + } + } + return 0 +}; +X.ZERO = ad(0); +X.ONE = ad(1); +q = X.prototype; +q.nb = function(a, b) { + this.D(0); + b == m && (b = 10); + for(var c = this.S(b), d = Math.pow(b, c), e = p, f = 0, h = 0, i = 0;i < a.length;++i) { + var j = Zc(a, i); + 0 > j ? "-" == a.charAt(i) && 0 == this.ra() && (e = l) : (h = b * h + j, ++f >= c && (this.Ia(d), this.Ha(h), h = f = 0)) + } + 0 < f && (this.Ia(Math.pow(b, f)), this.Ha(h)); + e && X.ZERO.t(this, this) +}; +q.S = function(a) { + return Math.floor(Math.LN2 * this.f / Math.log(a)) +}; +q.ra = function() { + return 0 > this.c ? -1 : 0 >= this.b || 1 == this.b && 0 >= this[0] ? 0 : 1 +}; +q.Ia = function(a) { + this[this.b] = this.ga(a - 1, this, 0, this.b); + ++this.b; + this.C() +}; +q.Ha = function(a) { + var b = 0; + if(0 != a) { + for(;this.b <= b;) { + this[this.b++] = 0 + } + for(this[b] += a;this[b] >= this.K;) { + this[b] -= this.K, ++b >= this.b && (this[this.b++] = 0), ++this[b] + } + } +}; +q.Fb = function(a) { + a == m && (a = 10); + if(0 == this.ra() || 2 > a || 36 < a) { + return"0" + } + var b = this.S(a), b = Math.pow(a, b), c = ad(b), d = Yc(), e = Yc(), f = ""; + for(this.Ja(c, d, e);0 < d.ra();) { + f = (b + e.Oa()).toString(a).substr(1) + f, d.Ja(c, d, e) + } + return e.Oa().toString(a) + f +}; +q.Oa = function() { + if(0 > this.c) { + if(1 == this.b) { + return this[0] - this.K + } + if(0 == this.b) { + return-1 + } + }else { + if(1 == this.b) { + return this[0] + } + if(0 == this.b) { + return 0 + } + } + return(this[1] & (1 << 32 - this.f) - 1) << this.f | this[0] +}; +q.fa = function(a, b) { + for(var c = 0, d = 0, e = Math.min(a.b, this.b);c < e;) { + d += this[c] + a[c], b[c++] = d & this.u, d >>= this.f + } + if(a.b < this.b) { + for(d += a.c;c < this.b;) { + d += this[c], b[c++] = d & this.u, d >>= this.f + } + d += this.c + }else { + for(d += this.c;c < a.b;) { + d += a[c], b[c++] = d & this.u, d >>= this.f + } + d += a.c + } + b.c = 0 > d ? -1 : 0; + 0 < d ? b[c++] = d : -1 > d && (b[c++] = this.K + d); + b.b = c; + b.C() +}; +var $ = {abs:function(a, b) { + var c = new Y(a, b), c = c.n() ? c.i() : c; + B[qb >> 2] = c.h; + B[qb + 4 >> 2] = c.j +}, Ka:function() { + $.kb || ($.kb = l, $.Xa = new X, $.Xa.k("4294967296", 10), $.sa = new X, $.sa.k("18446744073709551616", 10), $.xe = new X, $.ye = new X) +}, me:function(a, b) { + var c = new X; + c.k(b.toString(), 10); + var d = new X; + c.vb(d); + c = new X; + c.k(a.toString(), 10); + var e = new X; + c.fa(d, e); + return e +}, stringify:function(a, b, c) { + a = (new Y(a, b)).toString(); + c && "-" == a[0] && ($.Ka(), c = new X, c.k(a, 10), a = new X, $.sa.fa(c, a), a = a.toString(10)); + return a +}, k:function(a, b, c, d, e) { + $.Ka(); + var f = new X; + f.k(a, b); + a = new X; + a.k(c, 10); + c = new X; + c.k(d, 10); + e && 0 > f.U(X.ZERO) && (d = new X, f.fa($.sa, d), f = d); + d = p; + 0 > f.U(a) ? (f = a, d = l) : 0 < f.U(c) && (f = c, d = l); + f = Y.k(f.toString()); + B[qb >> 2] = f.h; + B[qb + 4 >> 2] = f.j; + d && g("range error") +}}; +lc = $; +var cd, dd; +s.callMain = s.$d = function(a) { + function b() { + for(var a = 0;3 > a;a++) { + d.push(0) + } + } + w(0 == L, "cannot call main when async dependencies remain! (listen on __ATMAIN__)"); + w(0 == Wa.length, "cannot call main when preRun functions remain to be called"); + a = a || []; + ab || (ab = l, Va(Xa)); + var c = a.length + 1, d = [F(J("/bin/this.program"), "i8", Ka)]; + b(); + for(var e = 0;e < c - 1;e += 1) { + d.push(F(J(a[e]), "i8", Ka)), b() + } + d.push(0); + d = F(d, "i32", Ka); + cd = u; + dd = l; + var f; + try { + f = s._main(c, d, 0) + }catch(h) { + if(h && "object" == typeof h && "ExitStatus" == h.type) { + return s.print("Exit Status: " + h.value), h.value + } + "SimulateInfiniteLoop" == h ? s.noExitRuntime = l : g(h) + }finally { + dd = p + } + s.noExitRuntime || ed(f) +}; +function lb(a) { + function b() { + ab || (ab = l, Va(Xa)); + Va(Ya); + gb = l; + s._main && kb && s.callMain(a); + if(s.postRun) { + for("function" == typeof s.postRun && (s.postRun = [s.postRun]);s.postRun.length;) { + cb(s.postRun.shift()) + } + } + Va($a) + } + a = a || s.arguments; + if(0 < L) { + s.P("run() called, but dependencies remain, so not running") + }else { + if(s.preRun) { + for("function" == typeof s.preRun && (s.preRun = [s.preRun]);s.preRun.length;) { + bb(s.preRun.shift()) + } + } + Va(Wa); + 0 < L || (s.setStatus ? (s.setStatus("Running..."), setTimeout(function() { + setTimeout(function() { + s.setStatus("") + }, 1); + za || b() + }, 1)) : b()) + } +} +s.run = s.we = lb; +function ed(a) { + za = l; + u = cd; + Va(Za); + dd && g({type:"ExitStatus", value:a}) +} +s.exit = s.de = ed; +function wa(a) { + a && s.print(a); + za = l; + g("abort() at " + Error().stack) +} +s.abort = s.abort = wa; +if(s.preInit) { + for("function" == typeof s.preInit && (s.preInit = [s.preInit]);0 < s.preInit.length;) { + s.preInit.pop()() + } +} +var kb = l; +s.noInitialRun && (kb = p); +lb(); +var scrypt = (function () { + var exports = {}; + + //--------------------------------------------------------------------------- + // Horrifying UTF-8 and hex codecs + + function encode_utf8(s) { + return encode_latin1(unescape(encodeURIComponent(s))); + } + + function encode_latin1(s) { + var result = new Uint8Array(s.length); + for (var i = 0; i < s.length; i++) { + var c = s.charCodeAt(i); + if ((c & 0xff) !== c) throw {message: "Cannot encode string in Latin1", str: s}; + result[i] = (c & 0xff); + } + return result; + } + + function decode_utf8(bs) { + return decodeURIComponent(escape(decode_latin1(bs))); + } + + function decode_latin1(bs) { + var encoded = []; + for (var i = 0; i < bs.length; i++) { + encoded.push(String.fromCharCode(bs[i])); + } + return encoded.join(''); + } + + function to_hex(bs) { + var encoded = []; + for (var i = 0; i < bs.length; i++) { + encoded.push("0123456789abcdef"[(bs[i] >> 4) & 15]); + encoded.push("0123456789abcdef"[bs[i] & 15]); + } + return encoded.join(''); + } + + //--------------------------------------------------------------------------- + + function injectBytes(bs, leftPadding) { + var p = leftPadding || 0; + var address = scrypt_raw._malloc(bs.length + p); + scrypt_raw.HEAPU8.set(bs, address + p); + for (var i = address; i < address + p; i++) { + scrypt_raw.HEAPU8[i] = 0; + } + return address; + } + + function check_injectBytes(function_name, what, thing, expected_length, leftPadding) { + check_length(function_name, what, thing, expected_length); + return injectBytes(thing, leftPadding); + } + + function extractBytes(address, length) { + var result = new Uint8Array(length); + result.set(scrypt_raw.HEAPU8.subarray(address, address + length)); + return result; + } + + //--------------------------------------------------------------------------- + + function check(function_name, result) { + if (result !== 0) { + throw {message: "scrypt_raw." + function_name + " signalled an error"}; + } + } + + function check_length(function_name, what, thing, expected_length) { + if (thing.length !== expected_length) { + throw {message: "scrypt." + function_name + " expected " + + expected_length + "-byte " + what + " but got length " + thing.length}; + } + } + + function Target(length) { + this.length = length; + this.address = scrypt_raw._malloc(length); + } + + Target.prototype.extractBytes = function (offset) { + var result = extractBytes(this.address + (offset || 0), this.length - (offset || 0)); + scrypt_raw._free(this.address); + this.address = null; + return result; + }; + + function free_all(addresses) { + for (var i = 0; i < addresses.length; i++) { + scrypt_raw._free(addresses[i]); + } + } + + //--------------------------------------------------------------------------- + + function random_bytes(count) { + var bs = new Uint8Array(count); + if(typeof(window.crypto) !== "undefined") { + if(typeof(window.crypto.getRandomValues) !== "undefined") { + window.crypto.getRandomValues(bs); + return bs; + } + } + if(typeof(window.msCrypto) !== "undefined") { + if(typeof(window.msCrypto.getRandomValues) !== "undefined") { + window.msCrypto.getRandomValues(bs); + return bs; + } + } + throw { message: "No suitable random number generator found!"}; + } + + function crypto_scrypt(passwd, salt, n, r, p, buflen) { + var buf = new Target(buflen); + var pa = injectBytes(passwd); + var sa = injectBytes(salt); + check("_crypto_scrypt", + scrypt_raw._crypto_scrypt(pa, passwd.length, + sa, salt.length, + n, 0, // 64 bits; zero upper half + r, + p, + buf.address, buf.length)); + free_all([pa, sa]); + return buf.extractBytes(); + } + + //--------------------------------------------------------------------------- + + exports.encode_utf8 = encode_utf8; + exports.encode_latin1 = encode_latin1; + exports.decode_utf8 = decode_utf8; + exports.decode_latin1 = decode_latin1; + exports.to_hex = to_hex; + + exports.random_bytes = random_bytes; + exports.crypto_scrypt = crypto_scrypt; + + return exports; +})(); + return scrypt; +}); + diff --git a/ucoinj-ui-wicket/src/main/webapp/js/ucoinj.js b/ucoinj-ui-wicket/src/main/webapp/js/ucoinj.js new file mode 100644 index 0000000000000000000000000000000000000000..528a6206d5a6cbd470a7a7eaf7fbc72a469d5814 --- /dev/null +++ b/ucoinj-ui-wicket/src/main/webapp/js/ucoinj.js @@ -0,0 +1,322 @@ +/*! + * uCoinj JavaScript Library v2.1.4 + * http://ucoinj.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 uCoinj Foundation, Inc. and other contributors + * Released under the MIT license + * http://ucoinj.org/license + * + * Date: 2015-04-28T16:01Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get uCoinj. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var uCoinj = require("ucoinj")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "uCoinj requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + strundefined = typeof undefined, + version = "1.0", + nacl, + scrypt, + base58, + base64, + + // Define a local copy of uCoinj + uCoinj = function(document) { + // The uCoinj object is actually just the init constructor 'enhanced' + // Need init if uCoinj is called (just allow error to be thrown if not included) + return new uCoinj.fn.init(document); + }; + +uCoinj.fn = uCoinj.prototype = { + // The current version of jQuery being used + ucoinj: version, + constructor: uCoinj, + nacl: null, + scrypt: null, + base58: null, + base64: null, + wallet: { + keypair: null, + uid: null, + pubkey: null + }, + crypto_sign_BYTES: 64, + SEED_LENGTH: 32, // Length of the key + SCRYPT_PARAMS: { + "N":4096, + "r":16, + "p":1 + } +}; + +uCoinj.fn.encode_utf8 = function(arr) { + var i, s = []; + for (i = 0; i < arr.length; i++) s.push(String.fromCharCode(arr[i])); + return decodeURIComponent(escape(s.join(''))); +}; + +uCoinj.fn.decode_utf8 = function(s) { + var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length); + for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i); + return b; +}; + +var + // A central reference to the root jQuery(document) + //rootuCoinj, + wallet = uCoinj.fn.wallet, + + get_scrypt = function() { + if (typeof module !== 'undefined' && module.exports) { + // add node.js implementations + require('scrypt-em'); + return scrypt_module_factory(); + } + else if (scrypt_module_factory !== null){ + return scrypt_module_factory(); + } + else { + return setTimetout(get_scrypt, 100); + } + }, + + get_nacl = function() { + if (typeof module !== 'undefined' && module.exports) { + // add node.js implementations + require('nacl_factory'); + return nacl_factory.instantiate(); + } + else if (nacl_factory !== null){ + return nacl_factory.instantiate(); + } + else { + return setTimetout(get_nacl, 100); + } + }, + + get_base58 = function() { + if (typeof module !== 'undefined' && module.exports) { + // add node.js implementations + require('base58'); + return Base58; + } + else if (Base58 !== null){ + return Base58; + } + else { + return setTimetout(get_base58, 100); + } + }, + + get_base64 = function() { + if (typeof module !== 'undefined' && module.exports) { + // add node.js implementations + require('base58'); + return Base64; + } + else if (Base64 !== null){ + return Base64; + } + else { + return setTimetout(get_base64, 100); + } + }, + + // Constructor + init = uCoinj.fn.init = function(document) { + + // load libraries + scrypt = uCoinj.fn.scrypt = get_scrypt(); + nacl = uCoinj.fn.nacl = get_nacl(); + base58 = uCoinj.fn.base58 = get_base58(); + base64 = uCoinj.fn.base64 = get_base64(); + + //var test = uCoinj.fn.test(); + //if (!test) { + // alert('Your navigator is not compatible: cryptographic features failed. Please report a bug.'); + //} + }, + + connect = uCoinj.fn.connect = function(salt, password) { + var seed = uCoinj.fn.scrypt.crypto_scrypt( + uCoinj.fn.nacl.encode_utf8(password), + uCoinj.fn.nacl.encode_utf8(salt), + 4096, 16, 1, 32 // see SCRYPT_PARAMS + ); + uCoinj.fn.wallet.keypair = uCoinj.fn.nacl.crypto_sign_keypair_from_seed(seed); + uCoinj.fn.wallet.pubkey = uCoinj.fn.base58.encode(uCoinj.fn.wallet.keypair.signPk); + }, + + isConnected = uCoinj.fn.isConnected = function() { + return uCoinj.fn.wallet.keypair !== null; + } + + disconnect = uCoinj.fn.disconnect = function() { + return uCoinj.fn.wallet.keypair !== null; + }, + + sign = uCoinj.fn.sign = function (message) { + if (!isConnected()) { + throw new Error('Not connected. Please connect using uCoinj().connect() method.') + } + var m = uCoinj.fn.decode_utf8(message); + var sk = uCoinj.fn.wallet.keypair.signSk; + var signedMsg = uCoinj.fn.nacl.crypto_sign(m, sk); + var sig = new Uint8Array(uCoinj.fn.crypto_sign_BYTES); + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; + return uCoinj.fn.base64.encode(sig); + }, + + verify = uCoinj.fn.verify = function (message, signature, publicKey) { + if (!isConnected()) { + throw new Error('Not connected. Please connect using uCoinj().connect() method.') + } + + var msg = uCoinj.fn.decode_utf8(message); + var sig = uCoinj.fn.base64.decode(signature); + var pub = uCoinj.fn.base58.decode(publicKey); + var m = new Uint8Array(uCoinj.fn.crypto_sign_BYTES + msg.length); + var sm = new Uint8Array(uCoinj.fn.crypto_sign_BYTES + msg.length); + var i; + for (i = 0; i < uCoinj.fn.crypto_sign_BYTES; i++) sm[i] = sig[i]; + for (i = 0; i < msg.length; i++) sm[i+uCoinj.fn.crypto_sign_BYTES] = msg[i]; + + // Call to verification lib... + var verified = uCoinj.fn.nacl.crypto_sign_open(sm, pub) !== null; + + return verified; + }, + + /** + * Unit test methods: should return true + */ + test = uCoinj.fn.test = function() { + var result = true; + var msg = 'my message to encrypt !'; + var expectedSignature = 'aAxVThibiZGbpJWrFo8MzZe8RDIoJ1gMC1UIr0utDBQilG44PjA/7o+pOoPAOXgDE3sosGeLHTw1Q/RhFBa4CA=='; + var expectedPubKey = 'G2CBgZBPLe6FSFUgpx2Jf1Aqsgta6iib3vmDRA1yLiqU'; + var expectedSecKey = '58LDg8QLmF5pv6Dn9h7X4yFKfMTdP8fdAiWVcyDoTRJu454fwRihCLULH4MW37zncsg4ruoTGJPZneWk22QmG1w4'; + connect('abc', 'def'); + if (!isConnected()) { + console.log('[uCoinj] Test failed: Could not generate key pair.'); + return false; + } + if (wallet.pubkey !== expectedPubKey) { + console.log('[uCoinj] Test failed: Bad public key, expected '+ expectedPubKey +' but get '+wallet.pubkey); + result = false; + } + var secKey = base58.encode(wallet.keypair.signSk); + if (secKey !== expectedSecKey) { + console.log('[uCoinj] Test failed: Bad secret key, expected '+ expectedSecKey +' but get '+secKey); + result = false; + } + + var signature = sign(msg); + if (signature !== expectedSignature) { + console.log('[uCoinj] Test failed: Bad signature, expected '+ expectedSignature +' but get '+signature); + result =false; + } + + var verified = verify(msg, expectedSignature, wallet.pubkey); + if (!verified) { + console.log('[uCoinj] Test failed: signature verification failed, expected to be valid but return invalid'); + result = false; + } + return result; + } +; + + + +// Give the init function the jQuery prototype for later instantiation +init.prototype = uCoinj.fn; + + +// Initialize central reference +//rootjQuery = uCoinj( document ); + + +// Register as a named AMD module, since uCoinj can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase ucoinj is used because AMD module names are +// derived from file names, and uCoinj is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of uCoinj, it will work. + +// Note that for maximum portability, libraries that are not uCoinj should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. uCoinj is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "ucoinj", [], function() { + return uCoinj; + }); +} + + +var + // Map over uCoinj in case of overwrite + _uCoinj = window.uCoinj, + + // Map over the $ in case of overwrite + _uc = window.uc; + +uCoinj.noConflict = function( deep ) { + if ( window._uc === uCoinj ) { + window.uc = _uc; + } + + if ( deep && window.uCoinj === uCoinj ) { + window.uCoinj = _uCoinj; + } + + return uCoinj; +}; + +// Expose uCoinj and $ identifiers, even in AMD +// and CommonJS for browser emulators +if ( typeof noGlobal === strundefined ) { + window.uCoinj = window.uc = uCoinj; +} + + + + +return uCoinj; + +})); diff --git a/ucoinj-web/src/main/webapp/js/zepto.min.js b/ucoinj-ui-wicket/src/main/webapp/js/zepto.min.js similarity index 100% rename from ucoinj-web/src/main/webapp/js/zepto.min.js rename to ucoinj-ui-wicket/src/main/webapp/js/zepto.min.js diff --git a/ucoinj-ui-wicket/src/test/resources/log4j.properties b/ucoinj-ui-wicket/src/test/resources/log4j.properties new file mode 100644 index 0000000000000000000000000000000000000000..f07ce5b932950c9057841d54abd8bd94233f77a9 --- /dev/null +++ b/ucoinj-ui-wicket/src/test/resources/log4j.properties @@ -0,0 +1,29 @@ +### +# Global logging configuration +log4j.rootLogger=ERROR, stdout + +# Console output +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %5p (%c:%L) - [%t] %m%n + +# file logging (compatible with Ifremer/RIC) +log4j.appender.file=org.apache.log4j.DailyRollingFileAppender +log4j.appender.file.file=${ucoinj.log.file} +log4j.appender.file.DatePattern='.'yyyy-MM-dd +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} %5p (%F:%L) %M %m%n + +# uCoinj levels +log4j.logger.io.ucoin.ucoinj=INFO +#log4j.logger.io.ucoin.ucoinj.core=WARN +log4j.logger.io.ucoin.ucoinj.elasticsearch=DEBUG + +log4j.logger.org.nuiton.util=WARN +log4j.logger.org.nuiton.config=WARN +log4j.logger.org.nuiton.converter=WARN +log4j.logger.org.apache.commons.beanutils=WARN +log4j.logger.org.apache.wicket=WARN +log4j.logger.org.elasticsearch=WARN +log4j.logger.org.springframework=WARN +log4j.logger.org.springframework.security=TRACE \ No newline at end of file diff --git a/ucoinj-ui-wicket/src/test/resources/ucoinj-ui-wicket-test.properties b/ucoinj-ui-wicket/src/test/resources/ucoinj-ui-wicket-test.properties new file mode 100644 index 0000000000000000000000000000000000000000..395a80c4b8e8a65b4682231e78bf10a914442db7 --- /dev/null +++ b/ucoinj-ui-wicket/src/test/resources/ucoinj-ui-wicket-test.properties @@ -0,0 +1,16 @@ +ucoinj.basedir=${user.home}/.ucoinj-web + +ucoinj.node.host=metab.ucoin.fr +ucoinj.node.port=9201 + +ucoinj.elasticsearch.embedded.enable=true +ucoinj.elasticsearch.http.enable=true +#ucoinj.elasticsearch.http.enable=false +ucoinj.elasticsearch.local=true + +ucoinj.elasticsearch.cluster.name=ucoinj-elasticsearch-test +#ucoinj.elasticsearch.cluster.name=data.ucoin.fr + +ucoinj.node.elasticsearch.host=localhost +ucoinj.node.elasticsearch.port=9300 + diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.java b/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.java deleted file mode 100644 index f832a14b0299d90ef50dad9b4c71fa01357cdf0b..0000000000000000000000000000000000000000 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.java +++ /dev/null @@ -1,91 +0,0 @@ -package io.ucoin.client.ui.application; - -/* - * #%L - * UCoin Java Client :: Web - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - - -import io.ucoin.client.ui.config.WebConfiguration; -import io.ucoin.client.ui.pages.home.HomePage; -import io.ucoin.client.ui.pages.login.LoginPage; -import io.ucoin.client.ui.pages.registry.CurrencyRegistryPage; -import io.ucoin.client.ui.pages.wallet.WalletPage; -import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; -import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; -import org.apache.wicket.markup.html.WebPage; -import org.apache.wicket.util.time.Duration; -import org.wicketstuff.rest.utils.mounting.PackageScanner; - -public class UcoinApplication extends AuthenticatedWebApplication { - - private WebConfiguration config; - - public UcoinApplication() { - config = WebConfiguration.instance(); - } - - /** - * @see org.apache.wicket.Application#init() - */ - @Override - public void init() { - super.init(); - // add the capability to gather extended browser info stuff like screen resolution - getRequestCycleSettings().setGatherExtendedBrowserInfo(true); - // set the default page timeout - getRequestCycleSettings().setTimeout(Duration.minutes(10)); - // set the UTF-8 charset - getRequestCycleSettings().setResponseRequestEncoding("UTF-8"); - getMarkupSettings().setDefaultMarkupEncoding("UTF-8"); - - mountPage("home", getHomePage()); - mountPage("login", LoginPage.class); - mountPage("wallet", WalletPage.class); - mountPage("register-currency", CurrencyRegistryPage.class); - - // Mount rest service, from annotations - PackageScanner.scanPackage("io.ucoin.client.ui.service.rest"); - - getMarkupSettings().setStripWicketTags(true); - } - - /** - * @see org.apache.wicket.Application#getHomePage() - */ - @Override - public Class getHomePage() { - return HomePage.class; - } - - @Override - protected Class<? extends AbstractAuthenticatedWebSession> getWebSessionClass() { - return UcoinSession.class; - } - - @Override - protected Class<? extends WebPage> getSignInPageClass() { - return LoginPage.class; - } - - public WebConfiguration getConfiguration() { - return config; - } -} \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.properties b/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.properties deleted file mode 100644 index 7048dfee36440d646c8098f4071a214452e1822b..0000000000000000000000000000000000000000 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/application/UcoinApplication.properties +++ /dev/null @@ -1,8 +0,0 @@ -base.pageTitle=uCoin registry -home.headerTitle=<h1>Welcome to <b>uCoin</b> registry</h1><h2>A open registry for all your <i>uCoin</i> currencies</h2> -base.footer=UCoin client v${version} -login.username=Username -home.search.hint=Search a currency name -home.searchButton=Search -home.result.divider.currency=Currencies -searchText=Search \ No newline at end of file diff --git a/ucoinj-web/src/main/java/io/ucoin/client/ui/config/WebConfiguration.java b/ucoinj-web/src/main/java/io/ucoin/client/ui/config/WebConfiguration.java deleted file mode 100644 index dc4beb74e746b3c419e28fa79ea76bfc19bf86cb..0000000000000000000000000000000000000000 --- a/ucoinj-web/src/main/java/io/ucoin/client/ui/config/WebConfiguration.java +++ /dev/null @@ -1,123 +0,0 @@ -package io.ucoin.client.ui.config; - -/* - * #%L - * SIH-Adagio :: UI for Core Allegro - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2012 - 2014 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import io.ucoin.client.core.config.Configuration; -import io.ucoin.client.core.service.ServiceLocator; -import io.ucoin.client.core.technical.UCoinTechnicalException; -import org.apache.commons.lang3.StringUtils; -import org.nuiton.config.ApplicationConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.naming.InitialContext; -import javax.naming.NamingException; -import java.io.File; - -public class WebConfiguration extends Configuration { - - private static final String CONFIG_FILE_NAME = "ucoinj-web.config"; - - private static final String CONFIG_FILE_ENV_PROPERTY = CONFIG_FILE_NAME; - - private static final String CONFIG_FILE_JNDI_NAME = "java:comp/env/" + CONFIG_FILE_NAME; - - - /* Logger */ - private static final Logger log = LoggerFactory.getLogger(WebConfiguration.class); - - static { - String configFile = getWebConfigFile(); - if (log.isDebugEnabled()) { - log.debug(String.format("Loading configuration from file [%s]", configFile)); - } - if (new File(configFile).exists() == false) { - log.warn(String.format("Configuration file not found [%s]. Make sure the path is correct.", configFile)); - } - instance = new WebConfiguration(configFile); - initDefault(); - } - - private static final WebConfiguration instance; - - public static void initDefault() { - setInstance(instance); - } - - public static WebConfiguration instance() { - return instance; - } - - public WebConfiguration(ApplicationConfig applicationConfig) { - super(applicationConfig); - } - - public WebConfiguration(String file, String... args) { - super(file, args); - - // Init Crypto (NaCL lib...) - initCrypto(); - } - - public String getVersionAsString() { - return getVersion().toString(); - } - - /* -- Internal methods -- */ - protected static String getWebConfigFile() { - // Could override config file name (useful for dev) - String configFile = CONFIG_FILE_NAME; - if (System.getProperty(CONFIG_FILE_ENV_PROPERTY) != null) { - configFile = System.getProperty(CONFIG_FILE_ENV_PROPERTY); - configFile = configFile.replaceAll("\\\\", "/"); - } - else { - try { - InitialContext ic = new InitialContext(); - String jndiPathToConfFile = (String) ic.lookup(CONFIG_FILE_JNDI_NAME); - if (StringUtils.isNotBlank(jndiPathToConfFile)) { - configFile = jndiPathToConfFile; - } - } catch (NamingException e) { - log.warn(String.format("Error while reading JNDI initial context. Skip configuration path override, from context [%s]", CONFIG_FILE_JNDI_NAME)); - } - } - - return configFile; - } - - protected void initCrypto() { - if (log.isInfoEnabled()) { - log.info("Starts Sodium (NaCL) library"); - } - - try { - // This call will load the sodium library - ServiceLocator.instance().getCryptoService(); - } catch (Throwable e) { - throw new UCoinTechnicalException("Crypto lib (NaCL) initialization failed. Make sure sodium has been installed (or add library into a ./lib directory).", e); - } - } -} diff --git a/ucoinj-web/src/main/webapp/WEB-INF/web.xml b/ucoinj-web/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index a47f30d7ceeeecb1810aedc273ae7b565133a043..0000000000000000000000000000000000000000 --- a/ucoinj-web/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" - version="2.5"> - - <display-name>UCoin Java Client :: Web ${project.version}</display-name> - - <context-param> - <param-name>webAppRootKey</param-name> - <param-value>ucoinj-web</param-value> - </context-param> - - <filter> - <filter-name>wicket.ucoinj-web-wicket</filter-name> - <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class> - <init-param> - <param-name>applicationClassName</param-name> - <param-value>io.ucoin.client.ui.application.UcoinApplication</param-value> - </init-param> - <init-param> - <param-name>configuration</param-name> - <param-value>${wicket.configuration}</param-value> - </init-param> - </filter> - - <filter-mapping> - <filter-name>wicket.ucoinj-web-wicket</filter-name> - <url-pattern>/*</url-pattern> - <dispatcher>REQUEST</dispatcher> - <dispatcher>ERROR</dispatcher> - </filter-mapping> - - <error-page> - <error-code>401</error-code> - <location>/loginfailed.html</location> - </error-page> - <error-page> - <error-code>403</error-code> - <location>/accessdenied.html</location> - </error-page> - <error-page> - <error-code>404</error-code> - <location>/notfound.html</location> - </error-page> - - <welcome-file-list> - <welcome-file>index.html</welcome-file> - </welcome-file-list> - - <session-config> - <session-timeout>60</session-timeout> - </session-config> - -</web-app> diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_diagonals-thick_18_b81900_40x40.png deleted file mode 100644 index 3cd530f34389e8090ec3286ffb5b20de8ac0d56e..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_diagonals-thick_18_b81900_40x40.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_0_aaaaaa_40x100.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100644 index 5035a5774efb308c09bb7ffe2006cd6aba88a1b0..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_75_ffffff_40x100.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_75_ffffff_40x100.png deleted file mode 100644 index 4dcc7d3bcca8295eb90507a95dfdd9349d436379..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_55_fbf9ee_1x400.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_55_fbf9ee_1x400.png deleted file mode 100644 index 46411fed1d103c95b34852ea5d6fc5e5e3fb1d65..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_55_fbf9ee_1x400.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_65_ffffff_1x400.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100644 index a771065f94a75e7a8ffc52a58433917644eb6006..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_dadada_1x400.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_dadada_1x400.png deleted file mode 100644 index 5e98ad612f82a0c9a21bb33a0f7a164d63ff8e9f..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_dadada_1x400.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_e6e6e6_1x400.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_e6e6e6_1x400.png deleted file mode 100644 index 71820dd0121939229898d369d6f1f1dc1689f52f..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_75_e6e6e6_1x400.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_95_fef1ec_1x400.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_95_fef1ec_1x400.png deleted file mode 100644 index 05f0a0b6fd89193bbca46a7d60beaa3f39d474c5..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_glass_95_fef1ec_1x400.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_highlight-soft_75_cccccc_1x100.png deleted file mode 100644 index e01a65a7e84daa2d1afa72c53c462daf95619223..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-bg_highlight-soft_75_cccccc_1x100.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_222222_256x240.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_222222_256x240.png deleted file mode 100644 index e9c8e16ac5e7f61c843fbac290ce30c5de7e40b6..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_222222_256x240.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_2e83ff_256x240.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_2e83ff_256x240.png deleted file mode 100644 index f2bf8388370920783b94285cb75827ce4b4cc1c5..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_2e83ff_256x240.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_454545_256x240.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_454545_256x240.png deleted file mode 100644 index d6169e8bf9389ab9b5b7d2c6f0c5fe3e4d363105..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_454545_256x240.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_888888_256x240.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_888888_256x240.png deleted file mode 100644 index d3e6e02a03d4cfdc6a2114f736aa57e8a898b98b..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_888888_256x240.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_cd0a0a_256x240.png b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_cd0a0a_256x240.png deleted file mode 100644 index 49370189231d006600b0f0c2967cad1583eba634..0000000000000000000000000000000000000000 Binary files a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/images/ui-icons_cd0a0a_256x240.png and /dev/null differ diff --git a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/jquery.mobile.ucoin.css b/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/jquery.mobile.ucoin.css deleted file mode 100644 index 312975163c496454385639167ae22f18c3eba5ea..0000000000000000000000000000000000000000 --- a/ucoinj-web/src/main/webapp/css/jquery-mobile-ucoin/jquery.mobile.ucoin.css +++ /dev/null @@ -1,309 +0,0 @@ -/* - * #%L - * UCoin Java Client :: Web - * %% - * Copyright (C) 2014 - 2015 EIS - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -/*.ui-overlay-a, .ui-page-theme-a, .ui-page-theme-a .ui-panel-wrapper { - background-color: #f9f9f9; - border-color: #bbb; - color: #333; - text-shadow: 0 1px 0 #f3f3f3; -}*/ - -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { - border: 1px solid red; - background: #fef1ec url("images/ui-bg_diagonals-thick_18_b81900_40x40.png") 50% 50% repeat-x; - color: #ffffff; -} - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { - width: 16px; - height: 16px; -} -.ui-icon, -.ui-widget-content .ui-icon { - background-image: url("images/ui-icons_222222_256x240.png"); -} -.ui-widget-header .ui-icon { - background-image: url("images/ui-icons_222222_256x240.png"); -} -.ui-state-default .ui-icon { - background-image: url("images/ui-icons_888888_256x240.png"); -} -.ui-state-hover .ui-icon, -.ui-state-focus .ui-icon { - background-image: url("images/ui-icons_454545_256x240.png"); -} -.ui-state-active .ui-icon { - background-image: url("images/ui-icons_454545_256x240.png"); -} -.ui-state-highlight .ui-icon { - background-image: url("images/ui-icons_2e83ff_256x240.png"); -} -.ui-state-error .ui-icon, -.ui-state-error-text .ui-icon { - background-image: url("images/ui-icons_222222_256x240.png"); -} - -/* positioning */ -.ui-icon-blank { background-position: 16px 16px; } -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-on { background-position: -96px -144px; } -.ui-icon-radio-off { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -div.wicket-aa-container { - color: #333; - text-shadow: 0 1px 0 #f3f3f3; - margin-top: 3px; -} - -div.wicket-aa { - font-size: 1em; - line-height: 1.3; - font-family: sans-serif; - background-color: #f6f6f6; - padding: 2px; - text-align:left; - - color: #333; - text-shadow: 0 1px 0 #f3f3f3; - - border-color: #ddd; - border-width: 1px 0 0; - border-style: solid; - margin: 0; - box-shadow: 0 1px 3px rgba(0,0,0,.15); - background-clip: padding-box; - border-radius: .3125em; -} - -div.wicket-aa ul { - list-style:none; - padding: 0; - margin: 0; -} - -div.wicket-aa li { - - display: block; - position: relative; - overflow: visible; - font-size: 16px; - cursor: pointer; - padding: .7em 1em; -} - -div.wicket-aa ul li.selected { - background-color: #ededed; - margin:0; -} \ No newline at end of file