diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e70f58c --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Build artifacts +/build/ +/*.o +/*.obj +/*.exe +/*.out +/*.dll +/*.so +/*.dylib + +# Compiled object and dependency files (in build/) +build/*.o +build/*.d +build/*.d.* + +# Editor and OS files +.DS_Store +Thumbs.db +.vscode/ +.idea/ +*.swp +*~ + +# Generated binaries and targets +/main + +# Shader SPIR-V outputs +shaders/*.spv + +# CMake/Make temporary files +CMakeFiles/ +CMakeCache.txt +cmake_install.cmake +Makefile.user + +# Coverage and debug +coverage/ +*.gcda +*.gcno +*.prof + +# Logs and temporary runtime files +*.log +*.tmp + +# Package manager / tooling +node_modules/ +dist/ + +# Secrets (keep patterns common) +.env +.env.local +.env.*.local + +# Misc +tags +.cache/ diff --git a/20260412_12h43m17s_grim.png b/20260412_12h43m17s_grim.png new file mode 100644 index 0000000..ec20ddd Binary files /dev/null and b/20260412_12h43m17s_grim.png differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5ce8976 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Kale: A simple hybrid renderer +Copyright (C) 2026 Hopeless Tyromantic +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 . diff --git a/LICENSES/kale-gpl b/LICENSES/kale-gpl new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSES/kale-gpl @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSES/tinyobjloader-mit b/LICENSES/tinyobjloader-mit new file mode 100644 index 0000000..63d6ea3 --- /dev/null +++ b/LICENSES/tinyobjloader-mit @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2012-Present, Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..45a5dbf --- /dev/null +++ b/Makefile @@ -0,0 +1,81 @@ +TARGET := main +SRC_DIR := src +SHADER_DIR := shaders +BUILD_DIR := build + +CXX := g++ +CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-unused-function +LDFLAGS := -lSDL3 + +GLSLC := glslc + +DEBUG ?= 0 +ifeq ($(DEBUG), 1) + CXXFLAGS += -g -O0 -DDEBUG +else + CXXFLAGS += -O2 -DNDEBUG +endif + + +SRCS := $(wildcard $(SRC_DIR)/*.cpp) +OBJS := $(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(SRCS)) +DEPS := $(OBJS:.o=.d) + +FRAG_SRCS := $(wildcard $(SHADER_DIR)/*.frag) +VERT_SRCS := $(wildcard $(SHADER_DIR)/*.vert) +SHADER_SRCS := $(FRAG_SRCS) $(VERT_SRCS) +SPIRV_OUTS := $(addsuffix .spv, $(SHADER_SRCS)) + + +.PHONY: all +all: $(TARGET) shaders + + +$(TARGET): $(OBJS) + $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) + @echo "Linked → $@" + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR) + $(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@ + @echo "Compiled → $@" + +-include $(DEPS) + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + + +.PHONY: shaders +shaders: $(SPIRV_OUTS) + +%.spv: % + $(GLSLC) $< -o $@ + @echo "Compiled shader → $@" + +.PHONY: run +run: all + ./$(TARGET) + + +.PHONY: clean +clean: + $(RM) -r $(BUILD_DIR) $(TARGET) $(SPIRV_OUTS) + @echo "Cleaned." + +.PHONY: clean-shaders +clean-shaders: + $(RM) $(SPIRV_OUTS) + @echo "Shader SPIR-V files removed." + +.PHONY: rebuild +rebuild: clean all + +.PHONY: info +info: + @echo "Target: $(TARGET)" + @echo "Sources: $(SRCS)" + @echo "Objects: $(OBJS)" + @echo "Frag shaders:$(FRAG_SRCS)" + @echo "Vert shaders:$(VERT_SRCS)" + @echo "SPIR-V outs: $(SPIRV_OUTS)" + @echo "Debug: $(DEBUG)" diff --git a/assets/homer.obj b/assets/homer.obj new file mode 100644 index 0000000..39ae09b --- /dev/null +++ b/assets/homer.obj @@ -0,0 +1,18008 @@ +v 0.729066 0.624986 0.61228 +v 0.604895 0.602681 0.477149 +v 0.68282 0.625957 0.591549 +v 0.488153 0.83139 0.562912 +v 0.496259 0.815964 0.560873 +v 0.493874 0.183256 0.515476 +v 0.627705 0.592589 0.46609 +v 0.545713 0.756448 0.566481 +v 0.532138 0.215201 0.523515 +v 0.548765 0.157024 0.445773 +v 0.429567 0.811183 0.429844 +v 0.656983 0.63139 0.523311 +v 0.467569 0.625424 0.55999 +v 0.520696 0.191894 0.567572 +v 0.484585 0.183647 0.565393 +v 0.459822 0.763116 0.583053 +v 0.648631 0.67093 0.453745 +v 0.522843 0.762973 0.544232 +v 0.349234 0.619635 0.59844 +v 0.34474 0.624592 0.525353 +v 0.535828 0.759959 0.559302 +v 0.539849 0.819779 0.534833 +v 0.265956 0.635225 0.590328 +v 0.379089 0.626248 0.504301 +v 0.319948 0.634496 0.625179 +v 0.709296 0.659638 0.584591 +v 0.469453 0.177811 0.586228 +v 0.561225 0.669329 0.526511 +v 0.675426 0.643295 0.60641 +v 0.568188 0.782391 0.496619 +v 0.287707 0.649793 0.613886 +v 0.64258 0.66846 0.442685 +v 0.560392 0.770886 0.436396 +v 0.663078 0.663196 0.4788 +v 0.552063 0.745123 0.559114 +v 0.544599 0.189669 0.577416 +v 0.28207 0.653728 0.591566 +v 0.50425 0.960192 0.515405 +v 0.714148 0.641752 0.620212 +v 0.610933 0.64754 0.502251 +v 0.38296 0.405798 0.464978 +v 0.342307 0.613299 0.607689 +v 0.609842 0.177809 0.545954 +v 0.540501 0.919075 0.395346 +v 0.728997 0.649727 0.580899 +v 0.414171 0.829363 0.450975 +v 0.491097 0.861098 0.53961 +v 0.581404 0.39578 0.416057 +v 0.400455 0.554801 0.48935 +v 0.32039 0.655128 0.582286 +v 0.463853 0.160714 0.531159 +v 0.420229 0.839288 0.446472 +v 0.380264 0.196273 0.491558 +v 0.441676 0.708674 0.518638 +v 0.310457 0.64019 0.625684 +v 0.512949 0.511497 0.368557 +v 0.518334 0.225429 0.44094 +v 0.561006 0.814248 0.432687 +v 0.66215 0.623933 0.60691 +v 0.465067 0.748389 0.558421 +v 0.597119 0.161338 0.55566 +v 0.415783 0.598534 0.495739 +v 0.446098 0.32596 0.52162 +v 0.429482 0.923723 0.463038 +v 0.461792 0.159492 0.567895 +v 0.459321 0.162922 0.472071 +v 0.576655 0.805087 0.462656 +v 0.458466 0.190737 0.578405 +v 0.567678 0.160943 0.548047 +v 0.394894 0.161507 0.542478 +v 0.45715 0.546548 0.572227 +v 0.544079 0.46659 0.355892 +v 0.610063 0.186854 0.527366 +v 0.673065 0.595745 0.552865 +v 0.412676 0.416567 0.41062 +v 0.404748 0.464264 0.395378 +v 0.428141 0.159321 0.518486 +v 0.634715 0.643481 0.426882 +v 0.576368 0.466844 0.369982 +v 0.451652 0.79632 0.562539 +v 0.513858 0.374413 0.429782 +v 0.493263 0.176969 0.485809 +v 0.588445 0.236825 0.416958 +v 0.663515 0.62565 0.564627 +v 0.548722 0.748844 0.556573 +v 0.465161 0.987936 0.455104 +v 0.66542 0.638514 0.584079 +v 0.579973 0.266321 0.522648 +v 0.674148 0.637198 0.44712 +v 0.40716 0.157033 0.501208 +v 0.692776 0.637168 0.607241 +v 0.442742 0.754065 0.547123 +v 0.379347 0.297928 0.477319 +v 0.501793 0.842997 0.576697 +v 0.509337 0.914132 0.383803 +v 0.462721 0.882993 0.53877 +v 0.488162 0.747515 0.568442 +v 0.569663 0.922556 0.469528 +v 0.548698 0.736979 0.564544 +v 0.348764 0.643809 0.509742 +v 0.681804 0.634204 0.60597 +v 0.477789 0.629961 0.404689 +v 0.555348 0.714732 0.523188 +v 0.492198 0.446297 0.363856 +v 0.410147 0.599268 0.461904 +v 0.401679 0.161682 0.555704 +v 0.434512 0.858454 0.49784 +v 0.364907 0.672806 0.440683 +v 0.566258 0.162968 0.573644 +v 0.550952 0.430705 0.557419 +v 0.317437 0.628683 0.625817 +v 0.510364 0.849321 0.570497 +v 0.59458 0.428372 0.530031 +v 0.425134 0.828793 0.430676 +v 0.437876 0.838261 0.431763 +v 0.445397 0.215424 0.533517 +v 0.279391 0.634633 0.599608 +v 0.53488 0.628358 0.560097 +v 0.568605 0.80911 0.431433 +v 0.440163 0.3914 0.409618 +v 0.706531 0.605397 0.480768 +v 0.546454 0.635702 0.41759 +v 0.450421 0.803474 0.525689 +v 0.653867 0.612123 0.602093 +v 0.613397 0.179272 0.447326 +v 0.586846 0.45999 0.544848 +v 0.535504 0.450015 0.356987 +v 0.386051 0.162657 0.517173 +v 0.340611 0.635173 0.578908 +v 0.34337 0.665248 0.485405 +v 0.725021 0.625912 0.53773 +v 0.395885 0.675679 0.496244 +v 0.516836 0.891419 0.539185 +v 0.429522 0.261346 0.524491 +v 0.416314 0.167581 0.419909 +v 0.349553 0.610406 0.437073 +v 0.522407 0.163382 0.562006 +v 0.33247 0.584279 0.463306 +v 0.462753 0.184298 0.584653 +v 0.504043 0.826408 0.565187 +v 0.682674 0.657913 0.587951 +v 0.457587 0.160941 0.550577 +v 0.371991 0.618035 0.432455 +v 0.735806 0.633074 0.60795 +v 0.705332 0.598761 0.568707 +v 0.717071 0.610306 0.503447 +v 0.686373 0.636889 0.462201 +v 0.454825 0.448096 0.357905 +v 0.59418 0.472164 0.396585 +v 0.57332 0.818604 0.428167 +v 0.568026 0.68236 0.427572 +v 0.408156 0.616198 0.490744 +v 0.584278 0.635258 0.504305 +v 0.401379 0.499339 0.422944 +v 0.55347 0.162429 0.555506 +v 0.315899 0.573855 0.511306 +v 0.421207 0.816472 0.454142 +v 0.57074 0.308725 0.412692 +v 0.306215 0.578772 0.488077 +v 0.417228 0.495561 0.387091 +v 0.503169 0.367785 0.495782 +v 0.288826 0.632346 0.623272 +v 0.501344 0.996432 0.463084 +v 0.429979 0.711034 0.449616 +v 0.555524 0.782568 0.560678 +v 0.287701 0.633175 0.600101 +v 0.674167 0.645257 0.585999 +v 0.272932 0.619144 0.536222 +v 0.436283 0.423726 0.378641 +v 0.572936 0.49981 0.565014 +v 0.713149 0.63511 0.622944 +v 0.409473 0.17155 0.568059 +v 0.525916 0.712552 0.558157 +v 0.671829 0.643466 0.515655 +v 0.659828 0.612243 0.595266 +v 0.470331 0.756001 0.570916 +v 0.616192 0.162531 0.493597 +v 0.597383 0.18729 0.54322 +v 0.552961 0.883074 0.529741 +v 0.567036 0.430215 0.376047 +v 0.276864 0.628656 0.589466 +v 0.575889 0.797858 0.442627 +v 0.529198 0.163196 0.437839 +v 0.559045 0.861986 0.520416 +v 0.585467 0.159698 0.480178 +v 0.575664 0.244392 0.413256 +v 0.502435 0.885223 0.536741 +v 0.566943 0.498645 0.374279 +v 0.585902 0.828874 0.450318 +v 0.441071 0.602688 0.419908 +v 0.495053 0.83699 0.574919 +v 0.290097 0.596164 0.561354 +v 0.575306 0.602278 0.51985 +v 0.431722 0.52173 0.393083 +v 0.506903 0.194366 0.502903 +v 0.504046 0.417057 0.557746 +v 0.384848 0.161384 0.500924 +v 0.719551 0.636326 0.533802 +v 0.537569 0.904297 0.521104 +v 0.471809 0.979131 0.415755 +v 0.566698 0.18058 0.580404 +v 0.504839 0.957117 0.389672 +v 0.682444 0.645259 0.513288 +v 0.523286 0.79636 0.577953 +v 0.478609 0.764439 0.545216 +v 0.304313 0.581302 0.536708 +v 0.528913 0.892985 0.536445 +v 0.69956 0.643791 0.611035 +v 0.460135 0.937877 0.510822 +v 0.436908 0.744267 0.531844 +v 0.47906 0.755716 0.544635 +v 0.451347 0.197656 0.560405 +v 0.519652 0.946492 0.388027 +v 0.462865 0.161953 0.576949 +v 0.575661 0.598176 0.43812 +v 0.421721 0.799269 0.455866 +v 0.702509 0.594907 0.479619 +v 0.694116 0.659412 0.558997 +v 0.476703 0.766106 0.55461 +v 0.565846 0.654381 0.535419 +v 0.655269 0.615883 0.588 +v 0.411603 0.644425 0.425525 +v 0.579737 0.173534 0.578427 +v 0.540991 0.433947 0.363627 +v 0.467804 0.852722 0.54494 +v 0.520707 0.841779 0.399134 +v 0.563382 0.765707 0.550124 +v 0.612925 0.171708 0.546623 +v 0.559573 0.964554 0.447223 +v 0.488549 0.275766 0.471482 +v 0.544539 0.957204 0.407478 +v 0.492833 0.464005 0.360471 +v 0.326603 0.623485 0.590792 +v 0.46595 0.841147 0.545319 +v 0.553867 0.379663 0.529812 +v 0.562609 0.836373 0.432564 +v 0.574034 0.711723 0.456137 +v 0.5235 0.170491 0.435734 +v 0.562893 0.950869 0.47546 +v 0.303907 0.659764 0.582429 +v 0.420027 0.180056 0.577473 +v 0.560269 0.75859 0.551448 +v 0.293045 0.65324 0.608288 +v 0.327262 0.61645 0.57932 +v 0.661613 0.630375 0.536297 +v 0.45619 0.959185 0.497853 +v 0.577498 0.18865 0.570534 +v 0.54961 0.63715 0.556408 +v 0.462406 0.758461 0.578808 +v 0.424484 0.711678 0.461279 +v 0.481632 0.981142 0.493916 +v 0.488127 0.904561 0.53063 +v 0.515479 0.458011 0.584004 +v 0.380753 0.3166 0.455588 +v 0.498033 0.773727 0.40303 +v 0.459832 0.868734 0.53699 +v 0.553513 0.384794 0.411563 +v 0.427711 0.288031 0.523535 +v 0.431698 0.30295 0.529382 +v 0.667958 0.64372 0.573003 +v 0.461084 0.902299 0.521156 +v 0.456173 0.162717 0.42625 +v 0.595567 0.555859 0.449794 +v 0.444967 0.957314 0.485178 +v 0.45642 0.164899 0.491561 +v 0.725137 0.613941 0.560182 +v 0.591808 0.452183 0.392984 +v 0.304689 0.65552 0.596168 +v 0.709962 0.647383 0.617283 +v 0.274731 0.608123 0.552089 +v 0.65312 0.621969 0.583283 +v 0.335043 0.647304 0.50613 +v 0.323243 0.650523 0.567163 +v 0.275335 0.618641 0.576828 +v 0.486912 0.758914 0.584558 +v 0.413891 0.159561 0.476967 +v 0.268764 0.636484 0.571178 +v 0.368079 0.597513 0.451609 +v 0.438646 0.858116 0.514131 +v 0.550836 0.42263 0.374206 +v 0.282777 0.593 0.531362 +v 0.457661 0.170835 0.420162 +v 0.610355 0.165837 0.547844 +v 0.590634 0.597004 0.477663 +v 0.39299 0.378395 0.438818 +v 0.483922 0.74381 0.406137 +v 0.687573 0.632044 0.62873 +v 0.694793 0.648089 0.52804 +v 0.582922 0.310908 0.526311 +v 0.26793 0.646776 0.59478 +v 0.581653 0.51716 0.404426 +v 0.412003 0.563588 0.521058 +v 0.563851 0.855936 0.507268 +v 0.491235 0.727996 0.576277 +v 0.730543 0.647234 0.593082 +v 0.450658 0.42358 0.372408 +v 0.399201 0.179648 0.427693 +v 0.479473 0.164178 0.457463 +v 0.427804 0.448595 0.5534 +v 0.322595 0.649535 0.599642 +v 0.5546 0.771233 0.572002 +v 0.371985 0.592996 0.48031 +v 0.734634 0.628374 0.605331 +v 0.447919 0.856106 0.416954 +v 0.531036 0.174605 0.42547 +v 0.491505 0.385723 0.425575 +v 0.591975 0.408352 0.420426 +v 0.38188 0.19481 0.453804 +v 0.455122 0.975 0.428615 +v 0.332329 0.574604 0.503295 +v 0.322588 0.627419 0.58899 +v 0.447744 0.741376 0.558957 +v 0.388426 0.603056 0.480029 +v 0.696194 0.577129 0.504132 +v 0.526693 0.483541 0.358121 +v 0.453545 0.389316 0.409727 +v 0.567572 0.919448 0.431773 +v 0.716938 0.643268 0.602048 +v 0.387722 0.178244 0.445422 +v 0.427012 0.160156 0.564769 +v 0.468178 0.163002 0.512866 +v 0.405465 0.603528 0.460161 +v 0.649806 0.624631 0.598684 +v 0.422484 0.702062 0.445469 +v 0.380725 0.175935 0.53331 +v 0.436985 0.235076 0.413097 +v 0.600266 0.249582 0.423466 +v 0.683987 0.657671 0.567609 +v 0.518055 0.745935 0.573325 +v 0.426333 0.602783 0.521145 +v 0.506916 0.38899 0.423972 +v 0.308366 0.633557 0.628478 +v 0.501633 0.639709 0.555238 +v 0.42649 0.818182 0.471074 +v 0.461684 0.633712 0.412421 +v 0.433488 0.687033 0.509636 +v 0.422158 0.806117 0.434365 +v 0.429009 0.309861 0.412832 +v 0.571681 0.611427 0.435081 +v 0.491229 0.430049 0.372593 +v 0.408456 0.200701 0.420932 +v 0.474514 0.163053 0.47374 +v 0.68293 0.634627 0.598539 +v 0.656764 0.634327 0.584648 +v 0.532162 0.446423 0.57489 +v 0.49707 0.359174 0.480173 +v 0.439125 0.53396 0.565262 +v 0.489689 0.218699 0.462405 +v 0.56017 0.843835 0.523785 +v 0.46351 0.224863 0.521191 +v 0.494519 0.892848 0.534796 +v 0.597048 0.556515 0.502191 +v 0.412586 0.312119 0.417456 +v 0.50879 0.987467 0.418466 +v 0.533822 0.497405 0.586631 +v 0.420721 0.165029 0.573779 +v 0.518341 0.260397 0.496239 +v 0.487154 0.271244 0.454893 +v 0.604831 0.651877 0.423779 +v 0.312842 0.574296 0.497476 +v 0.620405 0.175118 0.469087 +v 0.558164 0.8745 0.524817 +v 0.520845 0.20427 0.534106 +v 0.547571 0.302779 0.519601 +v 0.526706 0.170818 0.583695 +v 0.484688 0.381972 0.522108 +v 0.571161 0.926819 0.451018 +v 0.570493 0.627753 0.429095 +v 0.562093 0.737421 0.53632 +v 0.453991 0.750944 0.550226 +v 0.525509 0.746477 0.551588 +v 0.460205 0.74209 0.571245 +v 0.487909 0.947674 0.5196 +v 0.489286 0.983741 0.413114 +v 0.444557 0.255276 0.523886 +v 0.565227 0.762241 0.534307 +v 0.53752 0.737209 0.573558 +v 0.516045 0.177134 0.546515 +v 0.50861 0.190063 0.525035 +v 0.283639 0.633237 0.518512 +v 0.681293 0.629947 0.627161 +v 0.421087 0.656624 0.508219 +v 0.61231 0.161193 0.515579 +v 0.665922 0.620017 0.603967 +v 0.657629 0.617539 0.538442 +v 0.449932 0.720906 0.546959 +v 0.465484 0.765821 0.539765 +v 0.620655 0.191798 0.465228 +v 0.488488 0.853605 0.557126 +v 0.301384 0.592508 0.560429 +v 0.519122 0.185962 0.576658 +v 0.33308 0.627962 0.438051 +v 0.28333 0.650483 0.607635 +v 0.269535 0.642363 0.604386 +v 0.424312 0.468097 0.368911 +v 0.548546 0.340903 0.51886 +v 0.328804 0.629395 0.592419 +v 0.428705 0.317606 0.529256 +v 0.552832 0.402176 0.400074 +v 0.49899 0.556704 0.379811 +v 0.409126 0.60525 0.482436 +v 0.36767 0.59119 0.466635 +v 0.335643 0.628974 0.564661 +v 0.553547 0.167143 0.507291 +v 0.608451 0.1717 0.556381 +v 0.525847 0.982739 0.418643 +v 0.392191 0.359995 0.499278 +v 0.612463 0.193362 0.442252 +v 0.6877 0.627608 0.626197 +v 0.389816 0.221472 0.509363 +v 0.334172 0.636927 0.524849 +v 0.4171 0.36002 0.518913 +v 0.42944 0.926832 0.447952 +v 0.530437 0.159504 0.562644 +v 0.485815 0.603825 0.396347 +v 0.477045 0.275213 0.501412 +v 0.585989 0.588018 0.451722 +v 0.565343 0.202048 0.414584 +v 0.485382 0.766531 0.550771 +v 0.50998 0.99025 0.482264 +v 0.436476 0.904139 0.424529 +v 0.653301 0.578875 0.498428 +v 0.438803 0.159278 0.457936 +v 0.505756 0.854993 0.568877 +v 0.51758 0.687301 0.407402 +v 0.560458 0.534901 0.565761 +v 0.734989 0.641465 0.595994 +v 0.438262 0.829345 0.507935 +v 0.422665 0.1715 0.579612 +v 0.465578 0.677884 0.542873 +v 0.53516 0.840296 0.54524 +v 0.433295 0.929461 0.431392 +v 0.266677 0.625343 0.606682 +v 0.548495 0.803635 0.528596 +v 0.532072 0.683693 0.412844 +v 0.558039 0.438747 0.364726 +v 0.57411 0.840899 0.47059 +v 0.432384 0.36399 0.414866 +v 0.468572 0.769247 0.545203 +v 0.459781 0.168394 0.58224 +v 0.544365 0.973342 0.482403 +v 0.398904 0.612374 0.486599 +v 0.415186 0.832364 0.441954 +v 0.462577 0.604879 0.404701 +v 0.554206 0.190523 0.568368 +v 0.444543 0.849559 0.531391 +v 0.538709 0.985554 0.450446 +v 0.661216 0.645097 0.509312 +v 0.525771 0.94471 0.516523 +v 0.577692 0.182651 0.578123 +v 0.427825 0.397079 0.411083 +v 0.627505 0.596701 0.492453 +v 0.334029 0.620732 0.568106 +v 0.594085 0.162567 0.43705 +v 0.441679 0.622877 0.424548 +v 0.430474 0.160979 0.549056 +v 0.504111 0.735588 0.5799 +v 0.293019 0.660063 0.56231 +v 0.683195 0.583623 0.471119 +v 0.421969 0.61749 0.50493 +v 0.565581 0.873973 0.495059 +v 0.463047 0.378682 0.527686 +v 0.669965 0.648692 0.503088 +v 0.56292 0.637864 0.547452 +v 0.598594 0.53325 0.518037 +v 0.570112 0.15839 0.425562 +v 0.382932 0.373952 0.469407 +v 0.435143 0.66932 0.516909 +v 0.506514 0.93546 0.382919 +v 0.51184 0.216377 0.455125 +v 0.499328 0.400654 0.41343 +v 0.486292 0.209835 0.499934 +v 0.678498 0.642111 0.620515 +v 0.429615 0.16613 0.578041 +v 0.47349 0.164239 0.439386 +v 0.311662 0.628182 0.626604 +v 0.596269 0.500888 0.418488 +v 0.687215 0.644869 0.48832 +v 0.627471 0.668255 0.494052 +v 0.470734 0.162653 0.544698 +v 0.59844 0.616597 0.439936 +v 0.439641 0.88344 0.517422 +v 0.551064 0.225737 0.528008 +v 0.570414 0.711222 0.49706 +v 0.474896 0.194766 0.570428 +v 0.465277 0.840581 0.405191 +v 0.381146 0.169416 0.515307 +v 0.456389 0.434502 0.363253 +v 0.515146 0.210125 0.503809 +v 0.510105 0.825087 0.554038 +v 0.59187 0.206631 0.527144 +v 0.483687 0.332355 0.444016 +v 0.337539 0.64814 0.440492 +v 0.570536 0.156152 0.435445 +v 0.474184 0.184023 0.583797 +v 0.650185 0.579827 0.480416 +v 0.60826 0.498492 0.510028 +v 0.559128 0.287772 0.522828 +v 0.618663 0.176708 0.532403 +v 0.448044 0.201317 0.416756 +v 0.470502 0.759749 0.562049 +v 0.570955 0.664553 0.514704 +v 0.525971 0.198162 0.555135 +v 0.482546 0.180573 0.577223 +v 0.479262 0.775646 0.587534 +v 0.611346 0.275615 0.501481 +v 0.679883 0.618745 0.44896 +v 0.463383 0.802079 0.567231 +v 0.469826 0.728361 0.573019 +v 0.290511 0.600532 0.485146 +v 0.545072 0.758302 0.55202 +v 0.569272 0.188397 0.574658 +v 0.432329 0.947699 0.452874 +v 0.726431 0.643001 0.603897 +v 0.485427 0.170205 0.455335 +v 0.559217 0.625794 0.424786 +v 0.517534 0.836732 0.55123 +v 0.487569 0.852455 0.545323 +v 0.526297 0.334435 0.42988 +v 0.427373 0.847985 0.467772 +v 0.584386 0.706739 0.467261 +v 0.533221 0.209515 0.540413 +v 0.567246 0.948822 0.458809 +v 0.518073 0.173925 0.577495 +v 0.512529 0.273709 0.456382 +v 0.564654 0.666164 0.423474 +v 0.426419 0.812079 0.46476 +v 0.694731 0.642888 0.506629 +v 0.462032 0.746039 0.54273 +v 0.441455 0.731959 0.521342 +v 0.704062 0.585886 0.54054 +v 0.426501 0.693833 0.435825 +v 0.44079 0.789275 0.536464 +v 0.441471 0.838951 0.524169 +v 0.589255 0.488724 0.393587 +v 0.276693 0.630304 0.597516 +v 0.415645 0.157087 0.525616 +v 0.623219 0.179147 0.488625 +v 0.668676 0.610948 0.562312 +v 0.522985 0.404006 0.543579 +v 0.400966 0.623528 0.494488 +v 0.516972 0.993654 0.467931 +v 0.70267 0.635412 0.620267 +v 0.505061 0.975758 0.402723 +v 0.352643 0.600059 0.518779 +v 0.460273 0.651212 0.554693 +v 0.277881 0.603997 0.519775 +v 0.403565 0.240604 0.420782 +v 0.447058 0.773973 0.572772 +v 0.453838 0.757297 0.55298 +v 0.58482 0.165549 0.422557 +v 0.445546 0.429241 0.554647 +v 0.297626 0.579703 0.506763 +v 0.712372 0.635919 0.602548 +v 0.569643 0.443105 0.553472 +v 0.587273 0.157994 0.507149 +v 0.427709 0.799078 0.473772 +v 0.484151 0.181331 0.548243 +v 0.510941 0.208813 0.489105 +v 0.520435 0.360464 0.431278 +v 0.440735 0.819816 0.429119 +v 0.433255 0.830984 0.433571 +v 0.293339 0.644499 0.619626 +v 0.606744 0.439507 0.518072 +v 0.590655 0.587018 0.482896 +v 0.563358 0.358292 0.522916 +v 0.534196 0.51774 0.373459 +v 0.271559 0.630496 0.591975 +v 0.450357 0.716988 0.532346 +v 0.721349 0.630015 0.592307 +v 0.610142 0.159511 0.47843 +v 0.620978 0.169904 0.534297 +v 0.590644 0.178652 0.566393 +v 0.457238 0.917654 0.397593 +v 0.571446 0.785703 0.45971 +v 0.583575 0.370483 0.419401 +v 0.403298 0.364612 0.511005 +v 0.606596 0.312546 0.430885 +v 0.565822 0.405862 0.401425 +v 0.536338 0.605954 0.404522 +v 0.447154 0.167516 0.508263 +v 0.383867 0.389942 0.478364 +v 0.447686 0.356114 0.415467 +v 0.616654 0.295533 0.444475 +v 0.613696 0.160481 0.533028 +v 0.484595 0.266744 0.489283 +v 0.437495 0.159228 0.479189 +v 0.470251 0.341044 0.509437 +v 0.429568 0.722409 0.459862 +v 0.453889 0.628401 0.556605 +v 0.516871 0.771409 0.589014 +v 0.590287 0.595572 0.464384 +v 0.548013 0.799866 0.557584 +v 0.330967 0.63794 0.540666 +v 0.477842 0.437021 0.571809 +v 0.564615 0.26363 0.524244 +v 0.389115 0.186106 0.526941 +v 0.53478 0.223393 0.52065 +v 0.472882 0.60382 0.559381 +v 0.561066 0.736276 0.517902 +v 0.539135 0.705339 0.538235 +v 0.402305 0.187706 0.542473 +v 0.297559 0.613797 0.471093 +v 0.467471 0.816505 0.540497 +v 0.476996 0.907706 0.527114 +v 0.441236 0.472455 0.359714 +v 0.411238 0.165646 0.564277 +v 0.559737 0.89178 0.503482 +v 0.497782 0.363695 0.453609 +v 0.402772 0.161694 0.445139 +v 0.55232 0.325432 0.520752 +v 0.346015 0.582706 0.468057 +v 0.712073 0.619911 0.495195 +v 0.425299 0.821365 0.428453 +v 0.408917 0.178426 0.566466 +v 0.549805 0.899277 0.513323 +v 0.606578 0.504598 0.445703 +v 0.328179 0.596751 0.45174 +v 0.613769 0.662909 0.426061 +v 0.480442 0.696382 0.547148 +v 0.580442 0.214894 0.5302 +v 0.530091 0.823809 0.541168 +v 0.456117 0.733632 0.568038 +v 0.658453 0.58371 0.519543 +v 0.345333 0.620531 0.584823 +v 0.696797 0.653064 0.599812 +v 0.386427 0.160648 0.534124 +v 0.437936 0.745673 0.516166 +v 0.456313 0.851358 0.541514 +v 0.497483 0.358266 0.467291 +v 0.507927 0.900191 0.531787 +v 0.446269 0.180451 0.577891 +v 0.489822 0.609961 0.560514 +v 0.505158 0.355949 0.464188 +v 0.437646 0.333328 0.522521 +v 0.655651 0.620169 0.610293 +v 0.460177 0.205291 0.421639 +v 0.458397 0.774025 0.581883 +v 0.577481 0.305066 0.528642 +v 0.4804 0.368089 0.42865 +v 0.47231 0.640638 0.558879 +v 0.620991 0.231361 0.489465 +v 0.471232 0.951565 0.512589 +v 0.500219 0.702319 0.55235 +v 0.272986 0.634827 0.611435 +v 0.301057 0.660245 0.561918 +v 0.523267 0.905045 0.52813 +v 0.535173 0.332426 0.512196 +v 0.520176 0.168898 0.544266 +v 0.271828 0.63021 0.581747 +v 0.512496 0.197292 0.52821 +v 0.485239 0.175873 0.567366 +v 0.31291 0.658754 0.569002 +v 0.39187 0.50532 0.452746 +v 0.442433 0.162088 0.553146 +v 0.322514 0.619937 0.584937 +v 0.452576 0.502539 0.580762 +v 0.547952 0.757043 0.546749 +v 0.52403 0.53937 0.580876 +v 0.477327 0.672679 0.548061 +v 0.682607 0.652799 0.608237 +v 0.408545 0.329027 0.51586 +v 0.489109 0.180837 0.456704 +v 0.679593 0.648146 0.49575 +v 0.433196 0.397562 0.534828 +v 0.520184 0.436189 0.57184 +v 0.609486 0.604545 0.45239 +v 0.457179 0.40013 0.54059 +v 0.610156 0.512183 0.470992 +v 0.450791 0.901012 0.51307 +v 0.517474 0.670715 0.548607 +v 0.302191 0.649755 0.532442 +v 0.616639 0.44599 0.497492 +v 0.459795 0.357633 0.519321 +v 0.281199 0.630555 0.594842 +v 0.460076 0.176265 0.585198 +v 0.385577 0.305688 0.441128 +v 0.552792 0.753194 0.549334 +v 0.437227 0.627661 0.544408 +v 0.575297 0.163086 0.499432 +v 0.535056 0.163164 0.512464 +v 0.501956 0.377622 0.509547 +v 0.586914 0.164621 0.563418 +v 0.489804 0.354261 0.449093 +v 0.529741 0.270141 0.509261 +v 0.393069 0.526301 0.472173 +v 0.511827 0.180129 0.453126 +v 0.589502 0.158998 0.450292 +v 0.301996 0.648981 0.604385 +v 0.576126 0.166552 0.577204 +v 0.539874 0.762699 0.539226 +v 0.363244 0.661112 0.431866 +v 0.562257 0.473277 0.361815 +v 0.38675 0.198158 0.507424 +v 0.480961 0.180147 0.438082 +v 0.424679 0.307138 0.529585 +v 0.529139 0.603645 0.559509 +v 0.6188 0.450659 0.461711 +v 0.544185 0.719181 0.554859 +v 0.502116 0.822012 0.557568 +v 0.562585 0.829029 0.50768 +v 0.523475 0.181434 0.43205 +v 0.583403 0.394488 0.526546 +v 0.622035 0.170459 0.488908 +v 0.512221 0.334389 0.480578 +v 0.521274 0.834888 0.545752 +v 0.60285 0.165056 0.55952 +v 0.565806 0.946899 0.436335 +v 0.387346 0.376668 0.491154 +v 0.338505 0.624856 0.607017 +v 0.456247 0.807037 0.55008 +v 0.308935 0.62677 0.620721 +v 0.664235 0.623386 0.55636 +v 0.506642 0.943171 0.521871 +v 0.532263 0.419003 0.376555 +v 0.452212 0.978196 0.455094 +v 0.289147 0.629539 0.617564 +v 0.610993 0.380958 0.445348 +v 0.554728 0.797262 0.541538 +v 0.569051 0.724595 0.453578 +v 0.428299 0.163835 0.500654 +v 0.462673 0.484062 0.358314 +v 0.543241 0.158573 0.434716 +v 0.535848 0.985581 0.467856 +v 0.532517 0.768885 0.542581 +v 0.435919 0.881103 0.496686 +v 0.439791 0.288178 0.522891 +v 0.40146 0.606288 0.478334 +v 0.377737 0.176219 0.475869 +v 0.446375 0.17271 0.57736 +v 0.698333 0.635611 0.486813 +v 0.622 0.217521 0.456356 +v 0.518973 0.994517 0.450319 +v 0.573991 0.287565 0.523235 +v 0.536208 0.348903 0.421204 +v 0.476494 0.880637 0.543449 +v 0.515647 0.778429 0.404483 +v 0.730246 0.629973 0.61465 +v 0.706302 0.641586 0.621891 +v 0.575211 0.316383 0.528955 +v 0.427715 0.410377 0.400446 +v 0.397207 0.165526 0.55966 +v 0.584695 0.703466 0.453807 +v 0.535528 0.187473 0.58342 +v 0.475561 0.338969 0.431301 +v 0.524357 0.919148 0.387245 +v 0.56781 0.695734 0.434292 +v 0.436883 0.310631 0.528886 +v 0.415961 0.604825 0.448992 +v 0.435739 0.646498 0.424245 +v 0.526925 0.757482 0.567666 +v 0.488247 0.463335 0.586182 +v 0.473586 0.17039 0.432577 +v 0.280716 0.60187 0.558755 +v 0.58891 0.610186 0.489729 +v 0.522072 0.761679 0.586115 +v 0.396492 0.434312 0.52139 +v 0.487835 0.328522 0.479389 +v 0.516638 0.333004 0.443119 +v 0.498899 0.483613 0.36191 +v 0.439471 0.771291 0.436798 +v 0.618789 0.164454 0.533748 +v 0.389849 0.684851 0.486521 +v 0.539286 0.381132 0.414253 +v 0.483758 0.225805 0.44448 +v 0.413197 0.403457 0.417416 +v 0.568102 0.172617 0.41302 +v 0.651187 0.617243 0.527154 +v 0.421292 0.834091 0.436244 +v 0.597764 0.603282 0.47754 +v 0.463342 0.355369 0.421032 +v 0.600179 0.651894 0.501896 +v 0.432453 0.160763 0.570107 +v 0.598276 0.616234 0.491429 +v 0.531432 0.402648 0.399322 +v 0.437825 0.650128 0.539505 +v 0.623872 0.22181 0.475936 +v 0.430649 0.196116 0.554801 +v 0.48563 0.661189 0.406232 +v 0.480976 0.170712 0.545485 +v 0.674842 0.651553 0.577067 +v 0.4612 0.285893 0.419905 +v 0.443866 0.380379 0.412771 +v 0.478001 0.749723 0.546294 +v 0.554085 0.756391 0.552596 +v 0.394454 0.608286 0.449656 +v 0.68957 0.610113 0.583561 +v 0.545445 0.836291 0.540211 +v 0.432803 0.935826 0.472721 +v 0.551211 0.958992 0.489955 +v 0.309059 0.600524 0.461546 +v 0.55378 0.183822 0.576005 +v 0.53866 0.858692 0.404711 +v 0.331535 0.637402 0.55911 +v 0.493828 0.762123 0.548053 +v 0.408714 0.611325 0.446737 +v 0.536594 0.38278 0.529923 +v 0.495104 0.18617 0.494736 +v 0.553495 0.723035 0.528705 +v 0.510633 0.354459 0.447662 +v 0.68821 0.633875 0.606111 +v 0.462145 0.455771 0.577127 +v 0.422528 0.598853 0.440831 +v 0.591614 0.584453 0.469254 +v 0.535645 0.194487 0.575195 +v 0.619889 0.447266 0.478221 +v 0.505762 0.177659 0.489388 +v 0.468265 0.269824 0.511075 +v 0.463682 0.158941 0.441181 +v 0.565568 0.872155 0.509973 +v 0.452368 0.780067 0.421442 +v 0.733359 0.626662 0.611222 +v 0.504874 0.851411 0.394673 +v 0.551873 0.815649 0.523176 +v 0.58091 0.362151 0.519975 +v 0.316545 0.646814 0.496955 +v 0.498712 0.417643 0.386334 +v 0.412123 0.453645 0.383848 +v 0.566039 0.828185 0.433558 +v 0.482506 0.994715 0.456728 +v 0.642752 0.672339 0.482625 +v 0.515422 0.169692 0.453655 +v 0.400414 0.169261 0.432406 +v 0.446535 0.865269 0.528144 +v 0.687799 0.575025 0.515725 +v 0.454829 0.336943 0.517858 +v 0.584265 0.82773 0.4378 +v 0.415091 0.516792 0.408384 +v 0.545695 0.749699 0.551744 +v 0.508306 0.80294 0.575664 +v 0.263609 0.628176 0.608149 +v 0.495267 0.822172 0.55662 +v 0.451586 0.306612 0.520038 +v 0.590378 0.170344 0.567479 +v 0.469172 0.669296 0.411998 +v 0.480786 0.706235 0.553128 +v 0.414365 0.550907 0.533467 +v 0.716613 0.594772 0.536502 +v 0.65396 0.614232 0.608055 +v 0.490547 0.991765 0.4786 +v 0.692377 0.63084 0.621621 +v 0.489486 0.945789 0.385709 +v 0.414922 0.283284 0.520417 +v 0.468325 0.775432 0.410479 +v 0.488384 0.35445 0.493902 +v 0.276892 0.65101 0.589121 +v 0.427502 0.850252 0.457822 +v 0.446625 0.880019 0.52971 +v 0.584448 0.466524 0.378499 +v 0.377741 0.193523 0.475399 +v 0.487201 0.992027 0.430309 +v 0.451722 0.586584 0.554811 +v 0.525423 0.463084 0.356296 +v 0.358986 0.601117 0.444138 +v 0.581935 0.65468 0.508051 +v 0.581573 0.4424 0.381459 +v 0.616763 0.183686 0.516906 +v 0.498266 0.559934 0.577754 +v 0.535962 0.675011 0.543352 +v 0.45603 0.974322 0.480628 +v 0.404365 0.556426 0.507341 +v 0.727465 0.630678 0.592998 +v 0.549452 0.623602 0.556328 +v 0.402279 0.308424 0.512607 +v 0.475174 0.736353 0.577919 +v 0.504398 0.995746 0.439834 +v 0.537504 0.730763 0.57087 +v 0.52455 0.368716 0.517305 +v 0.492021 0.969894 0.508493 +v 0.671576 0.642534 0.58272 +v 0.480968 0.746287 0.55319 +v 0.396557 0.681804 0.433199 +v 0.512322 0.275923 0.477757 +v 0.435865 0.769956 0.536549 +v 0.488521 0.968761 0.397512 +v 0.327944 0.611895 0.567861 +v 0.584432 0.599359 0.450914 +v 0.380649 0.450194 0.472144 +v 0.459787 0.750338 0.539711 +v 0.314588 0.63418 0.602069 +v 0.654586 0.630822 0.580614 +v 0.559767 0.883923 0.519905 +v 0.520447 0.741075 0.577306 +v 0.333973 0.641716 0.51383 +v 0.504671 0.857298 0.545231 +v 0.319769 0.643487 0.456446 +v 0.608879 0.516688 0.490447 +v 0.534161 0.6885 0.540999 +v 0.393032 0.157532 0.488202 +v 0.352637 0.673338 0.454114 +v 0.665127 0.6196 0.567674 +v 0.549928 0.975629 0.44141 +v 0.50838 0.861105 0.539383 +v 0.502017 0.363347 0.455068 +v 0.592479 0.156761 0.521025 +v 0.686548 0.62623 0.619447 +v 0.581097 0.705221 0.482081 +v 0.346435 0.614351 0.606193 +v 0.663997 0.638389 0.521297 +v 0.422532 0.803327 0.461997 +v 0.568043 0.364856 0.414826 +v 0.525422 0.192514 0.575304 +v 0.47426 0.564036 0.385348 +v 0.45783 0.963292 0.40979 +v 0.42759 0.790291 0.462924 +v 0.38874 0.1657 0.546279 +v 0.724247 0.628021 0.611329 +v 0.565403 0.309948 0.529232 +v 0.587613 0.177415 0.417819 +v 0.646133 0.611377 0.436256 +v 0.565595 0.393589 0.410184 +v 0.515756 0.19696 0.447708 +v 0.379224 0.169987 0.534481 +v 0.565384 0.797075 0.439649 +v 0.491611 0.918713 0.383327 +v 0.46821 0.987569 0.437106 +v 0.504201 0.454794 0.361834 +v 0.412287 0.633707 0.429545 +v 0.705148 0.631043 0.61893 +v 0.379882 0.166834 0.486826 +v 0.442867 0.927559 0.411791 +v 0.567733 0.786804 0.44701 +v 0.733895 0.63708 0.591618 +v 0.43537 0.81893 0.430629 +v 0.542778 0.180968 0.417865 +v 0.525721 0.438287 0.362557 +v 0.353002 0.639485 0.429775 +v 0.42334 0.375518 0.416282 +v 0.559676 0.787458 0.54447 +v 0.699833 0.637257 0.60676 +v 0.601989 0.173937 0.563235 +v 0.347438 0.623151 0.605596 +v 0.596923 0.273796 0.514955 +v 0.557586 0.751783 0.548279 +v 0.67663 0.650601 0.602053 +v 0.42008 0.675404 0.504881 +v 0.422628 0.693102 0.497767 +v 0.456417 0.217174 0.530876 +v 0.579038 0.695225 0.495986 +v 0.618588 0.68637 0.448659 +v 0.522924 0.216936 0.512925 +v 0.379042 0.222071 0.45134 +v 0.424133 0.188323 0.572482 +v 0.331444 0.61603 0.587446 +v 0.515765 0.966986 0.508951 +v 0.538535 0.93981 0.395181 +v 0.553688 0.177316 0.578143 +v 0.32746 0.648361 0.503106 +v 0.412115 0.159419 0.449266 +v 0.696271 0.617302 0.465642 +v 0.411958 0.702838 0.474882 +v 0.539466 0.487673 0.359409 +v 0.559168 0.768417 0.563971 +v 0.46029 0.765956 0.540403 +v 0.521423 0.163879 0.457475 +v 0.496549 0.829539 0.569842 +v 0.425296 0.567488 0.418602 +v 0.626343 0.61048 0.437734 +v 0.478903 0.804466 0.572175 +v 0.390714 0.615009 0.492018 +v 0.646535 0.655792 0.435038 +v 0.731823 0.63897 0.608399 +v 0.556115 0.49311 0.365681 +v 0.466926 0.821537 0.538899 +v 0.45137 0.764247 0.578323 +v 0.323571 0.643592 0.588889 +v 0.269598 0.643965 0.568448 +v 0.57012 0.597565 0.532625 +v 0.547096 0.763715 0.578339 +v 0.455832 0.265253 0.518996 +v 0.687309 0.575888 0.491155 +v 0.504595 0.185853 0.495873 +v 0.444264 0.793105 0.551554 +v 0.43921 0.437573 0.365936 +v 0.365236 0.627785 0.511036 +v 0.484606 0.836727 0.398536 +v 0.480228 0.218439 0.50812 +v 0.387131 0.435197 0.505865 +v 0.440482 0.766226 0.561502 +v 0.55542 0.793371 0.523317 +v 0.286995 0.634618 0.60478 +v 0.672435 0.624683 0.590482 +v 0.563182 0.159449 0.480695 +v 0.542606 0.358814 0.520529 +v 0.428758 0.624916 0.431244 +v 0.468377 0.378869 0.41717 +v 0.435074 0.59519 0.537637 +v 0.390266 0.633915 0.500722 +v 0.490976 0.347509 0.478608 +v 0.482355 0.847925 0.546939 +v 0.483623 0.499816 0.590505 +v 0.706087 0.643542 0.523887 +v 0.445841 0.755767 0.55199 +v 0.712228 0.630246 0.616904 +v 0.269101 0.627833 0.61437 +v 0.42054 0.377846 0.522995 +v 0.425147 0.807971 0.431121 +v 0.36937 0.663238 0.49791 +v 0.482135 0.167586 0.568554 +v 0.274771 0.628107 0.610297 +v 0.449136 0.817352 0.524104 +v 0.620379 0.309685 0.460537 +v 0.410248 0.591319 0.479981 +v 0.450231 0.888893 0.528448 +v 0.451689 0.522755 0.38047 +v 0.4923 0.17691 0.515158 +v 0.387391 0.650015 0.423739 +v 0.381661 0.179105 0.519543 +v 0.728571 0.623926 0.607914 +v 0.565413 0.623302 0.54478 +v 0.477639 0.368995 0.516102 +v 0.677155 0.633262 0.620796 +v 0.574767 0.807195 0.431376 +v 0.415142 0.704836 0.458413 +v 0.681477 0.626971 0.621144 +v 0.568395 0.164227 0.417845 +v 0.603992 0.601167 0.467047 +v 0.335036 0.635147 0.590393 +v 0.48192 0.74459 0.575036 +v 0.576248 0.489042 0.37672 +v 0.467252 0.202489 0.552949 +v 0.572904 0.853063 0.461033 +v 0.593431 0.633879 0.499771 +v 0.385186 0.688728 0.44804 +v 0.444063 0.793049 0.521891 +v 0.670617 0.641591 0.543664 +v 0.311429 0.650421 0.612901 +v 0.496376 0.857426 0.544247 +v 0.539602 0.168837 0.582602 +v 0.669755 0.588479 0.458797 +v 0.480578 0.188467 0.573646 +v 0.532471 0.748096 0.563784 +v 0.546968 0.939288 0.504689 +v 0.549914 0.358294 0.415738 +v 0.462678 0.76726 0.547529 +v 0.552061 0.681389 0.529289 +v 0.537069 0.178896 0.585993 +v 0.337511 0.60488 0.543441 +v 0.429494 0.185117 0.578234 +v 0.625074 0.632278 0.426535 +v 0.473285 0.765252 0.587371 +v 0.661331 0.612735 0.604721 +v 0.584082 0.836544 0.454993 +v 0.537775 0.767476 0.546602 +v 0.420613 0.808266 0.442876 +v 0.487712 0.397608 0.536089 +v 0.492216 0.66944 0.550016 +v 0.421562 0.438743 0.378831 +v 0.509757 0.855306 0.561321 +v 0.498778 0.752113 0.548275 +v 0.339173 0.611399 0.601275 +v 0.669008 0.573544 0.495942 +v 0.453341 0.602451 0.552319 +v 0.620027 0.595827 0.477336 +v 0.678205 0.638145 0.600642 +v 0.530734 0.802716 0.570298 +v 0.654449 0.624362 0.433482 +v 0.282048 0.640463 0.617882 +v 0.481201 0.823494 0.545613 +v 0.546076 0.216258 0.532564 +v 0.525107 0.983172 0.486959 +v 0.499163 0.630305 0.401464 +v 0.514713 0.18135 0.568096 +v 0.503585 0.983748 0.494449 +v 0.351981 0.614897 0.521496 +v 0.607808 0.606991 0.485623 +v 0.568357 0.197115 0.554239 +v 0.504012 0.432995 0.370905 +v 0.471171 0.558365 0.574096 +v 0.510634 0.81987 0.554712 +v 0.319249 0.637368 0.598654 +v 0.468207 0.193101 0.57802 +v 0.520566 0.32988 0.498158 +v 0.552899 0.451426 0.358567 +v 0.3159 0.656185 0.59864 +v 0.436038 0.720476 0.443029 +v 0.568007 0.389391 0.531159 +v 0.723705 0.610029 0.531064 +v 0.314855 0.633793 0.628892 +v 0.615955 0.373965 0.48199 +v 0.457457 0.748286 0.563318 +v 0.382636 0.445085 0.455044 +v 0.572968 0.630934 0.533502 +v 0.524233 0.378777 0.420586 +v 0.298063 0.625246 0.475696 +v 0.434396 0.453664 0.362802 +v 0.376859 0.649291 0.503814 +v 0.394386 0.158607 0.522041 +v 0.577081 0.81351 0.461489 +v 0.605479 0.161996 0.542966 +v 0.447105 0.160081 0.530427 +v 0.415348 0.61097 0.492934 +v 0.324845 0.635992 0.587714 +v 0.502934 0.850202 0.574284 +v 0.482024 0.202261 0.532596 +v 0.507615 0.180058 0.520453 +v 0.526159 0.162806 0.576021 +v 0.333696 0.62217 0.558563 +v 0.504172 0.371444 0.441612 +v 0.512592 0.346111 0.488544 +v 0.560462 0.563699 0.402827 +v 0.547557 0.753507 0.544794 +v 0.613659 0.22434 0.437637 +v 0.566099 0.218073 0.53199 +v 0.283367 0.633131 0.618634 +v 0.280893 0.636877 0.599649 +v 0.386228 0.166544 0.463056 +v 0.472374 0.216708 0.518757 +v 0.485907 0.839415 0.567142 +v 0.665349 0.634673 0.559472 +v 0.71692 0.638878 0.616673 +v 0.289153 0.639067 0.624 +v 0.494073 0.846453 0.574666 +v 0.404739 0.62065 0.437218 +v 0.486758 0.849226 0.564999 +v 0.645098 0.626548 0.516817 +v 0.422164 0.703053 0.48834 +v 0.435716 0.799251 0.436787 +v 0.321933 0.635036 0.618247 +v 0.436365 0.701863 0.436767 +v 0.282981 0.652886 0.555942 +v 0.44712 0.750991 0.551046 +v 0.449233 0.699303 0.425707 +v 0.553645 0.170598 0.57604 +v 0.500592 0.875854 0.537929 +v 0.39365 0.663594 0.50003 +v 0.571739 0.452569 0.367542 +v 0.405521 0.207654 0.525402 +v 0.270838 0.620714 0.560898 +v 0.551758 0.790952 0.424103 +v 0.449326 0.799778 0.531779 +v 0.43265 0.156625 0.430365 +v 0.271574 0.624441 0.60798 +v 0.572868 0.72392 0.483027 +v 0.418128 0.313289 0.526562 +v 0.57303 0.793255 0.469727 +v 0.446194 0.206782 0.546898 +v 0.561972 0.773349 0.515733 +v 0.469331 0.159456 0.570197 +v 0.544414 0.201898 0.419371 +v 0.713677 0.652788 0.605963 +v 0.509208 0.503723 0.591233 +v 0.649396 0.618441 0.602371 +v 0.55332 0.653182 0.549132 +v 0.450769 0.680061 0.532194 +v 0.519994 0.164211 0.505803 +v 0.286835 0.610826 0.582265 +v 0.57868 0.815479 0.429853 +v 0.670338 0.629074 0.592158 +v 0.611894 0.377258 0.49411 +v 0.503557 0.668479 0.404904 +v 0.586876 0.492959 0.550784 +v 0.511664 0.392853 0.531118 +v 0.554915 0.759504 0.564584 +v 0.461757 0.464439 0.355765 +v 0.716979 0.631472 0.595349 +v 0.32014 0.578926 0.529747 +v 0.418049 0.825107 0.465417 +v 0.60295 0.372318 0.506328 +v 0.471527 0.97027 0.500912 +v 0.393618 0.602486 0.46567 +v 0.706005 0.656853 0.601336 +v 0.718888 0.652695 0.562797 +v 0.572872 0.724745 0.468098 +v 0.306439 0.63001 0.622844 +v 0.67353 0.616061 0.579865 +v 0.619223 0.171282 0.51573 +v 0.661117 0.617016 0.609247 +v 0.526425 0.181979 0.584437 +v 0.541325 0.74408 0.569015 +v 0.571874 0.16021 0.567039 +v 0.370916 0.630841 0.427037 +v 0.527782 0.208607 0.430654 +v 0.375875 0.225065 0.467264 +v 0.514782 0.764005 0.547617 +v 0.54264 0.167526 0.421908 +v 0.315011 0.629933 0.594089 +v 0.528046 0.757607 0.57963 +v 0.31614 0.59636 0.562158 +v 0.477111 0.865644 0.541585 +v 0.319187 0.644713 0.517429 +v 0.412371 0.413772 0.53026 +v 0.429737 0.631751 0.532563 +v 0.569274 0.475866 0.56628 +v 0.583468 0.828103 0.46324 +v 0.438028 0.357273 0.522889 +v 0.583523 0.559018 0.426327 +v 0.55492 0.835742 0.531325 +v 0.478665 0.173141 0.581193 +v 0.377361 0.179711 0.497458 +v 0.650914 0.637057 0.514479 +v 0.432201 0.165714 0.416597 +v 0.705016 0.630512 0.600678 +v 0.491381 0.190748 0.522725 +v 0.673401 0.579336 0.526874 +v 0.386875 0.388793 0.450921 +v 0.428572 0.489972 0.372575 +v 0.397126 0.179995 0.558737 +v 0.269947 0.649415 0.581192 +v 0.472852 0.204498 0.431402 +v 0.594539 0.600447 0.473969 +v 0.562268 0.936967 0.485586 +v 0.414835 0.635035 0.502116 +v 0.58573 0.563891 0.525943 +v 0.510965 0.335465 0.460769 +v 0.401319 0.647782 0.501583 +v 0.458018 0.707771 0.537615 +v 0.70921 0.632779 0.623565 +v 0.461412 0.179383 0.420069 +v 0.516379 0.844451 0.562735 +v 0.588627 0.184751 0.55916 +v 0.418867 0.242338 0.414192 +v 0.442575 0.894117 0.505247 +v 0.507234 0.838694 0.57462 +v 0.511819 0.831975 0.56641 +v 0.590857 0.295968 0.517996 +v 0.327615 0.646002 0.578432 +v 0.334473 0.616831 0.605773 +v 0.729311 0.63406 0.567892 +v 0.445432 0.469845 0.574182 +v 0.511488 0.604464 0.395889 +v 0.555585 0.72576 0.544904 +v 0.469449 0.985746 0.476697 +v 0.69032 0.598877 0.463055 +v 0.470805 0.167675 0.582875 +v 0.327929 0.641909 0.582607 +v 0.44483 0.379788 0.529379 +v 0.445661 0.562763 0.39816 +v 0.525087 0.643902 0.407819 +v 0.537608 0.70938 0.544051 +v 0.553203 0.851476 0.53449 +v 0.544515 0.255655 0.41707 +v 0.490343 0.203585 0.482047 +v 0.437137 0.874736 0.516489 +v 0.587867 0.306119 0.416872 +v 0.583045 0.413542 0.408986 +v 0.548647 0.890831 0.527816 +v 0.479008 0.194689 0.551585 +v 0.344949 0.629056 0.582183 +v 0.411077 0.588173 0.460565 +v 0.555277 0.607431 0.417689 +v 0.426924 0.722339 0.4754 +v 0.690932 0.587344 0.550993 +v 0.281535 0.6158 0.504432 +v 0.372522 0.597682 0.491087 +v 0.657601 0.601109 0.53647 +v 0.467641 0.420553 0.375008 +v 0.527698 0.973781 0.408446 +v 0.518225 0.766852 0.552645 +v 0.441116 0.156223 0.443022 +v 0.345016 0.613607 0.595755 +v 0.670932 0.604612 0.446969 +v 0.318787 0.62538 0.448804 +v 0.730462 0.645161 0.575161 +v 0.315446 0.62688 0.619431 +v 0.603941 0.20556 0.517927 +v 0.394404 0.452562 0.426061 +v 0.467461 0.484381 0.587014 +v 0.561008 0.645029 0.42344 +v 0.49767 0.438312 0.575255 +v 0.558586 0.26376 0.412754 +v 0.298219 0.624579 0.596539 +v 0.410492 0.462729 0.54225 +v 0.555792 0.914166 0.411064 +v 0.385752 0.661995 0.425414 +v 0.46226 0.717624 0.558278 +v 0.397345 0.302965 0.426154 +v 0.518943 0.730965 0.576771 +v 0.681622 0.648077 0.534277 +v 0.457153 0.945325 0.400037 +v 0.539945 0.746114 0.541074 +v 0.691873 0.633538 0.601499 +v 0.537626 0.852139 0.543894 +v 0.690877 0.638725 0.624157 +v 0.665756 0.578119 0.474667 +v 0.564099 0.80937 0.435364 +v 0.315347 0.582659 0.472416 +v 0.486117 0.883345 0.54267 +v 0.449103 0.757295 0.566893 +v 0.532732 0.817302 0.541134 +v 0.706501 0.583326 0.517673 +v 0.4245 0.334919 0.521589 +v 0.718317 0.610877 0.575 +v 0.537125 0.39314 0.408499 +v 0.516753 0.16925 0.567962 +v 0.605651 0.156867 0.492886 +v 0.404786 0.377622 0.426195 +v 0.526188 0.162597 0.469383 +v 0.496061 0.370962 0.441876 +v 0.568794 0.692881 0.507127 +v 0.395063 0.172218 0.560867 +v 0.612573 0.443568 0.441474 +v 0.534483 0.963968 0.502516 +v 0.509509 0.202604 0.474546 +v 0.518296 0.823867 0.546272 +v 0.264869 0.633605 0.611442 +v 0.667669 0.654415 0.452753 +v 0.578875 0.798829 0.452016 +v 0.472039 0.414095 0.552118 +v 0.541778 0.882475 0.536959 +v 0.604098 0.689821 0.483235 +v 0.705871 0.610289 0.584971 +v 0.614499 0.167451 0.462893 +v 0.472846 0.396281 0.407912 +v 0.467952 0.702604 0.543674 +v 0.289749 0.658789 0.59315 +v 0.520301 0.756451 0.544941 +v 0.518651 0.606262 0.561207 +v 0.583152 0.6141 0.440025 +v 0.424014 0.549447 0.546643 +v 0.632981 0.606168 0.507496 +v 0.526102 0.350905 0.509029 +v 0.378569 0.22486 0.488924 +v 0.66819 0.615653 0.57378 +v 0.533814 0.780099 0.411278 +v 0.423714 0.798464 0.442014 +v 0.484562 0.197243 0.448816 +v 0.706821 0.633449 0.606329 +v 0.511214 0.481666 0.590975 +v 0.451445 0.836217 0.537398 +v 0.510535 0.170513 0.506549 +v 0.388878 0.219475 0.434716 +v 0.416734 0.498284 0.554749 +v 0.438632 0.754743 0.543762 +v 0.589366 0.633568 0.428822 +v 0.594115 0.603056 0.457184 +v 0.30948 0.633409 0.607244 +v 0.668137 0.617656 0.591609 +v 0.380651 0.164818 0.533459 +v 0.393571 0.195923 0.432986 +v 0.430431 0.716095 0.497272 +v 0.318744 0.642401 0.621534 +v 0.539854 0.163952 0.480847 +v 0.658149 0.667046 0.466232 +v 0.656232 0.639354 0.434327 +v 0.517123 0.189239 0.548672 +v 0.451164 0.755181 0.548728 +v 0.572384 0.824839 0.478358 +v 0.541891 0.547324 0.572677 +v 0.443195 0.939289 0.493441 +v 0.561963 0.594831 0.542339 +v 0.306164 0.639633 0.622091 +v 0.688907 0.652236 0.608168 +v 0.695444 0.643864 0.605765 +v 0.576513 0.545427 0.548108 +v 0.306544 0.633932 0.602151 +v 0.647027 0.590093 0.456253 +v 0.519781 0.845328 0.547597 +v 0.471535 0.443341 0.360032 +v 0.555167 0.969067 0.465693 +v 0.431129 0.175061 0.581739 +v 0.589279 0.328043 0.517334 +v 0.714504 0.596482 0.504442 +v 0.495548 0.369416 0.500359 +v 0.555898 0.943239 0.412725 +v 0.406784 0.601164 0.471005 +v 0.570346 0.181008 0.411645 +v 0.602374 0.17569 0.43106 +v 0.295943 0.635106 0.618912 +v 0.724532 0.633403 0.612057 +v 0.436677 0.682594 0.4276 +v 0.577707 0.828248 0.431122 +v 0.602377 0.197584 0.428702 +v 0.585733 0.201 0.41803 +v 0.372106 0.612427 0.504696 +v 0.28554 0.592588 0.504376 +v 0.55234 0.164942 0.569738 +v 0.611458 0.618481 0.497443 +v 0.534695 0.161418 0.54621 +v 0.485355 0.167022 0.500149 +v 0.599797 0.424059 0.42386 +v 0.398902 0.394011 0.511486 +v 0.563781 0.159129 0.458328 +v 0.447421 0.647687 0.550252 +v 0.668256 0.634632 0.588783 +v 0.38228 0.448528 0.493414 +v 0.529403 0.986712 0.430518 +v 0.302317 0.641926 0.606087 +v 0.675627 0.620879 0.586148 +v 0.598585 0.499577 0.532317 +v 0.350892 0.580584 0.485066 +v 0.572179 0.847774 0.451255 +v 0.304136 0.610497 0.585848 +v 0.550917 0.69066 0.424236 +v 0.300124 0.642301 0.510814 +v 0.448681 0.494526 0.364479 +v 0.552759 0.494269 0.579062 +v 0.560775 0.717063 0.436788 +v 0.610444 0.634858 0.501747 +v 0.581923 0.162153 0.549398 +v 0.306107 0.641265 0.486015 +v 0.524782 0.960818 0.396175 +v 0.546675 0.773498 0.578652 +v 0.473867 0.959706 0.396442 +v 0.479965 0.359236 0.50821 +v 0.348632 0.631529 0.517127 +v 0.445581 0.956015 0.418667 +v 0.612686 0.675969 0.43223 +v 0.541798 0.408066 0.545931 +v 0.706957 0.659073 0.559839 +v 0.537529 0.160544 0.572596 +v 0.448466 0.22638 0.527645 +v 0.349789 0.67315 0.467409 +v 0.67687 0.633209 0.589783 +v 0.623731 0.652559 0.503199 +v 0.444359 0.188296 0.570894 +v 0.721968 0.630151 0.599356 +v 0.438257 0.774868 0.514861 +v 0.399716 0.42086 0.42505 +v 0.69694 0.660576 0.579741 +v 0.317935 0.648567 0.539564 +v 0.480355 0.513339 0.369446 +v 0.552019 0.160135 0.527791 +v 0.62095 0.195331 0.486952 +v 0.332861 0.616533 0.576717 +v 0.413768 0.179611 0.41676 +v 0.280391 0.643382 0.60021 +v 0.604308 0.455464 0.42397 +v 0.476787 0.162519 0.570054 +v 0.502514 0.35985 0.478617 +v 0.480542 0.330478 0.49682 +v 0.580697 0.837388 0.442206 +v 0.44329 0.729864 0.543612 +v 0.434486 0.176971 0.41218 +v 0.388069 0.17607 0.545051 +v 0.425871 0.159727 0.424259 +v 0.488929 0.823385 0.552951 +v 0.719281 0.651537 0.590052 +v 0.400305 0.499488 0.529353 +v 0.548828 0.593578 0.553337 +v 0.53778 0.200959 0.557576 +v 0.56817 0.172014 0.581127 +v 0.438914 0.959185 0.438784 +v 0.427394 0.215814 0.532189 +v 0.59858 0.378845 0.428783 +v 0.339299 0.623267 0.538679 +v 0.637101 0.616971 0.51323 +v 0.440902 0.963071 0.466065 +v 0.53306 0.645816 0.557476 +v 0.522148 0.749684 0.547019 +v 0.581759 0.607002 0.500624 +v 0.446952 0.165448 0.57061 +v 0.568613 0.846031 0.440177 +v 0.544606 0.266463 0.519331 +v 0.342328 0.61932 0.610668 +v 0.416654 0.162528 0.549968 +v 0.446859 0.271504 0.413778 +v 0.409841 0.478312 0.388617 +v 0.654758 0.626513 0.604972 +v 0.429225 0.200294 0.414656 +v 0.568442 0.334665 0.522572 +v 0.518919 0.882188 0.543174 +v 0.448284 0.402326 0.398765 +v 0.577684 0.643483 0.515233 +v 0.412937 0.187468 0.554026 +v 0.329208 0.574653 0.485215 +v 0.406936 0.546758 0.436727 +v 0.417659 0.822657 0.434503 +v 0.426347 0.489558 0.564399 +v 0.510903 0.360851 0.49875 +v 0.41605 0.835047 0.457759 +v 0.580207 0.809953 0.438775 +v 0.726506 0.63024 0.584284 +v 0.535526 0.771158 0.585466 +v 0.518135 0.6994 0.548185 +v 0.428357 0.831241 0.47899 +v 0.541995 0.465411 0.579238 +v 0.515837 0.852125 0.546133 +v 0.341283 0.583596 0.516697 +v 0.431348 0.783237 0.450392 +v 0.616173 0.3917 0.462141 +v 0.595221 0.378474 0.513866 +v 0.262519 0.637382 0.600919 +v 0.334104 0.659771 0.455795 +v 0.489847 0.338889 0.461933 +v 0.472436 0.924805 0.388701 +v 0.333999 0.617014 0.439146 +v 0.550866 0.96729 0.425688 +v 0.390988 0.507693 0.50062 +v 0.298007 0.585856 0.48641 +v 0.700503 0.584575 0.489074 +v 0.529374 0.561114 0.385399 +v 0.718786 0.641017 0.599628 +v 0.297413 0.580828 0.527257 +v 0.560378 0.522779 0.387105 +v 0.429833 0.847455 0.445813 +v 0.42493 0.645416 0.514395 +v 0.294841 0.633221 0.605532 +v 0.447941 0.660734 0.422051 +v 0.561275 0.74875 0.544303 +v 0.612761 0.20317 0.506947 +v 0.498285 0.85756 0.563981 +v 0.526195 0.866076 0.540866 +v 0.394973 0.262536 0.509759 +v 0.480945 0.83757 0.548367 +v 0.573572 0.704396 0.444403 +v 0.3438 0.629593 0.599046 +v 0.475187 0.892479 0.538472 +v 0.683555 0.637737 0.627256 +v 0.547307 0.867181 0.533585 +v 0.60317 0.67245 0.497474 +v 0.603261 0.180209 0.557898 +v 0.310104 0.630713 0.627752 +v 0.313196 0.630617 0.628358 +v 0.311446 0.633656 0.628629 +v 0.684556 0.63114 0.62838 +v 0.685684 0.634362 0.628723 +v 0.682075 0.632954 0.627807 +v 0.689168 0.634759 0.627275 +v 0.687546 0.638991 0.625413 +v 0.310187 0.626893 0.623864 +v 0.308701 0.628582 0.625576 +v 0.308063 0.628251 0.621123 +v 0.314748 0.628184 0.626476 +v 0.316197 0.630833 0.627619 +v 0.679535 0.630846 0.625175 +v 0.679057 0.630074 0.620179 +v 0.681316 0.628131 0.624873 +v 0.684433 0.628587 0.626826 +v 0.684498 0.626709 0.624418 +v 0.687673 0.629662 0.627383 +v 0.307599 0.631713 0.626169 +v 0.307372 0.635897 0.62592 +v 0.305807 0.635133 0.6221 +v 0.318918 0.631894 0.625561 +v 0.31786 0.6343 0.626858 +v 0.319548 0.630799 0.623221 +v 0.320704 0.634541 0.623263 +v 0.689783 0.628547 0.624885 +v 0.69021 0.631378 0.626256 +v 0.692062 0.6352 0.622555 +v 0.286514 0.632505 0.62188 +v 0.289164 0.634966 0.623485 +v 0.285748 0.635693 0.622304 +v 0.291717 0.633215 0.622071 +v 0.29244 0.636983 0.622752 +v 0.309487 0.636773 0.627257 +v 0.3085 0.640399 0.624 +v 0.312806 0.637161 0.627535 +v 0.319556 0.637239 0.624426 +v 0.316634 0.637765 0.626336 +v 0.678009 0.638615 0.620555 +v 0.679892 0.634679 0.625569 +v 0.680474 0.640149 0.623201 +v 0.704332 0.638058 0.621397 +v 0.705854 0.634164 0.622578 +v 0.707924 0.636261 0.623695 +v 0.710442 0.63766 0.623456 +v 0.710993 0.633902 0.623141 +v 0.713545 0.638413 0.621975 +v 0.71079 0.641146 0.622083 +v 0.31432 0.641544 0.623918 +v 0.311648 0.626972 0.619941 +v 0.313435 0.626602 0.6241 +v 0.31671 0.627715 0.623673 +v 0.318955 0.630648 0.618386 +v 0.687371 0.62655 0.623335 +v 0.684168 0.626765 0.620015 +v 0.689434 0.628235 0.620261 +v 0.288977 0.630929 0.62093 +v 0.286281 0.631052 0.617798 +v 0.292436 0.631572 0.618185 +v 0.708522 0.630351 0.617971 +v 0.71055 0.631019 0.621261 +v 0.707264 0.631463 0.621541 +v 0.703815 0.633203 0.619296 +v 0.713088 0.63253 0.620906 +v 0.715041 0.634777 0.616839 +v 0.714994 0.635939 0.620706 +v 0.282632 0.637315 0.617658 +v 0.285281 0.639848 0.620945 +v 0.291478 0.641825 0.621781 +v 0.29514 0.640416 0.619084 +v 0.71551 0.640748 0.618563 +v 0.311352 0.644539 0.620682 +v 0.31501 0.647255 0.616882 +v 0.680064 0.646774 0.615685 +v 0.682907 0.645812 0.618304 +v 0.711757 0.645014 0.618544 +v 0.708657 0.645458 0.618741 +v 0.291784 0.631718 0.611873 +v 0.295546 0.634246 0.612402 +v 0.684155 0.629951 0.612953 +v 0.681586 0.630708 0.612777 +v 0.729484 0.627084 0.613497 +v 0.726978 0.628556 0.613714 +v 0.727223 0.626006 0.612306 +v 0.730926 0.625653 0.611984 +v 0.732241 0.62825 0.612835 +v 0.727384 0.631701 0.613557 +v 0.724046 0.631436 0.611408 +v 0.304101 0.640845 0.613881 +v 0.304991 0.636304 0.614363 +v 0.693879 0.637459 0.614377 +v 0.692836 0.641619 0.615259 +v 0.321097 0.63927 0.619468 +v 0.701359 0.639493 0.615878 +v 0.701931 0.643066 0.615632 +v 0.285363 0.650369 0.610427 +v 0.282585 0.645679 0.612201 +v 0.284871 0.644966 0.616807 +v 0.288166 0.64405 0.619864 +v 0.308284 0.645159 0.6175 +v 0.68974 0.644712 0.617038 +v 0.686092 0.645424 0.618544 +v 0.714188 0.64629 0.614768 +v 0.711556 0.650231 0.61201 +v 0.716007 0.646068 0.610533 +v 0.290569 0.647106 0.6175 +v 0.686515 0.65241 0.607512 +v 0.339058 0.614555 0.60757 +v 0.342086 0.615896 0.6091 +v 0.338841 0.618061 0.609262 +v 0.343868 0.613703 0.607294 +v 0.344892 0.617042 0.608754 +v 0.654572 0.617116 0.609049 +v 0.657731 0.615488 0.608903 +v 0.658349 0.618589 0.609926 +v 0.267614 0.625784 0.611011 +v 0.269249 0.625154 0.607136 +v 0.270385 0.625561 0.611656 +v 0.265341 0.627269 0.606861 +v 0.265911 0.627716 0.611715 +v 0.271977 0.62772 0.613059 +v 0.273077 0.626187 0.609352 +v 0.658516 0.621874 0.609476 +v 0.661512 0.620185 0.608857 +v 0.726034 0.625577 0.609312 +v 0.72882 0.624429 0.610853 +v 0.731443 0.624964 0.609868 +v 0.264024 0.630551 0.610601 +v 0.263397 0.635461 0.606772 +v 0.262849 0.632579 0.605186 +v 0.266992 0.630368 0.613436 +v 0.309464 0.629233 0.615683 +v 0.31239 0.629792 0.612836 +v 0.68476 0.633436 0.60615 +v 0.687358 0.630289 0.613069 +v 0.27059 0.630627 0.614006 +v 0.268649 0.633841 0.612516 +v 0.274098 0.631063 0.611287 +v 0.288146 0.63186 0.611417 +v 0.28473 0.634157 0.610951 +v 0.307189 0.632192 0.614369 +v 0.315119 0.631573 0.60874 +v 0.312029 0.633141 0.605601 +v 0.32071 0.636024 0.607459 +v 0.317868 0.632556 0.609395 +v 0.316756 0.634359 0.601265 +v 0.690436 0.631837 0.613971 +v 0.702766 0.634031 0.613112 +v 0.703654 0.634428 0.60695 +v 0.705856 0.63226 0.612542 +v 0.701203 0.636496 0.614104 +v 0.709332 0.631639 0.61152 +v 0.733299 0.631724 0.611782 +v 0.734563 0.629434 0.610338 +v 0.733992 0.635944 0.608364 +v 0.730994 0.634094 0.612142 +v 0.270926 0.639304 0.607018 +v 0.267598 0.63853 0.607692 +v 0.299119 0.639483 0.610183 +v 0.299172 0.637383 0.606389 +v 0.305985 0.636933 0.60705 +v 0.679549 0.632534 0.611664 +v 0.680323 0.635272 0.604314 +v 0.677591 0.635136 0.611982 +v 0.691049 0.634921 0.60761 +v 0.692771 0.635154 0.612394 +v 0.693909 0.638847 0.607336 +v 0.728205 0.636036 0.611048 +v 0.729029 0.640923 0.606041 +v 0.725389 0.638512 0.607839 +v 0.322438 0.642595 0.608981 +v 0.32071 0.646117 0.611219 +v 0.676222 0.639601 0.611509 +v 0.676295 0.640642 0.603509 +v 0.675613 0.645476 0.604513 +v 0.676509 0.641975 0.612924 +v 0.677762 0.645695 0.613027 +v 0.699366 0.640625 0.609603 +v 0.297148 0.646089 0.612542 +v 0.299103 0.642265 0.61178 +v 0.692466 0.648364 0.607821 +v 0.290553 0.652149 0.610448 +v 0.293591 0.649271 0.6132 +v 0.296251 0.651774 0.606116 +v 0.340911 0.612413 0.605755 +v 0.33685 0.613447 0.603163 +v 0.343387 0.61225 0.604096 +v 0.653752 0.61321 0.605324 +v 0.651715 0.615835 0.60632 +v 0.651594 0.614685 0.601958 +v 0.657478 0.613198 0.606774 +v 0.6611 0.614971 0.607413 +v 0.657228 0.611968 0.603611 +v 0.347259 0.618789 0.606491 +v 0.34466 0.620923 0.608858 +v 0.65234 0.619297 0.607579 +v 0.336021 0.621459 0.606484 +v 0.340576 0.621543 0.609416 +v 0.343411 0.624045 0.607482 +v 0.649869 0.622756 0.599882 +v 0.65132 0.62199 0.605635 +v 0.651543 0.625274 0.601295 +v 0.654805 0.62261 0.608498 +v 0.664467 0.622106 0.605254 +v 0.663236 0.618161 0.607385 +v 0.734075 0.627288 0.608811 +v 0.73163 0.626131 0.605966 +v 0.345505 0.626294 0.601946 +v 0.341816 0.627356 0.603516 +v 0.658949 0.625642 0.60576 +v 0.722989 0.629579 0.605255 +v 0.725278 0.627029 0.603439 +v 0.277562 0.632976 0.605488 +v 0.277136 0.635767 0.605909 +v 0.277658 0.632008 0.603582 +v 0.279819 0.634788 0.600092 +v 0.290244 0.633158 0.605653 +v 0.735488 0.630775 0.60604 +v 0.2806 0.63904 0.600775 +v 0.277115 0.640502 0.602875 +v 0.712236 0.634006 0.608364 +v 0.709364 0.633637 0.605286 +v 0.282012 0.637901 0.609861 +v 0.283951 0.637712 0.603446 +v 0.281191 0.641758 0.610392 +v 0.697692 0.644772 0.606362 +v 0.697162 0.640636 0.60552 +v 0.714833 0.636615 0.609745 +v 0.716944 0.640966 0.608279 +v 0.714894 0.639031 0.603336 +v 0.735414 0.637389 0.602257 +v 0.733909 0.64027 0.602437 +v 0.281561 0.647313 0.604064 +v 0.302095 0.644052 0.608089 +v 0.305 0.645081 0.612093 +v 0.718062 0.64637 0.598371 +v 0.717568 0.646147 0.60372 +v 0.715648 0.65217 0.598547 +v 0.30681 0.649613 0.608345 +v 0.319773 0.6525 0.600626 +v 0.3178 0.649917 0.610251 +v 0.679488 0.652001 0.605612 +v 0.313675 0.652856 0.607201 +v 0.709899 0.65538 0.603213 +v 0.708542 0.651253 0.6112 +v 0.705409 0.64977 0.611602 +v 0.348102 0.616992 0.602707 +v 0.348434 0.621467 0.600831 +v 0.664032 0.616221 0.60425 +v 0.268799 0.628151 0.599288 +v 0.271548 0.627197 0.600536 +v 0.274293 0.62957 0.595249 +v 0.273946 0.627453 0.60256 +v 0.275736 0.628964 0.604309 +v 0.278148 0.632103 0.599491 +v 0.287434 0.635025 0.601953 +v 0.291687 0.632144 0.602088 +v 0.291925 0.629461 0.598972 +v 0.296878 0.629886 0.601092 +v 0.701687 0.634322 0.603736 +v 0.696888 0.636358 0.603718 +v 0.697746 0.630459 0.600344 +v 0.70607 0.633593 0.603619 +v 0.284009 0.637928 0.599936 +v 0.308277 0.635285 0.60374 +v 0.303842 0.637578 0.60386 +v 0.311225 0.633793 0.60147 +v 0.682354 0.635363 0.601879 +v 0.685788 0.634569 0.602221 +v 0.680213 0.636221 0.598595 +v 0.686823 0.633364 0.599716 +v 0.689471 0.63466 0.603325 +v 0.694414 0.638914 0.603987 +v 0.692274 0.636725 0.604485 +v 0.709629 0.633573 0.601623 +v 0.722219 0.636793 0.606684 +v 0.721558 0.633859 0.605744 +v 0.720165 0.634521 0.60031 +v 0.26582 0.640234 0.603694 +v 0.265017 0.642025 0.598423 +v 0.269092 0.644587 0.599592 +v 0.300639 0.633749 0.602992 +v 0.320938 0.639222 0.595898 +v 0.322697 0.640724 0.602502 +v 0.72233 0.642582 0.60166 +v 0.323697 0.645821 0.594848 +v 0.728146 0.645566 0.598687 +v 0.731556 0.643206 0.600801 +v 0.283102 0.652428 0.598742 +v 0.280765 0.649776 0.595224 +v 0.285994 0.654657 0.601928 +v 0.284418 0.655775 0.593724 +v 0.30296 0.653261 0.600288 +v 0.308613 0.653378 0.603555 +v 0.693336 0.653524 0.600286 +v 0.695463 0.649168 0.603486 +v 0.698602 0.647492 0.607117 +v 0.701596 0.64837 0.609954 +v 0.288482 0.654515 0.605549 +v 0.292295 0.655236 0.603294 +v 0.296871 0.654737 0.599532 +v 0.309897 0.656117 0.597615 +v 0.683491 0.656188 0.596566 +v 0.67919 0.654623 0.594718 +v 0.701359 0.65478 0.600064 +v 0.334912 0.613856 0.593763 +v 0.332912 0.616139 0.596973 +v 0.341696 0.612533 0.597295 +v 0.345881 0.613699 0.601437 +v 0.653905 0.613872 0.596494 +v 0.651622 0.616674 0.595414 +v 0.656806 0.612084 0.598748 +v 0.657964 0.613722 0.591026 +v 0.660582 0.612453 0.59993 +v 0.664129 0.614521 0.592806 +v 0.664335 0.61504 0.599184 +v 0.328894 0.619456 0.590556 +v 0.330145 0.620683 0.596511 +v 0.347596 0.616385 0.597503 +v 0.667057 0.618658 0.598367 +v 0.327515 0.625647 0.592748 +v 0.331499 0.623342 0.599532 +v 0.333778 0.626922 0.59978 +v 0.347777 0.623815 0.59188 +v 0.347114 0.625824 0.595686 +v 0.669327 0.622643 0.596044 +v 0.670455 0.621006 0.591984 +v 0.28574 0.631871 0.597796 +v 0.289041 0.626335 0.595109 +v 0.303283 0.62974 0.599681 +v 0.306424 0.625769 0.595487 +v 0.309859 0.631369 0.598636 +v 0.337059 0.629816 0.598714 +v 0.332006 0.632112 0.592616 +v 0.345394 0.628989 0.591915 +v 0.652888 0.629094 0.592247 +v 0.655627 0.630666 0.594513 +v 0.666553 0.626879 0.598841 +v 0.669669 0.631457 0.591595 +v 0.664551 0.629099 0.598181 +v 0.66191 0.630879 0.596983 +v 0.671679 0.627036 0.592172 +v 0.668031 0.624587 0.5984 +v 0.728101 0.627348 0.60081 +v 0.724562 0.629373 0.596682 +v 0.266255 0.629997 0.598862 +v 0.26419 0.631444 0.600782 +v 0.268697 0.632124 0.591265 +v 0.278743 0.63131 0.595782 +v 0.279934 0.633679 0.597465 +v 0.314505 0.633313 0.598385 +v 0.31777 0.635569 0.595324 +v 0.338554 0.632959 0.595028 +v 0.713989 0.634948 0.599449 +v 0.710795 0.629742 0.597724 +v 0.720308 0.63099 0.593583 +v 0.721496 0.630291 0.595212 +v 0.719476 0.632432 0.597105 +v 0.731402 0.62959 0.59929 +v 0.730984 0.633087 0.592734 +v 0.734193 0.632533 0.599349 +v 0.264065 0.635548 0.594954 +v 0.281727 0.634511 0.597691 +v 0.283563 0.635916 0.59883 +v 0.715756 0.638961 0.600058 +v 0.717246 0.643553 0.598828 +v 0.717554 0.636289 0.598289 +v 0.735515 0.635072 0.600632 +v 0.734818 0.639504 0.594048 +v 0.732785 0.644561 0.594561 +v 0.272513 0.645736 0.59794 +v 0.27165 0.649029 0.590902 +v 0.27491 0.643095 0.600686 +v 0.278303 0.647118 0.595074 +v 0.719508 0.646459 0.596082 +v 0.298677 0.657043 0.594451 +v 0.691995 0.65653 0.595698 +v 0.688753 0.657118 0.59467 +v 0.711712 0.656702 0.595451 +v 0.707099 0.658884 0.592846 +v 0.4981 0.504696 0.590607 +v 0.497425 0.487755 0.591552 +v 0.509673 0.492513 0.591762 +v 0.332172 0.615517 0.583178 +v 0.336377 0.613769 0.589309 +v 0.33985 0.614952 0.587658 +v 0.347745 0.620199 0.591788 +v 0.34493 0.616942 0.590175 +v 0.653981 0.61856 0.58627 +v 0.650916 0.620513 0.591843 +v 0.698343 0.620975 0.593953 +v 0.698293 0.609568 0.583682 +v 0.705384 0.620784 0.593282 +v 0.284201 0.621228 0.588993 +v 0.292307 0.618307 0.590595 +v 0.30095 0.617882 0.591379 +v 0.30961 0.620594 0.591035 +v 0.31744 0.623734 0.589586 +v 0.313658 0.614807 0.584652 +v 0.34532 0.62479 0.583105 +v 0.691954 0.623619 0.594662 +v 0.711887 0.621283 0.590806 +v 0.322135 0.624799 0.588511 +v 0.319928 0.628563 0.590339 +v 0.683179 0.63118 0.595124 +v 0.680184 0.633654 0.594431 +v 0.679737 0.62908 0.590884 +v 0.687078 0.628027 0.595553 +v 0.685864 0.620227 0.589987 +v 0.276896 0.630037 0.593292 +v 0.278241 0.62873 0.591236 +v 0.274459 0.630025 0.590104 +v 0.320051 0.637341 0.591219 +v 0.666143 0.636493 0.587722 +v 0.66051 0.633189 0.592849 +v 0.661144 0.636554 0.585075 +v 0.724112 0.630357 0.591934 +v 0.727268 0.631684 0.589193 +v 0.730191 0.634166 0.586363 +v 0.67791 0.637128 0.593764 +v 0.675161 0.644858 0.597058 +v 0.676038 0.64134 0.593442 +v 0.675016 0.64856 0.592858 +v 0.723381 0.647106 0.596504 +v 0.280908 0.65294 0.590453 +v 0.725835 0.649305 0.590974 +v 0.303884 0.657982 0.590864 +v 0.309749 0.658295 0.588595 +v 0.321677 0.652778 0.590347 +v 0.318332 0.656021 0.589279 +v 0.696986 0.657197 0.592188 +v 0.29814 0.659694 0.585962 +v 0.688369 0.659089 0.584469 +v 0.702073 0.659129 0.589995 +v 0.465413 0.176965 0.585982 +v 0.465657 0.172325 0.584978 +v 0.470257 0.173277 0.585029 +v 0.460052 0.171877 0.583565 +v 0.464911 0.168159 0.583085 +v 0.473863 0.175627 0.584482 +v 0.474749 0.170123 0.582069 +v 0.531622 0.174805 0.585471 +v 0.53122 0.180157 0.585859 +v 0.526362 0.176169 0.584207 +v 0.532277 0.169673 0.583584 +v 0.538375 0.17391 0.584432 +v 0.466356 0.18102 0.585895 +v 0.460515 0.180123 0.584808 +v 0.53694 0.183205 0.584518 +v 0.530715 0.185108 0.584203 +v 0.502606 0.46071 0.585562 +v 0.513733 0.468894 0.587331 +v 0.499557 0.473912 0.589293 +v 0.526966 0.462572 0.582981 +v 0.526143 0.474585 0.58629 +v 0.486652 0.481213 0.589741 +v 0.474151 0.489335 0.588814 +v 0.476637 0.475141 0.586962 +v 0.52353 0.487285 0.589015 +v 0.536723 0.482014 0.584647 +v 0.520897 0.500937 0.589329 +v 0.528975 0.51841 0.58425 +v 0.516811 0.521694 0.586099 +v 0.490324 0.529697 0.584803 +v 0.484984 0.558747 0.57635 +v 0.476375 0.528601 0.582711 +v 0.503547 0.527909 0.585774 +v 0.512022 0.551401 0.578953 +v 0.663381 0.614727 0.585868 +v 0.667889 0.616485 0.583836 +v 0.661892 0.616042 0.58064 +v 0.295988 0.609786 0.583848 +v 0.339471 0.618104 0.580715 +v 0.670905 0.617819 0.584431 +v 0.675385 0.617731 0.584518 +v 0.671927 0.619672 0.587803 +v 0.680146 0.62282 0.588292 +v 0.681637 0.61688 0.58586 +v 0.325211 0.62221 0.587951 +v 0.327185 0.618781 0.585842 +v 0.653825 0.626345 0.582111 +v 0.650856 0.623997 0.591932 +v 0.651609 0.627167 0.590821 +v 0.673626 0.623437 0.588443 +v 0.71788 0.621644 0.586419 +v 0.712459 0.611941 0.582188 +v 0.722767 0.621687 0.580333 +v 0.72158 0.629041 0.589012 +v 0.324617 0.625553 0.589318 +v 0.325361 0.628994 0.589792 +v 0.342526 0.632229 0.580305 +v 0.341952 0.633069 0.587589 +v 0.676596 0.626545 0.588355 +v 0.674521 0.628056 0.589385 +v 0.72346 0.63074 0.589816 +v 0.269137 0.633758 0.584434 +v 0.271688 0.631229 0.587271 +v 0.274296 0.628429 0.585529 +v 0.323528 0.639423 0.587552 +v 0.320605 0.633821 0.590204 +v 0.32302 0.631303 0.589264 +v 0.327159 0.632697 0.589409 +v 0.656039 0.633305 0.582791 +v 0.673196 0.631074 0.589888 +v 0.67256 0.634745 0.588093 +v 0.329776 0.635877 0.588214 +v 0.269241 0.647417 0.577681 +v 0.265773 0.642219 0.585425 +v 0.265714 0.6441 0.590033 +v 0.268487 0.647603 0.589092 +v 0.675399 0.639807 0.587871 +v 0.673512 0.643871 0.583329 +v 0.673677 0.638624 0.586091 +v 0.732274 0.646063 0.58755 +v 0.733133 0.64393 0.58685 +v 0.72967 0.64816 0.578978 +v 0.729581 0.648463 0.587802 +v 0.324184 0.649058 0.587236 +v 0.323383 0.651295 0.580397 +v 0.325355 0.64597 0.584002 +v 0.674153 0.648576 0.583442 +v 0.676178 0.652076 0.588725 +v 0.317295 0.656888 0.577388 +v 0.313994 0.658221 0.583471 +v 0.684053 0.658295 0.578287 +v 0.678659 0.65413 0.570909 +v 0.679033 0.655434 0.583377 +v 0.704232 0.660586 0.581304 +v 0.503489 0.760146 0.585391 +v 0.498868 0.763357 0.587444 +v 0.481195 0.76131 0.585557 +v 0.496396 0.774668 0.587937 +v 0.47779 0.769587 0.588278 +v 0.496935 0.767253 0.589 +v 0.517534 0.76563 0.588267 +v 0.531229 0.765347 0.586174 +v 0.527056 0.771885 0.586969 +v 0.46893 0.775558 0.584985 +v 0.464172 0.768433 0.585428 +v 0.510928 0.78666 0.583328 +v 0.494525 0.78844 0.58254 +v 0.461044 0.165293 0.579574 +v 0.466787 0.1642 0.579799 +v 0.526531 0.167256 0.580564 +v 0.53236 0.16517 0.580174 +v 0.532422 0.161523 0.575047 +v 0.538412 0.164047 0.577761 +v 0.425702 0.168814 0.579391 +v 0.430967 0.170641 0.580195 +v 0.426218 0.1731 0.58088 +v 0.421042 0.175323 0.578357 +v 0.425417 0.177915 0.580287 +v 0.522722 0.171876 0.58095 +v 0.521931 0.177946 0.581308 +v 0.546102 0.173709 0.580879 +v 0.54557 0.177857 0.581617 +v 0.5791 0.177528 0.577893 +v 0.573321 0.177327 0.58045 +v 0.574646 0.173082 0.580348 +v 0.578019 0.170181 0.57803 +v 0.572282 0.16866 0.579429 +v 0.424924 0.182911 0.578452 +v 0.430405 0.180325 0.579993 +v 0.437384 0.182538 0.5777 +v 0.438132 0.177892 0.579422 +v 0.455675 0.182639 0.581693 +v 0.453456 0.17839 0.581507 +v 0.47158 0.180563 0.585245 +v 0.476495 0.178827 0.583211 +v 0.479009 0.181976 0.580522 +v 0.480763 0.17758 0.57919 +v 0.51846 0.18043 0.577329 +v 0.522136 0.183979 0.580184 +v 0.571887 0.181471 0.579706 +v 0.567346 0.177151 0.580766 +v 0.45309 0.185772 0.578358 +v 0.451583 0.189431 0.573501 +v 0.445324 0.185071 0.575359 +v 0.460149 0.187587 0.581475 +v 0.468583 0.184714 0.584551 +v 0.471542 0.188277 0.581547 +v 0.465912 0.188658 0.582405 +v 0.543694 0.185288 0.580538 +v 0.545182 0.181651 0.581143 +v 0.553555 0.180439 0.578224 +v 0.540997 0.188882 0.579801 +v 0.548379 0.187209 0.576453 +v 0.462219 0.192114 0.577776 +v 0.529998 0.189771 0.580502 +v 0.525846 0.187303 0.580862 +v 0.534766 0.191357 0.579456 +v 0.53114 0.194058 0.574848 +v 0.494327 0.449891 0.58099 +v 0.50609 0.448999 0.580595 +v 0.4745 0.459672 0.581838 +v 0.465119 0.469888 0.582508 +v 0.525515 0.452095 0.57932 +v 0.536298 0.452886 0.576106 +v 0.45398 0.461644 0.575254 +v 0.456513 0.478227 0.581344 +v 0.543348 0.496564 0.582398 +v 0.548412 0.480319 0.579846 +v 0.447872 0.485913 0.578217 +v 0.460878 0.490797 0.584839 +v 0.467873 0.504497 0.585762 +v 0.53893 0.519151 0.580741 +v 0.532246 0.544559 0.576639 +v 0.455003 0.529039 0.575845 +v 0.463549 0.527175 0.579577 +v 0.461305 0.550698 0.572528 +v 0.328877 0.616744 0.582273 +v 0.329433 0.615995 0.577259 +v 0.670908 0.614198 0.575498 +v 0.680027 0.612057 0.579723 +v 0.276144 0.625482 0.584874 +v 0.273463 0.624649 0.57889 +v 0.278724 0.623719 0.586491 +v 0.280343 0.615219 0.579806 +v 0.326079 0.617566 0.581459 +v 0.267082 0.636322 0.58312 +v 0.269779 0.632921 0.576165 +v 0.332697 0.639703 0.585243 +v 0.328028 0.64345 0.581367 +v 0.330421 0.639468 0.584901 +v 0.336798 0.637048 0.587831 +v 0.670516 0.638313 0.585401 +v 0.731361 0.637391 0.580665 +v 0.728777 0.631576 0.576757 +v 0.265543 0.638401 0.585793 +v 0.327197 0.639464 0.585614 +v 0.668735 0.64072 0.582334 +v 0.32585 0.643036 0.583858 +v 0.274388 0.651556 0.586158 +v 0.724484 0.651193 0.582628 +v 0.281433 0.655043 0.589371 +v 0.279273 0.65434 0.583563 +v 0.714597 0.655838 0.58625 +v 0.503939 0.75829 0.582811 +v 0.525113 0.759603 0.583233 +v 0.45974 0.76166 0.581635 +v 0.466907 0.761468 0.583614 +v 0.462887 0.763518 0.584053 +v 0.479059 0.758988 0.582453 +v 0.535617 0.762419 0.582957 +v 0.540542 0.76613 0.583072 +v 0.540035 0.760244 0.578842 +v 0.455096 0.768008 0.581205 +v 0.460333 0.765388 0.583512 +v 0.457587 0.763205 0.581673 +v 0.547001 0.767868 0.579817 +v 0.541218 0.773411 0.581666 +v 0.540245 0.78677 0.575122 +v 0.534324 0.786181 0.578935 +v 0.526237 0.797924 0.575872 +v 0.528764 0.784797 0.581638 +v 0.478832 0.788896 0.580991 +v 0.468106 0.788106 0.578663 +v 0.49179 0.802219 0.574951 +v 0.521807 0.784865 0.583219 +v 0.518547 0.79803 0.577666 +v 0.466683 0.160805 0.57483 +v 0.470612 0.16265 0.576835 +v 0.472907 0.161231 0.569597 +v 0.474373 0.164764 0.577384 +v 0.545491 0.166586 0.576211 +v 0.544801 0.163342 0.571399 +v 0.420958 0.168273 0.576457 +v 0.425228 0.165286 0.576336 +v 0.431088 0.163354 0.574123 +v 0.438486 0.163198 0.569557 +v 0.437878 0.16589 0.574473 +v 0.477801 0.167157 0.576716 +v 0.55994 0.16694 0.574769 +v 0.566751 0.167213 0.577587 +v 0.560539 0.170944 0.578013 +v 0.571109 0.164448 0.575814 +v 0.415319 0.168394 0.571478 +v 0.417069 0.171868 0.574678 +v 0.437832 0.169503 0.577436 +v 0.43837 0.17358 0.579258 +v 0.445955 0.168814 0.575546 +v 0.453395 0.174618 0.581084 +v 0.453491 0.170777 0.579569 +v 0.521404 0.168112 0.577114 +v 0.547808 0.170301 0.578199 +v 0.552604 0.16744 0.573945 +v 0.414838 0.17576 0.573091 +v 0.446081 0.17628 0.578805 +v 0.55349 0.173363 0.578146 +v 0.560745 0.178731 0.579098 +v 0.560828 0.174953 0.579402 +v 0.48162 0.184291 0.575839 +v 0.477347 0.18652 0.579255 +v 0.516919 0.183696 0.573025 +v 0.51592 0.177492 0.573326 +v 0.5611 0.182313 0.577736 +v 0.568085 0.184316 0.578024 +v 0.561972 0.185904 0.575159 +v 0.57369 0.185775 0.576975 +v 0.474932 0.19058 0.577286 +v 0.477125 0.192299 0.571213 +v 0.4725 0.194404 0.572973 +v 0.52212 0.189011 0.576721 +v 0.540938 0.191573 0.576741 +v 0.51676 0.446513 0.578378 +v 0.508767 0.437968 0.574311 +v 0.482845 0.448875 0.579103 +v 0.486425 0.437414 0.573089 +v 0.4694 0.445867 0.574036 +v 0.527683 0.442281 0.573454 +v 0.439218 0.497158 0.572824 +v 0.436152 0.478828 0.569582 +v 0.547789 0.517794 0.577114 +v 0.521466 0.568778 0.572001 +v 0.508159 0.582943 0.569334 +v 0.294977 0.594726 0.561572 +v 0.294126 0.601833 0.572959 +v 0.288201 0.602223 0.570347 +v 0.301748 0.601413 0.57382 +v 0.710621 0.603198 0.571075 +v 0.705552 0.602989 0.574715 +v 0.324068 0.614094 0.576207 +v 0.318109 0.609035 0.575604 +v 0.324 0.603281 0.562492 +v 0.309929 0.603661 0.57484 +v 0.675019 0.607523 0.569631 +v 0.67129 0.607471 0.564904 +v 0.679992 0.60078 0.565146 +v 0.338588 0.621226 0.574763 +v 0.33389 0.618228 0.572707 +v 0.658839 0.620558 0.57587 +v 0.660216 0.618037 0.57767 +v 0.33448 0.640427 0.57955 +v 0.268218 0.638571 0.57108 +v 0.661858 0.638677 0.579085 +v 0.661324 0.637369 0.575045 +v 0.666462 0.641207 0.579455 +v 0.670179 0.644336 0.578558 +v 0.732847 0.641295 0.584249 +v 0.730385 0.638999 0.571287 +v 0.671504 0.646942 0.571824 +v 0.672659 0.646994 0.579576 +v 0.724579 0.651293 0.574195 +v 0.719142 0.653631 0.57731 +v 0.713929 0.656918 0.574035 +v 0.301817 0.660532 0.574243 +v 0.308251 0.659703 0.576446 +v 0.307624 0.658974 0.563681 +v 0.690287 0.660058 0.573572 +v 0.712093 0.655693 0.559706 +v 0.708453 0.659771 0.572325 +v 0.479503 0.727222 0.573725 +v 0.484038 0.732822 0.578373 +v 0.472179 0.732755 0.576108 +v 0.498246 0.732834 0.579317 +v 0.504718 0.727675 0.575328 +v 0.511171 0.734138 0.579285 +v 0.489172 0.736194 0.578973 +v 0.51021 0.738393 0.578692 +v 0.503581 0.742637 0.576809 +v 0.494202 0.739874 0.578072 +v 0.478584 0.740316 0.576869 +v 0.520883 0.73665 0.578046 +v 0.530189 0.739016 0.575409 +v 0.529186 0.735168 0.575981 +v 0.518065 0.743995 0.57503 +v 0.500859 0.745368 0.574413 +v 0.490751 0.757488 0.579487 +v 0.470431 0.756849 0.575198 +v 0.498825 0.756668 0.576076 +v 0.454576 0.760785 0.577901 +v 0.451615 0.774218 0.576761 +v 0.44846 0.768302 0.575662 +v 0.461141 0.790507 0.573996 +v 0.470438 0.802386 0.569221 +v 0.519572 0.805684 0.571464 +v 0.499038 0.840308 0.576092 +v 0.498263 0.844437 0.576118 +v 0.493996 0.841368 0.574731 +v 0.500692 0.836936 0.575176 +v 0.50351 0.84129 0.576031 +v 0.426681 0.162366 0.57248 +v 0.461653 0.160647 0.572341 +v 0.45636 0.163633 0.574513 +v 0.455873 0.162069 0.567996 +v 0.45372 0.16712 0.577046 +v 0.568379 0.161837 0.571605 +v 0.574967 0.162942 0.572254 +v 0.480989 0.169569 0.574211 +v 0.479819 0.166011 0.568615 +v 0.517383 0.17124 0.573385 +v 0.520561 0.166022 0.572363 +v 0.560292 0.163935 0.571388 +v 0.581428 0.165423 0.570242 +v 0.588956 0.167057 0.566341 +v 0.583129 0.168583 0.57257 +v 0.579442 0.162634 0.565454 +v 0.483193 0.171474 0.567433 +v 0.482604 0.174235 0.574794 +v 0.584588 0.172015 0.573097 +v 0.585096 0.176146 0.572769 +v 0.590917 0.174246 0.567761 +v 0.483932 0.178169 0.573266 +v 0.58314 0.181018 0.573116 +v 0.421084 0.1841 0.575262 +v 0.427834 0.18668 0.575931 +v 0.436506 0.186279 0.575033 +v 0.562186 0.189518 0.570184 +v 0.555387 0.187367 0.572851 +v 0.57841 0.185676 0.574062 +v 0.573384 0.189296 0.571998 +v 0.560181 0.483172 0.573771 +v 0.556971 0.470106 0.572407 +v 0.449642 0.542171 0.569158 +v 0.444581 0.517826 0.572806 +v 0.566851 0.51655 0.56562 +v 0.557137 0.515313 0.57253 +v 0.563685 0.497189 0.571584 +v 0.551445 0.541248 0.5691 +v 0.529528 0.575848 0.567624 +v 0.309 0.593676 0.56103 +v 0.690135 0.596829 0.565116 +v 0.698064 0.59949 0.570769 +v 0.327149 0.615606 0.576002 +v 0.329755 0.615684 0.572491 +v 0.666039 0.616984 0.571171 +v 0.722386 0.612301 0.566722 +v 0.725884 0.622576 0.57275 +v 0.271223 0.626463 0.57274 +v 0.272578 0.619733 0.56931 +v 0.659798 0.624561 0.571571 +v 0.663242 0.622775 0.566726 +v 0.660124 0.633358 0.571622 +v 0.658885 0.628473 0.571891 +v 0.270216 0.628181 0.56424 +v 0.331509 0.642941 0.57225 +v 0.326337 0.648298 0.57436 +v 0.320994 0.653705 0.574499 +v 0.725221 0.648384 0.566802 +v 0.276218 0.652195 0.572397 +v 0.284572 0.656696 0.57479 +v 0.289554 0.656938 0.560483 +v 0.291266 0.659968 0.573952 +v 0.296461 0.659646 0.562264 +v 0.295861 0.660745 0.576814 +v 0.532041 0.722607 0.565562 +v 0.52963 0.730123 0.573155 +v 0.521742 0.720577 0.566707 +v 0.463748 0.730737 0.571404 +v 0.464934 0.735584 0.574061 +v 0.537306 0.734564 0.572871 +v 0.458418 0.738464 0.570423 +v 0.467222 0.73952 0.574627 +v 0.468489 0.743501 0.573011 +v 0.539149 0.740382 0.571692 +v 0.531148 0.742533 0.573716 +v 0.530255 0.745134 0.571677 +v 0.449524 0.760737 0.572558 +v 0.455298 0.75798 0.573763 +v 0.456945 0.756361 0.568743 +v 0.499332 0.756654 0.571396 +v 0.525025 0.756675 0.573969 +v 0.549265 0.757446 0.565806 +v 0.544767 0.758592 0.57286 +v 0.540165 0.757018 0.572116 +v 0.550382 0.761468 0.572116 +v 0.552025 0.76772 0.574876 +v 0.551237 0.771646 0.574773 +v 0.556173 0.770276 0.568661 +v 0.554331 0.765251 0.570961 +v 0.502427 0.833784 0.572994 +v 0.504802 0.830905 0.569774 +v 0.509407 0.83535 0.570475 +v 0.501828 0.827538 0.567122 +v 0.506923 0.828425 0.565634 +v 0.495573 0.834348 0.57294 +v 0.490926 0.837965 0.571906 +v 0.489535 0.843065 0.571391 +v 0.490431 0.848419 0.569876 +v 0.485967 0.844171 0.565529 +v 0.50219 0.845723 0.575924 +v 0.50567 0.844855 0.574936 +v 0.506849 0.849236 0.572786 +v 0.509528 0.844721 0.572261 +v 0.512803 0.846998 0.567646 +v 0.512379 0.841095 0.569481 +v 0.498845 0.849178 0.574241 +v 0.507874 0.852649 0.569622 +v 0.504395 0.853315 0.570969 +v 0.500369 0.853811 0.57047 +v 0.495679 0.852056 0.570367 +v 0.464814 0.159331 0.568243 +v 0.528607 0.160621 0.569154 +v 0.532816 0.159876 0.566657 +v 0.423242 0.1623 0.569627 +v 0.416298 0.165475 0.568951 +v 0.419176 0.163025 0.564757 +v 0.430351 0.160622 0.567227 +v 0.523656 0.162814 0.568679 +v 0.519886 0.165843 0.56481 +v 0.526963 0.16117 0.562117 +v 0.561664 0.162268 0.567698 +v 0.409602 0.167896 0.566439 +v 0.51538 0.17514 0.567555 +v 0.414871 0.179523 0.572017 +v 0.408489 0.175179 0.567847 +v 0.416451 0.183569 0.56928 +v 0.484025 0.18199 0.57167 +v 0.485079 0.179931 0.566102 +v 0.4827 0.186451 0.568606 +v 0.583986 0.183879 0.568778 +v 0.59022 0.182258 0.56316 +v 0.582063 0.186987 0.564264 +v 0.455689 0.193697 0.570842 +v 0.447504 0.193064 0.565686 +v 0.51962 0.1889 0.572641 +v 0.51752 0.187171 0.567364 +v 0.522614 0.192563 0.570727 +v 0.548481 0.18975 0.573581 +v 0.56812 0.19192 0.566679 +v 0.559343 0.193691 0.563026 +v 0.460626 0.196043 0.568753 +v 0.471865 0.197521 0.563713 +v 0.466746 0.197521 0.566595 +v 0.480011 0.191269 0.564188 +v 0.476207 0.195205 0.562232 +v 0.543779 0.193293 0.570886 +v 0.536692 0.196483 0.568075 +v 0.530553 0.196892 0.566583 +v 0.473942 0.426652 0.562614 +v 0.485898 0.425839 0.564204 +v 0.568105 0.461303 0.561583 +v 0.556904 0.454879 0.566375 +v 0.571238 0.488237 0.566435 +v 0.432551 0.509251 0.566397 +v 0.455103 0.563511 0.565179 +v 0.46269 0.57498 0.564798 +v 0.699524 0.593583 0.560901 +v 0.286207 0.598505 0.560062 +v 0.282623 0.606814 0.571408 +v 0.704704 0.59341 0.557052 +v 0.711564 0.597446 0.557002 +v 0.277958 0.610123 0.568406 +v 0.669657 0.603832 0.55733 +v 0.669296 0.612056 0.566048 +v 0.331063 0.617434 0.568174 +v 0.667449 0.616655 0.565132 +v 0.340595 0.625034 0.574498 +v 0.339856 0.629598 0.572161 +v 0.335819 0.624311 0.566998 +v 0.335826 0.63749 0.570426 +v 0.329003 0.642982 0.5624 +v 0.666174 0.639265 0.5645 +v 0.275194 0.648062 0.561241 +v 0.317965 0.654883 0.566231 +v 0.673477 0.647908 0.562022 +v 0.669757 0.643185 0.559773 +v 0.677503 0.64995 0.55511 +v 0.68939 0.658544 0.562561 +v 0.696029 0.660735 0.56809 +v 0.699952 0.659059 0.558662 +v 0.702541 0.660899 0.570221 +v 0.535982 0.716136 0.556621 +v 0.540542 0.724861 0.56294 +v 0.542894 0.737464 0.570124 +v 0.543108 0.732863 0.567845 +v 0.545578 0.74082 0.567552 +v 0.469253 0.746494 0.569801 +v 0.459096 0.744928 0.567652 +v 0.484803 0.746672 0.571525 +v 0.471968 0.747873 0.566753 +v 0.504664 0.746866 0.571373 +v 0.524256 0.746983 0.569648 +v 0.508229 0.747544 0.566463 +v 0.537676 0.746709 0.56683 +v 0.474067 0.757309 0.56599 +v 0.491913 0.758749 0.565741 +v 0.539456 0.756485 0.567723 +v 0.445641 0.764698 0.570698 +v 0.444112 0.760749 0.563877 +v 0.557392 0.763555 0.564701 +v 0.444094 0.771592 0.567616 +v 0.445313 0.783336 0.562835 +v 0.441484 0.778103 0.556723 +v 0.555008 0.775258 0.567661 +v 0.551633 0.779314 0.569035 +v 0.557849 0.776626 0.561239 +v 0.449326 0.784871 0.567896 +v 0.454316 0.785451 0.572306 +v 0.4568 0.797534 0.565573 +v 0.490677 0.834313 0.569478 +v 0.490917 0.83051 0.565624 +v 0.486993 0.834982 0.564058 +v 0.514503 0.837963 0.564865 +v 0.491943 0.853279 0.565986 +v 0.503144 0.856175 0.567276 +v 0.459584 0.160456 0.561996 +v 0.452259 0.162734 0.560459 +v 0.552635 0.162979 0.564754 +v 0.543909 0.161871 0.563467 +v 0.576454 0.161426 0.558124 +v 0.584026 0.162775 0.55789 +v 0.40262 0.168524 0.563591 +v 0.401897 0.171774 0.564348 +v 0.396085 0.168557 0.559832 +v 0.403992 0.165734 0.562223 +v 0.414667 0.163496 0.558752 +v 0.422499 0.161829 0.55813 +v 0.594992 0.164852 0.561822 +v 0.596478 0.167927 0.563685 +v 0.60226 0.169719 0.562022 +v 0.596801 0.17207 0.564822 +v 0.402665 0.179076 0.562025 +v 0.395811 0.176239 0.559761 +v 0.40176 0.175207 0.564147 +v 0.59707 0.176114 0.564262 +v 0.41079 0.182945 0.562025 +v 0.404987 0.183308 0.556479 +v 0.602622 0.176806 0.561187 +v 0.597268 0.179461 0.56199 +v 0.418978 0.187687 0.563332 +v 0.427938 0.191076 0.564293 +v 0.420263 0.19272 0.553481 +v 0.433546 0.189014 0.571177 +v 0.43804 0.192143 0.564148 +v 0.481981 0.18833 0.559225 +v 0.522853 0.194231 0.562087 +v 0.521553 0.194812 0.552385 +v 0.519388 0.190526 0.5599 +v 0.51644 0.185123 0.559131 +v 0.57407 0.191366 0.564602 +v 0.580544 0.189853 0.557391 +v 0.547204 0.195655 0.563519 +v 0.458715 0.200186 0.558415 +v 0.499066 0.427433 0.566593 +v 0.488251 0.416039 0.55554 +v 0.513413 0.426624 0.565256 +v 0.522555 0.415382 0.554328 +v 0.530284 0.423259 0.559306 +v 0.463008 0.433042 0.563782 +v 0.460148 0.420175 0.553739 +v 0.536245 0.432137 0.563927 +v 0.546953 0.417727 0.551316 +v 0.455335 0.445098 0.568128 +v 0.539366 0.441437 0.568689 +v 0.444883 0.450221 0.565189 +v 0.434267 0.439011 0.553626 +v 0.436131 0.45913 0.563283 +v 0.54809 0.447345 0.56774 +v 0.559514 0.435071 0.555685 +v 0.426666 0.468438 0.559099 +v 0.444514 0.559782 0.559862 +v 0.526499 0.601963 0.56138 +v 0.534192 0.58202 0.563817 +v 0.544666 0.570894 0.562975 +v 0.539056 0.596767 0.558224 +v 0.479546 0.603906 0.561441 +v 0.47268 0.586222 0.564493 +v 0.482322 0.584341 0.567592 +v 0.494499 0.585966 0.568419 +v 0.503445 0.607823 0.561358 +v 0.66532 0.60625 0.551869 +v 0.665753 0.596664 0.544146 +v 0.721382 0.605039 0.54953 +v 0.71729 0.601467 0.55492 +v 0.274555 0.612963 0.56403 +v 0.277292 0.605298 0.555824 +v 0.273091 0.613751 0.555161 +v 0.333057 0.621512 0.563995 +v 0.333722 0.627036 0.561437 +v 0.331605 0.616183 0.562449 +v 0.664729 0.625753 0.561215 +v 0.665633 0.621157 0.562486 +v 0.727166 0.62356 0.562912 +v 0.663352 0.62876 0.563809 +v 0.338156 0.633595 0.570207 +v 0.334346 0.632235 0.563042 +v 0.496763 0.715994 0.564583 +v 0.485819 0.716425 0.564342 +v 0.489469 0.705477 0.553857 +v 0.509401 0.717627 0.565509 +v 0.475468 0.718482 0.564438 +v 0.466059 0.722411 0.565165 +v 0.470891 0.712108 0.555999 +v 0.514288 0.708957 0.556623 +v 0.451339 0.737035 0.562994 +v 0.445325 0.73715 0.552723 +v 0.448765 0.731348 0.555915 +v 0.453928 0.741578 0.565949 +v 0.451924 0.745245 0.561515 +v 0.550912 0.742337 0.561416 +v 0.547709 0.744059 0.563896 +v 0.473813 0.747889 0.562858 +v 0.486881 0.74714 0.561452 +v 0.471699 0.746959 0.555816 +v 0.462788 0.748886 0.561072 +v 0.54277 0.748354 0.560683 +v 0.545387 0.746623 0.562692 +v 0.550071 0.747294 0.558319 +v 0.459399 0.75657 0.560858 +v 0.461681 0.759131 0.557948 +v 0.543439 0.756615 0.560309 +v 0.54886 0.756675 0.561106 +v 0.56102 0.768599 0.556723 +v 0.560029 0.762736 0.55762 +v 0.448399 0.795038 0.558119 +v 0.53843 0.801103 0.564186 +v 0.547158 0.787648 0.56856 +v 0.552949 0.788987 0.559963 +v 0.532443 0.812349 0.552711 +v 0.525527 0.813515 0.557238 +v 0.479731 0.814733 0.558808 +v 0.471717 0.812008 0.557494 +v 0.485127 0.815823 0.559733 +v 0.484788 0.823778 0.550437 +v 0.489983 0.811326 0.566316 +v 0.491011 0.818058 0.55807 +v 0.500509 0.810869 0.567242 +v 0.519051 0.813063 0.561576 +v 0.510897 0.81203 0.564945 +v 0.515261 0.820807 0.552106 +v 0.503863 0.817115 0.559305 +v 0.510749 0.852049 0.566398 +v 0.513543 0.850314 0.5616 +v 0.48802 0.852052 0.560732 +v 0.49267 0.855653 0.559841 +v 0.50711 0.855323 0.566072 +v 0.504393 0.857187 0.561542 +v 0.434783 0.16084 0.559809 +v 0.437824 0.161585 0.563652 +v 0.445119 0.163299 0.561709 +v 0.449853 0.161996 0.551483 +v 0.464446 0.159986 0.559587 +v 0.477009 0.166053 0.542653 +v 0.478175 0.165729 0.558019 +v 0.47405 0.162616 0.558088 +v 0.481531 0.168768 0.560413 +v 0.531181 0.160448 0.557912 +v 0.536543 0.160644 0.560289 +v 0.548312 0.161065 0.550061 +v 0.564999 0.160943 0.549763 +v 0.568351 0.160847 0.556865 +v 0.5614 0.16164 0.561274 +v 0.592298 0.162945 0.558574 +v 0.599804 0.162786 0.55694 +v 0.406568 0.163643 0.559354 +v 0.399091 0.163665 0.557496 +v 0.408209 0.162467 0.553763 +v 0.606248 0.168479 0.558022 +v 0.605305 0.172764 0.560128 +v 0.606517 0.176 0.557114 +v 0.596101 0.182503 0.557717 +v 0.442087 0.196928 0.557906 +v 0.47444 0.198773 0.552821 +v 0.526164 0.195788 0.565045 +v 0.530868 0.200076 0.557063 +v 0.516448 0.408976 0.548567 +v 0.529831 0.405216 0.544941 +v 0.578814 0.499667 0.558646 +v 0.578875 0.483835 0.558588 +v 0.575359 0.519451 0.557636 +v 0.567073 0.541604 0.557836 +v 0.583378 0.514424 0.550336 +v 0.432085 0.543195 0.556009 +v 0.419619 0.521642 0.550752 +v 0.426819 0.516766 0.559769 +v 0.421421 0.494625 0.558932 +v 0.437714 0.570106 0.550555 +v 0.555545 0.560734 0.559818 +v 0.46338 0.593147 0.558331 +v 0.461688 0.604069 0.555904 +v 0.453768 0.597158 0.552015 +v 0.327437 0.589952 0.541453 +v 0.332431 0.597442 0.545075 +v 0.471026 0.616574 0.55941 +v 0.477212 0.619793 0.559833 +v 0.333327 0.60651 0.552368 +v 0.334659 0.614188 0.552717 +v 0.462757 0.62625 0.558945 +v 0.463032 0.615595 0.557788 +v 0.495681 0.625123 0.55791 +v 0.510433 0.625323 0.557824 +v 0.531364 0.616927 0.559532 +v 0.527443 0.620829 0.559898 +v 0.538728 0.614035 0.557755 +v 0.547927 0.611739 0.554146 +v 0.724543 0.612121 0.546989 +v 0.726669 0.621911 0.549505 +v 0.481591 0.627504 0.559246 +v 0.469285 0.630023 0.559717 +v 0.487231 0.639642 0.556806 +v 0.524122 0.629292 0.558903 +v 0.517539 0.642025 0.556171 +v 0.534314 0.634133 0.559345 +v 0.541245 0.625322 0.558672 +v 0.664775 0.629605 0.55606 +v 0.333308 0.629538 0.556733 +v 0.461949 0.635353 0.55844 +v 0.542323 0.633721 0.558551 +v 0.542714 0.641358 0.557219 +v 0.549864 0.631311 0.556293 +v 0.727724 0.630233 0.553835 +v 0.727658 0.63624 0.556544 +v 0.456659 0.640393 0.556251 +v 0.465242 0.646805 0.556438 +v 0.667543 0.638156 0.550951 +v 0.458559 0.725844 0.56337 +v 0.54708 0.727859 0.55984 +v 0.552908 0.73161 0.554143 +v 0.558346 0.736706 0.54618 +v 0.555197 0.741028 0.554117 +v 0.556129 0.746157 0.552884 +v 0.506344 0.746919 0.553494 +v 0.506672 0.747054 0.559545 +v 0.526285 0.746701 0.555471 +v 0.546818 0.749808 0.554722 +v 0.541703 0.748488 0.555902 +v 0.448278 0.756122 0.558824 +v 0.442871 0.757291 0.555269 +v 0.442122 0.755642 0.549152 +v 0.455032 0.755988 0.561244 +v 0.451211 0.756032 0.553828 +v 0.555051 0.757746 0.55843 +v 0.557713 0.757205 0.552698 +v 0.558571 0.759686 0.556356 +v 0.439313 0.761307 0.552122 +v 0.477058 0.76288 0.558645 +v 0.464889 0.763471 0.554395 +v 0.467962 0.766892 0.551424 +v 0.499574 0.761993 0.56123 +v 0.499468 0.765609 0.555528 +v 0.520273 0.763443 0.558632 +v 0.53239 0.763044 0.557372 +v 0.530088 0.767046 0.550773 +v 0.561532 0.760495 0.551528 +v 0.557153 0.785894 0.554557 +v 0.559988 0.777578 0.554776 +v 0.555184 0.79374 0.551466 +v 0.461132 0.806542 0.55772 +v 0.453203 0.801759 0.557005 +v 0.468714 0.814879 0.548871 +v 0.495539 0.819834 0.557122 +v 0.493093 0.822639 0.5565 +v 0.499994 0.819466 0.557678 +v 0.505512 0.82107 0.555428 +v 0.497995 0.822051 0.558688 +v 0.488665 0.82881 0.557945 +v 0.492427 0.826364 0.560892 +v 0.495658 0.824907 0.561136 +v 0.502967 0.824713 0.561692 +v 0.499252 0.82519 0.563334 +v 0.506974 0.825682 0.560295 +v 0.511224 0.828969 0.559814 +v 0.483911 0.839396 0.559161 +v 0.485164 0.833902 0.556408 +v 0.485297 0.830206 0.550147 +v 0.517151 0.84041 0.5571 +v 0.514952 0.834494 0.558802 +v 0.483673 0.843892 0.55678 +v 0.484608 0.847722 0.555539 +v 0.480434 0.843307 0.549094 +v 0.485771 0.850384 0.553232 +v 0.393698 0.165576 0.554552 +v 0.395076 0.163227 0.551354 +v 0.429981 0.160895 0.556249 +v 0.424072 0.161077 0.548937 +v 0.4337 0.160865 0.549899 +v 0.464541 0.161117 0.54837 +v 0.469419 0.160706 0.55869 +v 0.5268 0.162723 0.554464 +v 0.575684 0.160783 0.547313 +v 0.591034 0.162107 0.552849 +v 0.521882 0.165947 0.555117 +v 0.518473 0.169325 0.556893 +v 0.524907 0.16492 0.543055 +v 0.609088 0.168566 0.553089 +v 0.607108 0.165575 0.553235 +v 0.39148 0.169224 0.553693 +v 0.391214 0.173681 0.553543 +v 0.387545 0.170739 0.546507 +v 0.483228 0.173517 0.557417 +v 0.517111 0.172371 0.544541 +v 0.516533 0.17361 0.558127 +v 0.611986 0.168609 0.547537 +v 0.610441 0.171713 0.551244 +v 0.393479 0.178451 0.552658 +v 0.484358 0.178152 0.557929 +v 0.483909 0.176001 0.545914 +v 0.515606 0.179236 0.558593 +v 0.48387 0.183139 0.558031 +v 0.515416 0.182488 0.54776 +v 0.399876 0.183326 0.550967 +v 0.406534 0.188744 0.546814 +v 0.482932 0.188004 0.548854 +v 0.448672 0.201546 0.553823 +v 0.438484 0.202123 0.550186 +v 0.551763 0.20015 0.554865 +v 0.451069 0.412305 0.546595 +v 0.464423 0.408223 0.54582 +v 0.559698 0.413391 0.544941 +v 0.555574 0.399781 0.539088 +v 0.579211 0.453404 0.549837 +v 0.578252 0.468805 0.555483 +v 0.418643 0.454082 0.547595 +v 0.418486 0.475432 0.553865 +v 0.561935 0.569503 0.551425 +v 0.56648 0.577164 0.544381 +v 0.55852 0.593677 0.547037 +v 0.673783 0.588279 0.542342 +v 0.681866 0.592774 0.554709 +v 0.683305 0.584226 0.541063 +v 0.711138 0.590897 0.540204 +v 0.45398 0.614858 0.554282 +v 0.66068 0.619478 0.545095 +v 0.657933 0.611564 0.539159 +v 0.662017 0.612561 0.548567 +v 0.665801 0.615696 0.558595 +v 0.27046 0.629284 0.555857 +v 0.271898 0.619608 0.547033 +v 0.445838 0.627387 0.551365 +v 0.449067 0.637945 0.553376 +v 0.442293 0.63804 0.54862 +v 0.5558 0.637606 0.55262 +v 0.557257 0.63111 0.552016 +v 0.276759 0.638201 0.54206 +v 0.282556 0.64343 0.538702 +v 0.454539 0.649634 0.552618 +v 0.551443 0.643982 0.553491 +v 0.543786 0.651181 0.553341 +v 0.719627 0.644841 0.548919 +v 0.725087 0.641001 0.554755 +v 0.495609 0.654017 0.552834 +v 0.483256 0.654614 0.553957 +v 0.509912 0.655574 0.552333 +v 0.523642 0.658426 0.55239 +v 0.682899 0.652837 0.551327 +v 0.675605 0.645502 0.539258 +v 0.474846 0.657674 0.553404 +v 0.468837 0.66166 0.55131 +v 0.482575 0.670642 0.549747 +v 0.508661 0.698277 0.55056 +v 0.520828 0.705957 0.551761 +v 0.548797 0.721643 0.551273 +v 0.451859 0.726803 0.556533 +v 0.447348 0.725108 0.546688 +v 0.456628 0.719363 0.553641 +v 0.442919 0.746061 0.549847 +v 0.44047 0.741994 0.543553 +v 0.555615 0.748819 0.551877 +v 0.559061 0.750677 0.547841 +v 0.451098 0.74894 0.55662 +v 0.446939 0.747467 0.554566 +v 0.509922 0.748541 0.550108 +v 0.491614 0.748477 0.550242 +v 0.543159 0.747937 0.547785 +v 0.538076 0.746726 0.552048 +v 0.533576 0.746099 0.548045 +v 0.55293 0.749358 0.553815 +v 0.550836 0.750292 0.553242 +v 0.555124 0.752064 0.550065 +v 0.454861 0.750011 0.556444 +v 0.450913 0.751341 0.551981 +v 0.458736 0.749236 0.554118 +v 0.538986 0.759773 0.556262 +v 0.539729 0.75741 0.559469 +v 0.534811 0.759435 0.560984 +v 0.547833 0.756983 0.553144 +v 0.458067 0.761348 0.550979 +v 0.536975 0.762615 0.554739 +v 0.542077 0.76218 0.549505 +v 0.482801 0.767109 0.551938 +v 0.471292 0.768112 0.549552 +v 0.476302 0.767618 0.548546 +v 0.497935 0.766361 0.551946 +v 0.449667 0.800631 0.549742 +v 0.538972 0.809897 0.548476 +v 0.527236 0.819293 0.544835 +v 0.506331 0.823212 0.556179 +v 0.509997 0.8229 0.552525 +v 0.514125 0.83027 0.55292 +v 0.518389 0.841189 0.550269 +v 0.517548 0.844988 0.553502 +v 0.519581 0.848557 0.548208 +v 0.51577 0.848687 0.554491 +v 0.488026 0.852594 0.549908 +v 0.492294 0.855543 0.551722 +v 0.491111 0.855349 0.545135 +v 0.512207 0.85302 0.553606 +v 0.497028 0.857509 0.553138 +v 0.50709 0.856327 0.553285 +v 0.501769 0.857782 0.553703 +v 0.509747 0.855412 0.545913 +v 0.399279 0.161982 0.549347 +v 0.391881 0.162762 0.544733 +v 0.599823 0.161934 0.550754 +v 0.604968 0.163283 0.551664 +v 0.60876 0.163577 0.545852 +v 0.611949 0.174559 0.546629 +v 0.609168 0.174921 0.55214 +v 0.606234 0.179079 0.55184 +v 0.604936 0.182509 0.544005 +v 0.600706 0.183044 0.551133 +v 0.394713 0.182181 0.543831 +v 0.584613 0.192577 0.5475 +v 0.591555 0.18634 0.552466 +v 0.523997 0.200899 0.545285 +v 0.519142 0.197039 0.542482 +v 0.436688 0.208432 0.540978 +v 0.427812 0.20436 0.541867 +v 0.456005 0.205426 0.549387 +v 0.538604 0.212398 0.537441 +v 0.535571 0.206141 0.548096 +v 0.543778 0.207931 0.545473 +v 0.555521 0.207338 0.543779 +v 0.568896 0.41515 0.542044 +v 0.587625 0.472771 0.546912 +v 0.442775 0.590115 0.546537 +v 0.430541 0.573712 0.542375 +v 0.696773 0.585384 0.54422 +v 0.444995 0.61432 0.548507 +v 0.437408 0.610867 0.540132 +v 0.444953 0.602043 0.546131 +v 0.562454 0.607645 0.543 +v 0.55652 0.611148 0.54891 +v 0.557604 0.623166 0.550801 +v 0.339322 0.614446 0.541492 +v 0.335887 0.622205 0.549585 +v 0.271668 0.630672 0.549154 +v 0.33442 0.630536 0.548668 +v 0.564399 0.631097 0.54626 +v 0.659044 0.623218 0.538359 +v 0.662749 0.627306 0.547114 +v 0.66485 0.63305 0.547707 +v 0.330952 0.637916 0.549985 +v 0.334837 0.632011 0.539487 +v 0.437335 0.639499 0.543364 +v 0.44261 0.649625 0.544682 +v 0.665722 0.636042 0.538609 +v 0.281819 0.626403 0.514044 +v 0.275321 0.629227 0.535043 +v 0.55883 0.645263 0.548437 +v 0.722976 0.631433 0.536664 +v 0.32627 0.644414 0.552421 +v 0.325696 0.64335 0.540567 +v 0.320694 0.649795 0.553372 +v 0.71242 0.640511 0.527387 +v 0.713059 0.648246 0.543688 +v 0.314378 0.654731 0.556103 +v 0.707015 0.651401 0.542325 +v 0.688526 0.654116 0.547434 +v 0.302341 0.655147 0.546941 +v 0.295944 0.655818 0.549553 +v 0.505438 0.669556 0.549739 +v 0.544255 0.664564 0.545828 +v 0.534861 0.66162 0.550384 +v 0.462671 0.663492 0.548927 +v 0.456028 0.663056 0.546049 +v 0.471643 0.676054 0.546243 +v 0.528198 0.67239 0.54662 +v 0.516175 0.684123 0.54766 +v 0.505403 0.684844 0.549178 +v 0.489195 0.696455 0.549187 +v 0.486663 0.684403 0.548506 +v 0.49646 0.688296 0.54948 +v 0.479191 0.68327 0.546812 +v 0.481794 0.701632 0.548636 +v 0.465175 0.710868 0.550449 +v 0.474213 0.704695 0.548694 +v 0.53137 0.70975 0.551011 +v 0.541057 0.714268 0.549685 +v 0.528406 0.705611 0.546703 +v 0.459042 0.71253 0.545878 +v 0.455454 0.713728 0.541405 +v 0.460761 0.704464 0.540527 +v 0.54749 0.717468 0.543785 +v 0.442788 0.751844 0.548027 +v 0.463237 0.7473 0.550382 +v 0.458118 0.74837 0.546282 +v 0.46962 0.746386 0.548295 +v 0.478384 0.747934 0.548425 +v 0.485879 0.750666 0.547831 +v 0.524069 0.747873 0.548081 +v 0.513559 0.750819 0.548016 +v 0.52998 0.748019 0.544353 +v 0.452199 0.752249 0.548444 +v 0.448545 0.752825 0.549652 +v 0.549367 0.75158 0.550373 +v 0.549762 0.753454 0.547436 +v 0.54704 0.750915 0.547237 +v 0.443516 0.754975 0.548085 +v 0.44624 0.754121 0.548759 +v 0.447532 0.755302 0.549973 +v 0.452049 0.757394 0.550163 +v 0.547119 0.758574 0.548827 +v 0.551311 0.756257 0.549392 +v 0.55102 0.755027 0.547882 +v 0.554045 0.754783 0.549409 +v 0.556725 0.754602 0.549666 +v 0.559128 0.754731 0.5489 +v 0.456643 0.761796 0.547382 +v 0.438051 0.769901 0.548814 +v 0.436576 0.761008 0.541182 +v 0.491747 0.764827 0.549481 +v 0.505222 0.765036 0.55028 +v 0.505343 0.762484 0.548609 +v 0.516801 0.76605 0.549056 +v 0.52366 0.766737 0.54577 +v 0.527242 0.768224 0.547138 +v 0.465673 0.768737 0.546088 +v 0.534854 0.768587 0.54388 +v 0.439534 0.781705 0.54572 +v 0.551098 0.799777 0.548629 +v 0.556822 0.793878 0.542672 +v 0.463339 0.812681 0.543552 +v 0.47293 0.819898 0.542993 +v 0.513401 0.82583 0.549642 +v 0.516667 0.830827 0.548037 +v 0.481472 0.829487 0.545142 +v 0.518786 0.836046 0.547555 +v 0.521409 0.840141 0.546835 +v 0.501204 0.858044 0.545398 +v 0.404148 0.161618 0.544906 +v 0.425142 0.159783 0.54092 +v 0.415512 0.15972 0.537437 +v 0.44331 0.160488 0.541035 +v 0.452747 0.160535 0.540966 +v 0.56761 0.159822 0.539419 +v 0.561158 0.159199 0.535013 +v 0.576958 0.159519 0.537788 +v 0.59442 0.161322 0.543711 +v 0.61283 0.162988 0.540281 +v 0.609052 0.161029 0.536755 +v 0.615935 0.162327 0.533337 +v 0.614681 0.165135 0.541103 +v 0.61607 0.16784 0.541152 +v 0.617782 0.170646 0.539354 +v 0.619629 0.167936 0.533851 +v 0.487429 0.185814 0.535794 +v 0.484817 0.192633 0.538741 +v 0.403676 0.194086 0.535182 +v 0.411408 0.195028 0.541721 +v 0.486249 0.197579 0.528242 +v 0.480391 0.198089 0.541998 +v 0.41857 0.200196 0.540798 +v 0.516438 0.200526 0.530701 +v 0.514792 0.194219 0.537624 +v 0.585128 0.214738 0.5298 +v 0.575211 0.20486 0.539468 +v 0.581942 0.200479 0.539701 +v 0.593386 0.195153 0.535918 +v 0.417571 0.216914 0.530517 +v 0.475276 0.202914 0.541812 +v 0.52972 0.203722 0.54798 +v 0.526545 0.206937 0.537113 +v 0.494566 0.406947 0.546299 +v 0.500578 0.39639 0.533684 +v 0.50675 0.404733 0.544013 +v 0.42129 0.4337 0.543035 +v 0.428293 0.421008 0.54242 +v 0.410556 0.437927 0.535937 +v 0.412721 0.483042 0.548896 +v 0.593013 0.495632 0.540773 +v 0.587762 0.523687 0.541197 +v 0.303104 0.586437 0.547868 +v 0.311399 0.579965 0.533473 +v 0.310485 0.585556 0.546081 +v 0.318783 0.586574 0.544081 +v 0.297231 0.58802 0.548392 +v 0.292895 0.589055 0.545862 +v 0.301191 0.58127 0.53288 +v 0.278201 0.601026 0.541651 +v 0.282107 0.596506 0.544387 +v 0.339316 0.595734 0.5335 +v 0.720566 0.602161 0.532775 +v 0.275845 0.606027 0.538507 +v 0.273694 0.612328 0.541075 +v 0.275883 0.618259 0.524979 +v 0.293169 0.651591 0.541465 +v 0.308781 0.654806 0.549688 +v 0.558486 0.666316 0.534206 +v 0.552346 0.666731 0.539601 +v 0.559576 0.654962 0.542218 +v 0.694703 0.654146 0.544572 +v 0.701107 0.653441 0.543204 +v 0.70074 0.646813 0.526762 +v 0.443775 0.663223 0.536117 +v 0.44969 0.663225 0.54187 +v 0.458472 0.677982 0.539597 +v 0.473295 0.688751 0.544665 +v 0.534851 0.68133 0.540985 +v 0.52603 0.682208 0.544872 +v 0.526502 0.69338 0.544443 +v 0.536047 0.6959 0.539649 +v 0.529862 0.702266 0.543413 +v 0.47446 0.698561 0.545526 +v 0.537247 0.708382 0.540477 +v 0.450076 0.71881 0.539844 +v 0.45286 0.712897 0.534593 +v 0.559852 0.733217 0.538547 +v 0.56199 0.742758 0.539874 +v 0.469341 0.747435 0.544147 +v 0.54449 0.750804 0.542498 +v 0.444396 0.753177 0.547979 +v 0.441254 0.75447 0.545961 +v 0.478878 0.751937 0.54513 +v 0.487919 0.754074 0.546744 +v 0.51112 0.754862 0.546979 +v 0.520553 0.751819 0.545563 +v 0.478949 0.761079 0.544559 +v 0.486708 0.758565 0.546446 +v 0.485002 0.762764 0.546898 +v 0.495887 0.75769 0.547686 +v 0.506351 0.758467 0.547722 +v 0.515275 0.759762 0.546516 +v 0.547902 0.755908 0.545173 +v 0.561284 0.755306 0.547553 +v 0.564166 0.765984 0.542581 +v 0.563217 0.758512 0.545543 +v 0.563943 0.754964 0.539769 +v 0.460946 0.766566 0.544045 +v 0.456737 0.760394 0.543882 +v 0.520315 0.763593 0.545518 +v 0.522323 0.760801 0.544376 +v 0.544274 0.760444 0.542973 +v 0.54466 0.756574 0.541654 +v 0.543318 0.762346 0.545583 +v 0.540023 0.765706 0.542143 +v 0.472109 0.765058 0.542727 +v 0.473704 0.76717 0.545051 +v 0.467 0.767933 0.542024 +v 0.481553 0.765711 0.547756 +v 0.527836 0.765805 0.543036 +v 0.463924 0.768449 0.542336 +v 0.56233 0.774798 0.547953 +v 0.438558 0.781448 0.53639 +v 0.442111 0.790873 0.54206 +v 0.544718 0.806086 0.542358 +v 0.519743 0.829948 0.545291 +v 0.466426 0.832419 0.542627 +v 0.474451 0.830406 0.543504 +v 0.473737 0.838255 0.545572 +v 0.475739 0.824335 0.542034 +v 0.533139 0.832633 0.543316 +v 0.527403 0.836977 0.545263 +v 0.525409 0.829682 0.543748 +v 0.537926 0.829605 0.540818 +v 0.539467 0.838499 0.543314 +v 0.460129 0.845572 0.54362 +v 0.453557 0.84384 0.540035 +v 0.458997 0.837896 0.541811 +v 0.527973 0.843444 0.546078 +v 0.474165 0.844428 0.546185 +v 0.542968 0.845105 0.542347 +v 0.536178 0.845301 0.544929 +v 0.467022 0.847568 0.545317 +v 0.463805 0.852272 0.543826 +v 0.474068 0.850851 0.545301 +v 0.486073 0.851319 0.546413 +v 0.527791 0.848347 0.545792 +v 0.525773 0.852808 0.544786 +v 0.479707 0.856526 0.543486 +v 0.471331 0.856785 0.543626 +v 0.476269 0.874108 0.542267 +v 0.483568 0.87577 0.542145 +v 0.48062 0.88168 0.543198 +v 0.52973 0.881925 0.540715 +v 0.522417 0.87534 0.54152 +v 0.534125 0.874599 0.539329 +v 0.482265 0.888025 0.541158 +v 0.47613 0.886063 0.542024 +v 0.38706 0.162877 0.540015 +v 0.383517 0.165008 0.539056 +v 0.383893 0.162789 0.53377 +v 0.390224 0.16105 0.537504 +v 0.395972 0.16026 0.534891 +v 0.405654 0.160207 0.535801 +v 0.459929 0.160654 0.540167 +v 0.45731 0.16037 0.531733 +v 0.468064 0.161971 0.534938 +v 0.527925 0.163193 0.528825 +v 0.534347 0.161968 0.521271 +v 0.545798 0.160347 0.531971 +v 0.570618 0.158045 0.525058 +v 0.383342 0.168198 0.540502 +v 0.380347 0.167175 0.53393 +v 0.383126 0.172139 0.540198 +v 0.380317 0.1737 0.533957 +v 0.383561 0.176168 0.537407 +v 0.486417 0.173637 0.528692 +v 0.487866 0.179136 0.532726 +v 0.61599 0.174148 0.540368 +v 0.614096 0.177613 0.538944 +v 0.619554 0.172801 0.53331 +v 0.512183 0.178735 0.532753 +v 0.512298 0.184158 0.535778 +v 0.610165 0.181887 0.536698 +v 0.603605 0.187893 0.534873 +v 0.614958 0.181186 0.530245 +v 0.508381 0.185552 0.523519 +v 0.512121 0.189358 0.535065 +v 0.510661 0.193174 0.527745 +v 0.5735 0.217193 0.533095 +v 0.566044 0.207545 0.540562 +v 0.444736 0.212117 0.538117 +v 0.43887 0.214132 0.533887 +v 0.557026 0.214414 0.534249 +v 0.450077 0.2164 0.533223 +v 0.45249 0.211549 0.540122 +v 0.461247 0.210461 0.53962 +v 0.437436 0.411389 0.542272 +v 0.444836 0.400208 0.538943 +v 0.583101 0.435879 0.541175 +v 0.577902 0.416714 0.537883 +v 0.587932 0.412322 0.529692 +v 0.590725 0.445459 0.537512 +v 0.409949 0.499653 0.543924 +v 0.404926 0.476666 0.537155 +v 0.412249 0.524447 0.540485 +v 0.41827 0.550093 0.53863 +v 0.409115 0.532912 0.532563 +v 0.696358 0.580349 0.528991 +v 0.688524 0.580055 0.532573 +v 0.287811 0.591805 0.544314 +v 0.567815 0.612807 0.538306 +v 0.566866 0.594235 0.539167 +v 0.724601 0.61894 0.534532 +v 0.432968 0.640336 0.53604 +v 0.432929 0.629873 0.537857 +v 0.569235 0.626656 0.539977 +v 0.568086 0.636588 0.541306 +v 0.56469 0.645228 0.542357 +v 0.570092 0.642933 0.534846 +v 0.668169 0.639467 0.531647 +v 0.672351 0.642863 0.527387 +v 0.543671 0.677237 0.538208 +v 0.541578 0.686843 0.53634 +v 0.467135 0.690432 0.541803 +v 0.460928 0.691861 0.538295 +v 0.553852 0.723909 0.53506 +v 0.546221 0.715938 0.537177 +v 0.437339 0.749532 0.537728 +v 0.439456 0.737964 0.536058 +v 0.461237 0.747845 0.541729 +v 0.455864 0.750004 0.544434 +v 0.455147 0.753588 0.544053 +v 0.469059 0.749493 0.542558 +v 0.45888 0.758695 0.540176 +v 0.471027 0.760072 0.541809 +v 0.46352 0.758772 0.539486 +v 0.469573 0.753592 0.541856 +v 0.530819 0.751956 0.54206 +v 0.539467 0.754254 0.539898 +v 0.53015 0.763276 0.541751 +v 0.530583 0.758511 0.541527 +v 0.535661 0.766655 0.541001 +v 0.462508 0.765257 0.539788 +v 0.563137 0.774399 0.537736 +v 0.446805 0.797723 0.541725 +v 0.444531 0.794402 0.534693 +v 0.453218 0.804206 0.541735 +v 0.457414 0.807787 0.536048 +v 0.550045 0.801118 0.534135 +v 0.543035 0.809784 0.534097 +v 0.468071 0.81789 0.538696 +v 0.529369 0.820883 0.540896 +v 0.523514 0.824412 0.542987 +v 0.458797 0.828441 0.537765 +v 0.449505 0.850178 0.536235 +v 0.447551 0.843291 0.534739 +v 0.55111 0.835839 0.534958 +v 0.554087 0.842896 0.533747 +v 0.549104 0.844392 0.538333 +v 0.546306 0.85224 0.539238 +v 0.489074 0.855472 0.542607 +v 0.485646 0.855261 0.542798 +v 0.485846 0.863097 0.540611 +v 0.506528 0.857987 0.541901 +v 0.513044 0.857486 0.542105 +v 0.458594 0.860855 0.538417 +v 0.465533 0.858758 0.541747 +v 0.467841 0.866632 0.540214 +v 0.494714 0.858686 0.541175 +v 0.499617 0.862626 0.539149 +v 0.501494 0.859264 0.540966 +v 0.521683 0.858003 0.542828 +v 0.515442 0.86339 0.540248 +v 0.532278 0.859113 0.542009 +v 0.50586 0.867317 0.53851 +v 0.513738 0.871051 0.53981 +v 0.542314 0.85977 0.538828 +v 0.537913 0.866995 0.538266 +v 0.488735 0.871408 0.539873 +v 0.49162 0.879946 0.53983 +v 0.51071 0.878105 0.540428 +v 0.468984 0.874584 0.540583 +v 0.544376 0.874181 0.534951 +v 0.461443 0.87696 0.537968 +v 0.469696 0.881745 0.541092 +v 0.502214 0.882154 0.537531 +v 0.509536 0.883307 0.540115 +v 0.496718 0.884764 0.536845 +v 0.490005 0.887706 0.538853 +v 0.467725 0.887159 0.538981 +v 0.510121 0.888437 0.538319 +v 0.517057 0.887178 0.541072 +v 0.522298 0.892256 0.538215 +v 0.525001 0.887606 0.54052 +v 0.534924 0.887875 0.537297 +v 0.539155 0.892212 0.531945 +v 0.544594 0.88739 0.533206 +v 0.485546 0.893087 0.537128 +v 0.431837 0.159699 0.539522 +v 0.432155 0.158658 0.530223 +v 0.389893 0.159846 0.528527 +v 0.40427 0.157888 0.52267 +v 0.519582 0.166507 0.525636 +v 0.58757 0.159762 0.536441 +v 0.515471 0.170008 0.52657 +v 0.515286 0.167012 0.504671 +v 0.513157 0.173938 0.529017 +v 0.384264 0.179835 0.530701 +v 0.388961 0.18108 0.536483 +v 0.396196 0.187837 0.53459 +v 0.601121 0.195554 0.527215 +v 0.606383 0.193785 0.522425 +v 0.599069 0.210182 0.521762 +v 0.396644 0.194983 0.525263 +v 0.470083 0.209207 0.53458 +v 0.464914 0.21554 0.52686 +v 0.476968 0.208285 0.526992 +v 0.529439 0.395388 0.537201 +v 0.517797 0.399382 0.539239 +v 0.524323 0.387356 0.530285 +v 0.596276 0.453276 0.533547 +v 0.596693 0.470163 0.535806 +v 0.603515 0.469012 0.525397 +v 0.582284 0.55293 0.536733 +v 0.591283 0.53343 0.531572 +v 0.329494 0.580679 0.52451 +v 0.422908 0.570161 0.534764 +v 0.666268 0.588103 0.534702 +v 0.665522 0.581255 0.523158 +v 0.289491 0.587122 0.530425 +v 0.573391 0.573709 0.53868 +v 0.577167 0.579378 0.530473 +v 0.704768 0.583586 0.528095 +v 0.711521 0.588657 0.525915 +v 0.656361 0.592015 0.526542 +v 0.344707 0.609503 0.532198 +v 0.34472 0.617288 0.531174 +v 0.43219 0.616265 0.533922 +v 0.42985 0.600072 0.530051 +v 0.428819 0.619339 0.527159 +v 0.571176 0.615388 0.533034 +v 0.65671 0.624073 0.531518 +v 0.655742 0.616698 0.533912 +v 0.662931 0.634921 0.529007 +v 0.310088 0.649871 0.53542 +v 0.688415 0.649095 0.531922 +v 0.562978 0.664874 0.528996 +v 0.559314 0.671734 0.526992 +v 0.455472 0.696854 0.534165 +v 0.544983 0.69605 0.53345 +v 0.546448 0.714469 0.53318 +v 0.446468 0.723497 0.536688 +v 0.43613 0.755732 0.53281 +v 0.563548 0.747898 0.534132 +v 0.535591 0.822281 0.538596 +v 0.536473 0.818933 0.536425 +v 0.542491 0.825663 0.536214 +v 0.456371 0.818605 0.531355 +v 0.451096 0.827239 0.531164 +v 0.451232 0.85822 0.53504 +v 0.445671 0.856886 0.529458 +v 0.550219 0.859291 0.533754 +v 0.452446 0.866528 0.533374 +v 0.45325 0.874417 0.533562 +v 0.446657 0.872912 0.528583 +v 0.495033 0.86748 0.538606 +v 0.45441 0.881093 0.534389 +v 0.55492 0.879878 0.527917 +v 0.54929 0.883056 0.532156 +v 0.550568 0.877964 0.531409 +v 0.457034 0.886102 0.534463 +v 0.448136 0.884273 0.529385 +v 0.499547 0.888701 0.535139 +v 0.461925 0.891031 0.533286 +v 0.505074 0.89192 0.534882 +v 0.499872 0.895633 0.533166 +v 0.551376 0.886125 0.529228 +v 0.512806 0.894745 0.535065 +v 0.482239 0.907066 0.529775 +v 0.475994 0.898718 0.532073 +v 0.48252 0.897424 0.534446 +v 0.491252 0.897272 0.533422 +v 0.520051 0.896712 0.534276 +v 0.515267 0.905371 0.530204 +v 0.526414 0.897566 0.532224 +v 0.422425 0.157654 0.520933 +v 0.436016 0.160079 0.523151 +v 0.600501 0.159502 0.532901 +v 0.473835 0.163295 0.519286 +v 0.476949 0.164911 0.526223 +v 0.529021 0.162972 0.507864 +v 0.54098 0.162599 0.519542 +v 0.483261 0.169006 0.524283 +v 0.384676 0.183525 0.522354 +v 0.381333 0.177312 0.527705 +v 0.491748 0.182982 0.522887 +v 0.445867 0.21843 0.530736 +v 0.437503 0.223064 0.529678 +v 0.533109 0.213314 0.529538 +v 0.53764 0.216081 0.52803 +v 0.453227 0.22017 0.528633 +v 0.548997 0.219314 0.529091 +v 0.557976 0.224128 0.529705 +v 0.403201 0.423518 0.525307 +v 0.397287 0.415751 0.51649 +v 0.405449 0.402936 0.520691 +v 0.403151 0.449497 0.531062 +v 0.600406 0.431346 0.524134 +v 0.397478 0.461968 0.525549 +v 0.279635 0.598577 0.526111 +v 0.716118 0.595129 0.521175 +v 0.719203 0.602518 0.517524 +v 0.34487 0.60063 0.528881 +v 0.352589 0.607041 0.521576 +v 0.573858 0.600083 0.5267 +v 0.574305 0.61417 0.524112 +v 0.652582 0.609056 0.530308 +v 0.659055 0.630429 0.528145 +v 0.654409 0.625372 0.525851 +v 0.659649 0.63453 0.522717 +v 0.291255 0.646108 0.530681 +v 0.291483 0.639436 0.515836 +v 0.548482 0.709245 0.530301 +v 0.553436 0.699314 0.525092 +v 0.447353 0.714135 0.526024 +v 0.450682 0.705538 0.529263 +v 0.553712 0.720726 0.525862 +v 0.445276 0.722916 0.526969 +v 0.442468 0.730413 0.531645 +v 0.439211 0.73813 0.526578 +v 0.55722 0.727981 0.525282 +v 0.558486 0.73035 0.531721 +v 0.561415 0.738016 0.53027 +v 0.563279 0.765449 0.525997 +v 0.561042 0.779051 0.529141 +v 0.442652 0.789306 0.528029 +v 0.446049 0.795211 0.527063 +v 0.555493 0.794978 0.532907 +v 0.55253 0.799994 0.52633 +v 0.458928 0.809987 0.533201 +v 0.450853 0.801566 0.528097 +v 0.458551 0.812648 0.531866 +v 0.450773 0.808225 0.525452 +v 0.548503 0.808731 0.526424 +v 0.541955 0.81598 0.531642 +v 0.544148 0.820133 0.531463 +v 0.548773 0.826822 0.532097 +v 0.553821 0.827949 0.526622 +v 0.442869 0.845137 0.527645 +v 0.445944 0.836484 0.530508 +v 0.557836 0.839721 0.526973 +v 0.557155 0.847824 0.529045 +v 0.555888 0.856723 0.527863 +v 0.554133 0.86461 0.52747 +v 0.552676 0.871497 0.529028 +v 0.533881 0.897341 0.528946 +v 0.542446 0.896242 0.524712 +v 0.468951 0.905915 0.524622 +v 0.46681 0.896733 0.529721 +v 0.529819 0.906663 0.525229 +v 0.48841 0.925627 0.52527 +v 0.481678 0.926697 0.523532 +v 0.498587 0.905346 0.530549 +v 0.507058 0.917632 0.527499 +v 0.497003 0.924188 0.526256 +v 0.606545 0.158804 0.526419 +v 0.4666 0.161882 0.521473 +v 0.457705 0.162033 0.522121 +v 0.589568 0.156779 0.512511 +v 0.571547 0.159389 0.517834 +v 0.612258 0.160373 0.524927 +v 0.605871 0.158305 0.515847 +v 0.616366 0.163271 0.524937 +v 0.489436 0.172162 0.509315 +v 0.616376 0.16544 0.515566 +v 0.618943 0.167054 0.525251 +v 0.620383 0.170461 0.527529 +v 0.379996 0.173788 0.52673 +v 0.619463 0.174619 0.525075 +v 0.508727 0.175553 0.515467 +v 0.617579 0.179521 0.524599 +v 0.619074 0.177235 0.515768 +v 0.613416 0.185602 0.523301 +v 0.389285 0.192122 0.518074 +v 0.394515 0.202376 0.516387 +v 0.528567 0.214595 0.520591 +v 0.52753 0.211342 0.527168 +v 0.522162 0.209333 0.522785 +v 0.460441 0.219489 0.524837 +v 0.467116 0.224261 0.519238 +v 0.5331 0.217161 0.521603 +v 0.540383 0.218869 0.525918 +v 0.543126 0.226607 0.52485 +v 0.593909 0.231603 0.521183 +v 0.588255 0.241051 0.522752 +v 0.580703 0.24061 0.525537 +v 0.573154 0.240603 0.527192 +v 0.422815 0.268553 0.523346 +v 0.419525 0.245796 0.525394 +v 0.428374 0.241703 0.527048 +v 0.56633 0.287639 0.523956 +v 0.569458 0.298223 0.526674 +v 0.561978 0.298257 0.5254 +v 0.576636 0.297984 0.525618 +v 0.572198 0.306279 0.529272 +v 0.42034 0.298553 0.525145 +v 0.421447 0.30868 0.528172 +v 0.415652 0.301946 0.523241 +v 0.439168 0.301343 0.525959 +v 0.446079 0.296313 0.521973 +v 0.444029 0.309021 0.524233 +v 0.55866 0.318298 0.524614 +v 0.566154 0.322136 0.526336 +v 0.559537 0.328945 0.522448 +v 0.43251 0.324682 0.525981 +v 0.431621 0.335175 0.522893 +v 0.426994 0.325297 0.525518 +v 0.442926 0.329047 0.522264 +v 0.43723 0.321979 0.525969 +v 0.442336 0.319158 0.524522 +v 0.449177 0.357993 0.521938 +v 0.451532 0.368362 0.524801 +v 0.441179 0.368568 0.525187 +v 0.460606 0.369089 0.523401 +v 0.454365 0.378986 0.529092 +v 0.571859 0.3601 0.522337 +v 0.575023 0.374665 0.524427 +v 0.567019 0.372056 0.525774 +v 0.54532 0.381511 0.530521 +v 0.54008 0.370807 0.524595 +v 0.54917 0.369001 0.525333 +v 0.429764 0.368363 0.523485 +v 0.433357 0.378299 0.527063 +v 0.475526 0.381247 0.525761 +v 0.470223 0.372476 0.521802 +v 0.48068 0.37547 0.518365 +v 0.485363 0.387507 0.526964 +v 0.474003 0.389072 0.53216 +v 0.589748 0.388427 0.520487 +v 0.595423 0.400215 0.519985 +v 0.593779 0.544058 0.521453 +v 0.598495 0.519847 0.524478 +v 0.309745 0.577256 0.524633 +v 0.318257 0.575879 0.519925 +v 0.307169 0.576423 0.518205 +v 0.679894 0.576541 0.520959 +v 0.698013 0.578846 0.518092 +v 0.419353 0.582238 0.520976 +v 0.422785 0.580309 0.528112 +v 0.413545 0.555145 0.528397 +v 0.578953 0.58832 0.521091 +v 0.36155 0.598004 0.505815 +v 0.349048 0.592857 0.517082 +v 0.356451 0.589355 0.501826 +v 0.644021 0.610261 0.51966 +v 0.643965 0.603583 0.519007 +v 0.275245 0.612188 0.527546 +v 0.720757 0.616966 0.518223 +v 0.715487 0.614697 0.50108 +v 0.719403 0.622501 0.517258 +v 0.720674 0.610023 0.517166 +v 0.347493 0.62104 0.524386 +v 0.342659 0.623954 0.529622 +v 0.340751 0.629691 0.525579 +v 0.337377 0.630146 0.53159 +v 0.331941 0.636883 0.533331 +v 0.326024 0.64245 0.530464 +v 0.300995 0.646423 0.523743 +v 0.310407 0.646499 0.523662 +v 0.318662 0.645804 0.527685 +v 0.309441 0.644268 0.513286 +v 0.575217 0.636629 0.523306 +v 0.572288 0.648981 0.525419 +v 0.431536 0.648921 0.526993 +v 0.427796 0.637735 0.523739 +v 0.437059 0.661063 0.52722 +v 0.429815 0.657037 0.517144 +v 0.569154 0.658634 0.523852 +v 0.574665 0.654062 0.516162 +v 0.56444 0.667312 0.523041 +v 0.4416 0.673695 0.524294 +v 0.446369 0.694785 0.524794 +v 0.437455 0.747095 0.524626 +v 0.439481 0.73661 0.519127 +v 0.436784 0.758937 0.525259 +v 0.437463 0.771144 0.526083 +v 0.437022 0.75513 0.515625 +v 0.43958 0.781372 0.527295 +v 0.4409 0.788884 0.519485 +v 0.558067 0.78914 0.531874 +v 0.558146 0.78643 0.52166 +v 0.447099 0.799049 0.523772 +v 0.444863 0.829284 0.52374 +v 0.441736 0.853935 0.523487 +v 0.44182 0.862603 0.521569 +v 0.441477 0.877299 0.523583 +v 0.441582 0.870606 0.522404 +v 0.558663 0.868689 0.522076 +v 0.442271 0.881887 0.523888 +v 0.438262 0.879395 0.51663 +v 0.559963 0.878607 0.521908 +v 0.556273 0.883192 0.52566 +v 0.444794 0.886687 0.523057 +v 0.554241 0.888189 0.523617 +v 0.544775 0.904321 0.51674 +v 0.549476 0.894243 0.520501 +v 0.45676 0.895205 0.525063 +v 0.515653 0.924127 0.524844 +v 0.496644 0.944033 0.521357 +v 0.417568 0.158287 0.511246 +v 0.409619 0.156679 0.510898 +v 0.386245 0.161368 0.526035 +v 0.383137 0.163935 0.525303 +v 0.388829 0.160424 0.518431 +v 0.476364 0.16402 0.506149 +v 0.543575 0.165004 0.511049 +v 0.554359 0.163253 0.517952 +v 0.379896 0.170093 0.525969 +v 0.380887 0.166842 0.525407 +v 0.383366 0.165289 0.516271 +v 0.380377 0.174241 0.517514 +v 0.49367 0.181782 0.514142 +v 0.49349 0.185375 0.516533 +v 0.507377 0.191805 0.514299 +v 0.509761 0.196488 0.515763 +v 0.485025 0.204115 0.516194 +v 0.488696 0.199815 0.510376 +v 0.481217 0.208144 0.517836 +v 0.476582 0.21891 0.514861 +v 0.410163 0.243973 0.521751 +v 0.404307 0.269437 0.515725 +v 0.400532 0.238564 0.516633 +v 0.460099 0.244108 0.519731 +v 0.453364 0.24317 0.52309 +v 0.456683 0.22724 0.524589 +v 0.561368 0.276902 0.522776 +v 0.552643 0.279677 0.521075 +v 0.554621 0.2638 0.522565 +v 0.553676 0.294249 0.522141 +v 0.556359 0.307014 0.524407 +v 0.448282 0.278785 0.520814 +v 0.454246 0.285271 0.518532 +v 0.545269 0.283959 0.518425 +v 0.407681 0.293811 0.516749 +v 0.410248 0.308472 0.519511 +v 0.579923 0.314115 0.527298 +v 0.585683 0.315723 0.522431 +v 0.580632 0.321857 0.523858 +v 0.438402 0.343831 0.521863 +v 0.430328 0.346841 0.521788 +v 0.445382 0.338281 0.520524 +v 0.447249 0.347992 0.52057 +v 0.456535 0.348733 0.518097 +v 0.56604 0.347442 0.521791 +v 0.575553 0.346876 0.520708 +v 0.419037 0.367791 0.520003 +v 0.42625 0.359038 0.521379 +v 0.469234 0.364207 0.51785 +v 0.512901 0.373937 0.513268 +v 0.518656 0.380494 0.52281 +v 0.506604 0.384934 0.52127 +v 0.392696 0.438114 0.515502 +v 0.391511 0.461523 0.515763 +v 0.401197 0.529437 0.517523 +v 0.397709 0.530952 0.50656 +v 0.394245 0.503071 0.512776 +v 0.408651 0.557612 0.516884 +v 0.405939 0.536955 0.524233 +v 0.290199 0.585724 0.518618 +v 0.297681 0.57998 0.516321 +v 0.645319 0.589377 0.507606 +v 0.642603 0.597252 0.513348 +v 0.28228 0.597594 0.510368 +v 0.284361 0.592261 0.516822 +v 0.629727 0.601814 0.5014 +v 0.648967 0.621765 0.521739 +v 0.639874 0.621912 0.515565 +v 0.64402 0.616128 0.518868 +v 0.351204 0.623336 0.519088 +v 0.345736 0.627006 0.521731 +v 0.652141 0.627901 0.520768 +v 0.654986 0.633012 0.519291 +v 0.647465 0.63321 0.51572 +v 0.716025 0.627996 0.514321 +v 0.340748 0.633754 0.520552 +v 0.334038 0.639114 0.518699 +v 0.340969 0.637225 0.516148 +v 0.658437 0.636972 0.517472 +v 0.327182 0.642905 0.515386 +v 0.326696 0.642096 0.522196 +v 0.668756 0.642065 0.518808 +v 0.67585 0.644636 0.522749 +v 0.677048 0.644976 0.515456 +v 0.682432 0.646291 0.522941 +v 0.688604 0.646084 0.520002 +v 0.562385 0.675101 0.519755 +v 0.438271 0.696849 0.51394 +v 0.441543 0.685098 0.519738 +v 0.442096 0.723247 0.51988 +v 0.558884 0.722142 0.519267 +v 0.563136 0.75057 0.525703 +v 0.562943 0.758412 0.515582 +v 0.440461 0.835799 0.516497 +v 0.443365 0.821525 0.517306 +v 0.439845 0.847032 0.519023 +v 0.55964 0.852925 0.521896 +v 0.438052 0.866419 0.514455 +v 0.562239 0.873061 0.51785 +v 0.56276 0.878733 0.514709 +v 0.445109 0.89063 0.516017 +v 0.44985 0.893281 0.520591 +v 0.455589 0.903846 0.517499 +v 0.461498 0.916286 0.516851 +v 0.468236 0.92333 0.518908 +v 0.48041 0.947693 0.516869 +v 0.474087 0.932161 0.519359 +v 0.465689 0.942964 0.512225 +v 0.523978 0.924577 0.522294 +v 0.516885 0.943739 0.519309 +v 0.401967 0.156653 0.508225 +v 0.394273 0.157677 0.507233 +v 0.4377 0.16349 0.51434 +v 0.447791 0.163473 0.518643 +v 0.569179 0.162734 0.510169 +v 0.567139 0.164192 0.502026 +v 0.579597 0.161442 0.5019 +v 0.457031 0.165049 0.511111 +v 0.506123 0.187638 0.511526 +v 0.505575 0.182983 0.508512 +v 0.610425 0.192101 0.518342 +v 0.517744 0.206657 0.51886 +v 0.513605 0.202257 0.516519 +v 0.51079 0.201084 0.504023 +v 0.483553 0.216351 0.505054 +v 0.518816 0.21719 0.508742 +v 0.528577 0.223097 0.515967 +v 0.466033 0.243121 0.516352 +v 0.471224 0.234985 0.513828 +v 0.538584 0.28993 0.514552 +v 0.537526 0.266499 0.515416 +v 0.449298 0.330317 0.519941 +v 0.448352 0.319538 0.521489 +v 0.454571 0.317368 0.518182 +v 0.465363 0.349642 0.514268 +v 0.462865 0.333858 0.514154 +v 0.412331 0.346145 0.516746 +v 0.416307 0.332545 0.51951 +v 0.421128 0.347 0.519864 +v 0.540933 0.338131 0.515451 +v 0.537502 0.345993 0.514734 +v 0.531192 0.34228 0.510267 +v 0.545456 0.350199 0.518795 +v 0.53483 0.354384 0.515724 +v 0.474835 0.352247 0.508441 +v 0.470877 0.357446 0.513666 +v 0.486091 0.369999 0.510184 +v 0.490375 0.375817 0.511956 +v 0.582709 0.378604 0.522129 +v 0.588512 0.367631 0.517184 +v 0.611477 0.441467 0.508382 +v 0.608725 0.470329 0.515107 +v 0.611525 0.478979 0.50588 +v 0.605206 0.494957 0.518782 +v 0.602591 0.51815 0.515189 +v 0.327183 0.576125 0.515145 +v 0.336903 0.577681 0.508036 +v 0.693275 0.576132 0.508504 +v 0.699936 0.579507 0.5091 +v 0.290792 0.586447 0.506537 +v 0.634878 0.612446 0.511094 +v 0.362273 0.605515 0.510447 +v 0.361069 0.61291 0.51349 +v 0.716125 0.604209 0.503415 +v 0.358489 0.620944 0.515038 +v 0.367441 0.619658 0.509204 +v 0.578237 0.603608 0.514519 +v 0.576963 0.621162 0.517101 +v 0.424355 0.611526 0.51293 +v 0.425958 0.624547 0.518702 +v 0.358133 0.630023 0.514052 +v 0.423052 0.63196 0.510966 +v 0.579328 0.62822 0.510262 +v 0.340632 0.641445 0.5121 +v 0.349825 0.639163 0.512646 +v 0.662767 0.640767 0.514931 +v 0.654024 0.643437 0.510895 +v 0.327726 0.644373 0.509695 +v 0.321939 0.644953 0.509557 +v 0.667335 0.643535 0.512272 +v 0.575553 0.661462 0.510826 +v 0.579123 0.649399 0.511143 +v 0.569016 0.676019 0.511885 +v 0.56074 0.688269 0.517607 +v 0.435061 0.6764 0.51441 +v 0.560328 0.706055 0.516704 +v 0.563906 0.714243 0.511298 +v 0.445884 0.806687 0.520824 +v 0.554247 0.799967 0.521374 +v 0.557789 0.817995 0.516857 +v 0.558167 0.832081 0.520956 +v 0.561046 0.838776 0.516966 +v 0.562155 0.858691 0.513989 +v 0.561972 0.848569 0.514983 +v 0.562653 0.866616 0.514834 +v 0.445403 0.899873 0.508238 +v 0.44136 0.8877 0.509999 +v 0.554549 0.898526 0.509077 +v 0.555048 0.890819 0.516338 +v 0.559838 0.885984 0.511629 +v 0.548481 0.914234 0.509526 +v 0.541188 0.922309 0.513354 +v 0.532491 0.923901 0.518375 +v 0.480898 0.961227 0.510979 +v 0.480413 0.969525 0.50525 +v 0.471802 0.962209 0.5067 +v 0.489343 0.959557 0.514238 +v 0.497083 0.956256 0.517005 +v 0.50485 0.954851 0.517673 +v 0.499636 0.964041 0.512814 +v 0.512377 0.956136 0.515867 +v 0.508043 0.962696 0.513264 +v 0.614152 0.162126 0.50477 +v 0.608898 0.158681 0.50479 +v 0.611965 0.15933 0.494826 +v 0.380291 0.18017 0.509473 +v 0.379197 0.173842 0.505923 +v 0.383891 0.187092 0.513066 +v 0.381576 0.188374 0.503287 +v 0.505816 0.190785 0.499932 +v 0.613929 0.192862 0.510692 +v 0.609303 0.207517 0.512505 +v 0.389002 0.210103 0.507983 +v 0.395838 0.21767 0.515047 +v 0.531905 0.243252 0.514834 +v 0.525722 0.241085 0.509593 +v 0.385416 0.442607 0.500523 +v 0.389594 0.472942 0.509925 +v 0.598001 0.542106 0.511974 +v 0.591195 0.563588 0.512877 +v 0.314358 0.57402 0.504503 +v 0.30584 0.576228 0.51118 +v 0.324353 0.574034 0.506925 +v 0.678664 0.573979 0.506028 +v 0.670864 0.575199 0.5096 +v 0.654714 0.581614 0.508502 +v 0.66379 0.577409 0.510918 +v 0.414896 0.580015 0.512716 +v 0.710909 0.589357 0.511712 +v 0.372731 0.605245 0.49925 +v 0.279788 0.608864 0.509983 +v 0.290361 0.627945 0.496183 +v 0.289216 0.620346 0.490005 +v 0.370578 0.637669 0.507923 +v 0.361086 0.63936 0.5106 +v 0.628959 0.631391 0.50922 +v 0.634471 0.638362 0.509815 +v 0.619817 0.642554 0.504069 +v 0.625176 0.624795 0.50758 +v 0.361841 0.647001 0.506965 +v 0.6377 0.645273 0.508206 +v 0.710237 0.633778 0.509862 +v 0.704324 0.638469 0.508152 +v 0.694891 0.644865 0.516986 +v 0.699919 0.642252 0.512452 +v 0.697801 0.639304 0.498627 +v 0.333663 0.644346 0.509314 +v 0.333708 0.648099 0.505137 +v 0.672224 0.645036 0.509973 +v 0.662714 0.648635 0.505827 +v 0.677237 0.645799 0.507698 +v 0.688663 0.64474 0.510355 +v 0.428412 0.664094 0.511815 +v 0.423274 0.651408 0.510395 +v 0.577908 0.672346 0.506895 +v 0.435691 0.710583 0.508825 +v 0.432198 0.698886 0.5045 +v 0.438643 0.725968 0.514498 +v 0.435609 0.731184 0.508829 +v 0.44181 0.806681 0.515638 +v 0.557777 0.797332 0.517123 +v 0.437965 0.846287 0.510226 +v 0.563279 0.846689 0.507561 +v 0.564699 0.864833 0.507714 +v 0.454731 0.920724 0.510565 +v 0.536178 0.94182 0.511239 +v 0.540128 0.953436 0.50417 +v 0.530273 0.955512 0.509565 +v 0.520711 0.956745 0.513177 +v 0.525396 0.965849 0.505478 +v 0.504498 0.970034 0.508214 +v 0.387521 0.159664 0.496687 +v 0.389028 0.159569 0.508633 +v 0.601474 0.15671 0.506971 +v 0.385914 0.162327 0.510503 +v 0.41717 0.160179 0.500648 +v 0.427364 0.161952 0.50933 +v 0.43878 0.165669 0.504931 +v 0.473146 0.163758 0.494659 +v 0.480357 0.164664 0.486348 +v 0.382795 0.165109 0.506038 +v 0.493123 0.176745 0.499691 +v 0.490421 0.172319 0.490908 +v 0.50595 0.178523 0.504765 +v 0.507987 0.174151 0.495906 +v 0.494088 0.180972 0.488826 +v 0.494414 0.181091 0.503778 +v 0.494388 0.184429 0.509017 +v 0.505399 0.181195 0.491519 +v 0.620485 0.181265 0.502797 +v 0.621233 0.175419 0.502728 +v 0.493718 0.189317 0.506873 +v 0.49272 0.191277 0.488547 +v 0.491464 0.195835 0.501572 +v 0.523148 0.267931 0.502949 +v 0.520664 0.238588 0.503982 +v 0.604551 0.278626 0.508469 +v 0.606995 0.326867 0.502802 +v 0.600673 0.319617 0.509278 +v 0.532417 0.306434 0.510096 +v 0.527494 0.329347 0.506308 +v 0.525264 0.301318 0.503779 +v 0.405907 0.34361 0.513473 +v 0.401354 0.339256 0.510127 +v 0.405906 0.321791 0.515109 +v 0.596745 0.345525 0.511399 +v 0.594916 0.309822 0.514413 +v 0.479641 0.348568 0.50197 +v 0.484354 0.357043 0.501928 +v 0.4789 0.363964 0.511663 +v 0.487266 0.364139 0.504462 +v 0.610289 0.411062 0.503708 +v 0.605392 0.407759 0.510981 +v 0.608161 0.374389 0.501177 +v 0.614174 0.413268 0.495898 +v 0.603647 0.526157 0.505662 +v 0.609231 0.504281 0.50048 +v 0.602652 0.538441 0.496342 +v 0.30477 0.576668 0.503379 +v 0.661754 0.575721 0.498618 +v 0.340107 0.576793 0.495161 +v 0.348134 0.581554 0.498475 +v 0.291687 0.589012 0.495317 +v 0.297021 0.582722 0.496562 +v 0.639226 0.587787 0.494769 +v 0.698577 0.579944 0.498665 +v 0.704774 0.584159 0.503885 +v 0.419433 0.597582 0.507251 +v 0.411969 0.582657 0.500819 +v 0.707574 0.589756 0.497081 +v 0.588796 0.581646 0.501285 +v 0.584027 0.58457 0.512398 +v 0.621887 0.61208 0.501367 +v 0.623663 0.618271 0.505145 +v 0.374426 0.626213 0.506513 +v 0.376533 0.622072 0.504661 +v 0.419058 0.626842 0.50305 +v 0.42022 0.639826 0.507427 +v 0.582705 0.623482 0.502081 +v 0.581102 0.638108 0.508402 +v 0.611615 0.624466 0.499938 +v 0.301029 0.640267 0.500468 +v 0.294372 0.635229 0.500137 +v 0.583351 0.643849 0.506983 +v 0.315736 0.644797 0.507295 +v 0.308474 0.643245 0.502926 +v 0.321364 0.647782 0.500954 +v 0.682353 0.64568 0.504698 +v 0.673465 0.649933 0.499231 +v 0.687746 0.644607 0.501336 +v 0.343057 0.646935 0.507557 +v 0.35806 0.65248 0.503974 +v 0.373279 0.656562 0.501418 +v 0.416656 0.646064 0.505912 +v 0.639579 0.651998 0.504557 +v 0.625473 0.660196 0.49988 +v 0.648179 0.653572 0.503064 +v 0.405588 0.668085 0.501758 +v 0.397994 0.657679 0.501603 +v 0.41061 0.661526 0.503701 +v 0.42064 0.666472 0.506595 +v 0.412808 0.652709 0.504682 +v 0.59225 0.653268 0.503628 +v 0.602204 0.660325 0.50107 +v 0.59057 0.665632 0.503228 +v 0.427777 0.672127 0.509267 +v 0.426901 0.680404 0.506417 +v 0.584603 0.680855 0.501943 +v 0.573804 0.701159 0.496189 +v 0.568971 0.704457 0.503011 +v 0.57624 0.693406 0.500452 +v 0.566055 0.806024 0.500181 +v 0.561972 0.800124 0.510328 +v 0.564496 0.779615 0.50683 +v 0.437846 0.803948 0.508381 +v 0.436484 0.858016 0.50663 +v 0.435393 0.845081 0.500243 +v 0.435722 0.868041 0.50637 +v 0.563336 0.887176 0.498696 +v 0.563361 0.879809 0.506729 +v 0.565167 0.872357 0.502986 +v 0.437737 0.881498 0.508333 +v 0.439558 0.892334 0.502003 +v 0.436134 0.875717 0.507036 +v 0.448015 0.920189 0.504059 +v 0.442798 0.910663 0.500306 +v 0.451856 0.939322 0.502538 +v 0.45758 0.949999 0.503932 +v 0.449913 0.951304 0.495944 +v 0.463777 0.95599 0.505766 +v 0.463639 0.964734 0.499394 +v 0.509896 0.976388 0.501079 +v 0.498218 0.976883 0.501851 +v 0.401937 0.156858 0.496432 +v 0.380214 0.168513 0.500345 +v 0.382873 0.16358 0.495085 +v 0.451456 0.166327 0.501641 +v 0.442312 0.164641 0.495882 +v 0.463219 0.164541 0.500065 +v 0.536513 0.164344 0.496421 +v 0.545759 0.165294 0.495755 +v 0.557372 0.16378 0.493243 +v 0.552133 0.16215 0.481003 +v 0.619136 0.166964 0.491203 +v 0.620876 0.17078 0.500053 +v 0.61783 0.166501 0.504497 +v 0.37803 0.172612 0.49307 +v 0.622621 0.174111 0.489825 +v 0.621721 0.18681 0.488102 +v 0.618854 0.18883 0.501219 +v 0.381993 0.197163 0.497738 +v 0.379437 0.189599 0.493689 +v 0.617388 0.198016 0.498726 +v 0.488525 0.210457 0.4942 +v 0.51271 0.211719 0.496228 +v 0.509269 0.199649 0.493954 +v 0.385008 0.221035 0.501414 +v 0.39176 0.233571 0.509074 +v 0.38684 0.252479 0.500285 +v 0.517158 0.341125 0.494143 +v 0.523179 0.342836 0.503142 +v 0.518205 0.348184 0.498927 +v 0.397865 0.364399 0.506073 +v 0.397083 0.332208 0.50638 +v 0.491894 0.36187 0.496098 +v 0.386479 0.476328 0.498401 +v 0.401754 0.55514 0.496597 +v 0.396135 0.534683 0.494294 +v 0.32265 0.573401 0.498494 +v 0.331462 0.574369 0.494907 +v 0.686496 0.574518 0.502292 +v 0.692822 0.576641 0.498788 +v 0.41963 0.607667 0.500903 +v 0.418122 0.614628 0.498309 +v 0.415516 0.621801 0.497726 +v 0.586462 0.622527 0.497907 +v 0.585305 0.6106 0.493618 +v 0.381579 0.628163 0.503664 +v 0.383006 0.622777 0.501384 +v 0.705818 0.628857 0.492187 +v 0.378198 0.633354 0.505502 +v 0.384317 0.641713 0.503059 +v 0.394701 0.640252 0.500382 +v 0.390189 0.649235 0.50181 +v 0.396413 0.629615 0.497211 +v 0.40156 0.635194 0.49871 +v 0.407244 0.630035 0.497829 +v 0.408712 0.641165 0.501797 +v 0.587793 0.634446 0.501594 +v 0.588275 0.644153 0.504087 +v 0.595924 0.643611 0.501883 +v 0.600511 0.634521 0.49955 +v 0.603563 0.643203 0.50143 +v 0.607932 0.648748 0.50209 +v 0.610426 0.64445 0.501941 +v 0.614314 0.649049 0.502364 +v 0.385738 0.656945 0.500985 +v 0.347367 0.652885 0.502971 +v 0.610841 0.654908 0.501722 +v 0.614023 0.662741 0.499301 +v 0.383126 0.663875 0.498749 +v 0.408747 0.67677 0.500367 +v 0.394732 0.669804 0.498778 +v 0.42131 0.684493 0.502054 +v 0.408938 0.683948 0.496561 +v 0.428545 0.691388 0.503119 +v 0.427699 0.699927 0.498035 +v 0.566085 0.726746 0.505618 +v 0.434153 0.752732 0.503881 +v 0.568675 0.742448 0.497463 +v 0.565003 0.756229 0.506278 +v 0.433912 0.826732 0.495914 +v 0.433609 0.793357 0.498058 +v 0.564814 0.861024 0.502646 +v 0.565141 0.848715 0.499046 +v 0.434324 0.864986 0.4968 +v 0.549075 0.951464 0.496926 +v 0.543606 0.961036 0.49642 +v 0.486774 0.976362 0.500904 +v 0.477263 0.976389 0.497148 +v 0.589178 0.158898 0.49468 +v 0.580165 0.16079 0.491275 +v 0.613483 0.16076 0.485429 +v 0.607926 0.158309 0.483246 +v 0.569541 0.161853 0.491182 +v 0.378609 0.171291 0.481413 +v 0.376988 0.177718 0.485836 +v 0.62098 0.206342 0.488636 +v 0.617116 0.215446 0.497252 +v 0.485534 0.230091 0.493689 +v 0.482366 0.240557 0.498671 +v 0.615964 0.258039 0.496193 +v 0.612292 0.230615 0.504257 +v 0.389254 0.359767 0.495631 +v 0.395243 0.380862 0.503668 +v 0.392178 0.393041 0.501358 +v 0.319931 0.574494 0.491174 +v 0.677965 0.574327 0.49363 +v 0.302921 0.578655 0.495892 +v 0.302955 0.581386 0.487531 +v 0.360974 0.588091 0.489641 +v 0.283613 0.602189 0.50153 +v 0.287415 0.595898 0.495946 +v 0.286043 0.607709 0.493389 +v 0.41601 0.605153 0.493027 +v 0.412497 0.593418 0.490002 +v 0.413278 0.602573 0.486574 +v 0.382102 0.606852 0.491247 +v 0.381966 0.614239 0.497603 +v 0.59086 0.622729 0.495682 +v 0.593497 0.613882 0.490044 +v 0.596291 0.624166 0.495596 +v 0.604653 0.618473 0.49382 +v 0.602852 0.625819 0.496809 +v 0.390345 0.623412 0.497197 +v 0.395804 0.620202 0.493305 +v 0.405263 0.620564 0.49305 +v 0.411035 0.623969 0.496066 +v 0.412206 0.615427 0.492268 +v 0.312922 0.646324 0.491169 +v 0.692046 0.642199 0.496173 +v 0.683648 0.647139 0.492363 +v 0.690594 0.642363 0.487002 +v 0.663524 0.658832 0.489473 +v 0.656754 0.659663 0.493289 +v 0.649626 0.65894 0.497501 +v 0.385001 0.671229 0.495481 +v 0.614683 0.67175 0.49426 +v 0.589863 0.68595 0.49633 +v 0.591459 0.692011 0.489512 +v 0.603875 0.681842 0.490969 +v 0.420732 0.698456 0.492875 +v 0.426543 0.705794 0.491693 +v 0.430155 0.773913 0.489391 +v 0.569832 0.798188 0.489022 +v 0.567447 0.828321 0.493372 +v 0.432595 0.847081 0.490884 +v 0.554313 0.916649 0.502562 +v 0.456562 0.966837 0.490524 +v 0.463587 0.972996 0.490576 +v 0.52057 0.975468 0.498491 +v 0.530206 0.973337 0.495465 +v 0.516197 0.98774 0.484165 +v 0.507484 0.987601 0.48753 +v 0.514467 0.982955 0.492249 +v 0.596808 0.15695 0.500035 +v 0.595179 0.158073 0.484179 +v 0.426984 0.159702 0.478038 +v 0.432778 0.16169 0.488892 +v 0.420156 0.160942 0.489387 +v 0.446458 0.162364 0.485858 +v 0.466923 0.164018 0.485516 +v 0.382676 0.207052 0.498393 +v 0.379554 0.202897 0.489998 +v 0.384863 0.413503 0.491737 +v 0.382426 0.423138 0.485762 +v 0.381686 0.446911 0.483873 +v 0.385108 0.479609 0.485741 +v 0.618044 0.446544 0.487297 +v 0.615425 0.48058 0.484778 +v 0.6145 0.477711 0.494055 +v 0.667572 0.575429 0.485229 +v 0.676512 0.576702 0.482736 +v 0.309089 0.577 0.491532 +v 0.339587 0.576762 0.485099 +v 0.407503 0.575701 0.49295 +v 0.403905 0.566924 0.485337 +v 0.650545 0.579556 0.488915 +v 0.659873 0.575993 0.48787 +v 0.693606 0.579677 0.489265 +v 0.294479 0.593531 0.484404 +v 0.38951 0.607517 0.485446 +v 0.38145 0.601337 0.485136 +v 0.408876 0.610155 0.486445 +v 0.411867 0.607355 0.487115 +v 0.619187 0.606794 0.495267 +v 0.609939 0.612615 0.492955 +v 0.297879 0.619391 0.472964 +v 0.290191 0.613813 0.484577 +v 0.399687 0.616762 0.490484 +v 0.396378 0.613769 0.48838 +v 0.402958 0.61402 0.487862 +v 0.602386 0.611383 0.48779 +v 0.300725 0.633636 0.482296 +v 0.350423 0.658141 0.499246 +v 0.635084 0.671084 0.488837 +v 0.394115 0.68055 0.49219 +v 0.375381 0.671869 0.493208 +v 0.61698 0.678651 0.488012 +v 0.408289 0.69012 0.491676 +v 0.410789 0.696188 0.48679 +v 0.581183 0.700248 0.489195 +v 0.589282 0.699192 0.481738 +v 0.572241 0.720549 0.490028 +v 0.57078 0.755556 0.489275 +v 0.568363 0.856943 0.487005 +v 0.438612 0.912492 0.492925 +v 0.564499 0.907638 0.488874 +v 0.560281 0.913002 0.49531 +v 0.555297 0.937299 0.495148 +v 0.556646 0.949371 0.488355 +v 0.450045 0.958996 0.49065 +v 0.443633 0.95054 0.488111 +v 0.547521 0.966649 0.486206 +v 0.539489 0.969713 0.491963 +v 0.476312 0.983229 0.487027 +v 0.469874 0.978339 0.489322 +v 0.485663 0.98655 0.486379 +v 0.491962 0.982598 0.494346 +v 0.496736 0.98784 0.48724 +v 0.408846 0.158673 0.490329 +v 0.403286 0.158125 0.480575 +v 0.385136 0.162048 0.485919 +v 0.52253 0.163485 0.486251 +v 0.528835 0.163287 0.492661 +v 0.533483 0.162742 0.476168 +v 0.61159 0.162799 0.470441 +v 0.61632 0.164549 0.48014 +v 0.61901 0.168575 0.477502 +v 0.489675 0.173459 0.472048 +v 0.486785 0.168922 0.475602 +v 0.37847 0.195103 0.485373 +v 0.377435 0.185854 0.485686 +v 0.509681 0.209147 0.484022 +v 0.507494 0.195599 0.489958 +v 0.507 0.190698 0.483572 +v 0.622267 0.233806 0.483202 +v 0.622685 0.204035 0.480165 +v 0.513018 0.313345 0.479438 +v 0.516025 0.303907 0.488154 +v 0.515381 0.329237 0.488327 +v 0.485894 0.301891 0.484147 +v 0.485149 0.327711 0.487198 +v 0.482462 0.302578 0.492439 +v 0.493477 0.357658 0.487021 +v 0.496747 0.363006 0.48873 +v 0.500454 0.369048 0.496752 +v 0.499706 0.364682 0.488705 +v 0.503008 0.364243 0.489943 +v 0.397433 0.543423 0.48271 +v 0.390822 0.512716 0.485205 +v 0.594013 0.571408 0.492406 +v 0.598312 0.558618 0.486165 +v 0.58751 0.59395 0.490007 +v 0.636859 0.587122 0.486884 +v 0.636499 0.586784 0.479672 +v 0.371896 0.594118 0.484554 +v 0.363405 0.588063 0.48159 +v 0.623674 0.595745 0.484921 +v 0.381147 0.598415 0.479716 +v 0.410507 0.60139 0.481041 +v 0.589181 0.603121 0.484313 +v 0.586721 0.601663 0.48746 +v 0.592 0.599295 0.476153 +v 0.592133 0.603383 0.480881 +v 0.58918 0.595085 0.480447 +v 0.617988 0.601978 0.488145 +v 0.712528 0.60763 0.492898 +v 0.710765 0.601165 0.491492 +v 0.293949 0.607161 0.478105 +v 0.593599 0.606349 0.483174 +v 0.595946 0.602311 0.476222 +v 0.597413 0.608874 0.484838 +v 0.709376 0.612345 0.486472 +v 0.702105 0.610409 0.474123 +v 0.703102 0.618725 0.477811 +v 0.309471 0.634019 0.465334 +v 0.31285 0.642231 0.469552 +v 0.322287 0.652195 0.468647 +v 0.325065 0.650303 0.457313 +v 0.32884 0.655684 0.489916 +v 0.336311 0.657512 0.493788 +v 0.67011 0.656374 0.486416 +v 0.656991 0.665872 0.480089 +v 0.674274 0.654715 0.482551 +v 0.356464 0.665736 0.493595 +v 0.618527 0.683777 0.481683 +v 0.575445 0.706457 0.489442 +v 0.576327 0.710226 0.482389 +v 0.424807 0.709118 0.483645 +v 0.427855 0.722784 0.485593 +v 0.427905 0.757687 0.47655 +v 0.428643 0.760474 0.483503 +v 0.572588 0.760382 0.476333 +v 0.573046 0.799358 0.473894 +v 0.572065 0.775991 0.481505 +v 0.428132 0.803437 0.478099 +v 0.432201 0.865495 0.486476 +v 0.434143 0.903704 0.484357 +v 0.430589 0.889859 0.47604 +v 0.437871 0.936033 0.484295 +v 0.557799 0.955295 0.481446 +v 0.562516 0.945865 0.48006 +v 0.449924 0.965478 0.483107 +v 0.448236 0.969434 0.47291 +v 0.442993 0.96004 0.476378 +v 0.462304 0.97946 0.478907 +v 0.535513 0.977934 0.484893 +v 0.540994 0.979035 0.475478 +v 0.531072 0.984841 0.476816 +v 0.587393 0.159055 0.466164 +v 0.598635 0.158084 0.472537 +v 0.573593 0.159686 0.479515 +v 0.51863 0.164591 0.481668 +v 0.515438 0.166898 0.480331 +v 0.377666 0.18465 0.475889 +v 0.62211 0.185029 0.476651 +v 0.621891 0.193854 0.477089 +v 0.487627 0.23613 0.485385 +v 0.382546 0.329015 0.483467 +v 0.378594 0.264809 0.481588 +v 0.382976 0.307732 0.488838 +v 0.489834 0.350369 0.486439 +v 0.494146 0.354355 0.47919 +v 0.386699 0.490955 0.473011 +v 0.592587 0.582038 0.47752 +v 0.600143 0.552732 0.47946 +v 0.601133 0.547692 0.470624 +v 0.609297 0.51528 0.479912 +v 0.30938 0.580028 0.48248 +v 0.315208 0.577311 0.484789 +v 0.65816 0.578593 0.477269 +v 0.638156 0.587142 0.471728 +v 0.624391 0.593204 0.471856 +v 0.707685 0.595216 0.489591 +v 0.702114 0.591305 0.483483 +v 0.60986 0.60086 0.476624 +v 0.612983 0.601472 0.481289 +v 0.606084 0.603728 0.480022 +v 0.7041 0.599319 0.480021 +v 0.394888 0.605674 0.478653 +v 0.39578 0.609905 0.484459 +v 0.400076 0.610514 0.484234 +v 0.404889 0.610405 0.484288 +v 0.406117 0.606288 0.480283 +v 0.601681 0.606011 0.481669 +v 0.601885 0.6031 0.476692 +v 0.328646 0.657378 0.483119 +v 0.32518 0.655576 0.476757 +v 0.348734 0.670075 0.478542 +v 0.366267 0.675198 0.486186 +v 0.398412 0.692872 0.481724 +v 0.417439 0.703643 0.481666 +v 0.422471 0.710009 0.475542 +v 0.571837 0.871823 0.470397 +v 0.570778 0.872489 0.475905 +v 0.574002 0.843326 0.472738 +v 0.567773 0.897348 0.48181 +v 0.565993 0.930089 0.478779 +v 0.439091 0.95008 0.479059 +v 0.480094 0.989265 0.477457 +v 0.459028 0.163578 0.480891 +v 0.449333 0.161308 0.475577 +v 0.464286 0.16268 0.471568 +v 0.477943 0.163424 0.466236 +v 0.483114 0.165751 0.474421 +v 0.482428 0.166555 0.458824 +v 0.524297 0.162725 0.463416 +v 0.621301 0.172508 0.478303 +v 0.618032 0.171707 0.466203 +v 0.377312 0.204074 0.480694 +v 0.511907 0.236979 0.483599 +v 0.510829 0.237588 0.475275 +v 0.487304 0.27097 0.480308 +v 0.488078 0.305103 0.475329 +v 0.380681 0.329441 0.473367 +v 0.382512 0.350955 0.477958 +v 0.383088 0.376866 0.473168 +v 0.497514 0.357801 0.474706 +v 0.500073 0.359868 0.471444 +v 0.499287 0.360828 0.479937 +v 0.617896 0.415389 0.480243 +v 0.616871 0.383777 0.471712 +v 0.61838 0.417033 0.47084 +v 0.615912 0.480231 0.475759 +v 0.402765 0.563213 0.474955 +v 0.322292 0.578017 0.478715 +v 0.347887 0.580833 0.476407 +v 0.337966 0.578406 0.476232 +v 0.685154 0.57964 0.480786 +v 0.675422 0.580502 0.472923 +v 0.306468 0.584974 0.477743 +v 0.691597 0.584487 0.478645 +v 0.311814 0.590886 0.466806 +v 0.302804 0.592104 0.474625 +v 0.298829 0.599897 0.473718 +v 0.590507 0.593311 0.47305 +v 0.40388 0.603688 0.474276 +v 0.407676 0.602453 0.477215 +v 0.409488 0.59824 0.474284 +v 0.390708 0.60209 0.474208 +v 0.398459 0.603875 0.472407 +v 0.679881 0.649875 0.474192 +v 0.676351 0.653553 0.478218 +v 0.337 0.664088 0.463448 +v 0.662225 0.663972 0.474944 +v 0.3757 0.683286 0.479056 +v 0.427166 0.788407 0.468971 +v 0.428155 0.764905 0.468133 +v 0.573485 0.726662 0.474544 +v 0.572478 0.757202 0.470344 +v 0.427549 0.813694 0.472718 +v 0.426325 0.821576 0.47381 +v 0.428592 0.884494 0.465353 +v 0.426446 0.846859 0.47047 +v 0.429003 0.882893 0.470511 +v 0.430444 0.924109 0.466635 +v 0.436686 0.952254 0.469114 +v 0.553834 0.963922 0.478716 +v 0.549092 0.971771 0.475495 +v 0.5597 0.958711 0.472051 +v 0.545334 0.97826 0.466886 +v 0.513521 0.99193 0.475299 +v 0.521729 0.989041 0.476765 +v 0.500983 0.991223 0.480555 +v 0.402183 0.158855 0.466281 +v 0.412397 0.159303 0.464537 +v 0.381537 0.171053 0.46917 +v 0.382654 0.166229 0.476722 +v 0.487757 0.1756 0.456043 +v 0.491521 0.178381 0.471124 +v 0.622295 0.177657 0.478119 +v 0.492547 0.184511 0.476542 +v 0.490028 0.19031 0.468803 +v 0.489382 0.243098 0.46758 +v 0.489134 0.239252 0.476761 +v 0.489599 0.214809 0.469565 +v 0.509085 0.345572 0.4728 +v 0.508518 0.347668 0.462409 +v 0.510683 0.332181 0.470804 +v 0.500075 0.361452 0.462427 +v 0.501911 0.360831 0.466056 +v 0.383771 0.393236 0.466937 +v 0.383004 0.400796 0.471082 +v 0.381657 0.419036 0.475456 +v 0.61534 0.479358 0.466155 +v 0.618994 0.448067 0.46954 +v 0.392414 0.516409 0.463359 +v 0.385365 0.478946 0.462795 +v 0.324575 0.583347 0.467501 +v 0.330326 0.579337 0.473117 +v 0.648991 0.5839 0.468933 +v 0.657733 0.582918 0.466395 +v 0.356989 0.586818 0.467227 +v 0.359034 0.585721 0.475105 +v 0.370445 0.591712 0.473846 +v 0.698306 0.596158 0.47362 +v 0.695169 0.590757 0.475023 +v 0.686667 0.58966 0.467899 +v 0.381985 0.597617 0.47315 +v 0.378555 0.596668 0.465451 +v 0.411329 0.597741 0.461331 +v 0.409883 0.597102 0.467387 +v 0.408599 0.599622 0.465424 +v 0.408681 0.586011 0.470323 +v 0.303221 0.608428 0.46549 +v 0.401745 0.602792 0.468556 +v 0.600121 0.60183 0.472663 +v 0.60488 0.601485 0.473121 +v 0.598153 0.601239 0.469696 +v 0.612298 0.59858 0.471525 +v 0.698954 0.602928 0.471037 +v 0.694102 0.608755 0.463921 +v 0.643942 0.674255 0.473391 +v 0.381211 0.688231 0.471094 +v 0.616605 0.688107 0.474363 +v 0.597079 0.697352 0.476329 +v 0.622682 0.686194 0.465775 +v 0.582315 0.706535 0.47621 +v 0.576152 0.712744 0.475287 +v 0.57528 0.71449 0.468355 +v 0.428613 0.782749 0.457402 +v 0.429137 0.754178 0.46311 +v 0.426568 0.81413 0.467771 +v 0.426796 0.809008 0.469256 +v 0.422809 0.821871 0.468403 +v 0.422155 0.827095 0.470305 +v 0.417032 0.830029 0.462534 +v 0.421562 0.832365 0.46779 +v 0.579025 0.832189 0.467378 +v 0.57774 0.826187 0.46964 +v 0.422883 0.837353 0.464998 +v 0.429319 0.922395 0.456265 +v 0.428456 0.886412 0.459092 +v 0.574173 0.851288 0.466121 +v 0.571642 0.886381 0.46472 +v 0.566342 0.942165 0.472165 +v 0.485918 0.993523 0.468616 +v 0.476053 0.9909 0.467203 +v 0.505128 0.993619 0.473264 +v 0.495736 0.994348 0.47083 +v 0.396665 0.160181 0.46396 +v 0.407165 0.159701 0.449115 +v 0.425825 0.159366 0.465524 +v 0.438419 0.159487 0.46944 +v 0.600776 0.159103 0.464188 +v 0.388821 0.162075 0.473456 +v 0.393825 0.163724 0.455567 +v 0.448087 0.16029 0.463468 +v 0.468133 0.160514 0.454828 +v 0.473165 0.161835 0.450297 +v 0.575244 0.159342 0.467268 +v 0.57699 0.158769 0.45318 +v 0.518359 0.166494 0.457683 +v 0.512354 0.170045 0.477691 +v 0.510007 0.173939 0.472887 +v 0.508363 0.178357 0.471381 +v 0.513388 0.174273 0.453846 +v 0.507364 0.183939 0.475861 +v 0.620263 0.182016 0.466807 +v 0.486685 0.188696 0.453012 +v 0.488164 0.198206 0.463497 +v 0.494356 0.352722 0.472436 +v 0.491173 0.345385 0.470832 +v 0.493091 0.350929 0.464468 +v 0.617926 0.42514 0.461526 +v 0.339548 0.58356 0.465512 +v 0.667253 0.583033 0.465858 +v 0.658363 0.589546 0.456738 +v 0.677084 0.585821 0.465476 +v 0.636088 0.59081 0.46232 +v 0.587911 0.592897 0.45895 +v 0.589822 0.592845 0.466302 +v 0.589227 0.58644 0.459704 +v 0.59117 0.59572 0.471056 +v 0.592533 0.598211 0.469015 +v 0.615072 0.597809 0.46575 +v 0.408748 0.601525 0.461234 +v 0.405309 0.601954 0.465599 +v 0.699146 0.627661 0.477164 +v 0.691976 0.627613 0.4649 +v 0.692165 0.636083 0.473047 +v 0.681336 0.646241 0.467255 +v 0.666831 0.658801 0.461438 +v 0.351703 0.67358 0.458323 +v 0.345706 0.668313 0.454557 +v 0.409669 0.702596 0.466011 +v 0.387419 0.691821 0.462292 +v 0.427452 0.715461 0.461267 +v 0.425132 0.713688 0.468405 +v 0.428198 0.726564 0.465439 +v 0.421187 0.709231 0.4677 +v 0.430623 0.745545 0.456733 +v 0.573032 0.78561 0.46405 +v 0.571683 0.756506 0.463976 +v 0.4244 0.807581 0.462528 +v 0.425571 0.803342 0.467333 +v 0.576466 0.807555 0.460919 +v 0.574514 0.807437 0.46748 +v 0.575463 0.802267 0.464978 +v 0.575573 0.81735 0.469092 +v 0.580449 0.822265 0.462868 +v 0.579222 0.836679 0.463512 +v 0.583909 0.832769 0.459686 +v 0.57742 0.840365 0.4599 +v 0.428915 0.887863 0.452629 +v 0.426396 0.852348 0.461809 +v 0.432613 0.94511 0.462403 +v 0.435897 0.954658 0.458032 +v 0.565012 0.950067 0.467521 +v 0.561984 0.958856 0.462439 +v 0.453906 0.976709 0.468923 +v 0.44614 0.970454 0.460531 +v 0.525408 0.990206 0.467804 +v 0.510066 0.995097 0.465546 +v 0.45269 0.159869 0.458706 +v 0.459456 0.159641 0.456829 +v 0.452656 0.157418 0.442877 +v 0.551732 0.16077 0.467408 +v 0.562865 0.159631 0.471466 +v 0.380046 0.18473 0.46407 +v 0.378746 0.193764 0.466014 +v 0.380296 0.206403 0.452184 +v 0.378186 0.203977 0.461034 +v 0.377617 0.224924 0.458217 +v 0.510124 0.189553 0.465276 +v 0.514008 0.188442 0.450334 +v 0.512108 0.197572 0.459431 +v 0.487487 0.206318 0.457468 +v 0.512297 0.235977 0.456044 +v 0.511163 0.214234 0.461922 +v 0.51101 0.239528 0.465718 +v 0.381656 0.340561 0.462117 +v 0.378406 0.275862 0.461268 +v 0.379214 0.30189 0.468227 +v 0.497518 0.360948 0.458528 +v 0.49941 0.364139 0.454531 +v 0.384257 0.401305 0.459531 +v 0.384256 0.381053 0.460952 +v 0.381441 0.423435 0.467767 +v 0.381894 0.449051 0.462454 +v 0.382365 0.423553 0.460536 +v 0.386169 0.469792 0.453293 +v 0.608888 0.507956 0.458611 +v 0.613449 0.477908 0.455009 +v 0.401806 0.55647 0.466148 +v 0.400921 0.546203 0.456664 +v 0.589752 0.573729 0.449733 +v 0.594249 0.568014 0.459793 +v 0.331136 0.590239 0.457281 +v 0.320736 0.589777 0.461579 +v 0.619802 0.597826 0.459535 +v 0.628033 0.597921 0.453327 +v 0.319234 0.598332 0.455855 +v 0.679779 0.592963 0.459993 +v 0.591566 0.599078 0.461646 +v 0.594966 0.600646 0.465989 +v 0.606732 0.601883 0.459913 +v 0.400624 0.603646 0.462463 +v 0.400876 0.606278 0.455479 +v 0.393178 0.604611 0.456829 +v 0.599222 0.602201 0.462414 +v 0.600626 0.605361 0.454325 +v 0.306755 0.617858 0.460969 +v 0.314067 0.613342 0.454102 +v 0.679336 0.643758 0.458534 +v 0.656887 0.664288 0.453294 +v 0.651921 0.669608 0.457323 +v 0.605197 0.694916 0.457873 +v 0.633524 0.680243 0.457568 +v 0.397939 0.695705 0.453925 +v 0.371008 0.68357 0.456958 +v 0.585516 0.704735 0.458163 +v 0.59526 0.698176 0.452037 +v 0.421967 0.708911 0.460188 +v 0.570072 0.756045 0.457328 +v 0.571284 0.727967 0.460602 +v 0.424912 0.798576 0.463706 +v 0.422193 0.800884 0.457903 +v 0.424151 0.796705 0.458257 +v 0.574298 0.795146 0.456573 +v 0.575778 0.798048 0.461397 +v 0.577906 0.802333 0.457061 +v 0.579415 0.803368 0.446518 +v 0.578425 0.806952 0.452234 +v 0.579276 0.812804 0.451273 +v 0.423785 0.817426 0.463808 +v 0.42419 0.813923 0.459092 +v 0.419555 0.821234 0.460492 +v 0.415932 0.827041 0.457964 +v 0.414393 0.831727 0.45414 +v 0.421915 0.839653 0.458592 +v 0.570751 0.921726 0.460109 +v 0.571456 0.896964 0.455004 +v 0.569525 0.939001 0.454374 +v 0.568624 0.940114 0.463806 +v 0.43057 0.938998 0.45771 +v 0.431248 0.941617 0.449415 +v 0.460445 0.984367 0.455401 +v 0.460101 0.982409 0.466604 +v 0.46669 0.987281 0.463574 +v 0.472127 0.990766 0.456231 +v 0.492902 0.995929 0.460021 +v 0.425453 0.159008 0.453381 +v 0.382364 0.177341 0.46051 +v 0.386712 0.171962 0.454213 +v 0.617221 0.177372 0.458772 +v 0.613577 0.173452 0.45283 +v 0.384568 0.185915 0.45069 +v 0.486981 0.219439 0.453062 +v 0.483695 0.206029 0.446369 +v 0.493902 0.355874 0.45821 +v 0.49004 0.348884 0.455239 +v 0.507269 0.3549 0.455704 +v 0.510764 0.347093 0.453671 +v 0.385107 0.420085 0.451765 +v 0.600474 0.533119 0.448091 +v 0.60215 0.538294 0.459949 +v 0.34267 0.591288 0.454785 +v 0.350856 0.590893 0.455988 +v 0.670266 0.597787 0.451795 +v 0.679861 0.601529 0.454296 +v 0.588133 0.596725 0.457383 +v 0.588678 0.60156 0.454121 +v 0.410435 0.604154 0.454751 +v 0.406551 0.606948 0.452833 +v 0.413669 0.60949 0.447228 +v 0.412143 0.600858 0.456832 +v 0.403 0.610536 0.448478 +v 0.308309 0.62601 0.461268 +v 0.365408 0.679452 0.45162 +v 0.576973 0.71094 0.461259 +v 0.577962 0.70761 0.454957 +v 0.42661 0.711995 0.456055 +v 0.429986 0.715208 0.454371 +v 0.573465 0.715551 0.461849 +v 0.432023 0.725899 0.451786 +v 0.432958 0.712573 0.447114 +v 0.571399 0.715168 0.455303 +v 0.421137 0.813464 0.4479 +v 0.423199 0.810244 0.454616 +v 0.58196 0.820961 0.454454 +v 0.584682 0.828185 0.457136 +v 0.585908 0.832315 0.452045 +v 0.563311 0.957371 0.452853 +v 0.558348 0.966094 0.455161 +v 0.544316 0.980386 0.44605 +v 0.546552 0.978616 0.457261 +v 0.55242 0.973376 0.452288 +v 0.537592 0.985282 0.458874 +v 0.52972 0.98988 0.449628 +v 0.527503 0.990716 0.458806 +v 0.517719 0.994181 0.460193 +v 0.509711 0.996133 0.455604 +v 0.438961 0.158319 0.451158 +v 0.543342 0.160581 0.4624 +v 0.555658 0.158252 0.452138 +v 0.537335 0.159951 0.456193 +v 0.401721 0.16469 0.439488 +v 0.392787 0.168138 0.446872 +v 0.616879 0.184919 0.455196 +v 0.612474 0.185275 0.444492 +v 0.616982 0.193003 0.452808 +v 0.61772 0.202873 0.44986 +v 0.621136 0.201927 0.460541 +v 0.488206 0.242977 0.45852 +v 0.48598 0.25097 0.450253 +v 0.485426 0.346851 0.445837 +v 0.487064 0.334204 0.452033 +v 0.40839 0.565757 0.449063 +v 0.400424 0.531554 0.444693 +v 0.341985 0.598018 0.447882 +v 0.357551 0.591076 0.457983 +v 0.364407 0.598187 0.449418 +v 0.584683 0.594852 0.45194 +v 0.368122 0.593901 0.459961 +v 0.381275 0.600313 0.457433 +v 0.419742 0.60416 0.4456 +v 0.415592 0.591322 0.449765 +v 0.414753 0.599014 0.454295 +v 0.32131 0.608879 0.449566 +v 0.329654 0.605989 0.445965 +v 0.380133 0.602951 0.450612 +v 0.324683 0.619116 0.444478 +v 0.687813 0.617642 0.456657 +v 0.685711 0.608978 0.455714 +v 0.680573 0.637266 0.454687 +v 0.685369 0.627287 0.455754 +v 0.645612 0.670122 0.448729 +v 0.653853 0.662098 0.446389 +v 0.638706 0.676185 0.451788 +v 0.427552 0.706646 0.447618 +v 0.418083 0.703893 0.451396 +v 0.424438 0.708622 0.453765 +v 0.433628 0.750942 0.447444 +v 0.567559 0.754987 0.450064 +v 0.565703 0.723857 0.445376 +v 0.56403 0.749934 0.442684 +v 0.570603 0.78389 0.453461 +v 0.425765 0.794875 0.45273 +v 0.428393 0.794606 0.446897 +v 0.42261 0.798842 0.449894 +v 0.573848 0.795218 0.449934 +v 0.421803 0.805835 0.454131 +v 0.421123 0.802874 0.44965 +v 0.423504 0.841167 0.453015 +v 0.418197 0.83764 0.45138 +v 0.428267 0.854485 0.450269 +v 0.424696 0.840907 0.447366 +v 0.578085 0.840792 0.45357 +v 0.582202 0.83712 0.447605 +v 0.576561 0.840802 0.447657 +v 0.573196 0.85356 0.453999 +v 0.569854 0.919675 0.442663 +v 0.570664 0.885521 0.447752 +v 0.569855 0.874915 0.444139 +v 0.435004 0.952701 0.447638 +v 0.439924 0.962426 0.452506 +v 0.445481 0.969544 0.44676 +v 0.555033 0.970048 0.444648 +v 0.512307 0.995103 0.4449 +v 0.501937 0.996554 0.451852 +v 0.427495 0.157465 0.443279 +v 0.558309 0.156427 0.440292 +v 0.567722 0.157359 0.445507 +v 0.530312 0.161228 0.446386 +v 0.533517 0.16024 0.450566 +v 0.580063 0.158138 0.441684 +v 0.603054 0.161321 0.457634 +v 0.592004 0.159904 0.445052 +v 0.605555 0.165356 0.45068 +v 0.483485 0.174733 0.445316 +v 0.485456 0.180535 0.446942 +v 0.482618 0.188347 0.442627 +v 0.485663 0.298358 0.449682 +v 0.487884 0.306727 0.457737 +v 0.514303 0.3472 0.44521 +v 0.513208 0.333013 0.451685 +v 0.505764 0.360438 0.451378 +v 0.502834 0.366534 0.447818 +v 0.508082 0.362927 0.444345 +v 0.389628 0.345138 0.439874 +v 0.386082 0.348609 0.446595 +v 0.390179 0.380756 0.443043 +v 0.615538 0.447221 0.45214 +v 0.61489 0.417165 0.452101 +v 0.611214 0.413597 0.443579 +v 0.614436 0.384558 0.453344 +v 0.611003 0.469993 0.443669 +v 0.339831 0.6044 0.44329 +v 0.352239 0.605689 0.440263 +v 0.581586 0.590684 0.443787 +v 0.579835 0.599348 0.444898 +v 0.619306 0.606168 0.445335 +v 0.635497 0.601378 0.445691 +v 0.583567 0.606292 0.446067 +v 0.589138 0.608117 0.447978 +v 0.328034 0.627687 0.441719 +v 0.333444 0.624252 0.438181 +v 0.667368 0.621271 0.440836 +v 0.675648 0.611094 0.447849 +v 0.663311 0.61425 0.440261 +v 0.677944 0.627808 0.44837 +v 0.319003 0.635405 0.452674 +v 0.670051 0.646261 0.448673 +v 0.32785 0.645604 0.448474 +v 0.336925 0.655502 0.447604 +v 0.358774 0.673854 0.448288 +v 0.348165 0.665434 0.447514 +v 0.631755 0.676382 0.444498 +v 0.37527 0.680773 0.443625 +v 0.59629 0.694319 0.445168 +v 0.582203 0.703177 0.449753 +v 0.573179 0.70945 0.450977 +v 0.568995 0.712506 0.448382 +v 0.565928 0.708232 0.441372 +v 0.43863 0.753873 0.438979 +v 0.435542 0.774895 0.442639 +v 0.438928 0.785524 0.436654 +v 0.433098 0.792283 0.442636 +v 0.429156 0.798625 0.439657 +v 0.572179 0.795344 0.445442 +v 0.577311 0.798614 0.445921 +v 0.421618 0.802842 0.442089 +v 0.417306 0.823236 0.451819 +v 0.415829 0.826201 0.443452 +v 0.418561 0.819502 0.444098 +v 0.585008 0.832929 0.446076 +v 0.582961 0.832882 0.44019 +v 0.585219 0.827841 0.444162 +v 0.57497 0.838868 0.441898 +v 0.571071 0.852927 0.444625 +v 0.568954 0.937931 0.443722 +v 0.566995 0.94772 0.44802 +v 0.562531 0.956679 0.442033 +v 0.475329 0.991607 0.445733 +v 0.466359 0.987933 0.448136 +v 0.493454 0.995868 0.448029 +v 0.476523 0.164052 0.447457 +v 0.469143 0.161722 0.439862 +v 0.479307 0.166954 0.44606 +v 0.534714 0.161449 0.436162 +v 0.526022 0.163208 0.445072 +v 0.526809 0.166729 0.436354 +v 0.522166 0.16616 0.444376 +v 0.519374 0.169994 0.443435 +v 0.59899 0.168184 0.434844 +v 0.60769 0.171038 0.444655 +v 0.393043 0.173182 0.439993 +v 0.47977 0.170458 0.442217 +v 0.477131 0.174648 0.435473 +v 0.473618 0.166889 0.436727 +v 0.387314 0.195832 0.442405 +v 0.390144 0.187369 0.439204 +v 0.480917 0.329176 0.439026 +v 0.48302 0.285405 0.443259 +v 0.479069 0.278159 0.43722 +v 0.514997 0.253341 0.448203 +v 0.514516 0.299925 0.449567 +v 0.518028 0.285266 0.441704 +v 0.387729 0.448557 0.444242 +v 0.389988 0.423452 0.440104 +v 0.415035 0.575127 0.43995 +v 0.636798 0.610799 0.436974 +v 0.647464 0.599952 0.445832 +v 0.658331 0.598781 0.447898 +v 0.659436 0.607397 0.441893 +v 0.578547 0.605265 0.442586 +v 0.577365 0.612632 0.438398 +v 0.604796 0.61007 0.445991 +v 0.609348 0.615045 0.438634 +v 0.379513 0.606097 0.445375 +v 0.38277 0.611843 0.440023 +v 0.396946 0.613021 0.443599 +v 0.409097 0.616684 0.441419 +v 0.590455 0.616457 0.440349 +v 0.595742 0.609965 0.447756 +v 0.668419 0.629193 0.441095 +v 0.665654 0.637832 0.440558 +v 0.32746 0.636638 0.444323 +v 0.66127 0.646541 0.440909 +v 0.657918 0.654621 0.443322 +v 0.350429 0.661038 0.44076 +v 0.64431 0.662703 0.438975 +v 0.614958 0.682223 0.440382 +v 0.592963 0.690499 0.438524 +v 0.40557 0.69601 0.446498 +v 0.423413 0.697094 0.439352 +v 0.430211 0.702766 0.441579 +v 0.432299 0.697 0.436296 +v 0.432734 0.707327 0.44335 +v 0.437041 0.707545 0.439459 +v 0.563548 0.774424 0.440998 +v 0.559985 0.753082 0.436103 +v 0.561876 0.785302 0.437844 +v 0.566867 0.791736 0.443049 +v 0.578298 0.803122 0.440075 +v 0.419377 0.81456 0.438648 +v 0.582959 0.82014 0.444877 +v 0.582744 0.819748 0.437495 +v 0.414396 0.830817 0.445911 +v 0.416041 0.829116 0.438702 +v 0.41505 0.834064 0.449066 +v 0.417303 0.835756 0.444272 +v 0.420711 0.837404 0.441867 +v 0.41779 0.833107 0.438773 +v 0.425693 0.838111 0.441552 +v 0.430103 0.889024 0.445838 +v 0.431421 0.886263 0.439969 +v 0.431362 0.925683 0.44109 +v 0.566525 0.936594 0.432485 +v 0.433267 0.945009 0.441851 +v 0.435872 0.946896 0.433599 +v 0.559258 0.956472 0.430614 +v 0.556824 0.96518 0.437212 +v 0.459635 0.983102 0.444674 +v 0.541591 0.98038 0.435763 +v 0.534341 0.986541 0.441135 +v 0.42091 0.157978 0.438924 +v 0.436151 0.156339 0.436565 +v 0.448549 0.157509 0.433979 +v 0.546117 0.1575 0.441614 +v 0.557352 0.156652 0.433918 +v 0.417249 0.158933 0.436147 +v 0.582129 0.158808 0.434828 +v 0.517546 0.174703 0.442696 +v 0.517402 0.180708 0.441398 +v 0.522209 0.175582 0.434808 +v 0.394026 0.17968 0.434881 +v 0.399655 0.175209 0.42946 +v 0.609339 0.177808 0.441152 +v 0.397197 0.185937 0.429893 +v 0.518953 0.188371 0.44012 +v 0.382246 0.261865 0.445818 +v 0.386759 0.259755 0.437769 +v 0.383089 0.22305 0.444118 +v 0.484089 0.352076 0.440443 +v 0.485521 0.359591 0.43743 +v 0.491493 0.360812 0.445168 +v 0.478097 0.359346 0.430224 +v 0.48759 0.368736 0.434344 +v 0.514387 0.356855 0.439902 +v 0.512073 0.36582 0.437111 +v 0.516483 0.369443 0.430572 +v 0.509549 0.373695 0.434062 +v 0.392635 0.408525 0.43826 +v 0.39547 0.39865 0.435269 +v 0.606002 0.40715 0.435859 +v 0.607271 0.431258 0.433779 +v 0.602831 0.44095 0.423016 +v 0.608029 0.45329 0.433718 +v 0.391884 0.477381 0.440207 +v 0.606109 0.478046 0.434529 +v 0.595813 0.532471 0.435674 +v 0.591437 0.555993 0.440256 +v 0.396853 0.501947 0.436855 +v 0.403117 0.519892 0.430485 +v 0.423529 0.582023 0.429964 +v 0.416027 0.557258 0.427159 +v 0.585012 0.575641 0.440135 +v 0.577178 0.584737 0.432696 +v 0.421491 0.612966 0.440566 +v 0.426995 0.613185 0.436406 +v 0.649532 0.618342 0.434123 +v 0.41759 0.617251 0.439515 +v 0.4172 0.623736 0.434573 +v 0.656918 0.631446 0.434451 +v 0.33473 0.636167 0.438729 +v 0.650303 0.648132 0.434435 +v 0.364641 0.666969 0.435763 +v 0.35172 0.655171 0.435408 +v 0.63056 0.665425 0.432789 +v 0.630416 0.671443 0.437701 +v 0.379205 0.677349 0.436922 +v 0.391867 0.686581 0.440685 +v 0.40921 0.692517 0.439845 +v 0.562741 0.702186 0.435357 +v 0.573269 0.698995 0.438053 +v 0.429438 0.803548 0.434358 +v 0.425297 0.802538 0.43575 +v 0.422783 0.80742 0.433304 +v 0.422658 0.803118 0.436989 +v 0.571024 0.797515 0.441252 +v 0.570805 0.802062 0.436023 +v 0.575079 0.802283 0.437228 +v 0.420953 0.807734 0.437239 +v 0.567602 0.803756 0.435198 +v 0.564618 0.804807 0.436671 +v 0.566005 0.809554 0.434244 +v 0.561647 0.804014 0.434975 +v 0.563069 0.812117 0.434863 +v 0.564409 0.831552 0.434678 +v 0.564642 0.848052 0.433963 +v 0.5679 0.834736 0.436482 +v 0.581313 0.827689 0.433938 +v 0.579182 0.833461 0.436805 +v 0.435423 0.832812 0.434441 +v 0.431461 0.836676 0.439204 +v 0.434248 0.847415 0.43734 +v 0.56713 0.884136 0.434848 +v 0.549924 0.972804 0.434605 +v 0.453129 0.976574 0.440662 +v 0.44708 0.968115 0.434049 +v 0.461484 0.981477 0.433136 +v 0.523425 0.991422 0.440766 +v 0.485102 0.993849 0.442397 +v 0.477416 0.989927 0.4341 +v 0.495698 0.994093 0.435602 +v 0.516157 0.991936 0.434183 +v 0.588804 0.164456 0.4282 +v 0.593204 0.170063 0.425837 +v 0.528211 0.172648 0.429386 +v 0.527813 0.176918 0.428053 +v 0.52105 0.196736 0.438589 +v 0.526033 0.190681 0.431985 +v 0.607588 0.184905 0.436011 +v 0.602176 0.185529 0.429291 +v 0.60784 0.195059 0.434905 +v 0.613347 0.205122 0.440528 +v 0.608208 0.210947 0.433091 +v 0.522467 0.27736 0.435126 +v 0.527223 0.27503 0.430106 +v 0.522358 0.221954 0.436288 +v 0.478813 0.222627 0.438147 +v 0.473494 0.266715 0.431032 +v 0.486259 0.376698 0.428411 +v 0.493968 0.380253 0.431598 +v 0.3983 0.377345 0.431729 +v 0.401637 0.399795 0.427696 +v 0.605006 0.379714 0.435656 +v 0.600518 0.401332 0.429247 +v 0.396705 0.432877 0.424791 +v 0.397886 0.479464 0.423926 +v 0.600321 0.504636 0.431218 +v 0.601123 0.479853 0.422028 +v 0.591589 0.525927 0.423434 +v 0.572562 0.604998 0.436383 +v 0.567781 0.599818 0.428353 +v 0.56375 0.610919 0.427503 +v 0.342902 0.613304 0.4379 +v 0.360497 0.614237 0.434318 +v 0.367474 0.61086 0.437195 +v 0.570959 0.619698 0.432223 +v 0.57723 0.621509 0.433729 +v 0.624074 0.621734 0.431304 +v 0.63658 0.621256 0.431099 +v 0.387937 0.619201 0.434828 +v 0.584826 0.624042 0.434018 +v 0.595955 0.622626 0.434845 +v 0.608888 0.622883 0.432599 +v 0.422949 0.631537 0.429858 +v 0.408234 0.626569 0.43266 +v 0.344912 0.643637 0.434598 +v 0.340269 0.632625 0.434949 +v 0.357909 0.651207 0.430802 +v 0.378153 0.670645 0.431949 +v 0.632026 0.659066 0.430342 +v 0.61246 0.66942 0.42877 +v 0.416917 0.689459 0.434765 +v 0.585001 0.687894 0.433588 +v 0.439281 0.693846 0.431543 +v 0.430097 0.689754 0.432298 +v 0.559664 0.694219 0.43039 +v 0.556512 0.710889 0.430335 +v 0.443054 0.715672 0.433114 +v 0.44212 0.700144 0.432053 +v 0.55738 0.773131 0.432123 +v 0.558728 0.792699 0.432849 +v 0.557961 0.805374 0.430391 +v 0.571211 0.807676 0.431484 +v 0.576899 0.811681 0.430304 +v 0.579701 0.813408 0.433053 +v 0.577722 0.807633 0.434119 +v 0.420387 0.812767 0.433938 +v 0.437803 0.818977 0.431216 +v 0.439728 0.807477 0.431637 +v 0.435649 0.810559 0.432914 +v 0.563207 0.822344 0.433471 +v 0.564631 0.817309 0.433886 +v 0.567401 0.817731 0.432038 +v 0.581254 0.820739 0.433094 +v 0.437052 0.826848 0.431317 +v 0.434263 0.8258 0.431353 +v 0.439851 0.830115 0.429081 +v 0.56106 0.821199 0.432022 +v 0.418973 0.828636 0.434454 +v 0.42749 0.833758 0.435852 +v 0.427894 0.829458 0.431778 +v 0.424398 0.830395 0.432423 +v 0.573441 0.834591 0.436525 +v 0.571653 0.829365 0.432544 +v 0.559873 0.863552 0.424442 +v 0.563295 0.882325 0.427346 +v 0.437481 0.867419 0.429069 +v 0.433499 0.87939 0.434779 +v 0.562303 0.917081 0.421412 +v 0.449521 0.965473 0.423501 +v 0.442284 0.957981 0.428392 +v 0.445177 0.158992 0.428192 +v 0.429562 0.158432 0.428119 +v 0.439587 0.160474 0.423835 +v 0.459135 0.160322 0.433117 +v 0.569872 0.157415 0.430663 +v 0.559368 0.158158 0.428306 +v 0.581051 0.160117 0.429466 +v 0.411893 0.164018 0.428685 +v 0.414494 0.160773 0.432943 +v 0.410723 0.168405 0.424073 +v 0.419825 0.163984 0.421962 +v 0.466645 0.16354 0.433199 +v 0.466217 0.166688 0.429144 +v 0.535028 0.16457 0.430535 +v 0.543978 0.162612 0.427275 +v 0.532013 0.168551 0.428988 +v 0.535369 0.171998 0.423882 +v 0.468682 0.174367 0.426435 +v 0.472141 0.179958 0.429102 +v 0.533602 0.189379 0.425179 +v 0.535344 0.201987 0.424807 +v 0.505212 0.393945 0.41937 +v 0.500644 0.382169 0.432531 +v 0.49822 0.387083 0.427658 +v 0.493482 0.391685 0.421457 +v 0.409055 0.394529 0.422283 +v 0.406093 0.409656 0.421945 +v 0.407423 0.508226 0.41503 +v 0.410585 0.531303 0.422519 +v 0.441527 0.611137 0.423115 +v 0.432036 0.600962 0.429178 +v 0.432612 0.612259 0.431822 +v 0.434708 0.624167 0.428925 +v 0.357502 0.61958 0.432294 +v 0.351318 0.623935 0.432395 +v 0.372823 0.62373 0.429978 +v 0.564495 0.61857 0.428348 +v 0.564702 0.627203 0.42745 +v 0.359982 0.634359 0.428387 +v 0.344641 0.627955 0.433355 +v 0.639934 0.628502 0.429366 +v 0.39118 0.626063 0.430942 +v 0.392242 0.632382 0.42804 +v 0.576727 0.631023 0.429217 +v 0.609026 0.633353 0.427652 +v 0.630379 0.638472 0.426452 +v 0.644274 0.634466 0.429611 +v 0.643657 0.642039 0.429905 +v 0.373761 0.66116 0.428647 +v 0.369341 0.651426 0.426943 +v 0.626803 0.651912 0.42659 +v 0.637276 0.651037 0.429772 +v 0.393537 0.672015 0.428619 +v 0.415882 0.68167 0.4299 +v 0.407574 0.670961 0.426334 +v 0.56972 0.688158 0.430326 +v 0.589844 0.679454 0.429408 +v 0.445373 0.689 0.427069 +v 0.559015 0.685371 0.426905 +v 0.550134 0.741578 0.424208 +v 0.555646 0.744836 0.430179 +v 0.443657 0.77203 0.431597 +v 0.444256 0.745373 0.431936 +v 0.451662 0.72756 0.424151 +v 0.443387 0.792219 0.430146 +v 0.445503 0.807912 0.425667 +v 0.432038 0.81367 0.43053 +v 0.432112 0.807045 0.432761 +v 0.428001 0.809459 0.430527 +v 0.421631 0.814949 0.431403 +v 0.427926 0.815329 0.42887 +v 0.424496 0.815049 0.429451 +v 0.430749 0.820198 0.429502 +v 0.570789 0.814791 0.429806 +v 0.574067 0.812604 0.42914 +v 0.42135 0.822083 0.430961 +v 0.570409 0.822888 0.43047 +v 0.429853 0.825525 0.430379 +v 0.574926 0.823232 0.429314 +v 0.578724 0.821925 0.430166 +v 0.425469 0.826939 0.430281 +v 0.422234 0.827554 0.431686 +v 0.55749 0.826384 0.426782 +v 0.434695 0.91411 0.427603 +v 0.439202 0.945874 0.424357 +v 0.561196 0.945524 0.424737 +v 0.554899 0.954482 0.419453 +v 0.506974 0.991846 0.428967 +v 0.517994 0.988355 0.424911 +v 0.497523 0.990577 0.42472 +v 0.44417 0.163918 0.42094 +v 0.43103 0.162473 0.420278 +v 0.55566 0.161132 0.42464 +v 0.555782 0.165303 0.41978 +v 0.56779 0.160827 0.422484 +v 0.578295 0.161772 0.423967 +v 0.457158 0.166968 0.423148 +v 0.465185 0.170537 0.42526 +v 0.458736 0.174047 0.41993 +v 0.586562 0.170649 0.420458 +v 0.59523 0.177278 0.423891 +v 0.403965 0.180225 0.423838 +v 0.406796 0.173895 0.423464 +v 0.533038 0.18208 0.424058 +v 0.534862 0.176677 0.42259 +v 0.543732 0.17381 0.419005 +v 0.595448 0.186615 0.423283 +v 0.403445 0.188369 0.424051 +v 0.543113 0.189919 0.419488 +v 0.587219 0.187571 0.418189 +v 0.59455 0.201309 0.422704 +v 0.601513 0.219815 0.426498 +v 0.594071 0.222069 0.421187 +v 0.467859 0.306449 0.425033 +v 0.467258 0.249003 0.425525 +v 0.603352 0.277538 0.426724 +v 0.59542 0.277041 0.420524 +v 0.598304 0.311285 0.423967 +v 0.471638 0.362941 0.42452 +v 0.465412 0.36764 0.419695 +v 0.475844 0.373296 0.423157 +v 0.585294 0.347947 0.418907 +v 0.589841 0.370354 0.42249 +v 0.594288 0.343041 0.42344 +v 0.480355 0.38263 0.42112 +v 0.471425 0.38747 0.414385 +v 0.483289 0.390915 0.417172 +v 0.595263 0.412031 0.422363 +v 0.59467 0.399149 0.424066 +v 0.568534 0.584059 0.420931 +v 0.571441 0.562181 0.413246 +v 0.557933 0.5859 0.410884 +v 0.433542 0.585731 0.41939 +v 0.556843 0.619095 0.422226 +v 0.55343 0.629706 0.420975 +v 0.549154 0.620966 0.416573 +v 0.440456 0.637475 0.424869 +v 0.43353 0.6351 0.426907 +v 0.426087 0.640039 0.426946 +v 0.436517 0.650338 0.423321 +v 0.446877 0.641696 0.422312 +v 0.558635 0.634234 0.423833 +v 0.566553 0.634813 0.426078 +v 0.369271 0.644506 0.425948 +v 0.377544 0.640573 0.425261 +v 0.412174 0.639884 0.426915 +v 0.393774 0.63914 0.425897 +v 0.419936 0.645702 0.425072 +v 0.576936 0.639943 0.425743 +v 0.620943 0.648468 0.425022 +v 0.607534 0.657635 0.42444 +v 0.614852 0.642204 0.425091 +v 0.386749 0.65686 0.42492 +v 0.399714 0.645435 0.424466 +v 0.416008 0.650052 0.423573 +v 0.58068 0.649151 0.423827 +v 0.595925 0.642777 0.425371 +v 0.584429 0.65818 0.42345 +v 0.564397 0.659179 0.42336 +v 0.422009 0.658213 0.423448 +v 0.586807 0.665812 0.424496 +v 0.554512 0.662951 0.423149 +v 0.557126 0.674396 0.424341 +v 0.413277 0.66531 0.424783 +v 0.438533 0.673182 0.424672 +v 0.567231 0.67531 0.425246 +v 0.588742 0.672935 0.426555 +v 0.444509 0.830227 0.424064 +v 0.451157 0.82114 0.418448 +v 0.576218 0.816976 0.428716 +v 0.441811 0.850151 0.425081 +v 0.553088 0.853824 0.417209 +v 0.441505 0.882784 0.420607 +v 0.439295 0.914081 0.418894 +v 0.445401 0.898184 0.412936 +v 0.438094 0.93285 0.420755 +v 0.562005 0.935014 0.421131 +v 0.540296 0.97798 0.428066 +v 0.528047 0.983613 0.423283 +v 0.536184 0.976908 0.421154 +v 0.462975 0.977458 0.422298 +v 0.47 0.984233 0.426826 +v 0.51967 0.984673 0.418158 +v 0.422841 0.166779 0.418032 +v 0.577474 0.165088 0.419706 +v 0.44541 0.168157 0.417982 +v 0.433195 0.171341 0.414376 +v 0.44614 0.172768 0.415842 +v 0.414957 0.17169 0.418979 +v 0.423044 0.171798 0.415439 +v 0.411263 0.190814 0.419422 +v 0.418545 0.201193 0.416796 +v 0.421566 0.188475 0.415101 +v 0.554481 0.189977 0.415654 +v 0.553977 0.204584 0.416245 +v 0.457436 0.352951 0.418067 +v 0.457126 0.370372 0.416318 +v 0.417333 0.390975 0.417636 +v 0.413589 0.374646 0.420506 +v 0.516897 0.384653 0.421509 +v 0.522587 0.391754 0.414406 +v 0.528027 0.386651 0.415289 +v 0.587981 0.401971 0.418558 +v 0.589771 0.38966 0.422074 +v 0.582634 0.382656 0.418775 +v 0.412484 0.411485 0.414837 +v 0.408058 0.420085 0.414106 +v 0.588859 0.411339 0.416753 +v 0.59095 0.420716 0.413451 +v 0.595283 0.440663 0.406634 +v 0.59816 0.451144 0.408597 +v 0.450112 0.602511 0.412173 +v 0.451903 0.615097 0.415193 +v 0.452751 0.629054 0.417329 +v 0.455944 0.645943 0.417489 +v 0.553097 0.644341 0.421583 +v 0.529961 0.666811 0.411676 +v 0.538729 0.691844 0.416558 +v 0.538492 0.663961 0.416034 +v 0.537704 0.641361 0.413204 +v 0.547038 0.657851 0.419873 +v 0.457791 0.690275 0.419172 +v 0.459042 0.662335 0.417358 +v 0.451461 0.678315 0.42271 +v 0.460796 0.725603 0.416593 +v 0.533347 0.720677 0.413099 +v 0.542463 0.736978 0.418189 +v 0.543217 0.78395 0.416867 +v 0.545038 0.830887 0.413312 +v 0.547269 0.881642 0.407607 +v 0.55564 0.933503 0.410748 +v 0.549701 0.951022 0.409638 +v 0.54746 0.961413 0.414972 +v 0.45658 0.96937 0.418464 +v 0.452313 0.960397 0.413862 +v 0.478946 0.986449 0.423485 +v 0.481801 0.981919 0.414268 +v 0.488342 0.987561 0.420588 +v 0.497839 0.985956 0.415825 +v 0.425057 0.178459 0.41355 +v 0.448776 0.17873 0.415687 +v 0.568504 0.169003 0.415485 +v 0.555817 0.170335 0.416557 +v 0.555568 0.175726 0.414936 +v 0.576944 0.173921 0.41433 +v 0.578542 0.16993 0.416949 +v 0.568783 0.176697 0.412708 +v 0.579181 0.180028 0.414118 +v 0.453052 0.188028 0.417576 +v 0.442001 0.18749 0.414627 +v 0.578019 0.188643 0.414652 +v 0.567045 0.18955 0.413762 +v 0.558661 0.181621 0.413742 +v 0.414339 0.218708 0.417196 +v 0.423988 0.218594 0.414724 +v 0.428383 0.240909 0.41324 +v 0.43384 0.216688 0.414096 +v 0.583343 0.241103 0.415335 +v 0.587574 0.223279 0.417584 +v 0.579925 0.219124 0.415488 +v 0.442122 0.220737 0.41468 +v 0.441336 0.253292 0.413332 +v 0.448205 0.231051 0.415672 +v 0.460739 0.240199 0.421066 +v 0.45409 0.237628 0.417721 +v 0.454011 0.279558 0.416759 +v 0.572944 0.278876 0.412889 +v 0.577331 0.308322 0.414061 +v 0.581257 0.273512 0.414387 +v 0.461597 0.329588 0.420663 +v 0.454343 0.321553 0.417188 +v 0.431218 0.346058 0.414229 +v 0.438573 0.359339 0.414534 +v 0.438102 0.332019 0.413882 +v 0.446436 0.31282 0.414566 +v 0.438771 0.293152 0.412979 +v 0.577855 0.366217 0.416884 +v 0.577705 0.33875 0.415586 +v 0.560185 0.378219 0.413162 +v 0.558133 0.35649 0.414549 +v 0.552294 0.375927 0.413841 +v 0.434428 0.388095 0.412317 +v 0.432733 0.380139 0.414152 +v 0.425808 0.38936 0.414257 +v 0.436249 0.393601 0.409615 +v 0.44137 0.387702 0.411102 +v 0.558123 0.387605 0.410958 +v 0.567155 0.383998 0.412908 +v 0.574548 0.383454 0.41522 +v 0.574274 0.394387 0.412947 +v 0.532775 0.379554 0.416429 +v 0.538011 0.386887 0.412026 +v 0.421015 0.399345 0.413186 +v 0.48819 0.399871 0.409897 +v 0.519053 0.396724 0.411266 +v 0.533979 0.39744 0.405618 +v 0.512988 0.402947 0.40569 +v 0.574863 0.40257 0.410267 +v 0.581819 0.404405 0.413631 +v 0.404746 0.48718 0.408164 +v 0.401681 0.468973 0.40743 +v 0.596156 0.48264 0.4078 +v 0.598452 0.465717 0.408932 +v 0.589082 0.512601 0.411724 +v 0.58224 0.536682 0.414392 +v 0.421107 0.544709 0.414375 +v 0.461736 0.620788 0.409872 +v 0.465567 0.646409 0.412193 +v 0.46212 0.771897 0.413985 +v 0.468628 0.73009 0.411833 +v 0.456466 0.847622 0.410373 +v 0.458959 0.81149 0.413205 +v 0.53628 0.820061 0.408924 +v 0.443839 0.942679 0.414767 +v 0.537412 0.965384 0.408401 +v 0.539024 0.970743 0.415801 +v 0.46422 0.970776 0.412421 +v 0.527373 0.978697 0.415143 +v 0.432941 0.267569 0.412713 +v 0.42387 0.274753 0.413354 +v 0.570054 0.326661 0.413752 +v 0.566063 0.291319 0.412601 +v 0.562246 0.320879 0.413691 +v 0.44632 0.390339 0.408934 +v 0.450246 0.384911 0.411724 +v 0.460554 0.385206 0.412759 +v 0.461709 0.391753 0.40921 +v 0.545659 0.383175 0.412397 +v 0.547062 0.389413 0.410103 +v 0.552041 0.393517 0.40837 +v 0.436591 0.399701 0.405606 +v 0.442942 0.395502 0.406325 +v 0.452135 0.394685 0.405968 +v 0.460303 0.399836 0.40127 +v 0.558069 0.397558 0.405971 +v 0.546651 0.39753 0.404616 +v 0.559794 0.403906 0.399894 +v 0.567028 0.400683 0.406851 +v 0.573043 0.409382 0.403401 +v 0.428103 0.403379 0.406864 +v 0.420049 0.406778 0.409998 +v 0.419274 0.41504 0.404077 +v 0.401921 0.460064 0.404188 +v 0.405926 0.466812 0.394003 +v 0.410802 0.496286 0.399535 +v 0.592196 0.494779 0.404851 +v 0.586485 0.500483 0.398965 +v 0.444005 0.585509 0.40942 +v 0.433745 0.564609 0.409285 +v 0.540613 0.622356 0.411419 +v 0.546871 0.606042 0.410469 +v 0.530125 0.623661 0.406291 +v 0.469115 0.631572 0.408188 +v 0.473906 0.645197 0.40831 +v 0.482363 0.644662 0.405664 +v 0.478439 0.667339 0.408061 +v 0.525553 0.68832 0.409866 +v 0.524995 0.732686 0.409144 +v 0.476725 0.70789 0.408832 +v 0.476016 0.759038 0.407745 +v 0.485036 0.693081 0.40677 +v 0.516987 0.729168 0.4065 +v 0.523554 0.778652 0.4068 +v 0.467168 0.807673 0.408529 +v 0.449868 0.938309 0.405622 +v 0.450638 0.950241 0.409159 +v 0.488287 0.977183 0.406015 +v 0.480182 0.974088 0.405795 +v 0.506914 0.98168 0.41029 +v 0.496955 0.98012 0.407749 +v 0.517323 0.980953 0.412165 +v 0.516349 0.975305 0.405481 +v 0.436652 0.406635 0.398865 +v 0.402402 0.450192 0.40607 +v 0.405721 0.440092 0.40377 +v 0.5918 0.481308 0.395278 +v 0.416384 0.503233 0.395826 +v 0.414731 0.489874 0.38732 +v 0.572112 0.540406 0.404716 +v 0.571231 0.521418 0.395022 +v 0.559866 0.54269 0.395339 +v 0.429702 0.540889 0.403839 +v 0.424954 0.521372 0.399205 +v 0.437556 0.537403 0.395519 +v 0.455618 0.584971 0.4012 +v 0.546749 0.585551 0.4028 +v 0.48148 0.617361 0.401159 +v 0.47472 0.603323 0.399065 +v 0.471228 0.617776 0.404418 +v 0.524468 0.605367 0.399268 +v 0.518113 0.622628 0.402042 +v 0.491955 0.644406 0.403978 +v 0.487824 0.630154 0.402492 +v 0.493699 0.66654 0.40512 +v 0.50247 0.645604 0.40396 +v 0.512616 0.680101 0.406024 +v 0.519988 0.663265 0.40772 +v 0.512773 0.651492 0.405666 +v 0.511139 0.634954 0.403343 +v 0.491637 0.757718 0.40401 +v 0.500562 0.728164 0.404448 +v 0.493093 0.706734 0.405349 +v 0.5064 0.771884 0.403047 +v 0.509301 0.721947 0.404922 +v 0.475829 0.80339 0.40505 +v 0.483914 0.788541 0.403587 +v 0.492098 0.803854 0.400868 +v 0.501044 0.811097 0.399802 +v 0.510058 0.814018 0.400186 +v 0.518453 0.813814 0.402131 +v 0.527201 0.815652 0.405018 +v 0.473957 0.841307 0.401182 +v 0.529404 0.851073 0.401026 +v 0.452979 0.887366 0.40679 +v 0.461146 0.883207 0.400838 +v 0.540058 0.897971 0.399126 +v 0.546183 0.916666 0.401262 +v 0.450338 0.919774 0.404561 +v 0.457651 0.955604 0.404934 +v 0.472708 0.969383 0.405055 +v 0.46524 0.96224 0.403736 +v 0.481108 0.964511 0.397227 +v 0.496458 0.97245 0.4 +v 0.542068 0.402755 0.398056 +v 0.415753 0.425321 0.398964 +v 0.41033 0.432596 0.400393 +v 0.593415 0.461501 0.395051 +v 0.44061 0.523703 0.386669 +v 0.450191 0.543461 0.389015 +v 0.468284 0.585081 0.395094 +v 0.459956 0.564424 0.391258 +v 0.546013 0.563874 0.394316 +v 0.533427 0.58485 0.39582 +v 0.48043 0.584048 0.390914 +v 0.492921 0.617426 0.399266 +v 0.505339 0.619144 0.399446 +v 0.498494 0.602309 0.394772 +v 0.494619 0.84483 0.39571 +v 0.514248 0.847894 0.396454 +v 0.46941 0.88261 0.396354 +v 0.478415 0.882671 0.392938 +v 0.463792 0.917578 0.394034 +v 0.45707 0.933231 0.397821 +v 0.539931 0.929056 0.395038 +v 0.54781 0.93203 0.401985 +v 0.548369 0.941248 0.404162 +v 0.541849 0.949439 0.401517 +v 0.532082 0.951025 0.395534 +v 0.534965 0.958738 0.40142 +v 0.465315 0.951562 0.397614 +v 0.526209 0.967604 0.402456 +v 0.515162 0.968282 0.398876 +v 0.499848 0.407684 0.400583 +v 0.516365 0.410441 0.39281 +v 0.416526 0.444984 0.382567 +v 0.406632 0.460677 0.39271 +v 0.578859 0.503255 0.390767 +v 0.570687 0.506324 0.384052 +v 0.583631 0.489298 0.38634 +v 0.519464 0.583553 0.390703 +v 0.534323 0.916876 0.392387 +v 0.531515 0.888557 0.395622 +v 0.531363 0.932769 0.390143 +v 0.464756 0.938625 0.39372 +v 0.505084 0.966659 0.395893 +v 0.496638 0.962786 0.393083 +v 0.514164 0.960104 0.393025 +v 0.470471 0.408355 0.391704 +v 0.458779 0.41044 0.387531 +v 0.484595 0.408096 0.396475 +v 0.482536 0.417741 0.382552 +v 0.54339 0.410449 0.387906 +v 0.531976 0.410165 0.388851 +v 0.551603 0.41186 0.387688 +v 0.543054 0.419836 0.376131 +v 0.516444 0.41822 0.381824 +v 0.424518 0.423878 0.38986 +v 0.432795 0.417784 0.388778 +v 0.429732 0.430321 0.378152 +v 0.574924 0.435848 0.37941 +v 0.582862 0.428006 0.395859 +v 0.574944 0.42229 0.391977 +v 0.587821 0.447195 0.388883 +v 0.590051 0.433535 0.401753 +v 0.587979 0.459032 0.384817 +v 0.589824 0.469673 0.387767 +v 0.423205 0.506839 0.390225 +v 0.430809 0.506617 0.382956 +v 0.421578 0.493746 0.381636 +v 0.568973 0.496818 0.375166 +v 0.564914 0.505582 0.378275 +v 0.545533 0.5428 0.386953 +v 0.463538 0.542273 0.382724 +v 0.492402 0.581746 0.388405 +v 0.486122 0.559957 0.381989 +v 0.50562 0.581544 0.388221 +v 0.513436 0.558989 0.381864 +v 0.522187 0.875943 0.394142 +v 0.514755 0.885153 0.390457 +v 0.487951 0.882843 0.390356 +v 0.482794 0.917747 0.386186 +v 0.473121 0.945239 0.3915 +v 0.481469 0.952309 0.390648 +v 0.481149 0.938671 0.386588 +v 0.528063 0.943433 0.390793 +v 0.52217 0.952946 0.391604 +v 0.4891 0.957882 0.391156 +v 0.497162 0.951761 0.387562 +v 0.51302 0.951401 0.388493 +v 0.457397 0.420971 0.374611 +v 0.450312 0.414825 0.383046 +v 0.55876 0.414094 0.387989 +v 0.441677 0.413546 0.387985 +v 0.443505 0.422715 0.376455 +v 0.503667 0.42519 0.37748 +v 0.516577 0.426094 0.373551 +v 0.566591 0.417464 0.389513 +v 0.582671 0.454274 0.378276 +v 0.411644 0.46595 0.383337 +v 0.586956 0.478329 0.385446 +v 0.439676 0.506382 0.3767 +v 0.532258 0.534846 0.379018 +v 0.545735 0.522649 0.379357 +v 0.507419 0.893138 0.387696 +v 0.497565 0.884214 0.38898 +v 0.501684 0.912999 0.383965 +v 0.51454 0.913342 0.385414 +v 0.513467 0.941276 0.38552 +v 0.522333 0.936396 0.387007 +v 0.515517 0.930416 0.38427 +v 0.489877 0.934121 0.383598 +v 0.505295 0.946442 0.385779 +v 0.497914 0.940561 0.383968 +v 0.492867 0.424637 0.37773 +v 0.48101 0.426404 0.373098 +v 0.497159 0.431413 0.37278 +v 0.419009 0.46189 0.3746 +v 0.417524 0.472497 0.377067 +v 0.581648 0.477516 0.377966 +v 0.418893 0.482857 0.378469 +v 0.450783 0.506294 0.371613 +v 0.439736 0.492916 0.367992 +v 0.477438 0.538732 0.377536 +v 0.465119 0.520341 0.374643 +v 0.490934 0.534912 0.374542 +v 0.508206 0.925274 0.382901 +v 0.498906 0.929872 0.382464 +v 0.436847 0.431223 0.371932 +v 0.431024 0.439198 0.370273 +v 0.579392 0.467285 0.373165 +v 0.578748 0.458284 0.372803 +v 0.574532 0.46189 0.368692 +v 0.576502 0.448011 0.373569 +v 0.563615 0.497556 0.372119 +v 0.55639 0.507754 0.375503 +v 0.545745 0.505091 0.369882 +v 0.453434 0.429027 0.367617 +v 0.46145 0.428935 0.367321 +v 0.527734 0.429039 0.368491 +v 0.515545 0.435306 0.367124 +v 0.537153 0.426858 0.368931 +v 0.533556 0.434914 0.363554 +v 0.545421 0.428278 0.368319 +v 0.559328 0.425485 0.375844 +v 0.554102 0.431244 0.368299 +v 0.562206 0.435511 0.369201 +v 0.564085 0.444496 0.365655 +v 0.569583 0.441398 0.370742 +v 0.426955 0.446793 0.369894 +v 0.436657 0.445287 0.364307 +v 0.422921 0.453651 0.371692 +v 0.428385 0.46103 0.36622 +v 0.571196 0.46995 0.367004 +v 0.569204 0.480543 0.368124 +v 0.576326 0.475435 0.37202 +v 0.425693 0.477516 0.370387 +v 0.535534 0.502233 0.365982 +v 0.547711 0.490898 0.362605 +v 0.505446 0.534178 0.374395 +v 0.497302 0.513592 0.369159 +v 0.5194 0.536806 0.37648 +v 0.525345 0.517086 0.371142 +v 0.550016 0.43633 0.364014 +v 0.445033 0.430261 0.368809 +v 0.448821 0.436035 0.364075 +v 0.470254 0.43181 0.366625 +v 0.481172 0.435555 0.366675 +v 0.490981 0.437975 0.367513 +v 0.484494 0.445524 0.362632 +v 0.497587 0.440253 0.367314 +v 0.514794 0.446431 0.362223 +v 0.504631 0.443242 0.365468 +v 0.497986 0.450307 0.363371 +v 0.567056 0.461945 0.364041 +v 0.432063 0.470048 0.364171 +v 0.434628 0.480472 0.365209 +v 0.44428 0.483725 0.361956 +v 0.559162 0.483903 0.363624 +v 0.566275 0.489007 0.369271 +v 0.519734 0.494326 0.362292 +v 0.514981 0.48497 0.36043 +v 0.505539 0.497741 0.364833 +v 0.462367 0.503166 0.366971 +v 0.456166 0.489658 0.361305 +v 0.471923 0.495864 0.36311 +v 0.489543 0.498186 0.364966 +v 0.526869 0.499249 0.363873 +v 0.532232 0.486072 0.358879 +v 0.462975 0.437702 0.361908 +v 0.546724 0.44273 0.360453 +v 0.555963 0.444486 0.36198 +v 0.51436 0.459456 0.359444 +v 0.524491 0.450709 0.358834 +v 0.531778 0.45534 0.356621 +v 0.531243 0.444715 0.359302 +v 0.562279 0.452939 0.362471 +v 0.491918 0.454332 0.361585 +v 0.481272 0.454648 0.359575 +v 0.498394 0.461561 0.361545 +v 0.558206 0.46165 0.35989 +v 0.438611 0.463343 0.360567 +v 0.4936 0.471299 0.36061 +v 0.503843 0.468416 0.360978 +v 0.551041 0.479889 0.359649 +v 0.451952 0.478022 0.3583 +v 0.525708 0.474031 0.357068 +v 0.513596 0.472818 0.359046 +v 0.455637 0.441213 0.36043 +v 0.46203 0.446727 0.358156 +v 0.538114 0.442218 0.359884 +v 0.543597 0.450325 0.357648 +v 0.446506 0.443273 0.361487 +v 0.445948 0.450945 0.359599 +v 0.447506 0.459166 0.35816 +v 0.456702 0.454428 0.356975 +v 0.468115 0.454597 0.357284 +v 0.449993 0.46812 0.357416 +v 0.539835 0.457824 0.356054 +v 0.549022 0.459432 0.357102 +v 0.479735 0.464761 0.358345 +v 0.534514 0.465226 0.35577 +v 0.463446 0.475079 0.357099 +v 0.552095 0.469681 0.358172 +v 0.479769 0.474624 0.35858 +v 0.535397 0.475012 0.356536 +v 0.478261 0.485259 0.36031 +v 0.543025 0.477033 0.357416 +v 0.47959 0.406351 0.545325 +v 0.424273 0.404079 0.533596 +v 0.471178 0.398359 0.538915 +v 0.540002 0.394664 0.537512 +v 0.438701 0.388632 0.532159 +v 0.449984 0.389654 0.534341 +v 0.461145 0.389225 0.53407 +v 0.55986 0.383489 0.530856 +v 0.550068 0.391931 0.53578 +v 0.557386 0.243144 0.526209 +v 0.565783 0.241286 0.52744 +v 0.575545 0.310655 0.529617 +v 0.570849 0.314896 0.529332 +v 0.428965 0.304387 0.529381 +v 0.433637 0.305049 0.529213 +v 0.430413 0.309522 0.53021 +v 0.426792 0.312361 0.529977 +v 0.423844 0.316712 0.528298 +v 0.432313 0.315371 0.529116 +v 0.573161 0.323736 0.525676 +v 0.426787 0.389163 0.529002 +v 0.415542 0.394488 0.525335 +v 0.49299 0.381359 0.5164 +v 0.495889 0.388102 0.52347 +v 0.576176 0.393295 0.530021 +v 0.547929 0.244543 0.523495 +v 0.53916 0.244335 0.519557 +v 0.588381 0.267147 0.519651 +v 0.437922 0.240342 0.526667 +v 0.572098 0.26302 0.524315 +v 0.430231 0.296539 0.526572 +v 0.425235 0.297355 0.526251 +v 0.434837 0.297229 0.526396 +v 0.432803 0.28701 0.523864 +v 0.58239 0.290474 0.521343 +v 0.583494 0.300278 0.523621 +v 0.580965 0.307584 0.527148 +v 0.5868 0.30664 0.522295 +v 0.549919 0.316816 0.520549 +v 0.420648 0.323513 0.524146 +v 0.578953 0.332955 0.521003 +v 0.558504 0.369709 0.525962 +v 0.552934 0.358185 0.522259 +v 0.530373 0.375147 0.524048 +v 0.600765 0.238612 0.515654 +v 0.449212 0.259262 0.522222 +v 0.445901 0.245078 0.524898 +v 0.57765 0.278679 0.522094 +v 0.586432 0.282113 0.519322 +v 0.438549 0.257525 0.524486 +v 0.442378 0.269709 0.522787 +v 0.434596 0.274382 0.523445 +v 0.569696 0.276781 0.523269 +v 0.42779 0.278138 0.523011 +v 0.42244 0.286898 0.522811 +v 0.592808 0.288617 0.516565 +v 0.591161 0.306894 0.517836 +v 0.412922 0.319949 0.520412 +v 0.550703 0.333442 0.519262 +v 0.558511 0.338476 0.521044 +v 0.556212 0.348177 0.521053 +v 0.533415 0.363805 0.51909 +v 0.408875 0.386022 0.517946 +v 0.606952 0.238017 0.510007 +v 0.461455 0.266234 0.516061 +v 0.540973 0.314127 0.515611 +v 0.399288 0.294493 0.510588 +v 0.461628 0.308874 0.514421 +v 0.459136 0.291595 0.516034 +v 0.468761 0.313011 0.509644 +v 0.544535 0.328564 0.517147 +v 0.584947 0.347547 0.518013 +v 0.525788 0.359643 0.512501 +v 0.5082 0.368885 0.504097 +v 0.516939 0.364449 0.508244 +v 0.410629 0.36152 0.515791 +v 0.410548 0.373413 0.516381 +v 0.402013 0.378659 0.510852 +v 0.497821 0.374385 0.505523 +v 0.474652 0.241058 0.509268 +v 0.598138 0.37808 0.512271 +v 0.593037 0.356927 0.513933 +v 0.502755 0.371002 0.501222 +v 0.505713 0.365397 0.496044 +v 0.600237 0.405483 0.516983 +v 0.480591 0.272646 0.497014 +v 0.478124 0.25005 0.503501 +v 0.474527 0.272251 0.505258 +v 0.51974 0.292538 0.496196 +v 0.474092 0.303411 0.504503 +v 0.47596 0.332205 0.5033 +v 0.518328 0.35617 0.503754 +v 0.388019 0.406361 0.497502 +v 0.392149 0.413999 0.508163 +v 0.392109 0.30221 0.503035 +v 0.477995 0.296515 0.499543 +v 0.483659 0.345378 0.495109 +v 0.512194 0.353447 0.493598 +v 0.516654 0.229357 0.499073 +v 0.51425 0.235404 0.491532 +v 0.385946 0.300605 0.494814 +v 0.61612 0.308027 0.491077 +v 0.612117 0.321565 0.496693 +v 0.515269 0.269219 0.488304 +v 0.61856 0.300083 0.485596 +v 0.615001 0.370449 0.48902 +v 0.486462 0.342267 0.487501 +v 0.385082 0.380797 0.48587 +v 0.616617 0.414177 0.488585 +v 0.488504 0.339998 0.478977 +v 0.512414 0.341872 0.48401 +v 0.5081 0.350446 0.476755 +v 0.507443 0.354014 0.482633 +v 0.506843 0.359209 0.489189 +v 0.377566 0.265023 0.473893 +v 0.504256 0.357649 0.470703 +v 0.622687 0.20248 0.470974 +v 0.623235 0.221664 0.465808 +v 0.376345 0.221466 0.477143 +v 0.511635 0.306912 0.468843 +v 0.620371 0.289383 0.478474 +v 0.618623 0.334615 0.47101 +v 0.617153 0.357425 0.462088 +v 0.62201 0.26988 0.468845 +v 0.503982 0.359797 0.459705 +v 0.376987 0.203848 0.470755 +v 0.621829 0.258894 0.459051 +v 0.488436 0.274568 0.462751 +v 0.511641 0.274191 0.466852 +v 0.488855 0.307775 0.466573 +v 0.489244 0.331504 0.471537 +v 0.51347 0.205978 0.453078 +v 0.512276 0.307732 0.458639 +v 0.494782 0.360656 0.452361 +v 0.383787 0.352588 0.454101 +v 0.619516 0.256921 0.450085 +v 0.618598 0.302092 0.451983 +v 0.379463 0.265599 0.453606 +v 0.616214 0.346089 0.453268 +v 0.384952 0.20456 0.443653 +v 0.391494 0.20351 0.434674 +v 0.51457 0.220122 0.4487 +v 0.517483 0.205571 0.443762 +v 0.382704 0.310493 0.448893 +v 0.614069 0.334197 0.445189 +v 0.49704 0.365307 0.449405 +v 0.499673 0.367382 0.44889 +v 0.500668 0.372786 0.442252 +v 0.617806 0.222537 0.446216 +v 0.615629 0.259338 0.441508 +v 0.521256 0.328917 0.435766 +v 0.518806 0.349763 0.437103 +v 0.612227 0.305116 0.438336 +v 0.60888 0.347329 0.438003 +v 0.479775 0.197157 0.439941 +v 0.610358 0.268418 0.433864 +v 0.504077 0.378993 0.434352 +v 0.476254 0.18813 0.434176 +v 0.390929 0.302917 0.433929 +v 0.392927 0.261583 0.429985 +v 0.394872 0.343123 0.432875 +v 0.524673 0.352155 0.430301 +v 0.602442 0.346994 0.430398 +v 0.401266 0.343318 0.42655 +v 0.468173 0.187901 0.426255 +v 0.465465 0.206296 0.424829 +v 0.461035 0.190731 0.421404 +v 0.398166 0.208809 0.427412 +v 0.400716 0.197379 0.426393 +v 0.60708 0.239912 0.4302 +v 0.400203 0.268106 0.423418 +v 0.397346 0.231627 0.42634 +v 0.528117 0.359512 0.425471 +v 0.530044 0.333233 0.42636 +v 0.510268 0.380565 0.428254 +v 0.517408 0.376444 0.425739 +v 0.405225 0.21965 0.421409 +v 0.533068 0.281654 0.425103 +v 0.540359 0.297336 0.419781 +v 0.537225 0.236578 0.422723 +v 0.469081 0.34599 0.425094 +v 0.523203 0.368787 0.425485 +v 0.530369 0.368711 0.421033 +v 0.537759 0.37013 0.417591 +v 0.454675 0.205543 0.41872 +v 0.544276 0.225265 0.418608 +v 0.410775 0.242901 0.417377 +v 0.592909 0.244479 0.419224 +v 0.407879 0.274478 0.418651 +v 0.415607 0.276454 0.415356 +v 0.404648 0.308358 0.421473 +v 0.54309 0.349668 0.417581 +v 0.547424 0.307723 0.416194 +v 0.408969 0.345801 0.421435 +v 0.417634 0.346327 0.417202 +v 0.431296 0.187743 0.413535 +v 0.438416 0.200208 0.414841 +v 0.57531 0.201796 0.415115 +v 0.550469 0.261604 0.414977 +v 0.552495 0.22821 0.41548 +v 0.571153 0.222904 0.413974 +v 0.561674 0.227424 0.413906 +v 0.567179 0.252331 0.412636 +v 0.588402 0.263476 0.416752 +v 0.420622 0.311586 0.414522 +v 0.424937 0.343321 0.414675 +v 0.429666 0.365529 0.414885 +v 0.55459 0.311956 0.414421 +v 0.544703 0.373383 0.415243 +v 0.437304 0.372448 0.414322 +v 0.447035 0.371631 0.414487 +v 0.455322 0.378842 0.414228 +v -50.0 -1.0 50.0 +v -50.0 -1.0 -50.0 +v 50.0 -1.0 -50.0 +v 50.0 -1.0 50.0 +f 6003 6004 6005 +f 6005 6006 6003 +f 332 1503 1505 +f 1503 476 1504 +f 1505 1504 1079 +f 1503 1504 1505 +f 381 1506 1508 +f 1506 287 1507 +f 1508 1507 1499 +f 1506 1507 1508 +f 287 1509 1507 +f 1509 1274 1510 +f 1507 1510 1499 +f 1509 1510 1507 +f 712 1511 1513 +f 1511 476 1512 +f 1513 1512 1165 +f 1511 1512 1513 +f 476 1514 1504 +f 1514 111 1515 +f 1504 1515 1079 +f 1514 1515 1504 +f 381 1516 1518 +f 1516 1012 1517 +f 1518 1517 1015 +f 1516 1517 1518 +f 409 1519 1520 +f 1519 381 1518 +f 1520 1518 1015 +f 1519 1518 1520 +f 287 1506 1521 +f 1506 381 1519 +f 1521 1519 409 +f 1506 1519 1521 +f 1165 1522 1524 +f 1522 332 1523 +f 1524 1523 1342 +f 1522 1523 1524 +f 476 1503 1512 +f 1503 332 1522 +f 1512 1522 1165 +f 1503 1522 1512 +f 111 1525 1515 +f 1525 25 1526 +f 1515 1526 1079 +f 1525 1526 1515 +f 25 1525 1528 +f 1525 111 1527 +f 1528 1527 1119 +f 1525 1527 1528 +f 287 1521 1530 +f 1521 409 1529 +f 1530 1529 841 +f 1521 1529 1530 +f 287 1530 1509 +f 1530 841 1531 +f 1509 1531 1274 +f 1530 1531 1509 +f 1105 1532 1534 +f 1532 162 1533 +f 1534 1533 1112 +f 1532 1533 1534 +f 1112 1533 1536 +f 1533 162 1535 +f 1536 1535 1359 +f 1533 1535 1536 +f 332 1537 1523 +f 1537 55 1538 +f 1523 1538 1342 +f 1537 1538 1523 +f 55 1537 1539 +f 1537 332 1505 +f 1539 1505 1079 +f 1537 1505 1539 +f 1079 1526 1541 +f 1526 25 1540 +f 1541 1540 1332 +f 1526 1540 1541 +f 473 1542 1544 +f 1542 1012 1543 +f 1544 1543 1499 +f 1542 1543 1544 +f 1012 1516 1543 +f 1516 381 1508 +f 1543 1508 1499 +f 1516 1508 1543 +f 739 1545 1547 +f 1545 543 1546 +f 1547 1546 1208 +f 1545 1546 1547 +f 171 1548 1549 +f 1548 739 1547 +f 1549 1547 1208 +f 1548 1547 1549 +f 171 1550 1548 +f 1550 39 1551 +f 1548 1551 739 +f 1550 1551 1548 +f 55 1539 1552 +f 1539 1079 1541 +f 1552 1541 1332 +f 1539 1541 1552 +f 476 1511 1554 +f 1511 712 1553 +f 1554 1553 1255 +f 1511 1553 1554 +f 111 1514 1555 +f 1514 476 1554 +f 1555 1554 1255 +f 1514 1554 1555 +f 1119 1527 1556 +f 1527 111 1555 +f 1556 1555 1255 +f 1527 1555 1556 +f 896 1557 1558 +f 1557 409 1520 +f 1558 1520 1015 +f 1557 1520 1558 +f 841 1529 1559 +f 1529 409 1557 +f 1559 1557 896 +f 1529 1557 1559 +f 717 1560 1561 +f 1560 162 1532 +f 1561 1532 1105 +f 1560 1532 1561 +f 162 1560 1535 +f 1560 717 1562 +f 1535 1562 1359 +f 1560 1562 1535 +f 919 1563 1565 +f 1563 994 1564 +f 1565 1564 1208 +f 1563 1564 1565 +f 543 1566 1546 +f 1566 919 1565 +f 1546 1565 1208 +f 1566 1565 1546 +f 994 1567 1564 +f 1567 171 1549 +f 1564 1549 1208 +f 1567 1549 1564 +f 171 1567 1569 +f 1567 994 1568 +f 1569 1568 1111 +f 1567 1568 1569 +f 1058 1570 1571 +f 1570 1105 1534 +f 1571 1534 1112 +f 1570 1534 1571 +f 563 1572 1573 +f 1572 1112 1536 +f 1573 1536 1359 +f 1572 1536 1573 +f 39 1550 1574 +f 1550 171 1569 +f 1574 1569 1111 +f 1550 1569 1574 +f 1027 1575 1576 +f 1575 55 1552 +f 1576 1552 1332 +f 1575 1552 1576 +f 661 1577 1578 +f 1577 473 1544 +f 1578 1544 1499 +f 1577 1544 1578 +f 39 1579 1551 +f 1579 269 1580 +f 1551 1580 739 +f 1579 1580 1551 +f 1359 1562 1582 +f 1562 717 1581 +f 1582 1581 1488 +f 1562 1581 1582 +f 101 1583 1584 +f 1583 896 1558 +f 1584 1558 1015 +f 1583 1558 1584 +f 1 1585 1587 +f 1585 738 1586 +f 1587 1586 907 +f 1585 1586 1587 +f 738 1585 1589 +f 1585 1 1588 +f 1589 1588 812 +f 1585 1588 1589 +f 907 1586 1591 +f 1586 738 1590 +f 1591 1590 1360 +f 1586 1590 1591 +f 1165 1524 1593 +f 1524 1342 1592 +f 1593 1592 1378 +f 1524 1592 1593 +f 1274 1531 1595 +f 1531 841 1594 +f 1595 1594 1344 +f 1531 1594 1595 +f 25 1528 1540 +f 1528 1119 1596 +f 1540 1596 1332 +f 1528 1596 1540 +f 208 1597 1598 +f 1597 543 1545 +f 1598 1545 739 +f 1597 1545 1598 +f 31 1599 1601 +f 1599 393 1600 +f 1601 1600 1058 +f 1599 1600 1601 +f 31 1601 1602 +f 1601 1058 1571 +f 1602 1571 1112 +f 1601 1571 1602 +f 55 1575 1538 +f 1575 1027 1603 +f 1538 1603 1342 +f 1575 1603 1538 +f 1274 1604 1510 +f 1604 1343 1605 +f 1510 1605 1499 +f 1604 1605 1510 +f 269 1579 1607 +f 1579 39 1606 +f 1607 1606 1141 +f 1579 1606 1607 +f 39 1574 1606 +f 1574 1111 1608 +f 1606 1608 1141 +f 1574 1608 1606 +f 563 1609 1572 +f 1609 31 1602 +f 1572 1602 1112 +f 1609 1602 1572 +f 1343 1610 1605 +f 1610 661 1578 +f 1605 1578 1499 +f 1610 1578 1605 +f 1218 1611 1613 +f 1611 42 1612 +f 1613 1612 1445 +f 1611 1612 1613 +f 42 1614 1612 +f 1614 898 1615 +f 1612 1615 1445 +f 1614 1615 1612 +f 636 1616 1618 +f 1616 839 1617 +f 1618 1617 1168 +f 1616 1617 1618 +f 995 1619 1621 +f 1619 433 1620 +f 1621 1620 1133 +f 1619 1620 1621 +f 831 1622 1623 +f 1622 433 1619 +f 1623 1619 995 +f 1622 1619 1623 +f 1000 1624 1625 +f 1624 995 1621 +f 1625 1621 1133 +f 1624 1621 1625 +f 59 1626 1627 +f 1626 636 1618 +f 1627 1618 1168 +f 1626 1618 1627 +f 1 1587 1629 +f 1587 907 1628 +f 1629 1628 1009 +f 1587 1628 1629 +f 812 1588 1630 +f 1588 1 1629 +f 1630 1629 1009 +f 1588 1629 1630 +f 831 1631 1633 +f 1631 1296 1632 +f 1633 1632 1473 +f 1631 1632 1633 +f 831 1623 1631 +f 1623 995 1634 +f 1631 1634 1296 +f 1623 1634 1631 +f 1255 1553 1636 +f 1553 712 1635 +f 1636 1635 1327 +f 1553 1635 1636 +f 101 1637 1583 +f 1637 801 1638 +f 1583 1638 896 +f 1637 1638 1583 +f 995 1639 1634 +f 1639 645 1640 +f 1634 1640 1296 +f 1639 1640 1634 +f 645 1639 1641 +f 1639 995 1624 +f 1641 1624 1000 +f 1639 1624 1641 +f 981 1642 1643 +f 1642 717 1561 +f 1643 1561 1105 +f 1642 1561 1643 +f 712 1513 1635 +f 1513 1165 1644 +f 1635 1644 1327 +f 1513 1644 1635 +f 880 1645 1646 +f 1645 1255 1636 +f 1646 1636 1327 +f 1645 1636 1646 +f 1071 1647 1648 +f 1647 1119 1556 +f 1648 1556 1255 +f 1647 1556 1648 +f 880 1649 1645 +f 1649 1071 1648 +f 1645 1648 1255 +f 1649 1648 1645 +f 801 1650 1638 +f 1650 841 1559 +f 1638 1559 896 +f 1650 1559 1638 +f 919 1651 1653 +f 1651 930 1652 +f 1653 1652 1318 +f 1651 1652 1653 +f 919 1566 1651 +f 1566 543 1654 +f 1651 1654 930 +f 1566 1654 1651 +f 994 1563 1655 +f 1563 919 1653 +f 1655 1653 1318 +f 1563 1653 1655 +f 144 1656 1657 +f 1656 738 1589 +f 1657 1589 812 +f 1656 1589 1657 +f 738 1656 1659 +f 1656 144 1658 +f 1659 1658 962 +f 1656 1658 1659 +f 645 1660 1640 +f 1660 394 1661 +f 1640 1661 1296 +f 1660 1661 1640 +f 1378 1662 1663 +f 1662 1359 1582 +f 1663 1582 1488 +f 1662 1582 1663 +f 1327 1644 1664 +f 1644 1165 1593 +f 1664 1593 1378 +f 1644 1593 1664 +f 101 1584 1666 +f 1584 1015 1665 +f 1666 1665 1055 +f 1584 1665 1666 +f 1015 1517 1665 +f 1517 1012 1667 +f 1665 1667 1055 +f 1517 1667 1665 +f 801 1668 1650 +f 1668 91 1669 +f 1650 1669 841 +f 1668 1669 1650 +f 841 1669 1594 +f 1669 91 1670 +f 1594 1670 1344 +f 1669 1670 1594 +f 738 1659 1590 +f 1659 962 1671 +f 1590 1671 1360 +f 1659 1671 1590 +f 962 1672 1671 +f 1672 514 1673 +f 1671 1673 1360 +f 1672 1673 1671 +f 1119 1674 1596 +f 1674 300 1675 +f 1596 1675 1332 +f 1674 1675 1596 +f 1012 1676 1667 +f 1676 29 1677 +f 1667 1677 1055 +f 1676 1677 1667 +f 935 1678 1679 +f 1678 29 1676 +f 1679 1676 1012 +f 1678 1676 1679 +f 473 1680 1542 +f 1680 935 1679 +f 1542 1679 1012 +f 1680 1679 1542 +f 543 1597 1654 +f 1597 208 1681 +f 1654 1681 930 +f 1597 1681 1654 +f 689 1682 1683 +f 1682 563 1573 +f 1683 1573 1359 +f 1682 1573 1683 +f 1343 1604 1684 +f 1604 1274 1595 +f 1684 1595 1344 +f 1604 1595 1684 +f 243 1685 1686 +f 1685 31 1609 +f 1686 1609 563 +f 1685 1609 1686 +f 243 1686 1687 +f 1686 563 1682 +f 1687 1682 689 +f 1686 1682 1687 +f 1051 1688 1689 +f 1688 42 1611 +f 1689 1611 1218 +f 1688 1611 1689 +f 898 1614 1690 +f 1614 42 1688 +f 1690 1688 1051 +f 1614 1688 1690 +f 124 1691 1693 +f 1691 839 1692 +f 1693 1692 1143 +f 1691 1692 1693 +f 839 1694 1617 +f 1694 1042 1695 +f 1617 1695 1168 +f 1694 1695 1617 +f 839 1691 1694 +f 1691 124 1696 +f 1694 1696 1042 +f 1691 1696 1694 +f 898 1697 1615 +f 1697 932 1698 +f 1615 1698 1445 +f 1697 1698 1615 +f 839 1616 1692 +f 1616 636 1699 +f 1692 1699 1143 +f 1616 1699 1692 +f 710 1700 1701 +f 1700 1218 1613 +f 1701 1613 1445 +f 1700 1613 1701 +f 932 1702 1698 +f 1702 710 1701 +f 1698 1701 1445 +f 1702 1701 1698 +f 323 1703 1705 +f 1703 1143 1704 +f 1705 1704 1449 +f 1703 1704 1705 +f 1143 1699 1704 +f 1699 636 1706 +f 1704 1706 1449 +f 1699 1706 1704 +f 384 1707 1708 +f 1707 59 1627 +f 1708 1627 1168 +f 1707 1627 1708 +f 303 1709 1710 +f 1709 812 1630 +f 1710 1630 1009 +f 1709 1630 1710 +f 710 1702 1712 +f 1702 932 1711 +f 1712 1711 1497 +f 1702 1711 1712 +f 636 1626 1706 +f 1626 59 1713 +f 1706 1713 1449 +f 1626 1713 1706 +f 1009 1628 1715 +f 1628 907 1714 +f 1715 1714 1407 +f 1628 1714 1715 +f 645 1641 1717 +f 1641 1000 1716 +f 1717 1716 1106 +f 1641 1716 1717 +f 1000 1718 1716 +f 1718 117 1719 +f 1716 1719 1106 +f 1718 1719 1716 +f 717 1642 1581 +f 1642 981 1720 +f 1581 1720 1488 +f 1642 1720 1581 +f 303 1721 1709 +f 1721 144 1657 +f 1709 1657 812 +f 1721 1657 1709 +f 645 1717 1723 +f 1717 1106 1722 +f 1723 1722 1417 +f 1717 1722 1723 +f 554 1724 1725 +f 1724 994 1655 +f 1725 1655 1318 +f 1724 1655 1725 +f 981 1643 1727 +f 1643 1105 1726 +f 1727 1726 1417 +f 1643 1726 1727 +f 1105 1570 1726 +f 1570 1058 1728 +f 1726 1728 1417 +f 1570 1728 1726 +f 930 1681 1730 +f 1681 208 1729 +f 1730 1729 1344 +f 1681 1729 1730 +f 994 1731 1568 +f 1731 318 1732 +f 1568 1732 1111 +f 1731 1732 1568 +f 554 1733 1724 +f 1733 318 1731 +f 1724 1731 994 +f 1733 1731 1724 +f 144 1734 1658 +f 1734 427 1735 +f 1658 1735 962 +f 1734 1735 1658 +f 1058 1600 1728 +f 1600 393 1736 +f 1728 1736 1417 +f 1600 1736 1728 +f 689 1683 1737 +f 1683 1359 1662 +f 1737 1662 1378 +f 1683 1662 1737 +f 1342 1738 1592 +f 1738 689 1737 +f 1592 1737 1378 +f 1738 1737 1592 +f 1111 1732 1740 +f 1732 318 1739 +f 1740 1739 1428 +f 1732 1739 1740 +f 1141 1608 1741 +f 1608 1111 1740 +f 1741 1740 1428 +f 1608 1740 1741 +f 1027 1742 1603 +f 1742 689 1738 +f 1603 1738 1342 +f 1742 1738 1603 +f 300 1743 1675 +f 1743 1075 1744 +f 1675 1744 1332 +f 1743 1744 1675 +f 473 1577 1680 +f 1577 661 1745 +f 1680 1745 935 +f 1577 1745 1680 +f 1075 1746 1744 +f 1746 1027 1576 +f 1744 1576 1332 +f 1746 1576 1744 +f 269 1607 1748 +f 1607 1141 1747 +f 1748 1747 1162 +f 1607 1747 1748 +f 739 1580 1749 +f 1580 269 1748 +f 1749 1748 1162 +f 1580 1748 1749 +f 898 1750 1697 +f 1750 19 1751 +f 1697 1751 932 +f 1750 1751 1697 +f 1042 1752 1695 +f 1752 384 1708 +f 1695 1708 1168 +f 1752 1708 1695 +f 433 1753 1620 +f 1753 568 1754 +f 1620 1754 1133 +f 1753 1754 1620 +f 568 1755 1754 +f 1755 536 1756 +f 1754 1756 1133 +f 1755 1756 1754 +f 536 1757 1756 +f 1757 1000 1625 +f 1756 1625 1133 +f 1757 1625 1756 +f 536 1758 1757 +f 1758 117 1718 +f 1757 1718 1000 +f 1758 1718 1757 +f 981 1759 1720 +f 1759 166 1760 +f 1720 1760 1488 +f 1759 1760 1720 +f 166 1761 1760 +f 1761 1262 1762 +f 1760 1762 1488 +f 1761 1762 1760 +f 1193 1763 1765 +f 1763 930 1764 +f 1765 1764 1272 +f 1763 1764 1765 +f 930 1763 1652 +f 1763 1193 1766 +f 1652 1766 1318 +f 1763 1766 1652 +f 166 1759 1767 +f 1759 981 1727 +f 1767 1727 1417 +f 1759 1727 1767 +f 1346 1768 1769 +f 1768 1327 1664 +f 1769 1664 1378 +f 1768 1664 1769 +f 880 1646 1770 +f 1646 1327 1768 +f 1770 1768 1346 +f 1646 1768 1770 +f 101 1771 1637 +f 1771 343 1772 +f 1637 1772 801 +f 1771 1772 1637 +f 343 1771 1773 +f 1771 101 1666 +f 1773 1666 1055 +f 1771 1666 1773 +f 801 1772 1775 +f 1772 343 1774 +f 1775 1774 1272 +f 1772 1774 1775 +f 1272 1764 1776 +f 1764 930 1730 +f 1776 1730 1344 +f 1764 1730 1776 +f 91 1777 1670 +f 1777 1272 1776 +f 1670 1776 1344 +f 1777 1776 1670 +f 91 1668 1777 +f 1668 801 1775 +f 1777 1775 1272 +f 1668 1775 1777 +f 1193 1778 1766 +f 1778 554 1725 +f 1766 1725 1318 +f 1778 1725 1766 +f 907 1591 1780 +f 1591 1360 1779 +f 1780 1779 1483 +f 1591 1779 1780 +f 1407 1714 1781 +f 1714 907 1780 +f 1781 1780 1483 +f 1714 1780 1781 +f 1296 1782 1632 +f 1782 290 1783 +f 1632 1783 1473 +f 1782 1783 1632 +f 394 1784 1661 +f 1784 290 1782 +f 1661 1782 1296 +f 1784 1782 1661 +f 1346 1769 1785 +f 1769 1378 1663 +f 1785 1663 1488 +f 1769 1663 1785 +f 1071 1786 1647 +f 1786 966 1787 +f 1647 1787 1119 +f 1786 1787 1647 +f 1360 1673 1779 +f 1673 514 1788 +f 1779 1788 1483 +f 1673 1788 1779 +f 966 1789 1787 +f 1789 300 1674 +f 1787 1674 1119 +f 1789 1674 1787 +f 295 1790 1791 +f 1790 514 1672 +f 1791 1672 962 +f 1790 1672 1791 +f 393 1792 1736 +f 1792 37 1793 +f 1736 1793 1417 +f 1792 1793 1736 +f 37 1792 1795 +f 1792 393 1794 +f 1795 1794 1306 +f 1792 1794 1795 +f 268 1796 1797 +f 1796 689 1742 +f 1797 1742 1027 +f 1796 1742 1797 +f 626 1798 1799 +f 1798 1343 1684 +f 1799 1684 1344 +f 1798 1684 1799 +f 208 1800 1729 +f 1800 626 1799 +f 1729 1799 1344 +f 1800 1799 1729 +f 626 1800 1801 +f 1800 208 1598 +f 1801 1598 739 +f 1800 1598 1801 +f 393 1599 1794 +f 1599 31 1802 +f 1794 1802 1306 +f 1599 1802 1794 +f 31 1685 1802 +f 1685 243 1803 +f 1802 1803 1306 +f 1685 1803 1802 +f 243 1687 1803 +f 1687 689 1804 +f 1803 1804 1306 +f 1687 1804 1803 +f 268 1797 1805 +f 1797 1027 1746 +f 1805 1746 1075 +f 1797 1746 1805 +f 661 1806 1745 +f 1806 141 1807 +f 1745 1807 935 +f 1806 1807 1745 +f 626 1801 1808 +f 1801 739 1749 +f 1808 1749 1162 +f 1801 1749 1808 +f 944 1809 1810 +f 1809 1051 1689 +f 1810 1689 1218 +f 1809 1689 1810 +f 898 1690 1812 +f 1690 1051 1811 +f 1812 1811 1251 +f 1690 1811 1812 +f 221 1813 1814 +f 1813 124 1693 +f 1814 1693 1143 +f 1813 1693 1814 +f 175 1815 1816 +f 1815 124 1813 +f 1816 1813 221 +f 1815 1813 1816 +f 124 1815 1696 +f 1815 175 1817 +f 1696 1817 1042 +f 1815 1817 1696 +f 1042 1817 1819 +f 1817 175 1818 +f 1819 1818 1328 +f 1817 1818 1819 +f 233 1820 1821 +f 1820 944 1810 +f 1821 1810 1218 +f 1820 1810 1821 +f 19 1750 1822 +f 1750 898 1812 +f 1822 1812 1251 +f 1750 1812 1822 +f 384 1752 1823 +f 1752 1042 1819 +f 1823 1819 1328 +f 1752 1819 1823 +f 397 1824 1825 +f 1824 233 1821 +f 1825 1821 1218 +f 1824 1821 1825 +f 710 1826 1700 +f 1826 397 1825 +f 1700 1825 1218 +f 1826 1825 1700 +f 932 1751 1828 +f 1751 19 1827 +f 1828 1827 1239 +f 1751 1827 1828 +f 982 1829 1830 +f 1829 384 1823 +f 1830 1823 1328 +f 1829 1823 1830 +f 166 1831 1761 +f 1831 675 1832 +f 1761 1832 1262 +f 1831 1832 1761 +f 1262 1833 1762 +f 1833 1346 1785 +f 1762 1785 1488 +f 1833 1785 1762 +f 1262 1834 1833 +f 1834 1177 1835 +f 1833 1835 1346 +f 1834 1835 1833 +f 397 1826 1837 +f 1826 710 1836 +f 1837 1836 1018 +f 1826 1836 1837 +f 932 1828 1711 +f 1828 1239 1838 +f 1711 1838 1497 +f 1828 1838 1711 +f 344 1839 1840 +f 1839 323 1705 +f 1840 1705 1449 +f 1839 1705 1840 +f 59 1841 1843 +f 1841 1149 1842 +f 1843 1842 1375 +f 1841 1842 1843 +f 59 1843 1713 +f 1843 1375 1844 +f 1713 1844 1449 +f 1843 1844 1713 +f 384 1829 1846 +f 1829 982 1845 +f 1846 1845 1149 +f 1829 1845 1846 +f 59 1707 1841 +f 1707 384 1846 +f 1841 1846 1149 +f 1707 1846 1841 +f 862 1847 1848 +f 1847 1009 1715 +f 1848 1715 1407 +f 1847 1715 1848 +f 23 1849 1850 +f 1849 433 1622 +f 1850 1622 831 +f 1849 1622 1850 +f 433 1849 1753 +f 1849 23 1851 +f 1753 1851 568 +f 1849 1851 1753 +f 117 1758 1853 +f 1758 536 1852 +f 1853 1852 675 +f 1758 1852 1853 +f 1177 1854 1835 +f 1854 880 1770 +f 1835 1770 1346 +f 1854 1770 1835 +f 1071 1649 1855 +f 1649 880 1854 +f 1855 1854 1177 +f 1649 1854 1855 +f 1018 1836 1856 +f 1836 710 1712 +f 1856 1712 1497 +f 1836 1712 1856 +f 1156 1857 1858 +f 1857 554 1778 +f 1858 1778 1193 +f 1857 1778 1858 +f 1156 1859 1861 +f 1859 570 1860 +f 1861 1860 1407 +f 1859 1860 1861 +f 862 1862 1847 +f 1862 303 1710 +f 1847 1710 1009 +f 1862 1710 1847 +f 303 1862 1864 +f 1862 862 1863 +f 1864 1863 923 +f 1862 1863 1864 +f 23 1850 1865 +f 1850 831 1633 +f 1865 1633 1473 +f 1850 1633 1865 +f 117 1853 1719 +f 1853 675 1866 +f 1719 1866 1106 +f 1853 1866 1719 +f 675 1831 1866 +f 1831 166 1867 +f 1866 1867 1106 +f 1831 1867 1866 +f 1106 1867 1722 +f 1867 166 1767 +f 1722 1767 1417 +f 1867 1767 1722 +f 318 1733 1869 +f 1733 554 1868 +f 1869 1868 1483 +f 1733 1868 1869 +f 554 1857 1868 +f 1857 1156 1870 +f 1868 1870 1483 +f 1857 1870 1868 +f 1156 1861 1870 +f 1861 1407 1781 +f 1870 1781 1483 +f 1861 1781 1870 +f 427 1734 1872 +f 1734 144 1871 +f 1872 1871 923 +f 1734 1871 1872 +f 144 1721 1871 +f 1721 303 1864 +f 1871 1864 923 +f 1721 1864 1871 +f 427 1873 1735 +f 1873 295 1791 +f 1735 1791 962 +f 1873 1791 1735 +f 290 1784 1875 +f 1784 394 1874 +f 1875 1874 846 +f 1784 1874 1875 +f 394 1660 1874 +f 1660 645 1876 +f 1874 1876 846 +f 1660 1876 1874 +f 846 1876 1877 +f 1876 645 1723 +f 1877 1723 1417 +f 1876 1723 1877 +f 1428 1739 1878 +f 1739 318 1869 +f 1878 1869 1483 +f 1739 1869 1878 +f 689 1796 1804 +f 1796 268 1879 +f 1804 1879 1306 +f 1796 1879 1804 +f 661 1610 1881 +f 1610 1343 1880 +f 1881 1880 1410 +f 1610 1880 1881 +f 1141 1882 1747 +f 1882 26 1883 +f 1747 1883 1162 +f 1882 1883 1747 +f 1142 1884 1886 +f 1884 991 1885 +f 1886 1885 1319 +f 1884 1885 1886 +f 1051 1809 1888 +f 1809 944 1887 +f 1888 1887 1415 +f 1809 1887 1888 +f 1251 1811 1889 +f 1811 1051 1888 +f 1889 1888 1415 +f 1811 1888 1889 +f 625 1890 1891 +f 1890 19 1822 +f 1891 1822 1251 +f 1890 1822 1891 +f 271 1892 1893 +f 1892 221 1814 +f 1893 1814 1143 +f 1892 1814 1893 +f 1193 1894 1896 +f 1894 787 1895 +f 1896 1895 1302 +f 1894 1895 1896 +f 675 1897 1832 +f 1897 1147 1898 +f 1832 1898 1262 +f 1897 1898 1832 +f 1177 1834 1900 +f 1834 1262 1899 +f 1900 1899 1383 +f 1834 1899 1900 +f 656 1901 1902 +f 1901 1177 1900 +f 1902 1900 1383 +f 1901 1900 1902 +f 19 1890 1827 +f 1890 625 1903 +f 1827 1903 1239 +f 1890 1903 1827 +f 787 1894 1904 +f 1894 1193 1765 +f 1904 1765 1272 +f 1894 1765 1904 +f 1156 1858 1905 +f 1858 1193 1896 +f 1905 1896 1302 +f 1858 1896 1905 +f 656 1906 1901 +f 1906 311 1907 +f 1901 1907 1177 +f 1906 1907 1901 +f 3 1908 1910 +f 1908 343 1909 +f 1910 1909 1404 +f 1908 1909 1910 +f 343 1908 1774 +f 1908 3 1911 +f 1774 1911 1272 +f 1908 1911 1774 +f 3 1912 1911 +f 1912 787 1904 +f 1911 1904 1272 +f 1912 1904 1911 +f 536 1913 1852 +f 1913 181 1914 +f 1852 1914 675 +f 1913 1914 1852 +f 181 1913 1915 +f 1913 536 1755 +f 1915 1755 568 +f 1913 1755 1915 +f 966 1786 1916 +f 1786 1071 1855 +f 1916 1855 1177 +f 1786 1855 1916 +f 1375 1917 1844 +f 1917 87 1918 +f 1844 1918 1449 +f 1917 1918 1844 +f 87 1919 1918 +f 1919 344 1840 +f 1918 1840 1449 +f 1919 1840 1918 +f 570 1920 1860 +f 1920 862 1848 +f 1860 1848 1407 +f 1920 1848 1860 +f 923 1863 1922 +f 1863 862 1921 +f 1922 1921 1463 +f 1863 1921 1922 +f 343 1773 1909 +f 1773 1055 1923 +f 1909 1923 1404 +f 1773 1923 1909 +f 29 1924 1677 +f 1924 167 1925 +f 1677 1925 1055 +f 1924 1925 1677 +f 167 1924 1926 +f 1924 29 1678 +f 1926 1678 935 +f 1924 1678 1926 +f 514 1927 1788 +f 1927 1428 1878 +f 1788 1878 1483 +f 1927 1878 1788 +f 37 1928 1793 +f 1928 846 1877 +f 1793 1877 1417 +f 1928 1877 1793 +f 514 1790 1927 +f 1790 295 1929 +f 1927 1929 1428 +f 1790 1929 1927 +f 240 1930 1931 +f 1930 268 1805 +f 1931 1805 1075 +f 1930 1805 1931 +f 300 1932 1743 +f 1932 50 1933 +f 1743 1933 1075 +f 1932 1933 1743 +f 1343 1798 1880 +f 1798 626 1934 +f 1880 1934 1410 +f 1798 1934 1880 +f 268 1930 1879 +f 1930 240 1935 +f 1879 1935 1306 +f 1930 1935 1879 +f 141 1806 1936 +f 1806 661 1881 +f 1936 1881 1410 +f 1806 1881 1936 +f 626 1808 1934 +f 1808 1162 1937 +f 1934 1937 1410 +f 1808 1937 1934 +f 27 1938 1940 +f 1938 676 1939 +f 1940 1939 1225 +f 1938 1939 1940 +f 676 1941 1939 +f 1941 440 1942 +f 1939 1942 1225 +f 1941 1942 1939 +f 1189 1943 1944 +f 1943 27 1940 +f 1944 1940 1225 +f 1943 1940 1944 +f 365 1945 1947 +f 1945 1037 1946 +f 1947 1946 1169 +f 1945 1946 1947 +f 365 1948 1945 +f 1948 1029 1949 +f 1945 1949 1037 +f 1948 1949 1945 +f 27 1950 1938 +f 1950 139 1951 +f 1938 1951 676 +f 1950 1951 1938 +f 1037 1952 1946 +f 1952 744 1953 +f 1946 1953 1169 +f 1952 1953 1946 +f 752 1954 1956 +f 1954 253 1955 +f 1956 1955 1319 +f 1954 1955 1956 +f 1319 1955 1958 +f 1955 253 1957 +f 1958 1957 1467 +f 1955 1957 1958 +f 991 1959 1885 +f 1959 752 1956 +f 1885 1956 1319 +f 1959 1956 1885 +f 752 1959 1961 +f 1959 991 1960 +f 1961 1960 1258 +f 1959 1960 1961 +f 355 1962 1963 +f 1962 1319 1958 +f 1963 1958 1467 +f 1962 1958 1963 +f 355 1964 1962 +f 1964 1142 1886 +f 1962 1886 1319 +f 1964 1886 1962 +f 355 1965 1964 +f 1965 659 1966 +f 1964 1966 1142 +f 1965 1966 1964 +f 991 1967 1969 +f 1967 858 1968 +f 1969 1968 1069 +f 1967 1968 1969 +f 858 1967 1970 +f 1967 991 1884 +f 1970 1884 1142 +f 1967 1884 1970 +f 659 1971 1966 +f 1971 858 1970 +f 1966 1970 1142 +f 1971 1970 1966 +f 175 1972 1818 +f 1972 1314 1973 +f 1818 1973 1328 +f 1972 1973 1818 +f 175 1816 1972 +f 1816 221 1974 +f 1972 1974 1314 +f 1816 1974 1972 +f 1262 1898 1899 +f 1898 1147 1975 +f 1899 1975 1383 +f 1898 1975 1899 +f 625 1891 1976 +f 1891 1251 1889 +f 1976 1889 1415 +f 1891 1889 1976 +f 1328 1977 1979 +f 1977 1166 1978 +f 1979 1978 1379 +f 1977 1978 1979 +f 787 1912 1981 +f 1912 3 1980 +f 1981 1980 1379 +f 1912 1980 1981 +f 233 1982 1820 +f 1982 656 1983 +f 1820 1983 944 +f 1982 1983 1820 +f 881 1984 1985 +f 1984 271 1893 +f 1985 1893 1143 +f 1984 1893 1985 +f 323 1986 1703 +f 1986 881 1985 +f 1703 1985 1143 +f 1986 1985 1703 +f 982 1830 1987 +f 1830 1328 1979 +f 1987 1979 1379 +f 1830 1979 1987 +f 1283 1988 1989 +f 1988 1156 1905 +f 1989 1905 1302 +f 1988 1905 1989 +f 1156 1988 1991 +f 1988 1283 1990 +f 1991 1990 1463 +f 1988 1990 1991 +f 233 1992 1982 +f 1992 311 1906 +f 1982 1906 656 +f 1992 1906 1982 +f 311 1992 1993 +f 1992 233 1824 +f 1993 1824 397 +f 1992 1824 1993 +f 1239 1994 1838 +f 1994 129 1995 +f 1838 1995 1497 +f 1994 1995 1838 +f 982 1987 1997 +f 1987 1379 1996 +f 1997 1996 1404 +f 1987 1996 1997 +f 1379 1980 1996 +f 1980 3 1910 +f 1996 1910 1404 +f 1980 1910 1996 +f 570 1859 1998 +f 1859 1156 1991 +f 1998 1991 1463 +f 1859 1991 1998 +f 568 1851 2000 +f 1851 23 1999 +f 2000 1999 650 +f 1851 1999 2000 +f 181 1915 2001 +f 1915 568 2000 +f 2001 2000 650 +f 1915 2000 2001 +f 1093 2002 2003 +f 2002 966 1916 +f 2003 1916 1177 +f 2002 1916 2003 +f 311 2004 1907 +f 2004 1093 2003 +f 1907 2003 1177 +f 2004 2003 1907 +f 311 1993 2004 +f 1993 397 2005 +f 2004 2005 1093 +f 1993 2005 2004 +f 323 1839 1986 +f 1839 344 2006 +f 1986 2006 881 +f 1839 2006 1986 +f 1149 1845 2007 +f 1845 982 1997 +f 2007 1997 1404 +f 1845 1997 2007 +f 1375 1842 2008 +f 1842 1149 2007 +f 2008 2007 1404 +f 1842 2007 2008 +f 862 1920 1921 +f 1920 570 1998 +f 1921 1998 1463 +f 1920 1998 1921 +f 397 1837 2005 +f 1837 1018 2009 +f 2005 2009 1093 +f 1837 2009 2005 +f 1199 2010 2012 +f 2010 967 2011 +f 2012 2011 1473 +f 2010 2011 2012 +f 290 2013 1783 +f 2013 1199 2012 +f 1783 2012 1473 +f 2013 2012 1783 +f 1055 1925 1923 +f 1925 167 2014 +f 1923 2014 1404 +f 1925 2014 1923 +f 167 2015 2014 +f 2015 870 2016 +f 2014 2016 1404 +f 2015 2016 2014 +f 45 2017 2019 +f 2017 427 2018 +f 2019 2018 1254 +f 2017 2018 2019 +f 45 2020 2017 +f 2020 295 1873 +f 2017 1873 427 +f 2020 1873 2017 +f 50 1932 2022 +f 1932 300 2021 +f 2022 2021 1217 +f 1932 2021 2022 +f 300 1789 2021 +f 1789 966 2023 +f 2021 2023 1217 +f 1789 2023 2021 +f 781 2024 2025 +f 2024 167 1926 +f 2025 1926 935 +f 2024 1926 2025 +f 50 2026 1933 +f 2026 653 2027 +f 1933 2027 1075 +f 2026 2027 1933 +f 141 2028 2030 +f 2028 328 2029 +f 2030 2029 781 +f 2028 2029 2030 +f 141 2030 1807 +f 2030 781 2025 +f 1807 2025 935 +f 2030 2025 1807 +f 1162 1883 1937 +f 1883 26 2031 +f 1937 2031 1410 +f 1883 2031 1937 +f 275 2032 2034 +f 2032 756 2033 +f 2034 2033 1041 +f 2032 2033 2034 +f 591 2035 2037 +f 2035 505 2036 +f 2037 2036 1041 +f 2035 2036 2037 +f 756 2038 2033 +f 2038 591 2037 +f 2033 2037 1041 +f 2038 2037 2033 +f 591 2038 2040 +f 2038 756 2039 +f 2040 2039 1464 +f 2038 2039 2040 +f 505 2041 2036 +f 2041 638 2042 +f 2036 2042 1041 +f 2041 2042 2036 +f 505 2035 2044 +f 2035 591 2043 +f 2044 2043 830 +f 2035 2043 2044 +f 440 2045 1942 +f 2045 214 2046 +f 1942 2046 1225 +f 2045 2046 1942 +f 1029 1948 2048 +f 1948 365 2047 +f 2048 2047 1097 +f 1948 2047 2048 +f 1029 2048 2050 +f 2048 1097 2049 +f 2050 2049 1401 +f 2048 2049 2050 +f 429 2051 2053 +f 2051 474 2052 +f 2053 2052 1351 +f 2051 2052 2053 +f 241 2054 2055 +f 2054 429 2053 +f 2055 2053 1351 +f 2054 2053 2055 +f 524 2056 2057 +f 2056 365 1947 +f 2057 1947 1169 +f 2056 1947 2057 +f 1029 2058 1949 +f 2058 947 2059 +f 1949 2059 1037 +f 2058 2059 1949 +f 223 2060 2062 +f 2060 450 2061 +f 2062 2061 1432 +f 2060 2061 2062 +f 690 2063 2064 +f 2063 223 2062 +f 2064 2062 1432 +f 2063 2062 2064 +f 1039 2065 2066 +f 2065 241 2055 +f 2066 2055 1351 +f 2065 2055 2066 +f 632 2067 2068 +f 2067 1039 2066 +f 2068 2066 1351 +f 2067 2066 2068 +f 139 2069 1951 +f 2069 632 2070 +f 1951 2070 676 +f 2069 2070 1951 +f 495 2071 2072 +f 2071 27 1943 +f 2072 1943 1189 +f 2071 1943 2072 +f 504 2073 2074 +f 2073 495 2072 +f 2074 2072 1189 +f 2073 2072 2074 +f 391 2075 2076 +f 2075 524 2057 +f 2076 2057 1169 +f 2075 2057 2076 +f 450 2077 2061 +f 2077 201 2078 +f 2061 2078 1432 +f 2077 2078 2061 +f 632 2079 2081 +f 2079 68 2080 +f 2081 2080 1406 +f 2079 2080 2081 +f 139 2082 2069 +f 2082 68 2079 +f 2069 2079 632 +f 2082 2079 2069 +f 139 1950 2083 +f 1950 27 2071 +f 2083 2071 495 +f 1950 2071 2083 +f 139 2083 2085 +f 2083 495 2084 +f 2085 2084 1072 +f 2083 2084 2085 +f 792 2086 2087 +f 2086 744 1952 +f 2087 1952 1037 +f 2086 1952 2087 +f 947 2088 2059 +f 2088 792 2087 +f 2059 2087 1037 +f 2088 2087 2059 +f 36 2089 2090 +f 2089 744 2086 +f 2090 2086 792 +f 2089 2086 2090 +f 68 2082 2091 +f 2082 139 2085 +f 2091 2085 1072 +f 2082 2085 2091 +f 744 2092 1953 +f 2092 902 2093 +f 1953 2093 1169 +f 2092 2093 1953 +f 744 2094 2092 +f 2094 805 2095 +f 2092 2095 902 +f 2094 2095 2092 +f 253 1954 2097 +f 1954 752 2096 +f 2097 2096 1260 +f 1954 2096 2097 +f 802 2098 2099 +f 2098 752 1961 +f 2099 1961 1258 +f 2098 1961 2099 +f 253 2100 1957 +f 2100 345 2101 +f 1957 2101 1467 +f 2100 2101 1957 +f 1220 2102 2103 +f 2102 802 2099 +f 2103 2099 1258 +f 2102 2099 2103 +f 1387 2104 2105 +f 2104 355 1963 +f 2105 1963 1467 +f 2104 1963 2105 +f 657 2106 2107 +f 2106 1220 2103 +f 2107 2103 1258 +f 2106 2103 2107 +f 991 2108 1960 +f 2108 657 2107 +f 1960 2107 1258 +f 2108 2107 1960 +f 659 1965 2110 +f 1965 355 2109 +f 2110 2109 1339 +f 1965 2109 2110 +f 71 2111 2113 +f 2111 657 2112 +f 2113 2112 1069 +f 2111 2112 2113 +f 657 2108 2112 +f 2108 991 1969 +f 2112 1969 1069 +f 2108 1969 2112 +f 944 2114 1887 +f 2114 244 2115 +f 1887 2115 1415 +f 2114 2115 1887 +f 1314 2116 1973 +f 2116 1166 1977 +f 1973 1977 1328 +f 2116 1977 1973 +f 1166 2117 1978 +f 2117 787 1981 +f 1978 1981 1379 +f 2117 1981 1978 +f 274 2118 2119 +f 2118 181 2001 +f 2119 2001 650 +f 2118 2001 2119 +f 675 2120 1897 +f 2120 274 2121 +f 1897 2121 1147 +f 2120 2121 1897 +f 181 2118 1914 +f 2118 274 2120 +f 1914 2120 675 +f 2118 2120 1914 +f 656 2122 1983 +f 2122 244 2114 +f 1983 2114 944 +f 2122 2114 1983 +f 23 2123 1999 +f 2123 277 2124 +f 1999 2124 650 +f 2123 2124 1999 +f 1018 2125 2127 +f 2125 1217 2126 +f 2127 2126 1226 +f 2125 2126 2127 +f 1217 2125 2128 +f 2125 1018 1856 +f 2128 1856 1497 +f 2125 1856 2128 +f 870 2129 2016 +f 2129 1375 2008 +f 2016 2008 1404 +f 2129 2008 2016 +f 1219 2130 2131 +f 2130 923 1922 +f 2131 1922 1463 +f 2130 1922 2131 +f 277 2123 2132 +f 2123 23 1865 +f 2132 1865 1473 +f 2123 1865 2132 +f 1093 2009 2133 +f 2009 1018 2127 +f 2133 2127 1226 +f 2009 2127 2133 +f 870 2134 2129 +f 2134 87 1917 +f 2129 1917 1375 +f 2134 1917 2129 +f 966 2002 2135 +f 2002 1093 2133 +f 2135 2133 1226 +f 2002 2133 2135 +f 290 1875 2013 +f 1875 846 2136 +f 2013 2136 1199 +f 1875 2136 2013 +f 295 2020 1929 +f 2020 45 2137 +f 1929 2137 1428 +f 2020 2137 1929 +f 846 1928 2138 +f 1928 37 1795 +f 2138 1795 1306 +f 1928 1795 2138 +f 1199 2136 2139 +f 2136 846 2138 +f 2139 2138 1306 +f 2136 2138 2139 +f 26 1882 2140 +f 1882 1141 1741 +f 2140 1741 1428 +f 1882 1741 2140 +f 756 2032 2142 +f 2032 275 2141 +f 2142 2141 1178 +f 2032 2141 2142 +f 16 2143 2145 +f 2143 249 2144 +f 2145 2144 1041 +f 2143 2144 2145 +f 249 2146 2144 +f 2146 275 2034 +f 2144 2034 1041 +f 2146 2034 2144 +f 756 2147 2039 +f 2147 969 2148 +f 2039 2148 1464 +f 2147 2148 2039 +f 969 2147 2149 +f 2147 756 2142 +f 2149 2142 1178 +f 2147 2142 2149 +f 638 2150 2042 +f 2150 965 2151 +f 2042 2151 1041 +f 2150 2151 2042 +f 965 2152 2151 +f 2152 16 2145 +f 2151 2145 1041 +f 2152 2145 2151 +f 969 2153 2148 +f 2153 1393 2154 +f 2148 2154 1464 +f 2153 2154 2148 +f 1393 2155 2154 +f 2155 1056 2156 +f 2154 2156 1464 +f 2155 2156 2154 +f 1056 2157 2156 +f 2157 204 2158 +f 2156 2158 1464 +f 2157 2158 2156 +f 638 2041 2160 +f 2041 505 2159 +f 2160 2159 959 +f 2041 2159 2160 +f 505 2044 2159 +f 2044 830 2161 +f 2159 2161 959 +f 2044 2161 2159 +f 591 2162 2043 +f 2162 204 2163 +f 2043 2163 830 +f 2162 2163 2043 +f 204 2162 2158 +f 2162 591 2040 +f 2158 2040 1464 +f 2162 2040 2158 +f 214 2164 2046 +f 2164 1139 2165 +f 2046 2165 1225 +f 2164 2165 2046 +f 1225 2165 2167 +f 2165 1139 2166 +f 2167 2166 1419 +f 2165 2166 2167 +f 1367 2168 2169 +f 2168 1029 2050 +f 2169 2050 1401 +f 2168 2050 2169 +f 429 2170 2051 +f 2170 356 2171 +f 2051 2171 474 +f 2170 2171 2051 +f 474 2172 2174 +f 2172 773 2173 +f 2174 2173 1442 +f 2172 2173 2174 +f 1189 1944 2175 +f 1944 1225 2167 +f 2175 2167 1419 +f 1944 2167 2175 +f 1124 2176 2178 +f 2176 109 2177 +f 2178 2177 1432 +f 2176 2177 2178 +f 109 2179 2177 +f 2179 690 2064 +f 2177 2064 1432 +f 2179 2064 2177 +f 172 2180 2181 +f 2180 356 2170 +f 2181 2170 429 +f 2180 2170 2181 +f 474 2182 2052 +f 2182 730 2183 +f 2052 2183 1351 +f 2182 2183 2052 +f 730 2182 2184 +f 2182 474 2174 +f 2184 2174 1442 +f 2182 2174 2184 +f 440 1941 2186 +f 1941 676 2185 +f 2186 2185 730 +f 1941 2185 2186 +f 365 2056 2047 +f 2056 524 2187 +f 2047 2187 1097 +f 2056 2187 2047 +f 1124 2188 2189 +f 2188 1029 2168 +f 2189 2168 1367 +f 2188 2168 2189 +f 241 2190 2054 +f 2190 172 2181 +f 2054 2181 429 +f 2190 2181 2054 +f 730 2191 2183 +f 2191 632 2068 +f 2183 2068 1351 +f 2191 2068 2183 +f 676 2070 2185 +f 2070 632 2191 +f 2185 2191 730 +f 2070 2191 2185 +f 947 2058 2192 +f 2058 1029 2188 +f 2192 2188 1124 +f 2058 2188 2192 +f 201 2193 2078 +f 2193 947 2194 +f 2078 2194 1432 +f 2193 2194 2078 +f 947 2192 2194 +f 2192 1124 2178 +f 2194 2178 1432 +f 2192 2178 2194 +f 495 2073 2196 +f 2073 504 2195 +f 2196 2195 1031 +f 2073 2195 2196 +f 524 2075 2198 +f 2075 391 2197 +f 2198 2197 1063 +f 2075 2197 2198 +f 201 2199 2193 +f 2199 792 2088 +f 2193 2088 947 +f 2199 2088 2193 +f 201 2200 2199 +f 2200 512 2201 +f 2199 2201 792 +f 2200 2201 2199 +f 201 2077 2200 +f 2077 450 2202 +f 2200 2202 512 +f 2077 2202 2200 +f 495 2196 2084 +f 2196 1031 2203 +f 2084 2203 1072 +f 2196 2203 2084 +f 1031 2204 2203 +f 2204 485 2205 +f 2203 2205 1072 +f 2204 2205 2203 +f 902 2206 2093 +f 2206 391 2076 +f 2093 2076 1169 +f 2206 2076 2093 +f 744 2089 2094 +f 2089 36 2207 +f 2094 2207 805 +f 2089 2207 2094 +f 666 2208 2209 +f 2208 253 2097 +f 2209 2097 1260 +f 2208 2097 2209 +f 752 2210 2096 +f 2210 595 2211 +f 2096 2211 1260 +f 2210 2211 2096 +f 595 2210 2212 +f 2210 752 2098 +f 2212 2098 802 +f 2210 2098 2212 +f 345 2100 2213 +f 2100 253 2208 +f 2213 2208 666 +f 2100 2208 2213 +f 1220 2106 2215 +f 2106 657 2214 +f 2215 2214 1459 +f 2106 2214 2215 +f 1339 2109 2216 +f 2109 355 2104 +f 2216 2104 1387 +f 2109 2104 2216 +f 858 1971 2218 +f 1971 659 2217 +f 2218 2217 1308 +f 1971 2217 2218 +f 192 2219 2221 +f 2219 390 2220 +f 2221 2220 1147 +f 2219 2220 2221 +f 1147 2220 1975 +f 2220 390 2222 +f 1975 2222 1383 +f 2220 2222 1975 +f 145 2223 2224 +f 2223 1283 1989 +f 2224 1989 1302 +f 2223 1989 2224 +f 876 2225 2227 +f 2225 656 2226 +f 2227 2226 1179 +f 2225 2226 2227 +f 1179 2226 2228 +f 2226 656 1902 +f 2228 1902 1383 +f 2226 1902 2228 +f 74 2229 2230 +f 2229 1166 2116 +f 2230 2116 1314 +f 2229 2116 2230 +f 74 2231 2229 +f 2231 787 2117 +f 2229 2117 1166 +f 2231 2117 2229 +f 453 2232 2233 +f 2232 625 1976 +f 2233 1976 1415 +f 2232 1976 2233 +f 221 1892 2235 +f 1892 271 2234 +f 2235 2234 891 +f 1892 2234 2235 +f 129 2236 1995 +f 2236 1217 2128 +f 1995 2128 1497 +f 2236 2128 1995 +f 967 2237 2011 +f 2237 277 2132 +f 2011 2132 1473 +f 2237 2132 2011 +f 344 2238 2006 +f 2238 260 2239 +f 2006 2239 881 +f 2238 2239 2006 +f 87 2240 1919 +f 2240 260 2238 +f 1919 2238 344 +f 2240 2238 1919 +f 260 2240 2241 +f 2240 87 2134 +f 2241 2134 870 +f 2240 2134 2241 +f 427 1872 2018 +f 1872 923 2242 +f 2018 2242 1254 +f 1872 2242 2018 +f 923 2130 2242 +f 2130 1219 2243 +f 2242 2243 1254 +f 2130 2243 2242 +f 1217 2023 2126 +f 2023 966 2135 +f 2126 2135 1226 +f 2023 2135 2126 +f 781 2244 2245 +f 2244 260 2241 +f 2245 2241 870 +f 2244 2241 2245 +f 167 2024 2015 +f 2024 781 2245 +f 2015 2245 870 +f 2024 2245 2015 +f 45 2246 2137 +f 2246 1163 2247 +f 2137 2247 1428 +f 2246 2247 2137 +f 1163 2248 2247 +f 2248 26 2140 +f 2247 2140 1428 +f 2248 2140 2247 +f 646 2249 2251 +f 2249 240 2250 +f 2251 2250 653 +f 2249 2250 2251 +f 653 2250 2027 +f 2250 240 1931 +f 2027 1931 1075 +f 2250 1931 2027 +f 328 2028 2252 +f 2028 141 1936 +f 2252 1936 1410 +f 2028 1936 2252 +f 26 2248 2254 +f 2248 1163 2253 +f 2254 2253 1400 +f 2248 2253 2254 +f 509 2255 2257 +f 2255 294 2256 +f 2257 2256 865 +f 2255 2256 2257 +f 457 2258 2260 +f 2258 294 2259 +f 2260 2259 1268 +f 2258 2259 2260 +f 294 2258 2256 +f 2258 457 2261 +f 2256 2261 865 +f 2258 2261 2256 +f 457 2262 2264 +f 2262 883 2263 +f 2264 2263 1019 +f 2262 2263 2264 +f 865 2261 2265 +f 2261 457 2264 +f 2265 2264 1019 +f 2261 2264 2265 +f 883 2262 2266 +f 2262 457 2260 +f 2266 2260 1268 +f 2262 2260 2266 +f 377 2267 2268 +f 2267 883 2266 +f 2268 2266 1268 +f 2267 2266 2268 +f 883 2269 2263 +f 2269 329 2270 +f 2263 2270 1019 +f 2269 2270 2263 +f 275 2146 2141 +f 2146 249 2271 +f 2141 2271 1178 +f 2146 2271 2141 +f 249 2272 2271 +f 2272 176 2273 +f 2271 2273 1178 +f 2272 2273 2271 +f 249 2143 2274 +f 2143 16 2152 +f 2274 2152 965 +f 2143 2152 2274 +f 638 2275 2150 +f 2275 549 2276 +f 2150 2276 965 +f 2275 2276 2150 +f 508 2277 2278 +f 2277 638 2160 +f 2278 2160 959 +f 2277 2160 2278 +f 830 2163 2279 +f 2163 204 2157 +f 2279 2157 1056 +f 2163 2157 2279 +f 191 2280 2282 +f 2280 94 2281 +f 2282 2281 1113 +f 2280 2281 2282 +f 94 2280 2284 +f 2280 191 2283 +f 2284 2283 1214 +f 2280 2283 2284 +f 474 2171 2172 +f 2171 356 2285 +f 2172 2285 773 +f 2171 2285 2172 +f 65 2286 2288 +f 2286 214 2287 +f 2288 2287 1442 +f 2286 2287 2288 +f 214 2045 2287 +f 2045 440 2289 +f 2287 2289 1442 +f 2045 2289 2287 +f 690 2179 2291 +f 2179 109 2290 +f 2291 2290 1171 +f 2179 2290 2291 +f 440 2186 2289 +f 2186 730 2184 +f 2289 2184 1442 +f 2186 2184 2289 +f 999 2292 2293 +f 2292 1189 2175 +f 2293 2175 1419 +f 2292 2175 2293 +f 1097 2187 2295 +f 2187 524 2294 +f 2295 2294 1285 +f 2187 2294 2295 +f 109 2176 2296 +f 2176 1124 2189 +f 2296 2189 1367 +f 2176 2189 2296 +f 690 2297 2299 +f 2297 683 2298 +f 2299 2298 834 +f 2297 2298 2299 +f 683 2297 2300 +f 2297 690 2291 +f 2300 2291 1171 +f 2297 2291 2300 +f 999 2301 2292 +f 2301 652 2302 +f 2292 2302 1189 +f 2301 2302 2292 +f 223 2063 2303 +f 2063 690 2299 +f 2303 2299 834 +f 2063 2299 2303 +f 573 2304 2305 +f 2304 223 2303 +f 2305 2303 834 +f 2304 2303 2305 +f 652 2306 2302 +f 2306 504 2074 +f 2302 2074 1189 +f 2306 2074 2302 +f 450 2060 2307 +f 2060 223 2304 +f 2307 2304 573 +f 2060 2304 2307 +f 943 2308 2309 +f 2308 241 2065 +f 2309 2065 1039 +f 2308 2065 2309 +f 1039 2067 2310 +f 2067 632 2081 +f 2310 2081 1406 +f 2067 2081 2310 +f 512 2311 2201 +f 2311 445 2312 +f 2201 2312 792 +f 2311 2312 2201 +f 450 2313 2202 +f 2313 247 2314 +f 2202 2314 512 +f 2313 2314 2202 +f 1184 2315 2316 +f 2315 1387 2105 +f 2316 2105 1467 +f 2315 2105 2316 +f 71 2317 2111 +f 2317 347 2318 +f 2111 2318 657 +f 2317 2318 2111 +f 170 2319 2321 +f 2319 426 2320 +f 2321 2320 1387 +f 2319 2320 2321 +f 426 2322 2320 +f 2322 1339 2216 +f 2320 2216 1387 +f 2322 2216 2320 +f 1308 2217 2323 +f 2217 659 2110 +f 2323 2110 1339 +f 2217 2110 2323 +f 390 2324 2222 +f 2324 1179 2228 +f 2222 2228 1383 +f 2324 2228 2222 +f 787 2325 1895 +f 2325 1243 2326 +f 1895 2326 1302 +f 2325 2326 1895 +f 244 2122 2327 +f 2122 656 2225 +f 2327 2225 876 +f 2122 2225 2327 +f 244 2327 2115 +f 2327 876 2328 +f 2115 2328 1415 +f 2327 2328 2115 +f 221 2235 1974 +f 2235 891 2329 +f 1974 2329 1314 +f 2235 2329 1974 +f 1283 2330 1990 +f 2330 266 2331 +f 1990 2331 1463 +f 2330 2331 1990 +f 274 2119 2333 +f 2119 650 2332 +f 2333 2332 1129 +f 2119 2332 2333 +f 271 2334 2234 +f 2334 84 2335 +f 2234 2335 891 +f 2334 2335 2234 +f 271 1984 2337 +f 1984 881 2336 +f 2337 2336 1110 +f 1984 2336 2337 +f 650 2124 2332 +f 2124 277 2338 +f 2332 2338 1129 +f 2124 2338 2332 +f 129 2339 2236 +f 2339 273 2340 +f 2236 2340 1217 +f 2339 2340 2236 +f 273 2341 2340 +f 2341 50 2022 +f 2340 2022 1217 +f 2341 2022 2340 +f 1163 2246 2342 +f 2246 45 2019 +f 2342 2019 1254 +f 2246 2019 2342 +f 1121 2343 2344 +f 2343 1199 2139 +f 2344 2139 1306 +f 2343 2139 2344 +f 458 2345 2346 +f 2345 1121 2344 +f 2346 2344 1306 +f 2345 2344 2346 +f 646 2347 2348 +f 2347 458 2346 +f 2348 2346 1306 +f 2347 2346 2348 +f 240 2249 1935 +f 2249 646 2348 +f 1935 2348 1306 +f 2249 2348 1935 +f 173 2349 2351 +f 2349 867 2350 +f 2351 2350 1268 +f 2349 2350 2351 +f 623 2352 2353 +f 2352 509 2257 +f 2353 2257 865 +f 2352 2257 2353 +f 867 2354 2350 +f 2354 377 2268 +f 2350 2268 1268 +f 2354 2268 2350 +f 372 2355 2356 +f 2355 623 2353 +f 2356 2353 865 +f 2355 2353 2356 +f 372 2356 2357 +f 2356 865 2265 +f 2357 2265 1019 +f 2356 2265 2357 +f 883 2267 2359 +f 2267 377 2358 +f 2359 2358 1170 +f 2267 2358 2359 +f 329 2269 2360 +f 2269 883 2359 +f 2360 2359 1170 +f 2269 2359 2360 +f 249 2274 2362 +f 2274 965 2361 +f 2362 2361 1279 +f 2274 2361 2362 +f 176 2272 2363 +f 2272 249 2362 +f 2363 2362 1279 +f 2272 2362 2363 +f 176 2364 2273 +f 2364 751 2365 +f 2273 2365 1178 +f 2364 2365 2273 +f 8 2366 2368 +f 2366 1154 2367 +f 2368 2367 1178 +f 2366 2367 2368 +f 1154 2369 2367 +f 2369 969 2149 +f 2367 2149 1178 +f 2369 2149 2367 +f 969 2370 2153 +f 2370 301 2371 +f 2153 2371 1393 +f 2370 2371 2153 +f 953 2372 2373 +f 2372 301 2370 +f 2373 2370 969 +f 2372 2370 2373 +f 1214 2374 2376 +f 2374 956 2375 +f 2376 2375 1215 +f 2374 2375 2376 +f 956 2377 2375 +f 2377 140 2378 +f 2375 2378 1215 +f 2377 2378 2375 +f 191 2379 2283 +f 2379 956 2374 +f 2283 2374 1214 +f 2379 2374 2283 +f 1109 2380 2381 +f 2380 191 2282 +f 2381 2282 1113 +f 2380 2282 2381 +f 1109 2381 2383 +f 2381 1113 2382 +f 2383 2382 1115 +f 2381 2382 2383 +f 1094 2384 2385 +f 2384 94 2284 +f 2385 2284 1214 +f 2384 2284 2385 +f 112 2386 2387 +f 2386 1094 2385 +f 2387 2385 1214 +f 2386 2385 2387 +f 1210 2388 2389 +f 2388 112 2387 +f 2389 2387 1214 +f 2388 2387 2389 +f 94 2384 2281 +f 2384 1094 2390 +f 2281 2390 1113 +f 2384 2390 2281 +f 112 2391 2386 +f 2391 424 2392 +f 2386 2392 1094 +f 2391 2392 2386 +f 1113 2390 2394 +f 2390 1094 2393 +f 2394 2393 1492 +f 2390 2393 2394 +f 214 2286 2164 +f 2286 65 2395 +f 2164 2395 1139 +f 2286 2395 2164 +f 1097 2396 2049 +f 2396 414 2397 +f 2049 2397 1401 +f 2396 2397 2049 +f 320 2398 2400 +f 2398 356 2399 +f 2400 2399 607 +f 2398 2399 2400 +f 356 2398 2285 +f 2398 320 2401 +f 2285 2401 773 +f 2398 2401 2285 +f 137 2402 2403 +f 2402 1097 2295 +f 2403 2295 1285 +f 2402 2295 2403 +f 137 2404 2402 +f 2404 414 2396 +f 2402 2396 1097 +f 2404 2396 2402 +f 1171 2290 2405 +f 2290 109 2296 +f 2405 2296 1367 +f 2290 2296 2405 +f 356 2180 2399 +f 2180 172 2406 +f 2399 2406 607 +f 2180 2406 2399 +f 524 2198 2294 +f 2198 1063 2407 +f 2294 2407 1285 +f 2198 2407 2294 +f 172 2190 2409 +f 2190 241 2408 +f 2409 2408 615 +f 2190 2408 2409 +f 615 2408 2410 +f 2408 241 2308 +f 2410 2308 943 +f 2408 2308 2410 +f 15 2411 2412 +f 2411 504 2306 +f 2412 2306 652 +f 2411 2306 2412 +f 504 2411 2195 +f 2411 15 2413 +f 2195 2413 1031 +f 2411 2413 2195 +f 247 2313 2414 +f 2313 450 2307 +f 2414 2307 573 +f 2313 2307 2414 +f 247 2414 2416 +f 2414 573 2415 +f 2416 2415 1211 +f 2414 2415 2416 +f 68 2417 2080 +f 2417 212 2418 +f 2080 2418 1406 +f 2417 2418 2080 +f 391 2419 2197 +f 2419 14 2420 +f 2197 2420 1063 +f 2419 2420 2197 +f 14 2419 2421 +f 2419 391 2206 +f 2421 2206 902 +f 2419 2206 2421 +f 445 2422 2312 +f 2422 36 2090 +f 2312 2090 792 +f 2422 2090 2312 +f 445 2311 2424 +f 2311 512 2423 +f 2424 2423 1067 +f 2311 2423 2424 +f 212 2417 2425 +f 2417 68 2091 +f 2425 2091 1072 +f 2417 2091 2425 +f 485 2426 2205 +f 2426 1021 2427 +f 2205 2427 1072 +f 2426 2427 2205 +f 485 2204 2429 +f 2204 1031 2428 +f 2429 2428 1238 +f 2204 2428 2429 +f 36 2422 2207 +f 2422 445 2430 +f 2207 2430 805 +f 2422 2430 2207 +f 902 2095 2432 +f 2095 805 2431 +f 2432 2431 1431 +f 2095 2431 2432 +f 1260 2211 2434 +f 2211 595 2433 +f 2434 2433 1299 +f 2211 2433 2434 +f 555 2435 2436 +f 2435 1184 2316 +f 2436 2316 1467 +f 2435 2316 2436 +f 1184 2437 2315 +f 2437 170 2321 +f 2315 2321 1387 +f 2437 2321 2315 +f 657 2318 2214 +f 2318 347 2438 +f 2214 2438 1459 +f 2318 2438 2214 +f 852 2439 2440 +f 2439 71 2113 +f 2440 2113 1069 +f 2439 2113 2440 +f 1243 2441 2326 +f 2441 145 2224 +f 2326 2224 1302 +f 2441 2224 2326 +f 754 2442 2443 +f 2442 192 2221 +f 2443 2221 1147 +f 2442 2221 2443 +f 145 2444 2223 +f 2444 531 2445 +f 2223 2445 1283 +f 2444 2445 2223 +f 274 2446 2121 +f 2446 754 2443 +f 2121 2443 1147 +f 2446 2443 2121 +f 539 2447 2448 +f 2447 74 2230 +f 2448 2230 1314 +f 2447 2230 2448 +f 876 2449 2328 +f 2449 453 2233 +f 2328 2233 1415 +f 2449 2233 2328 +f 891 2450 2329 +f 2450 539 2448 +f 2329 2448 1314 +f 2450 2448 2329 +f 625 2451 1903 +f 2451 403 2452 +f 1903 2452 1239 +f 2451 2452 1903 +f 453 2453 2232 +f 2453 403 2451 +f 2232 2451 625 +f 2453 2451 2232 +f 273 2339 2455 +f 2339 129 2454 +f 2455 2454 794 +f 2339 2454 2455 +f 881 2239 2336 +f 2239 260 2456 +f 2336 2456 1110 +f 2239 2456 2336 +f 1121 2457 2343 +f 2457 967 2010 +f 2343 2010 1199 +f 2457 2010 2343 +f 50 2341 2026 +f 2341 273 2458 +f 2026 2458 653 +f 2341 2458 2026 +f 260 2244 2460 +f 2244 781 2459 +f 2460 2459 1026 +f 2244 2459 2460 +f 781 2029 2459 +f 2029 328 2461 +f 2459 2461 1026 +f 2029 2461 2459 +f 218 2462 2463 +f 2462 328 2252 +f 2463 2252 1410 +f 2462 2252 2463 +f 1400 2464 2465 +f 2464 218 2463 +f 2465 2463 1410 +f 2464 2463 2465 +f 26 2254 2031 +f 2254 1400 2465 +f 2031 2465 1410 +f 2254 2465 2031 +f 173 2466 2349 +f 2466 699 2467 +f 2349 2467 867 +f 2466 2467 2349 +f 99 2468 2469 +f 2468 377 2354 +f 2469 2354 867 +f 2468 2354 2469 +f 377 2468 2358 +f 2468 99 2470 +f 2358 2470 1170 +f 2468 2470 2358 +f 372 2357 2472 +f 2357 1019 2471 +f 2472 2471 1081 +f 2357 2471 2472 +f 1019 2473 2471 +f 2473 97 2474 +f 2471 2474 1081 +f 2473 2474 2471 +f 329 2475 2270 +f 2475 97 2473 +f 2270 2473 1019 +f 2475 2473 2270 +f 97 2475 2477 +f 2475 329 2476 +f 2477 2476 1032 +f 2475 2476 2477 +f 1032 2476 2478 +f 2476 329 2360 +f 2478 2360 1170 +f 2476 2360 2478 +f 176 2479 2364 +f 2479 501 2480 +f 2364 2480 751 +f 2479 2480 2364 +f 751 2481 2365 +f 2481 8 2368 +f 2365 2368 1178 +f 2481 2368 2365 +f 965 2482 2361 +f 2482 979 2483 +f 2361 2483 1279 +f 2482 2483 2361 +f 953 2373 2484 +f 2373 969 2369 +f 2484 2369 1154 +f 2373 2369 2484 +f 965 2276 2482 +f 2276 549 2485 +f 2482 2485 979 +f 2276 2485 2482 +f 549 2486 2485 +f 2486 973 2487 +f 2485 2487 979 +f 2486 2487 2485 +f 301 2488 2371 +f 2488 165 2489 +f 2371 2489 1393 +f 2488 2489 2371 +f 165 2488 2490 +f 2488 301 2372 +f 2490 2372 953 +f 2488 2372 2490 +f 80 2491 2492 +f 2491 549 2275 +f 2492 2275 638 +f 2491 2275 2492 +f 508 2493 2277 +f 2493 80 2492 +f 2277 2492 638 +f 2493 2492 2277 +f 956 2379 2494 +f 2379 191 2380 +f 2494 2380 1109 +f 2379 2380 2494 +f 4 2495 2496 +f 2495 956 2494 +f 2496 2494 1109 +f 2495 2494 2496 +f 1210 2389 2497 +f 2389 1214 2376 +f 2497 2376 1215 +f 2389 2376 2497 +f 1115 2382 2498 +f 2382 1113 2394 +f 2498 2394 1492 +f 2382 2394 2498 +f 1094 2392 2393 +f 2392 424 2499 +f 2393 2499 1492 +f 2392 2499 2393 +f 142 2500 2501 +f 2500 65 2288 +f 2501 2288 1442 +f 2500 2288 2501 +f 155 2502 2503 +f 2502 1367 2169 +f 2503 2169 1401 +f 2502 2169 2503 +f 683 2300 2505 +f 2300 1171 2504 +f 2505 2504 1390 +f 2300 2504 2505 +f 742 2506 2508 +f 2506 172 2507 +f 2508 2507 1291 +f 2506 2507 2508 +f 607 2406 2509 +f 2406 172 2506 +f 2509 2506 742 +f 2406 2506 2509 +f 320 2400 2511 +f 2400 607 2510 +f 2511 2510 1446 +f 2400 2510 2511 +f 683 2512 2298 +f 2512 707 2513 +f 2298 2513 834 +f 2512 2513 2298 +f 834 2513 2515 +f 2513 707 2514 +f 2515 2514 931 +f 2513 2514 2515 +f 615 2516 2518 +f 2516 1198 2517 +f 2518 2517 1291 +f 2516 2517 2518 +f 172 2409 2507 +f 2409 615 2518 +f 2507 2518 1291 +f 2409 2518 2507 +f 573 2305 2519 +f 2305 834 2515 +f 2519 2515 931 +f 2305 2515 2519 +f 1198 2516 2521 +f 2516 615 2520 +f 2521 2520 1455 +f 2516 2520 2521 +f 573 2519 2523 +f 2519 931 2522 +f 2523 2522 1502 +f 2519 2522 2523 +f 615 2410 2520 +f 2410 943 2524 +f 2520 2524 1455 +f 2410 2524 2520 +f 943 2525 2524 +f 2525 778 2526 +f 2524 2526 1455 +f 2525 2526 2524 +f 778 2525 2528 +f 2525 943 2527 +f 2528 2527 1406 +f 2525 2527 2528 +f 943 2309 2527 +f 2309 1039 2310 +f 2527 2310 1406 +f 2309 2310 2527 +f 1031 2413 2428 +f 2413 15 2529 +f 2428 2529 1238 +f 2413 2529 2428 +f 14 2530 2532 +f 2530 503 2531 +f 2532 2531 1336 +f 2530 2531 2532 +f 1063 2420 2533 +f 2420 14 2532 +f 2533 2532 1336 +f 2420 2532 2533 +f 1067 2534 2535 +f 2534 247 2416 +f 2535 2416 1211 +f 2534 2416 2535 +f 805 2430 2431 +f 2430 445 2536 +f 2431 2536 1431 +f 2430 2536 2431 +f 512 2314 2423 +f 2314 247 2534 +f 2423 2534 1067 +f 2314 2534 2423 +f 1021 2537 2427 +f 2537 212 2425 +f 2427 2425 1072 +f 2537 2425 2427 +f 196 2538 2539 +f 2538 1260 2434 +f 2539 2434 1299 +f 2538 2434 2539 +f 196 2540 2538 +f 2540 666 2209 +f 2538 2209 1260 +f 2540 2209 2538 +f 666 2540 2542 +f 2540 196 2541 +f 2542 2541 1399 +f 2540 2541 2542 +f 595 2543 2433 +f 2543 552 2544 +f 2433 2544 1299 +f 2543 2544 2433 +f 110 2545 2546 +f 2545 666 2542 +f 2546 2542 1399 +f 2545 2542 2546 +f 552 2543 2547 +f 2543 595 2212 +f 2547 2212 802 +f 2543 2212 2547 +f 110 2548 2545 +f 2548 345 2213 +f 2545 2213 666 +f 2548 2213 2545 +f 552 2547 2549 +f 2547 802 2102 +f 2549 2102 1220 +f 2547 2102 2549 +f 299 2550 2551 +f 2550 552 2549 +f 2551 2549 1220 +f 2550 2549 2551 +f 345 2548 2101 +f 2548 110 2552 +f 2101 2552 1467 +f 2548 2552 2101 +f 110 2553 2552 +f 2553 555 2436 +f 2552 2436 1467 +f 2553 2436 2552 +f 299 2551 2554 +f 2551 1220 2215 +f 2554 2215 1459 +f 2551 2215 2554 +f 347 2317 2555 +f 2317 71 2439 +f 2555 2439 852 +f 2317 2439 2555 +f 697 2556 2557 +f 2556 1308 2323 +f 2557 2323 1339 +f 2556 2323 2557 +f 697 2557 2559 +f 2557 1339 2558 +f 2559 2558 1430 +f 2557 2558 2559 +f 633 2560 2562 +f 2560 599 2561 +f 2562 2561 1069 +f 2560 2561 2562 +f 858 2563 1968 +f 2563 633 2562 +f 1968 2562 1069 +f 2563 2562 1968 +f 633 2563 2564 +f 2563 858 2218 +f 2564 2218 1308 +f 2563 2218 2564 +f 74 2447 2566 +f 2447 539 2565 +f 2566 2565 1246 +f 2447 2565 2566 +f 838 2567 2568 +f 2567 266 2330 +f 2568 2330 1283 +f 2567 2330 2568 +f 274 2569 2446 +f 2569 270 2570 +f 2446 2570 754 +f 2569 2570 2446 +f 270 2569 2571 +f 2569 274 2333 +f 2571 2333 1129 +f 2569 2333 2571 +f 403 2453 2573 +f 2453 453 2572 +f 2573 2572 1098 +f 2453 2572 2573 +f 453 2449 2572 +f 2449 876 2574 +f 2572 2574 1098 +f 2449 2574 2572 +f 84 2575 2335 +f 2575 713 2576 +f 2335 2576 891 +f 2575 2576 2335 +f 266 2577 2331 +f 2577 1219 2131 +f 2331 2131 1463 +f 2577 2131 2331 +f 84 2334 2578 +f 2334 271 2337 +f 2578 2337 1110 +f 2334 2337 2578 +f 794 2454 2579 +f 2454 129 1994 +f 2579 1994 1239 +f 2454 1994 2579 +f 403 2580 2452 +f 2580 794 2579 +f 2452 2579 1239 +f 2580 2579 2452 +f 644 2581 2583 +f 2581 294 2582 +f 2583 2582 836 +f 2581 2582 2583 +f 294 2581 2259 +f 2581 644 2584 +f 2259 2584 1268 +f 2581 2584 2259 +f 836 2585 2587 +f 2585 509 2586 +f 2587 2586 1266 +f 2585 2586 2587 +f 294 2255 2582 +f 2255 509 2585 +f 2582 2585 836 +f 2255 2585 2582 +f 644 2588 2584 +f 2588 173 2351 +f 2584 2351 1268 +f 2588 2351 2584 +f 623 2589 2591 +f 2589 312 2590 +f 2591 2590 1423 +f 2589 2590 2591 +f 372 2592 2355 +f 2592 312 2589 +f 2355 2589 623 +f 2592 2589 2355 +f 312 2592 2593 +f 2592 372 2472 +f 2593 2472 1081 +f 2592 2472 2593 +f 99 2594 2470 +f 2594 35 2595 +f 2470 2595 1170 +f 2594 2595 2470 +f 60 2596 2598 +f 2596 97 2597 +f 2598 2597 871 +f 2596 2597 2598 +f 97 2596 2474 +f 2596 60 2599 +f 2474 2599 1081 +f 2596 2599 2474 +f 85 2600 2601 +f 2600 1032 2478 +f 2601 2478 1170 +f 2600 2478 2601 +f 35 2602 2595 +f 2602 85 2601 +f 2595 2601 1170 +f 2602 2601 2595 +f 501 2479 2604 +f 2479 176 2603 +f 2604 2603 550 +f 2479 2603 2604 +f 8 2481 2606 +f 2481 751 2605 +f 2606 2605 785 +f 2481 2605 2606 +f 227 2607 2608 +f 2607 953 2484 +f 2608 2484 1154 +f 2607 2484 2608 +f 549 2491 2486 +f 2491 80 2609 +f 2486 2609 973 +f 2491 2609 2486 +f 593 2610 2611 +f 2610 1056 2155 +f 2611 2155 1393 +f 2610 2155 2611 +f 165 2612 2489 +f 2612 593 2611 +f 2489 2611 1393 +f 2612 2611 2489 +f 1056 2610 2614 +f 2610 593 2613 +f 2614 2613 1295 +f 2610 2613 2614 +f 508 2278 2616 +f 2278 959 2615 +f 2616 2615 1059 +f 2278 2615 2616 +f 1059 2615 2618 +f 2615 959 2617 +f 2618 2617 1427 +f 2615 2617 2618 +f 959 2619 2617 +f 2619 5 2620 +f 2617 2620 1427 +f 2619 2620 2617 +f 830 2621 2161 +f 2621 5 2619 +f 2161 2619 959 +f 2621 2619 2161 +f 830 2279 2623 +f 2279 1056 2622 +f 2623 2622 1070 +f 2279 2622 2623 +f 1070 2622 2624 +f 2622 1056 2614 +f 2624 2614 1295 +f 2622 2614 2624 +f 5 2621 2625 +f 2621 830 2623 +f 2625 2623 1070 +f 2621 2623 2625 +f 1049 2626 2627 +f 2626 112 2388 +f 2627 2388 1210 +f 2626 2388 2627 +f 389 2628 2629 +f 2628 1115 2498 +f 2629 2498 1492 +f 2628 2498 2629 +f 424 2391 2630 +f 2391 112 2626 +f 2630 2626 1049 +f 2391 2626 2630 +f 424 2630 2499 +f 2630 1049 2631 +f 2499 2631 1492 +f 2630 2631 2499 +f 320 2632 2401 +f 2632 655 2633 +f 2401 2633 773 +f 2632 2633 2401 +f 773 2633 2173 +f 2633 655 2634 +f 2173 2634 1442 +f 2633 2634 2173 +f 655 2635 2634 +f 2635 142 2501 +f 2634 2501 1442 +f 2635 2501 2634 +f 65 2500 2395 +f 2500 142 2636 +f 2395 2636 1139 +f 2500 2636 2395 +f 480 2637 2639 +f 2637 780 2638 +f 2639 2638 1419 +f 2637 2638 2639 +f 780 2640 2638 +f 2640 999 2293 +f 2638 2293 1419 +f 2640 2293 2638 +f 414 2641 2397 +f 2641 1369 2642 +f 2397 2642 1401 +f 2641 2642 2397 +f 1369 2643 2642 +f 2643 155 2503 +f 2642 2503 1401 +f 2643 2503 2642 +f 155 2644 2646 +f 2644 69 2645 +f 2646 2645 1171 +f 2644 2645 2646 +f 155 2646 2502 +f 2646 1171 2405 +f 2502 2405 1367 +f 2646 2405 2502 +f 683 2647 2512 +f 2647 61 2648 +f 2512 2648 707 +f 2647 2648 2512 +f 106 2649 2650 +f 2649 607 2509 +f 2650 2509 742 +f 2649 2509 2650 +f 607 2649 2510 +f 2649 106 2651 +f 2510 2651 1446 +f 2649 2651 2510 +f 707 2652 2514 +f 2652 405 2653 +f 2514 2653 931 +f 2652 2653 2514 +f 931 2653 2522 +f 2653 405 2654 +f 2522 2654 1502 +f 2653 2654 2522 +f 1211 2415 2655 +f 2415 573 2523 +f 2655 2523 1502 +f 2415 2523 2655 +f 212 2656 2418 +f 2656 778 2528 +f 2418 2528 1406 +f 2656 2528 2418 +f 1021 2426 2657 +f 2426 485 2429 +f 2657 2429 1238 +f 2426 2429 2657 +f 503 2530 2658 +f 2530 14 2421 +f 2658 2421 902 +f 2530 2421 2658 +f 503 2658 2659 +f 2658 902 2432 +f 2659 2432 1431 +f 2658 2432 2659 +f 196 2660 2541 +f 2660 540 2661 +f 2541 2661 1399 +f 2660 2661 2541 +f 1152 2662 2663 +f 2662 170 2437 +f 2663 2437 1184 +f 2662 2437 2663 +f 426 2319 2665 +f 2319 170 2664 +f 2665 2664 1345 +f 2319 2664 2665 +f 170 2662 2664 +f 2662 1152 2666 +f 2664 2666 1345 +f 2662 2666 2664 +f 347 2667 2669 +f 2667 1310 2668 +f 2669 2668 1323 +f 2667 2668 2669 +f 347 2669 2438 +f 2669 1323 2670 +f 2438 2670 1459 +f 2669 2670 2438 +f 347 2555 2667 +f 2555 852 2671 +f 2667 2671 1310 +f 2555 2671 2667 +f 1339 2322 2558 +f 2322 426 2672 +f 2558 2672 1430 +f 2322 2672 2558 +f 599 2673 2561 +f 2673 852 2440 +f 2561 2440 1069 +f 2673 2440 2561 +f 852 2673 2675 +f 2673 599 2674 +f 2675 2674 1053 +f 2673 2674 2675 +f 876 2227 2677 +f 2227 1179 2676 +f 2677 2676 1469 +f 2227 2676 2677 +f 13 2678 2679 +f 2678 599 2560 +f 2679 2560 633 +f 2678 2560 2679 +f 876 2680 2574 +f 2680 1038 2681 +f 2574 2681 1098 +f 2680 2681 2574 +f 13 2682 2678 +f 2682 590 2683 +f 2678 2683 599 +f 2682 2683 2678 +f 333 2684 2685 +f 2684 633 2564 +f 2685 2564 1308 +f 2684 2564 2685 +f 697 2686 2556 +f 2686 118 2687 +f 2556 2687 1308 +f 2686 2687 2556 +f 863 2688 2689 +f 2688 697 2559 +f 2689 2559 1430 +f 2688 2559 2689 +f 266 2690 2577 +f 2690 1078 2691 +f 2577 2691 1219 +f 2690 2691 2577 +f 13 2679 2693 +f 2679 633 2692 +f 2693 2692 641 +f 2679 2692 2693 +f 633 2684 2692 +f 2684 333 2694 +f 2692 2694 641 +f 2684 2694 2692 +f 333 2685 2696 +f 2685 1308 2695 +f 2696 2695 1439 +f 2685 2695 2696 +f 1308 2687 2695 +f 2687 118 2697 +f 2695 2697 1439 +f 2687 2697 2695 +f 118 2686 2698 +f 2686 697 2688 +f 2698 2688 863 +f 2686 2688 2698 +f 713 2575 2699 +f 2575 84 2578 +f 2699 2578 1110 +f 2575 2578 2699 +f 794 2580 2700 +f 2580 403 2573 +f 2700 2573 1098 +f 2580 2573 2700 +f 590 2682 2701 +f 2682 13 2693 +f 2701 2693 641 +f 2682 2693 2701 +f 118 2702 2697 +f 2702 248 2703 +f 2697 2703 1439 +f 2702 2703 2697 +f 248 2702 2704 +f 2702 118 2698 +f 2704 2698 863 +f 2702 2698 2704 +f 1219 2705 2243 +f 2705 131 2706 +f 2243 2706 1254 +f 2705 2706 2243 +f 546 2707 2708 +f 2707 590 2701 +f 2708 2701 641 +f 2707 2701 2708 +f 260 2460 2456 +f 2460 1026 2709 +f 2456 2709 1110 +f 2460 2709 2456 +f 509 2352 2586 +f 2352 623 2710 +f 2586 2710 1266 +f 2352 2710 2586 +f 699 2711 2467 +f 2711 99 2469 +f 2467 2469 867 +f 2711 2469 2467 +f 99 2712 2714 +f 2712 1222 2713 +f 2714 2713 1490 +f 2712 2713 2714 +f 35 2594 2715 +f 2594 99 2714 +f 2715 2714 1490 +f 2594 2714 2715 +f 371 2716 2718 +f 2716 871 2717 +f 2718 2717 1032 +f 2716 2717 2718 +f 871 2597 2717 +f 2597 97 2477 +f 2717 2477 1032 +f 2597 2477 2717 +f 85 2719 2600 +f 2719 829 2720 +f 2600 2720 1032 +f 2719 2720 2600 +f 993 2721 2723 +f 2721 1279 2722 +f 2723 2722 1324 +f 2721 2722 2723 +f 550 2603 2725 +f 2603 176 2724 +f 2725 2724 993 +f 2603 2724 2725 +f 993 2724 2721 +f 2724 176 2363 +f 2721 2363 1279 +f 2724 2363 2721 +f 8 2606 2366 +f 2606 785 2726 +f 2366 2726 1154 +f 2606 2726 2366 +f 785 2727 2726 +f 2727 242 2728 +f 2726 2728 1154 +f 2727 2728 2726 +f 1279 2483 2722 +f 2483 979 2729 +f 2722 2729 1324 +f 2483 2729 2722 +f 219 2730 2732 +f 2730 501 2731 +f 2732 2731 1035 +f 2730 2731 2732 +f 501 2730 2480 +f 2730 219 2733 +f 2480 2733 751 +f 2730 2733 2480 +f 751 2733 2735 +f 2733 219 2734 +f 2735 2734 1249 +f 2733 2734 2735 +f 1044 2736 2737 +f 2736 751 2735 +f 2737 2735 1249 +f 2736 2735 2737 +f 242 2738 2728 +f 2738 227 2608 +f 2728 2608 1154 +f 2738 2608 2728 +f 929 2739 2740 +f 2739 165 2490 +f 2740 2490 953 +f 2739 2490 2740 +f 593 2612 2741 +f 2612 165 2739 +f 2741 2739 929 +f 2612 2739 2741 +f 80 2493 2743 +f 2493 508 2742 +f 2743 2742 711 +f 2493 2742 2743 +f 711 2742 2744 +f 2742 508 2616 +f 2744 2616 1059 +f 2742 2616 2744 +f 5 2745 2620 +f 2745 832 2746 +f 2620 2746 1427 +f 2745 2746 2620 +f 700 2747 2748 +f 2747 5 2625 +f 2748 2625 1070 +f 2747 2625 2748 +f 5 2747 2745 +f 2747 700 2749 +f 2745 2749 832 +f 2747 2749 2745 +f 956 2495 2751 +f 2495 4 2750 +f 2751 2750 1427 +f 2495 2750 2751 +f 832 2752 2746 +f 2752 956 2751 +f 2746 2751 1427 +f 2752 2751 2746 +f 700 2753 2754 +f 2753 140 2377 +f 2754 2377 956 +f 2753 2377 2754 +f 832 2749 2752 +f 2749 700 2754 +f 2752 2754 956 +f 2749 2754 2752 +f 140 2755 2378 +f 2755 490 2756 +f 2378 2756 1215 +f 2755 2756 2378 +f 4 2496 2758 +f 2496 1109 2757 +f 2758 2757 1495 +f 2496 2757 2758 +f 1427 2750 2759 +f 2750 4 2758 +f 2759 2758 1495 +f 2750 2758 2759 +f 517 2760 2761 +f 2760 1210 2497 +f 2761 2497 1215 +f 2760 2497 2761 +f 1109 2383 2757 +f 2383 1115 2762 +f 2757 2762 1495 +f 2383 2762 2757 +f 1115 2763 2762 +f 2763 990 2764 +f 2762 2764 1495 +f 2763 2764 2762 +f 389 2765 2628 +f 2765 990 2763 +f 2628 2763 1115 +f 2765 2763 2628 +f 106 2650 2767 +f 2650 742 2766 +f 2767 2766 906 +f 2650 2766 2767 +f 456 2768 2769 +f 2768 320 2511 +f 2769 2511 1446 +f 2768 2511 2769 +f 320 2768 2632 +f 2768 456 2770 +f 2632 2770 655 +f 2768 2770 2632 +f 142 2771 2636 +f 2771 480 2772 +f 2636 2772 1139 +f 2771 2772 2636 +f 1139 2772 2166 +f 2772 480 2639 +f 2166 2639 1419 +f 2772 2639 2166 +f 414 2404 2641 +f 2404 137 2773 +f 2641 2773 1369 +f 2404 2773 2641 +f 1171 2645 2504 +f 2645 69 2774 +f 2504 2774 1390 +f 2645 2774 2504 +f 61 2647 2775 +f 2647 683 2505 +f 2775 2505 1390 +f 2647 2505 2775 +f 649 2776 2777 +f 2776 137 2403 +f 2777 2403 1285 +f 2776 2403 2777 +f 137 2776 2773 +f 2776 649 2778 +f 2773 2778 1369 +f 2776 2778 2773 +f 283 2779 2780 +f 2779 405 2652 +f 2780 2652 707 +f 2779 2652 2780 +f 906 2781 2783 +f 2781 1291 2782 +f 2783 2782 1425 +f 2781 2782 2783 +f 906 2766 2781 +f 2766 742 2508 +f 2781 2508 1291 +f 2766 2508 2781 +f 780 2784 2640 +f 2784 652 2301 +f 2640 2301 999 +f 2784 2301 2640 +f 378 2785 2786 +f 2785 649 2777 +f 2786 2777 1285 +f 2785 2777 2786 +f 283 2787 2779 +f 2787 228 2788 +f 2779 2788 405 +f 2787 2788 2779 +f 1291 2517 2782 +f 2517 1198 2789 +f 2782 2789 1425 +f 2517 2789 2782 +f 558 2790 2791 +f 2790 652 2784 +f 2791 2784 780 +f 2790 2784 2791 +f 1063 2792 2407 +f 2792 378 2786 +f 2407 2786 1285 +f 2792 2786 2407 +f 558 2793 2790 +f 2793 15 2412 +f 2790 2412 652 +f 2793 2412 2790 +f 378 2792 2794 +f 2792 1063 2533 +f 2794 2533 1336 +f 2792 2533 2794 +f 602 2795 2796 +f 2795 1198 2521 +f 2796 2521 1455 +f 2795 2521 2796 +f 15 2793 2529 +f 2793 558 2797 +f 2529 2797 1238 +f 2793 2797 2529 +f 778 2656 2799 +f 2656 212 2798 +f 2799 2798 1137 +f 2656 2798 2799 +f 445 2424 2536 +f 2424 1067 2800 +f 2536 2800 1431 +f 2424 2800 2536 +f 552 2801 2544 +f 2801 668 2802 +f 2544 2802 1299 +f 2801 2802 2544 +f 1077 2803 2804 +f 2803 110 2546 +f 2804 2546 1399 +f 2803 2546 2804 +f 555 2805 2435 +f 2805 126 2806 +f 2435 2806 1184 +f 2805 2806 2435 +f 1263 2807 2808 +f 2807 299 2554 +f 2808 2554 1459 +f 2807 2554 2808 +f 426 2665 2672 +f 2665 1345 2809 +f 2672 2809 1430 +f 2665 2809 2672 +f 1345 2810 2809 +f 2810 1341 2811 +f 2809 2811 1430 +f 2810 2811 2809 +f 787 2231 2813 +f 2231 74 2812 +f 2813 2812 1195 +f 2231 2812 2813 +f 787 2813 2325 +f 2813 1195 2814 +f 2325 2814 1243 +f 2813 2814 2325 +f 531 2815 2445 +f 2815 838 2568 +f 2445 2568 1283 +f 2815 2568 2445 +f 599 2683 2674 +f 2683 590 2816 +f 2674 2816 1053 +f 2683 2816 2674 +f 713 2817 2819 +f 2817 385 2818 +f 2819 2818 1246 +f 2817 2818 2819 +f 539 2820 2565 +f 2820 713 2819 +f 2565 2819 1246 +f 2820 2819 2565 +f 713 2820 2576 +f 2820 539 2450 +f 2576 2450 891 +f 2820 2450 2576 +f 277 2821 2338 +f 2821 168 2822 +f 2338 2822 1129 +f 2821 2822 2338 +f 679 2823 2825 +f 2823 590 2824 +f 2825 2824 1374 +f 2823 2824 2825 +f 464 2826 2827 +f 2826 248 2704 +f 2827 2704 863 +f 2826 2704 2827 +f 380 2828 2829 +f 2828 967 2457 +f 2829 2457 1121 +f 2828 2457 2829 +f 590 2707 2824 +f 2707 546 2830 +f 2824 2830 1374 +f 2707 2830 2824 +f 248 2831 2703 +f 2831 1144 2832 +f 2703 2832 1439 +f 2831 2832 2703 +f 198 2833 2834 +f 2833 1163 2342 +f 2834 2342 1254 +f 2833 2342 2834 +f 641 2694 2836 +f 2694 333 2835 +f 2836 2835 1047 +f 2694 2835 2836 +f 671 2837 2838 +f 2837 333 2696 +f 2838 2696 1439 +f 2837 2696 2838 +f 1026 2461 2840 +f 2461 328 2839 +f 2840 2839 1269 +f 2461 2839 2840 +f 546 2708 2842 +f 2708 641 2841 +f 2842 2841 660 +f 2708 2841 2842 +f 660 2841 2843 +f 2841 641 2836 +f 2843 2836 1047 +f 2841 2836 2843 +f 173 2588 2845 +f 2588 644 2844 +f 2845 2844 1465 +f 2588 2844 2845 +f 99 2711 2712 +f 2711 699 2846 +f 2712 2846 1222 +f 2711 2846 2712 +f 386 2847 2848 +f 2847 623 2591 +f 2848 2591 1423 +f 2847 2591 2848 +f 623 2847 2710 +f 2847 386 2849 +f 2710 2849 1266 +f 2847 2849 2710 +f 312 2850 2590 +f 2850 1324 2851 +f 2590 2851 1423 +f 2850 2851 2590 +f 934 2852 2853 +f 2852 35 2715 +f 2853 2715 1490 +f 2852 2715 2853 +f 312 2593 2855 +f 2593 1081 2854 +f 2855 2854 1122 +f 2593 2854 2855 +f 871 2716 2857 +f 2716 371 2856 +f 2857 2856 1050 +f 2716 2856 2857 +f 1032 2720 2859 +f 2720 829 2858 +f 2859 2858 1271 +f 2720 2858 2859 +f 371 2718 2860 +f 2718 1032 2859 +f 2860 2859 1271 +f 2718 2859 2860 +f 85 2602 2862 +f 2602 35 2861 +f 2862 2861 678 +f 2602 2861 2862 +f 678 2861 2863 +f 2861 35 2852 +f 2863 2852 934 +f 2861 2852 2863 +f 1081 2864 2854 +f 2864 370 2865 +f 2854 2865 1122 +f 2864 2865 2854 +f 60 2866 2599 +f 2866 370 2864 +f 2599 2864 1081 +f 2866 2864 2599 +f 21 2867 2869 +f 2867 511 2868 +f 2869 2868 751 +f 2867 2868 2869 +f 751 2868 2605 +f 2868 511 2870 +f 2605 2870 785 +f 2868 2870 2605 +f 501 2604 2731 +f 2604 550 2871 +f 2731 2871 1035 +f 2604 2871 2731 +f 21 2869 2872 +f 2869 751 2736 +f 2872 2736 1044 +f 2869 2736 2872 +f 511 2867 2873 +f 2867 21 2872 +f 2873 2872 1044 +f 2867 2872 2873 +f 419 2874 2876 +f 2874 219 2875 +f 2876 2875 439 +f 2874 2875 2876 +f 219 2874 2734 +f 2874 419 2877 +f 2734 2877 1249 +f 2874 2877 2734 +f 80 2743 2609 +f 2743 711 2878 +f 2609 2878 973 +f 2743 2878 2609 +f 593 2879 2613 +f 2879 1280 2880 +f 2613 2880 1295 +f 2879 2880 2613 +f 490 2881 2882 +f 2881 700 2748 +f 2882 2748 1070 +f 2881 2748 2882 +f 490 2755 2881 +f 2755 140 2753 +f 2881 2753 700 +f 2755 2753 2881 +f 490 2883 2756 +f 2883 517 2761 +f 2756 2761 1215 +f 2883 2761 2756 +f 1210 2760 2885 +f 2760 517 2884 +f 2885 2884 1348 +f 2760 2884 2885 +f 1210 2885 2887 +f 2885 1348 2886 +f 2887 2886 1468 +f 2885 2886 2887 +f 518 2888 2890 +f 2888 389 2889 +f 2890 2889 1028 +f 2888 2889 2890 +f 1049 2627 2891 +f 2627 1210 2887 +f 2891 2887 1468 +f 2627 2887 2891 +f 1028 2889 2892 +f 2889 389 2629 +f 2892 2629 1492 +f 2889 2629 2892 +f 1049 2893 2631 +f 2893 885 2894 +f 2631 2894 1492 +f 2893 2894 2631 +f 885 2893 2895 +f 2893 1049 2891 +f 2895 2891 1468 +f 2893 2891 2895 +f 70 2896 2897 +f 2896 106 2767 +f 2897 2767 906 +f 2896 2767 2897 +f 707 2648 2899 +f 2648 61 2898 +f 2899 2898 1090 +f 2648 2898 2899 +f 283 2780 2900 +f 2780 707 2899 +f 2900 2899 1090 +f 2780 2899 2900 +f 228 2901 2788 +f 2901 43 2902 +f 2788 2902 405 +f 2901 2902 2788 +f 405 2902 2654 +f 2902 43 2903 +f 2654 2903 1502 +f 2902 2903 2654 +f 43 2904 2903 +f 2904 178 2905 +f 2903 2905 1502 +f 2904 2905 2903 +f 1198 2795 2789 +f 2795 602 2906 +f 2789 2906 1425 +f 2795 2906 2789 +f 178 2907 2908 +f 2907 1067 2535 +f 2908 2535 1211 +f 2907 2535 2908 +f 178 2908 2905 +f 2908 1211 2655 +f 2905 2655 1502 +f 2908 2655 2905 +f 503 2909 2531 +f 2909 363 2910 +f 2531 2910 1336 +f 2909 2910 2531 +f 778 2799 2912 +f 2799 1137 2911 +f 2912 2911 1434 +f 2799 2911 2912 +f 212 2537 2798 +f 2537 1021 2913 +f 2798 2913 1137 +f 2537 2913 2798 +f 1060 2914 2916 +f 2914 522 2915 +f 2916 2915 1431 +f 2914 2915 2916 +f 1067 2917 2800 +f 2917 1060 2916 +f 2800 2916 1431 +f 2917 2916 2800 +f 555 2553 2918 +f 2553 110 2803 +f 2918 2803 1077 +f 2553 2803 2918 +f 126 2919 2806 +f 2919 1152 2663 +f 2806 2663 1184 +f 2919 2663 2806 +f 852 2920 2671 +f 2920 987 2921 +f 2671 2921 1310 +f 2920 2921 2671 +f 531 2444 2922 +f 2444 145 2441 +f 2922 2441 1243 +f 2444 2441 2922 +f 590 2823 2816 +f 2823 679 2923 +f 2816 2923 1053 +f 2823 2923 2816 +f 679 2924 2923 +f 2924 987 2925 +f 2923 2925 1053 +f 2924 2925 2923 +f 1341 2926 2811 +f 2926 1010 2927 +f 2811 2927 1430 +f 2926 2927 2811 +f 1010 2928 2927 +f 2928 863 2689 +f 2927 2689 1430 +f 2928 2689 2927 +f 1098 2681 2930 +f 2681 1038 2929 +f 2930 2929 1436 +f 2681 2929 2930 +f 168 2821 2931 +f 2821 277 2237 +f 2931 2237 967 +f 2821 2237 2931 +f 794 2700 2932 +f 2700 1098 2930 +f 2932 2930 1436 +f 2700 2930 2932 +f 464 2827 2933 +f 2827 863 2928 +f 2933 2928 1010 +f 2827 2928 2933 +f 245 2934 2935 +f 2934 385 2817 +f 2935 2817 713 +f 2934 2817 2935 +f 245 2935 2936 +f 2935 713 2699 +f 2936 2699 1110 +f 2935 2699 2936 +f 594 2937 2938 +f 2937 794 2932 +f 2938 2932 1436 +f 2937 2932 2938 +f 776 2939 2940 +f 2939 679 2825 +f 2940 2825 1374 +f 2939 2825 2940 +f 1026 2941 2709 +f 2941 245 2936 +f 2709 2936 1110 +f 2941 2936 2709 +f 967 2828 2943 +f 2828 380 2942 +f 2943 2942 1244 +f 2828 2942 2943 +f 248 2826 2831 +f 2826 464 2944 +f 2831 2944 1144 +f 2826 2944 2831 +f 131 2945 2706 +f 2945 198 2834 +f 2706 2834 1254 +f 2945 2834 2706 +f 594 2946 2937 +f 2946 273 2455 +f 2937 2455 794 +f 2946 2455 2937 +f 273 2946 2948 +f 2946 594 2947 +f 2948 2947 1411 +f 2946 2947 2948 +f 198 2949 2833 +f 2949 992 2950 +f 2833 2950 1163 +f 2949 2950 2833 +f 653 2458 2951 +f 2458 273 2948 +f 2951 2948 1411 +f 2458 2948 2951 +f 1163 2950 2253 +f 2950 992 2952 +f 2253 2952 1400 +f 2950 2952 2253 +f 328 2462 2839 +f 2462 218 2953 +f 2839 2953 1269 +f 2462 2953 2839 +f 458 2347 2955 +f 2347 646 2954 +f 2955 2954 672 +f 2347 2954 2955 +f 333 2837 2835 +f 2837 671 2956 +f 2835 2956 1047 +f 2837 2956 2835 +f 1144 2957 2832 +f 2957 859 2958 +f 2832 2958 1439 +f 2957 2958 2832 +f 546 2959 2830 +f 2959 430 2960 +f 2830 2960 1374 +f 2959 2960 2830 +f 430 2959 2961 +f 2959 546 2842 +f 2961 2842 660 +f 2959 2842 2961 +f 859 2962 2958 +f 2962 671 2838 +f 2958 2838 1439 +f 2962 2838 2958 +f 1047 2956 2964 +f 2956 671 2963 +f 2964 2963 1465 +f 2956 2963 2964 +f 644 2965 2967 +f 2965 620 2966 +f 2967 2966 1047 +f 2965 2966 2967 +f 620 2968 2966 +f 2968 660 2843 +f 2966 2843 1047 +f 2968 2843 2966 +f 644 2967 2844 +f 2967 1047 2964 +f 2844 2964 1465 +f 2967 2964 2844 +f 620 2965 2969 +f 2965 644 2583 +f 2969 2583 836 +f 2965 2583 2969 +f 836 2587 2971 +f 2587 1266 2970 +f 2971 2970 1305 +f 2587 2970 2971 +f 699 2466 2973 +f 2466 173 2972 +f 2973 2972 1230 +f 2466 2972 2973 +f 1230 2972 2974 +f 2972 173 2845 +f 2974 2845 1465 +f 2972 2845 2974 +f 1266 2849 2970 +f 2849 386 2975 +f 2970 2975 1305 +f 2849 2975 2970 +f 386 2976 2975 +f 2976 1207 2977 +f 2975 2977 1305 +f 2976 2977 2975 +f 1222 2846 2978 +f 2846 699 2973 +f 2978 2973 1230 +f 2846 2973 2978 +f 312 2855 2850 +f 2855 1122 2979 +f 2850 2979 1324 +f 2855 2979 2850 +f 370 2866 2981 +f 2866 60 2980 +f 2981 2980 529 +f 2866 2980 2981 +f 529 2980 2982 +f 2980 60 2598 +f 2982 2598 871 +f 2980 2598 2982 +f 784 2983 2984 +f 2983 871 2857 +f 2984 2857 1050 +f 2983 2857 2984 +f 1050 2856 2986 +f 2856 371 2985 +f 2986 2985 1440 +f 2856 2985 2986 +f 371 2860 2985 +f 2860 1271 2987 +f 2985 2987 1440 +f 2860 2987 2985 +f 1122 2865 2989 +f 2865 370 2988 +f 2989 2988 1337 +f 2865 2988 2989 +f 829 2990 2992 +f 2990 678 2991 +f 2992 2991 1102 +f 2990 2991 2992 +f 85 2862 2719 +f 2862 678 2990 +f 2719 2990 829 +f 2862 2990 2719 +f 993 2993 2995 +f 2993 92 2994 +f 2995 2994 1337 +f 2993 2994 2995 +f 550 2725 2996 +f 2725 993 2995 +f 2996 2995 1337 +f 2725 2995 2996 +f 511 2997 2870 +f 2997 658 2998 +f 2870 2998 785 +f 2997 2998 2870 +f 658 2999 2998 +f 2999 678 3000 +f 2998 3000 785 +f 2999 3000 2998 +f 785 3000 3001 +f 3000 678 2863 +f 3001 2863 934 +f 3000 2863 3001 +f 242 2727 3002 +f 2727 785 3001 +f 3002 3001 934 +f 2727 3001 3002 +f 1035 2871 3003 +f 2871 550 2996 +f 3003 2996 1337 +f 2871 2996 3003 +f 979 3004 2729 +f 3004 874 3005 +f 2729 3005 1324 +f 3004 3005 2729 +f 419 3006 2877 +f 3006 795 3007 +f 2877 3007 1249 +f 3006 3007 2877 +f 795 3008 3007 +f 3008 1175 3009 +f 3007 3009 1249 +f 3008 3009 3007 +f 1175 3010 3009 +f 3010 725 3011 +f 3009 3011 1249 +f 3010 3011 3009 +f 439 2875 3012 +f 2875 219 2732 +f 3012 2732 1035 +f 2875 2732 3012 +f 725 3013 3011 +f 3013 1044 2737 +f 3011 2737 1249 +f 3013 2737 3011 +f 973 3014 2487 +f 3014 874 3004 +f 2487 3004 979 +f 3014 3004 2487 +f 719 3015 3016 +f 3015 593 2741 +f 3016 2741 929 +f 3015 2741 3016 +f 604 3017 3018 +f 3017 711 2744 +f 3018 2744 1059 +f 3017 2744 3018 +f 490 2882 3019 +f 2882 1070 2624 +f 3019 2624 1295 +f 2882 2624 3019 +f 517 2883 3020 +f 2883 490 3019 +f 3020 3019 1295 +f 2883 3019 3020 +f 1059 2618 3021 +f 2618 1427 2759 +f 3021 2759 1495 +f 2618 2759 3021 +f 517 3022 2884 +f 3022 706 3023 +f 2884 3023 1348 +f 3022 3023 2884 +f 885 3024 2894 +f 3024 1028 2892 +f 2894 2892 1492 +f 3024 2892 2894 +f 106 2896 2651 +f 2896 70 3025 +f 2651 3025 1446 +f 2896 3025 2651 +f 537 3026 3027 +f 3026 456 2769 +f 3027 2769 1446 +f 3026 2769 3027 +f 142 2635 3029 +f 2635 655 3028 +f 3029 3028 1091 +f 2635 3028 3029 +f 895 3030 3031 +f 3030 155 2643 +f 3031 2643 1369 +f 3030 2643 3031 +f 69 2644 3032 +f 2644 155 3030 +f 3032 3030 895 +f 2644 3030 3032 +f 1090 2898 3033 +f 2898 61 2775 +f 3033 2775 1390 +f 2898 2775 3033 +f 585 3034 3035 +f 3034 283 2900 +f 3035 2900 1090 +f 3034 2900 3035 +f 283 3034 3037 +f 3034 585 3036 +f 3037 3036 762 +f 3034 3036 3037 +f 228 2787 3038 +f 2787 283 3037 +f 3038 3037 762 +f 2787 3037 3038 +f 572 3039 3040 +f 3039 228 3038 +f 3040 3038 762 +f 3039 3038 3040 +f 558 3041 2797 +f 3041 1194 3042 +f 2797 3042 1238 +f 3041 3042 2797 +f 1128 3043 3044 +f 3043 602 2796 +f 3044 2796 1455 +f 3043 2796 3044 +f 1194 3045 3042 +f 3045 1095 3046 +f 3042 3046 1238 +f 3045 3046 3042 +f 778 3047 2526 +f 3047 1128 3044 +f 2526 3044 1455 +f 3047 3044 2526 +f 363 3048 2910 +f 3048 651 3049 +f 2910 3049 1336 +f 3048 3049 2910 +f 491 3050 3052 +f 3050 621 3051 +f 3052 3051 1067 +f 3050 3051 3052 +f 178 3053 2907 +f 3053 491 3052 +f 2907 3052 1067 +f 3053 3052 2907 +f 1128 3047 3054 +f 3047 778 2912 +f 3054 2912 1434 +f 3047 2912 3054 +f 1095 3055 3046 +f 3055 1021 2657 +f 3046 2657 1238 +f 3055 2657 3046 +f 363 2909 3057 +f 2909 503 3056 +f 3057 3056 522 +f 2909 3056 3057 +f 196 3058 3060 +f 3058 1046 3059 +f 3060 3059 1153 +f 3058 3059 3060 +f 552 2550 3062 +f 2550 299 3061 +f 3062 3061 1182 +f 2550 3061 3062 +f 1182 3061 3063 +f 3061 299 2807 +f 3063 2807 1263 +f 3061 2807 3063 +f 1323 3064 2670 +f 3064 1263 2808 +f 2670 2808 1459 +f 3064 2808 2670 +f 1345 2666 3066 +f 2666 1152 3065 +f 3066 3065 1380 +f 2666 3065 3066 +f 390 3067 3069 +f 3067 206 3068 +f 3069 3068 1157 +f 3067 3068 3069 +f 390 3069 2324 +f 3069 1157 3070 +f 2324 3070 1179 +f 3069 3070 2324 +f 192 3071 2219 +f 3071 206 3067 +f 2219 3067 390 +f 3071 3067 2219 +f 206 3071 3073 +f 3071 192 3072 +f 3073 3072 1484 +f 3071 3072 3073 +f 987 2920 2925 +f 2920 852 2675 +f 2925 2675 1053 +f 2920 2675 2925 +f 270 3074 2570 +f 3074 281 3075 +f 2570 3075 754 +f 3074 3075 2570 +f 1038 2680 3076 +f 2680 876 2677 +f 3076 2677 1469 +f 2680 2677 3076 +f 266 2567 2690 +f 2567 838 3077 +f 2690 3077 1078 +f 2567 3077 2690 +f 547 3078 3079 +f 3078 270 2571 +f 3079 2571 1129 +f 3078 2571 3079 +f 168 2931 3080 +f 2931 967 2943 +f 3080 2943 1244 +f 2931 2943 3080 +f 458 2955 2345 +f 2955 672 3081 +f 2345 3081 1121 +f 2955 3081 2345 +f 646 2251 3082 +f 2251 653 2951 +f 3082 2951 1411 +f 2251 2951 3082 +f 220 3083 3085 +f 3083 1036 3084 +f 3085 3084 1144 +f 3083 3084 3085 +f 288 3086 3087 +f 3086 218 2464 +f 3087 2464 1400 +f 3086 2464 3087 +f 992 3088 2952 +f 3088 288 3087 +f 2952 3087 1400 +f 3088 3087 2952 +f 1145 3089 3090 +f 3089 776 2940 +f 3090 2940 1374 +f 3089 2940 3090 +f 430 3091 2960 +f 3091 1145 3090 +f 2960 3090 1374 +f 3091 3090 2960 +f 620 3092 2968 +f 3092 430 2961 +f 2968 2961 660 +f 3092 2961 2968 +f 671 2962 3094 +f 2962 859 3093 +f 3094 3093 888 +f 2962 3093 3094 +f 671 3094 2963 +f 3094 888 3095 +f 2963 3095 1465 +f 3094 3095 2963 +f 888 3096 3095 +f 3096 601 3097 +f 3095 3097 1465 +f 3096 3097 3095 +f 620 2969 3098 +f 2969 836 2971 +f 3098 2971 1305 +f 2969 2971 3098 +f 601 3099 3097 +f 3099 1230 2974 +f 3097 2974 1465 +f 3099 2974 3097 +f 386 3100 2976 +f 3100 569 3101 +f 2976 3101 1207 +f 3100 3101 2976 +f 1222 3102 2713 +f 3102 369 3103 +f 2713 3103 1490 +f 3102 3103 2713 +f 784 3104 2983 +f 3104 529 2982 +f 2983 2982 871 +f 3104 2982 2983 +f 829 2992 2858 +f 2992 1102 3105 +f 2858 3105 1271 +f 2992 3105 2858 +f 1122 3106 2979 +f 3106 92 3107 +f 2979 3107 1324 +f 3106 3107 2979 +f 92 3106 2994 +f 3106 1122 2989 +f 2994 2989 1337 +f 3106 2989 2994 +f 211 3108 3109 +f 3108 784 2984 +f 3109 2984 1050 +f 3108 2984 3109 +f 1307 3110 3111 +f 3110 1050 2986 +f 3111 2986 1440 +f 3110 2986 3111 +f 92 2993 3107 +f 2993 993 2723 +f 3107 2723 1324 +f 2993 2723 3107 +f 205 3112 3114 +f 3112 211 3113 +f 3114 3113 795 +f 3112 3113 3114 +f 795 3113 3115 +f 3113 211 3109 +f 3115 3109 1050 +f 3113 3109 3115 +f 795 3115 3008 +f 3115 1050 3116 +f 3008 3116 1175 +f 3115 3116 3008 +f 1175 3116 3117 +f 3116 1050 3110 +f 3117 3110 1307 +f 3116 3110 3117 +f 678 2999 2991 +f 2999 658 3118 +f 2991 3118 1102 +f 2999 3118 2991 +f 242 3002 3119 +f 3002 934 2853 +f 3119 2853 1490 +f 3002 2853 3119 +f 376 3120 3122 +f 3120 227 3121 +f 3122 3121 1490 +f 3120 3121 3122 +f 227 2738 3121 +f 2738 242 3119 +f 3121 3119 1490 +f 2738 3119 3121 +f 954 3123 3124 +f 3123 1035 3003 +f 3124 3003 1337 +f 3123 3003 3124 +f 18 3125 3126 +f 3125 1175 3117 +f 3126 3117 1307 +f 3125 3117 3126 +f 658 3127 3118 +f 3127 691 3128 +f 3118 3128 1102 +f 3127 3128 3118 +f 691 3127 3130 +f 3127 658 3129 +f 3130 3129 1044 +f 3127 3129 3130 +f 658 2997 3129 +f 2997 511 2873 +f 3129 2873 1044 +f 2997 2873 3129 +f 387 3131 3133 +f 3131 205 3132 +f 3133 3132 439 +f 3131 3132 3133 +f 205 3134 3132 +f 3134 419 2876 +f 3132 2876 439 +f 3134 2876 3132 +f 419 3134 3006 +f 3134 205 3114 +f 3006 3114 795 +f 3134 3114 3006 +f 18 3135 3125 +f 3135 725 3010 +f 3125 3010 1175 +f 3135 3010 3125 +f 954 3136 3123 +f 3136 439 3012 +f 3123 3012 1035 +f 3136 3012 3123 +f 227 3137 2607 +f 3137 929 2740 +f 2607 2740 953 +f 3137 2740 2607 +f 533 3138 3139 +f 3138 874 3014 +f 3139 3014 973 +f 3138 3014 3139 +f 593 3015 2879 +f 3015 719 3140 +f 2879 3140 1280 +f 3015 3140 2879 +f 706 3022 3141 +f 3022 517 3020 +f 3141 3020 1295 +f 3022 3020 3141 +f 234 3142 3144 +f 3142 964 3143 +f 3144 3143 1495 +f 3142 3143 3144 +f 964 3145 3143 +f 3145 1059 3021 +f 3143 3021 1495 +f 3145 3021 3143 +f 622 3146 3148 +f 3146 431 3147 +f 3148 3147 706 +f 3146 3147 3148 +f 431 3146 3150 +f 3146 622 3149 +f 3150 3149 788 +f 3146 3149 3150 +f 234 3151 3153 +f 3151 629 3152 +f 3153 3152 1320 +f 3151 3152 3153 +f 706 3147 3023 +f 3147 431 3154 +f 3023 3154 1348 +f 3147 3154 3023 +f 990 3155 2764 +f 3155 234 3144 +f 2764 3144 1495 +f 3155 3144 2764 +f 431 3150 3157 +f 3150 788 3156 +f 3157 3156 1273 +f 3150 3156 3157 +f 234 3158 3151 +f 3158 225 3159 +f 3151 3159 629 +f 3158 3159 3151 +f 225 3158 3160 +f 3158 234 3155 +f 3160 3155 990 +f 3158 3155 3160 +f 389 2888 2765 +f 2888 518 3161 +f 2765 3161 990 +f 2888 3161 2765 +f 431 3157 3154 +f 3157 1273 3162 +f 3154 3162 1348 +f 3157 3162 3154 +f 1348 3162 2886 +f 3162 1273 3163 +f 2886 3163 1468 +f 3162 3163 2886 +f 225 3160 3165 +f 3160 990 3164 +f 3165 3164 1180 +f 3160 3164 3165 +f 736 3166 3168 +f 3166 1180 3167 +f 3168 3167 1278 +f 3166 3167 3168 +f 1300 3169 3171 +f 3169 1452 3170 +f 3171 3170 1493 +f 3169 3170 3171 +f 736 3168 3173 +f 3168 1278 3172 +f 3173 3172 1498 +f 3168 3172 3173 +f 627 3174 3176 +f 3174 906 3175 +f 3176 3175 1329 +f 3174 3175 3176 +f 627 3177 3174 +f 3177 70 2897 +f 3174 2897 906 +f 3177 2897 3174 +f 70 3178 3025 +f 3178 1088 3179 +f 3025 3179 1446 +f 3178 3179 3025 +f 51 3180 3181 +f 3180 142 3029 +f 3181 3029 1091 +f 3180 3029 3181 +f 142 3180 2771 +f 3180 51 3182 +f 2771 3182 480 +f 3180 3182 2771 +f 1369 3183 3185 +f 3183 1146 3184 +f 3185 3184 1413 +f 3183 3184 3185 +f 895 3031 3186 +f 3031 1369 3185 +f 3186 3185 1413 +f 3031 3185 3186 +f 906 3187 3175 +f 3187 913 3188 +f 3175 3188 1329 +f 3187 3188 3175 +f 913 3187 3189 +f 3187 906 2783 +f 3189 2783 1425 +f 3187 2783 3189 +f 325 3190 3191 +f 3190 913 3189 +f 3191 3189 1425 +f 3190 3189 3191 +f 558 2791 3193 +f 2791 780 3192 +f 3193 3192 1006 +f 2791 3192 3193 +f 43 2901 3195 +f 2901 228 3194 +f 3195 3194 499 +f 2901 3194 3195 +f 499 3194 3196 +f 3194 228 3039 +f 3196 3039 572 +f 3194 3039 3196 +f 1096 3197 3198 +f 3197 378 2794 +f 3198 2794 1336 +f 3197 2794 3198 +f 43 3199 2904 +f 3199 73 3200 +f 2904 3200 178 +f 3199 3200 2904 +f 73 3199 3201 +f 3199 43 3195 +f 3201 3195 499 +f 3199 3195 3201 +f 379 3202 3203 +f 3202 1096 3198 +f 3203 3198 1336 +f 3202 3198 3203 +f 651 3204 3049 +f 3204 379 3203 +f 3049 3203 1336 +f 3204 3203 3049 +f 1067 3051 3206 +f 3051 621 3205 +f 3206 3205 1104 +f 3051 3205 3206 +f 1137 3207 2911 +f 3207 116 3208 +f 2911 3208 1434 +f 3207 3208 2911 +f 522 3056 2915 +f 3056 503 2659 +f 2915 2659 1431 +f 3056 2659 2915 +f 1060 2917 3209 +f 2917 1067 3206 +f 3209 3206 1104 +f 2917 3206 3209 +f 938 3210 3211 +f 3210 116 3207 +f 3211 3207 1137 +f 3210 3207 3211 +f 1021 3212 2913 +f 3212 938 3211 +f 2913 3211 1137 +f 3212 3211 2913 +f 552 3213 2801 +f 3213 665 3214 +f 2801 3214 668 +f 3213 3214 2801 +f 113 3215 3217 +f 3215 555 3216 +f 3217 3216 703 +f 3215 3216 3217 +f 113 3218 3215 +f 3218 126 2805 +f 3215 2805 555 +f 3218 2805 3215 +f 1263 3064 3220 +f 3064 1323 3219 +f 3220 3219 1429 +f 3064 3219 3220 +f 1323 2668 3219 +f 2668 1310 3221 +f 3219 3221 1429 +f 2668 3221 3219 +f 1310 3222 3221 +f 3222 837 3223 +f 3221 3223 1429 +f 3222 3223 3221 +f 825 3224 3225 +f 3224 531 2922 +f 3225 2922 1243 +f 3224 2922 3225 +f 192 2442 3072 +f 2442 754 3226 +f 3072 3226 1484 +f 2442 3226 3072 +f 968 3227 3228 +f 3227 1010 2926 +f 3228 2926 1341 +f 3227 2926 3228 +f 1078 3229 2691 +f 3229 131 2705 +f 2691 2705 1219 +f 3229 2705 2691 +f 679 2939 3231 +f 2939 776 3230 +f 3231 3230 1183 +f 2939 3230 3231 +f 464 2933 3233 +f 2933 1010 3232 +f 3233 3232 1083 +f 2933 3232 3233 +f 220 3234 3235 +f 3234 464 3233 +f 3235 3233 1083 +f 3234 3233 3235 +f 899 3236 3237 +f 3236 1026 2840 +f 3237 2840 1269 +f 3236 2840 3237 +f 464 3234 2944 +f 3234 220 3085 +f 2944 3085 1144 +f 3234 3085 2944 +f 1036 3238 3084 +f 3238 859 2957 +f 3084 2957 1144 +f 3238 2957 3084 +f 888 3093 3239 +f 3093 859 3238 +f 3239 3238 1036 +f 3093 3238 3239 +f 1145 3091 3241 +f 3091 430 3240 +f 3241 3240 1305 +f 3091 3240 3241 +f 430 3092 3240 +f 3092 620 3098 +f 3240 3098 1305 +f 3092 3098 3240 +f 799 3242 3243 +f 3242 1222 2978 +f 3243 2978 1230 +f 3242 2978 3243 +f 1324 3244 2851 +f 3244 210 3245 +f 2851 3245 1423 +f 3244 3245 2851 +f 370 2981 3247 +f 2981 529 3246 +f 3247 3246 879 +f 2981 3246 3247 +f 370 3247 2988 +f 3247 879 3248 +f 2988 3248 1337 +f 3247 3248 2988 +f 529 3104 3246 +f 3104 784 3249 +f 3246 3249 879 +f 3104 3249 3246 +f 879 3250 3248 +f 3250 954 3124 +f 3248 3124 1337 +f 3250 3124 3248 +f 211 3251 3253 +f 3251 387 3252 +f 3253 3252 879 +f 3251 3252 3253 +f 784 3108 3249 +f 3108 211 3253 +f 3249 3253 879 +f 3108 3253 3249 +f 1271 3254 2987 +f 3254 1307 3111 +f 2987 3111 1440 +f 3254 3111 2987 +f 1102 3128 3105 +f 3128 691 3255 +f 3105 3255 1271 +f 3128 3255 3105 +f 691 3256 3257 +f 3256 18 3126 +f 3257 3126 1307 +f 3256 3126 3257 +f 211 3112 3251 +f 3112 205 3131 +f 3251 3131 387 +f 3112 3131 3251 +f 18 3256 3135 +f 3256 691 3258 +f 3135 3258 725 +f 3256 3258 3135 +f 725 3258 3013 +f 3258 691 3130 +f 3013 3130 1044 +f 3258 3130 3013 +f 387 3133 3259 +f 3133 439 3136 +f 3259 3136 954 +f 3133 3136 3259 +f 227 3120 3137 +f 3120 376 3260 +f 3137 3260 929 +f 3120 3260 3137 +f 533 3139 3262 +f 3139 973 3261 +f 3262 3261 1131 +f 3139 3261 3262 +f 973 2878 3261 +f 2878 711 3263 +f 3261 3263 1131 +f 2878 3263 3261 +f 711 3017 3263 +f 3017 604 3264 +f 3263 3264 1131 +f 3017 3264 3263 +f 719 3265 3140 +f 3265 434 3266 +f 3140 3266 1280 +f 3265 3266 3140 +f 964 3267 3145 +f 3267 604 3018 +f 3145 3018 1059 +f 3267 3018 3145 +f 1280 3268 2880 +f 3268 622 3269 +f 2880 3269 1295 +f 3268 3269 2880 +f 964 3142 3270 +f 3142 234 3153 +f 3270 3153 1320 +f 3142 3153 3270 +f 622 3148 3269 +f 3148 706 3141 +f 3269 3141 1295 +f 3148 3141 3269 +f 629 3271 3152 +f 3271 446 3272 +f 3152 3272 1320 +f 3271 3272 3152 +f 788 3273 3275 +f 3273 1188 3274 +f 3275 3274 1231 +f 3273 3274 3275 +f 788 3275 3156 +f 3275 1231 3276 +f 3156 3276 1273 +f 3275 3276 3156 +f 518 3277 3161 +f 3277 47 3278 +f 3161 3278 990 +f 3277 3278 3161 +f 990 3278 3164 +f 3278 47 3279 +f 3164 3279 1180 +f 3278 3279 3164 +f 893 3280 3281 +f 3280 885 2895 +f 3281 2895 1468 +f 3280 2895 3281 +f 256 3282 3284 +f 3282 629 3283 +f 3284 3283 1180 +f 3282 3283 3284 +f 629 3159 3283 +f 3159 225 3165 +f 3283 3165 1180 +f 3159 3165 3283 +f 47 3277 3285 +f 3277 518 2890 +f 3285 2890 1028 +f 3277 2890 3285 +f 893 3286 3287 +f 3286 47 3285 +f 3287 3285 1028 +f 3286 3285 3287 +f 885 3280 3024 +f 3280 893 3287 +f 3024 3287 1028 +f 3280 3287 3024 +f 893 3281 3289 +f 3281 1468 3288 +f 3289 3288 1493 +f 3281 3288 3289 +f 1468 3163 3288 +f 3163 1273 3290 +f 3288 3290 1493 +f 3163 3290 3288 +f 1125 3291 3292 +f 3291 893 3289 +f 3292 3289 1493 +f 3291 3289 3292 +f 1493 3290 3294 +f 3290 1273 3293 +f 3294 3293 1500 +f 3290 3293 3294 +f 1180 3295 3167 +f 3295 1125 3296 +f 3167 3296 1278 +f 3295 3296 3167 +f 1452 3297 3170 +f 3297 1125 3292 +f 3170 3292 1493 +f 3297 3292 3170 +f 736 3298 3166 +f 3298 256 3284 +f 3166 3284 1180 +f 3298 3284 3166 +f 1300 3171 3299 +f 3171 1493 3294 +f 3299 3294 1500 +f 3171 3294 3299 +f 96 3300 3301 +f 3300 256 3298 +f 3301 3298 736 +f 3300 3298 3301 +f 187 3302 3303 +f 3302 1125 3297 +f 3303 3297 1452 +f 3302 3297 3303 +f 1125 3304 3296 +f 3304 351 3305 +f 3296 3305 1278 +f 3304 3305 3296 +f 96 3301 3306 +f 3301 736 3173 +f 3306 3173 1498 +f 3301 3173 3306 +f 133 3307 3308 +f 3307 187 3303 +f 3308 3303 1452 +f 3307 3303 3308 +f 207 3309 3310 +f 3309 133 3308 +f 3310 3308 1452 +f 3309 3308 3310 +f 1300 3311 3169 +f 3311 207 3310 +f 3169 3310 1452 +f 3311 3310 3169 +f 1237 3312 3313 +f 3312 207 3311 +f 3313 3311 1300 +f 3312 3311 3313 +f 1278 3305 3172 +f 3305 351 3314 +f 3172 3314 1498 +f 3305 3314 3172 +f 456 3026 2770 +f 3026 537 3315 +f 2770 3315 655 +f 3026 3315 2770 +f 655 3315 3028 +f 3315 537 3316 +f 3028 3316 1091 +f 3315 3316 3028 +f 70 3177 3178 +f 3177 627 3317 +f 3178 3317 1088 +f 3177 3317 3178 +f 1088 3318 3179 +f 3318 537 3027 +f 3179 3027 1446 +f 3318 3027 3179 +f 649 3319 2778 +f 3319 1146 3183 +f 2778 3183 1369 +f 3319 3183 2778 +f 69 3032 2774 +f 3032 895 3320 +f 2774 3320 1390 +f 3032 3320 2774 +f 1146 3319 3322 +f 3319 649 3321 +f 3322 3321 1321 +f 3319 3321 3322 +f 649 2785 3321 +f 2785 378 3323 +f 3321 3323 1321 +f 2785 3323 3321 +f 597 3324 3325 +f 3324 325 3191 +f 3325 3191 1425 +f 3324 3191 3325 +f 602 3326 2906 +f 3326 597 3325 +f 2906 3325 1425 +f 3326 3325 2906 +f 491 3327 3329 +f 3327 73 3328 +f 3329 3328 1256 +f 3327 3328 3329 +f 178 3200 3053 +f 3200 73 3327 +f 3053 3327 491 +f 3200 3327 3053 +f 597 3326 3330 +f 3326 602 3043 +f 3330 3043 1128 +f 3326 3043 3330 +f 938 3212 3332 +f 3212 1021 3331 +f 3332 3331 1108 +f 3212 3331 3332 +f 1021 3055 3331 +f 3055 1095 3333 +f 3331 3333 1108 +f 3055 3333 3331 +f 797 3334 3336 +f 3334 540 3335 +f 3336 3335 1153 +f 3334 3335 3336 +f 126 3337 2919 +f 3337 564 3338 +f 2919 3338 1152 +f 3337 3338 2919 +f 1152 3338 3065 +f 3338 564 3339 +f 3065 3339 1380 +f 3338 3339 3065 +f 1204 3340 3341 +f 3340 1345 3066 +f 3341 3066 1380 +f 3340 3066 3341 +f 1179 3070 2676 +f 3070 1157 3342 +f 2676 3342 1469 +f 3070 3342 2676 +f 987 3343 2921 +f 3343 837 3222 +f 2921 3222 1310 +f 3343 3222 2921 +f 74 3344 2812 +f 3344 624 3345 +f 2812 3345 1195 +f 3344 3345 2812 +f 754 3075 3226 +f 3075 281 3346 +f 3226 3346 1484 +f 3075 3346 3226 +f 968 3228 3347 +f 3228 1341 2810 +f 3347 2810 1345 +f 3228 2810 3347 +f 1204 3348 3340 +f 3348 968 3347 +f 3340 3347 1345 +f 3348 3347 3340 +f 838 2815 3350 +f 2815 531 3349 +f 3350 3349 1281 +f 2815 3349 3350 +f 624 3344 3351 +f 3344 74 2566 +f 3351 2566 1246 +f 3344 2566 3351 +f 1038 3352 2929 +f 3352 1065 3353 +f 2929 3353 1436 +f 3352 3353 2929 +f 679 3354 2924 +f 3354 330 3355 +f 2924 3355 987 +f 3354 3355 2924 +f 330 3354 3356 +f 3354 679 3231 +f 3356 3231 1183 +f 3354 3231 3356 +f 1010 3227 3232 +f 3227 968 3357 +f 3232 3357 1083 +f 3227 3357 3232 +f 385 2934 3359 +f 2934 245 3358 +f 3359 3358 768 +f 2934 3358 3359 +f 899 3360 3236 +f 3360 245 2941 +f 3236 2941 1026 +f 3360 2941 3236 +f 672 2954 3361 +f 2954 646 3082 +f 3361 3082 1411 +f 2954 3082 3361 +f 218 3086 2953 +f 3086 288 3362 +f 2953 3362 1269 +f 3086 3362 2953 +f 220 3363 3083 +f 3363 28 3364 +f 3083 3364 1036 +f 3363 3364 3083 +f 1207 3365 2977 +f 3365 1145 3241 +f 2977 3241 1305 +f 3365 3241 2977 +f 601 3096 3366 +f 3096 888 3239 +f 3366 3239 1036 +f 3096 3239 3366 +f 601 3367 3099 +f 3367 799 3243 +f 3099 3243 1230 +f 3367 3243 3099 +f 569 3100 3368 +f 3100 386 2848 +f 3368 2848 1423 +f 3100 2848 3368 +f 874 3369 3005 +f 3369 210 3244 +f 3005 3244 1324 +f 3369 3244 3005 +f 369 3370 3103 +f 3370 376 3122 +f 3103 3122 1490 +f 3370 3122 3103 +f 1271 3255 3254 +f 3255 691 3257 +f 3254 3257 1307 +f 3255 3257 3254 +f 879 3252 3250 +f 3252 387 3259 +f 3250 3259 954 +f 3252 3259 3250 +f 22 3371 3372 +f 3371 622 3268 +f 3372 3268 1280 +f 3371 3268 3372 +f 622 3371 3149 +f 3371 22 3373 +f 3149 3373 788 +f 3371 3373 3149 +f 1001 3374 3375 +f 3374 964 3270 +f 3375 3270 1320 +f 3374 3270 3375 +f 446 3271 3377 +f 3271 629 3376 +f 3377 3376 824 +f 3271 3376 3377 +f 1273 3276 3293 +f 3276 1231 3378 +f 3293 3378 1500 +f 3276 3378 3293 +f 629 3282 3376 +f 3282 256 3379 +f 3376 3379 824 +f 3282 3379 3376 +f 824 3379 3381 +f 3379 256 3380 +f 3381 3380 848 +f 3379 3380 3381 +f 47 3382 3279 +f 3382 1125 3295 +f 3279 3295 1180 +f 3382 3295 3279 +f 47 3286 3382 +f 3286 893 3291 +f 3382 3291 1125 +f 3286 3291 3382 +f 256 3300 3380 +f 3300 96 3383 +f 3380 3383 848 +f 3300 3383 3380 +f 362 3384 3386 +f 3384 179 3385 +f 3386 3385 1300 +f 3384 3385 3386 +f 848 3383 3388 +f 3383 96 3387 +f 3388 3387 1004 +f 3383 3387 3388 +f 187 3389 3302 +f 3389 351 3304 +f 3302 3304 1125 +f 3389 3304 3302 +f 1004 3387 3390 +f 3387 96 3306 +f 3390 3306 1498 +f 3387 3306 3390 +f 351 3389 3392 +f 3389 187 3391 +f 3392 3391 631 +f 3389 3391 3392 +f 179 3393 3385 +f 3393 1237 3313 +f 3385 3313 1300 +f 3393 3313 3385 +f 187 3307 3391 +f 3307 133 3394 +f 3391 3394 631 +f 3307 3394 3391 +f 252 3395 3397 +f 3395 605 3396 +f 3397 3396 1498 +f 3395 3396 3397 +f 351 3398 3314 +f 3398 252 3397 +f 3314 3397 1498 +f 3398 3397 3314 +f 631 3394 3400 +f 3394 133 3399 +f 3400 3399 647 +f 3394 3399 3400 +f 133 3309 3399 +f 3309 207 3401 +f 3399 3401 647 +f 3309 3401 3399 +f 537 3402 3316 +f 3402 77 3403 +f 3316 3403 1091 +f 3402 3403 3316 +f 895 3404 3320 +f 3404 1090 3033 +f 3320 3033 1390 +f 3404 3033 3320 +f 480 3182 3406 +f 3182 51 3405 +f 3406 3405 1370 +f 3182 3405 3406 +f 1146 3407 3184 +f 3407 681 3408 +f 3184 3408 1413 +f 3407 3408 3184 +f 780 2637 3409 +f 2637 480 3406 +f 3409 3406 1370 +f 2637 3406 3409 +f 325 3324 3411 +f 3324 597 3410 +f 3411 3410 1008 +f 3324 3410 3411 +f 558 3193 3041 +f 3193 1006 3412 +f 3041 3412 1194 +f 3193 3412 3041 +f 116 3413 3208 +f 3413 1402 3414 +f 3208 3414 1434 +f 3413 3414 3208 +f 9 3415 3416 +f 3415 522 2914 +f 3416 2914 1060 +f 3415 2914 3416 +f 116 3210 3413 +f 3210 938 3417 +f 3413 3417 1402 +f 3210 3417 3413 +f 483 3418 3419 +f 3418 1060 3209 +f 3419 3209 1104 +f 3418 3209 3419 +f 1182 3420 3422 +f 3420 757 3421 +f 3422 3421 1372 +f 3420 3421 3422 +f 757 3420 3423 +f 3420 1182 3063 +f 3423 3063 1263 +f 3420 3063 3423 +f 126 3218 3337 +f 3218 113 3424 +f 3337 3424 564 +f 3218 3424 3337 +f 757 3423 3425 +f 3423 1263 3220 +f 3425 3220 1429 +f 3423 3220 3425 +f 281 3074 3426 +f 3074 270 3078 +f 3426 3078 547 +f 3074 3078 3426 +f 1078 3077 3428 +f 3077 838 3427 +f 3428 3427 1353 +f 3077 3427 3428 +f 1038 3429 3352 +f 3429 545 3430 +f 3352 3430 1065 +f 3429 3430 3352 +f 968 3431 3357 +f 3431 193 3432 +f 3357 3432 1083 +f 3431 3432 3357 +f 385 3359 2818 +f 3359 768 3433 +f 2818 3433 1246 +f 3359 3433 2818 +f 245 3434 3358 +f 3434 12 3435 +f 3358 3435 768 +f 3434 3435 3358 +f 12 3434 3436 +f 3434 245 3360 +f 3436 3360 899 +f 3434 3360 3436 +f 380 2829 3438 +f 2829 1121 3437 +f 3438 3437 1385 +f 2829 3437 3438 +f 103 3439 3440 +f 3439 601 3366 +f 3440 3366 1036 +f 3439 3366 3440 +f 569 3441 3101 +f 3441 54 3442 +f 3101 3442 1207 +f 3441 3442 3101 +f 601 3439 3367 +f 3439 103 3443 +f 3367 3443 799 +f 3439 3443 3367 +f 530 3444 3445 +f 3444 569 3368 +f 3445 3368 1423 +f 3444 3368 3445 +f 210 3446 3245 +f 3446 530 3445 +f 3245 3445 1423 +f 3446 3445 3245 +f 799 3447 3242 +f 3447 600 3448 +f 3242 3448 1222 +f 3447 3448 3242 +f 600 3449 3448 +f 3449 369 3102 +f 3448 3102 1222 +f 3449 3102 3448 +f 929 3260 3451 +f 3260 376 3450 +f 3451 3450 1138 +f 3260 3450 3451 +f 1025 3452 3453 +f 3452 533 3262 +f 3453 3262 1131 +f 3452 3262 3453 +f 434 3265 3455 +f 3265 719 3454 +f 3455 3454 980 +f 3265 3454 3455 +f 604 3456 3264 +f 3456 123 3457 +f 3264 3457 1131 +f 3456 3457 3264 +f 123 3458 3459 +f 3458 964 3374 +f 3459 3374 1001 +f 3458 3374 3459 +f 123 3456 3458 +f 3456 604 3267 +f 3458 3267 964 +f 3456 3267 3458 +f 434 3460 3266 +f 3460 814 3461 +f 3266 3461 1280 +f 3460 3461 3266 +f 814 3462 3461 +f 3462 22 3372 +f 3461 3372 1280 +f 3462 3372 3461 +f 788 3463 3273 +f 3463 814 3464 +f 3273 3464 1188 +f 3463 3464 3273 +f 788 3373 3463 +f 3373 22 3462 +f 3463 3462 814 +f 3373 3462 3463 +f 446 3465 3272 +f 3465 534 3466 +f 3272 3466 1320 +f 3465 3466 3272 +f 1188 3467 3274 +f 3467 349 3468 +f 3274 3468 1231 +f 3467 3468 3274 +f 1231 3469 3378 +f 3469 184 3470 +f 3378 3470 1500 +f 3469 3470 3378 +f 362 3386 3471 +f 3386 1300 3299 +f 3471 3299 1500 +f 3386 3299 3471 +f 199 3472 3473 +f 3472 207 3312 +f 3473 3312 1237 +f 3472 3312 3473 +f 605 3474 3396 +f 3474 261 3475 +f 3396 3475 1498 +f 3474 3475 3396 +f 207 3472 3401 +f 3472 199 3476 +f 3401 3476 647 +f 3472 3476 3401 +f 252 3477 3395 +f 3477 373 3478 +f 3395 3478 605 +f 3477 3478 3395 +f 252 3479 3481 +f 3479 631 3480 +f 3481 3480 714 +f 3479 3480 3481 +f 252 3398 3479 +f 3398 351 3392 +f 3479 3392 631 +f 3398 3392 3479 +f 895 3482 3404 +f 3482 585 3035 +f 3404 3035 1090 +f 3482 3035 3404 +f 321 3483 3484 +f 3483 51 3181 +f 3484 3181 1091 +f 3483 3181 3484 +f 556 3485 3486 +f 3485 895 3186 +f 3486 3186 1413 +f 3485 3186 3486 +f 383 3487 3488 +f 3487 585 3482 +f 3488 3482 895 +f 3487 3482 3488 +f 585 3487 3036 +f 3487 383 3489 +f 3036 3489 762 +f 3487 3489 3036 +f 1006 3192 3490 +f 3192 780 3409 +f 3490 3409 1370 +f 3192 3409 3490 +f 762 3489 3492 +f 3489 383 3491 +f 3492 3491 1167 +f 3489 3491 3492 +f 572 3040 3493 +f 3040 762 3492 +f 3493 3492 1167 +f 3040 3492 3493 +f 913 3190 3494 +f 3190 325 3411 +f 3494 3411 1008 +f 3190 3411 3494 +f 499 3196 3495 +f 3196 572 3493 +f 3495 3493 1167 +f 3196 3493 3495 +f 378 3197 3323 +f 3197 1096 3496 +f 3323 3496 1321 +f 3197 3496 3323 +f 857 3497 3498 +f 3497 499 3495 +f 3498 3495 1167 +f 3497 3495 3498 +f 73 3201 3499 +f 3201 499 3497 +f 3499 3497 857 +f 3201 3497 3499 +f 694 3500 3501 +f 3500 597 3330 +f 3501 3330 1128 +f 3500 3330 3501 +f 522 3415 3503 +f 3415 9 3502 +f 3503 3502 941 +f 3415 3502 3503 +f 363 3057 3504 +f 3057 522 3503 +f 3504 3503 941 +f 3057 3503 3504 +f 350 3505 3506 +f 3505 938 3332 +f 3506 3332 1108 +f 3505 3332 3506 +f 598 3507 3508 +f 3507 9 3416 +f 3508 3416 1060 +f 3507 3416 3508 +f 483 3509 3418 +f 3509 598 3508 +f 3418 3508 1060 +f 3509 3508 3418 +f 621 3050 3511 +f 3050 491 3510 +f 3511 3510 933 +f 3050 3510 3511 +f 621 3512 3205 +f 3512 88 3513 +f 3205 3513 1104 +f 3512 3513 3205 +f 134 3514 3516 +f 3514 843 3515 +f 3516 3515 1434 +f 3514 3515 3516 +f 498 3517 3519 +f 3517 734 3518 +f 3519 3518 908 +f 3517 3518 3519 +f 734 3520 3518 +f 3520 639 3521 +f 3518 3521 908 +f 3520 3521 3518 +f 843 3522 3524 +f 3522 696 3523 +f 3524 3523 1135 +f 3522 3523 3524 +f 748 3525 3527 +f 3525 727 3526 +f 3527 3526 833 +f 3525 3526 3527 +f 611 3528 3530 +f 3528 908 3529 +f 3530 3529 1451 +f 3528 3529 3530 +f 398 3531 3533 +f 3531 635 3532 +f 3533 3532 1282 +f 3531 3532 3533 +f 63 3534 3536 +f 3534 635 3535 +f 3536 3535 748 +f 3534 3535 3536 +f 1186 3537 3539 +f 3537 674 3538 +f 3539 3538 1227 +f 3537 3538 3539 +f 674 3540 3538 +f 3540 462 3541 +f 3538 3541 1227 +f 3540 3541 3538 +f 566 3542 3544 +f 3542 815 3543 +f 3544 3543 1077 +f 3542 3543 3544 +f 235 3545 3547 +f 3545 797 3546 +f 3547 3546 984 +f 3545 3546 3547 +f 996 3548 3549 +f 3548 1186 3539 +f 3549 3539 1227 +f 3548 3539 3549 +f 366 3550 3552 +f 3550 462 3551 +f 3552 3551 1011 +f 3550 3551 3552 +f 462 3550 3554 +f 3550 366 3553 +f 3554 3553 1046 +f 3550 3553 3554 +f 113 3217 3556 +f 3217 703 3555 +f 3556 3555 1472 +f 3217 3555 3556 +f 465 3557 3558 +f 3557 1204 3341 +f 3558 3341 1380 +f 3557 3341 3558 +f 206 3559 3068 +f 3559 156 3560 +f 3068 3560 1157 +f 3559 3560 3068 +f 156 3559 3561 +f 3559 206 3073 +f 3561 3073 1484 +f 3559 3073 3561 +f 1195 3562 2814 +f 3562 825 3225 +f 2814 3225 1243 +f 3562 3225 2814 +f 531 3224 3349 +f 3224 825 3563 +f 3349 3563 1281 +f 3224 3563 3349 +f 330 3564 3355 +f 3564 292 3565 +f 3355 3565 987 +f 3564 3565 3355 +f 292 3566 3565 +f 3566 837 3343 +f 3565 3343 987 +f 3566 3343 3565 +f 193 3431 3567 +f 3431 968 3348 +f 3567 3348 1204 +f 3431 3348 3567 +f 1245 3568 3570 +f 3568 545 3569 +f 3570 3569 1469 +f 3568 3569 3570 +f 545 3429 3569 +f 3429 1038 3076 +f 3569 3076 1469 +f 3429 3076 3569 +f 1246 3433 3572 +f 3433 768 3571 +f 3572 3571 1311 +f 3433 3571 3572 +f 168 3573 2822 +f 3573 547 3079 +f 2822 3079 1129 +f 3573 3079 2822 +f 131 3574 3576 +f 3574 146 3575 +f 3576 3575 613 +f 3574 3575 3576 +f 146 3574 3577 +f 3574 131 3229 +f 3577 3229 1078 +f 3574 3229 3577 +f 1065 3578 3353 +f 3578 20 3579 +f 3353 3579 1436 +f 3578 3579 3353 +f 20 3580 3579 +f 3580 411 3581 +f 3579 3581 1436 +f 3580 3581 3579 +f 411 3582 3581 +f 3582 594 2938 +f 3581 2938 1436 +f 3582 2938 3581 +f 594 3582 2947 +f 3582 411 3583 +f 2947 3583 1411 +f 3582 3583 2947 +f 1121 3081 3437 +f 3081 672 3584 +f 3437 3584 1385 +f 3081 3584 3437 +f 1181 3585 3586 +f 3585 672 3361 +f 3586 3361 1411 +f 3585 3361 3586 +f 672 3585 3584 +f 3585 1181 3587 +f 3584 3587 1385 +f 3585 3587 3584 +f 220 3235 3589 +f 3235 1083 3588 +f 3589 3588 1454 +f 3235 3588 3589 +f 1183 3230 3591 +f 3230 776 3590 +f 3591 3590 1487 +f 3230 3590 3591 +f 776 3592 3590 +f 3592 468 3593 +f 3590 3593 1487 +f 3592 3593 3590 +f 502 3594 3595 +f 3594 220 3589 +f 3595 3589 1454 +f 3594 3589 3595 +f 28 3363 3596 +f 3363 220 3594 +f 3596 3594 502 +f 3363 3594 3596 +f 468 3592 3597 +f 3592 776 3089 +f 3597 3089 1145 +f 3592 3089 3597 +f 54 3598 3442 +f 3598 1145 3365 +f 3442 3365 1207 +f 3598 3365 3442 +f 530 3446 3600 +f 3446 210 3599 +f 3600 3599 628 +f 3446 3599 3600 +f 628 3601 3603 +f 3601 874 3602 +f 3603 3602 1408 +f 3601 3602 3603 +f 874 3138 3602 +f 3138 533 3604 +f 3602 3604 1408 +f 3138 3604 3602 +f 533 3452 3604 +f 3452 1025 3605 +f 3604 3605 1408 +f 3452 3605 3604 +f 980 3606 3607 +f 3606 929 3451 +f 3607 3451 1138 +f 3606 3451 3607 +f 719 3016 3454 +f 3016 929 3606 +f 3454 3606 980 +f 3016 3606 3454 +f 123 3608 3457 +f 3608 1025 3453 +f 3457 3453 1131 +f 3608 3453 3457 +f 534 3609 3466 +f 3609 1001 3375 +f 3466 3375 1320 +f 3609 3375 3466 +f 279 3610 3611 +f 3610 446 3377 +f 3611 3377 824 +f 3610 3377 3611 +f 824 3381 3613 +f 3381 848 3612 +f 3613 3612 1234 +f 3381 3612 3613 +f 184 3614 3470 +f 3614 362 3471 +f 3470 3471 1500 +f 3614 3471 3470 +f 848 3615 3612 +f 3615 482 3616 +f 3612 3616 1234 +f 3615 3616 3612 +f 179 3384 3618 +f 3384 362 3617 +f 3618 3617 882 +f 3384 3617 3618 +f 482 3615 3619 +f 3615 848 3388 +f 3619 3388 1004 +f 3615 3388 3619 +f 179 3618 3393 +f 3618 882 3620 +f 3393 3620 1237 +f 3618 3620 3393 +f 616 3621 3622 +f 3621 199 3473 +f 3622 3473 1237 +f 3621 3473 3622 +f 261 3623 3475 +f 3623 1004 3390 +f 3475 3390 1498 +f 3623 3390 3475 +f 631 3400 3480 +f 3400 647 3624 +f 3480 3624 714 +f 3400 3624 3480 +f 373 3477 3625 +f 3477 252 3481 +f 3625 3481 714 +f 3477 3481 3625 +f 90 3626 3627 +f 3626 77 3402 +f 3627 3402 537 +f 3626 3402 3627 +f 128 3628 3629 +f 3628 627 3176 +f 3629 3176 1329 +f 3628 3176 3629 +f 627 3628 3317 +f 3628 128 3630 +f 3317 3630 1088 +f 3628 3630 3317 +f 51 3483 3405 +f 3483 321 3631 +f 3405 3631 1370 +f 3483 3631 3405 +f 681 3632 3408 +f 3632 404 3633 +f 3408 3633 1413 +f 3632 3633 3408 +f 913 3634 3188 +f 3634 487 3635 +f 3188 3635 1329 +f 3634 3635 3188 +f 487 3636 3635 +f 3636 128 3629 +f 3635 3629 1329 +f 3636 3629 3635 +f 487 3634 3637 +f 3634 913 3494 +f 3637 3494 1008 +f 3634 3494 3637 +f 1006 3638 3412 +f 3638 6 3639 +f 3412 3639 1194 +f 3638 3639 3412 +f 195 3640 3641 +f 3640 379 3204 +f 3641 3204 651 +f 3640 3204 3641 +f 472 3642 3643 +f 3642 1095 3045 +f 3643 3045 1194 +f 3642 3045 3643 +f 1095 3644 3333 +f 3644 977 3645 +f 3333 3645 1108 +f 3644 3645 3333 +f 1128 3646 3648 +f 3646 843 3647 +f 3648 3647 1494 +f 3646 3647 3648 +f 350 3649 3651 +f 3649 970 3650 +f 3651 3650 1402 +f 3649 3650 3651 +f 596 3652 3654 +f 3652 498 3653 +f 3654 3653 1444 +f 3652 3653 3654 +f 364 3655 3656 +f 3655 498 3519 +f 3656 3519 908 +f 3655 3519 3656 +f 833 3526 3658 +f 3526 727 3657 +f 3658 3657 970 +f 3526 3657 3658 +f 498 3655 3653 +f 3655 364 3659 +f 3653 3659 1444 +f 3655 3659 3653 +f 864 3660 3661 +f 3660 843 3524 +f 3661 3524 1135 +f 3660 3524 3661 +f 740 3662 3664 +f 3662 289 3663 +f 3664 3663 1352 +f 3662 3663 3664 +f 635 3665 3532 +f 3665 1186 3666 +f 3532 3666 1282 +f 3665 3666 3532 +f 635 3667 3665 +f 3667 826 3668 +f 3665 3668 1186 +f 3667 3668 3665 +f 826 3669 3668 +f 3669 674 3537 +f 3668 3537 1186 +f 3669 3537 3668 +f 815 3542 3671 +f 3542 566 3670 +f 3671 3670 1451 +f 3542 3670 3671 +f 996 3672 3548 +f 3672 412 3673 +f 3548 3673 1186 +f 3672 3673 3548 +f 462 3540 3551 +f 3540 674 3674 +f 3551 3674 1011 +f 3540 3674 3551 +f 682 3675 3677 +f 3675 868 3676 +f 3677 3676 1153 +f 3675 3676 3677 +f 978 3678 3679 +f 3678 757 3425 +f 3679 3425 1429 +f 3678 3425 3679 +f 1429 3680 3682 +f 3680 861 3681 +f 3682 3681 1479 +f 3680 3681 3682 +f 292 3683 3684 +f 3683 861 3680 +f 3684 3680 1429 +f 3683 3680 3684 +f 837 3566 3223 +f 3566 292 3684 +f 3223 3684 1429 +f 3566 3684 3223 +f 281 3685 3346 +f 3685 553 3686 +f 3346 3686 1484 +f 3685 3686 3346 +f 452 3687 3688 +f 3687 624 3351 +f 3688 3351 1246 +f 3687 3351 3688 +f 281 3426 3690 +f 3426 547 3689 +f 3690 3689 1366 +f 3426 3689 3690 +f 452 3688 3691 +f 3688 1246 3572 +f 3691 3572 1311 +f 3688 3572 3691 +f 768 3692 3694 +f 3692 1116 3693 +f 3694 3693 1437 +f 3692 3693 3694 +f 20 3578 3696 +f 3578 1065 3695 +f 3696 3695 1396 +f 3578 3695 3696 +f 1116 3697 3699 +f 3697 12 3698 +f 3699 3698 1191 +f 3697 3698 3699 +f 768 3435 3692 +f 3435 12 3697 +f 3692 3697 1116 +f 3435 3697 3692 +f 198 2945 3700 +f 2945 131 3576 +f 3700 3576 613 +f 2945 3576 3700 +f 411 3580 3701 +f 3580 20 3696 +f 3701 3696 1396 +f 3580 3696 3701 +f 884 3702 3703 +f 3702 411 3701 +f 3703 3701 1396 +f 3702 3701 3703 +f 12 3436 3698 +f 3436 899 3704 +f 3698 3704 1191 +f 3436 3704 3698 +f 411 3702 3706 +f 3702 884 3705 +f 3706 3705 1181 +f 3702 3705 3706 +f 411 3706 3583 +f 3706 1181 3586 +f 3583 3586 1411 +f 3706 3586 3583 +f 174 3707 3708 +f 3707 899 3237 +f 3708 3237 1269 +f 3707 3237 3708 +f 203 3709 3710 +f 3709 174 3708 +f 3710 3708 1269 +f 3709 3708 3710 +f 288 3711 3362 +f 3711 203 3710 +f 3362 3710 1269 +f 3711 3710 3362 +f 28 3596 3364 +f 3596 502 3712 +f 3364 3712 1036 +f 3596 3712 3364 +f 54 3713 3598 +f 3713 336 3714 +f 3598 3714 1145 +f 3713 3714 3598 +f 530 3715 3444 +f 3715 54 3441 +f 3444 3441 569 +f 3715 3441 3444 +f 103 3716 3443 +f 3716 600 3447 +f 3443 3447 799 +f 3716 3447 3443 +f 376 3370 3717 +f 3370 369 3449 +f 3717 3449 600 +f 3370 3449 3717 +f 376 3717 3450 +f 3717 600 3718 +f 3450 3718 1138 +f 3717 3718 3450 +f 628 3599 3601 +f 3599 210 3369 +f 3601 3369 874 +f 3599 3369 3601 +f 534 3719 3609 +f 3719 428 3720 +f 3609 3720 1001 +f 3719 3720 3609 +f 446 3610 3465 +f 3610 279 3721 +f 3465 3721 534 +f 3610 3721 3465 +f 349 3722 3468 +f 3722 184 3469 +f 3468 3469 1231 +f 3722 3469 3468 +f 279 3611 3723 +f 3611 824 3613 +f 3723 3613 1234 +f 3611 3613 3723 +f 362 3724 3617 +f 3724 810 3725 +f 3617 3725 882 +f 3724 3725 3617 +f 670 3726 3727 +f 3726 482 3619 +f 3727 3619 1004 +f 3726 3619 3727 +f 261 3728 3623 +f 3728 670 3727 +f 3623 3727 1004 +f 3728 3727 3623 +f 209 3729 3730 +f 3729 261 3474 +f 3730 3474 605 +f 3729 3474 3730 +f 605 3478 3732 +f 3478 373 3731 +f 3732 3731 643 +f 3478 3731 3732 +f 209 3730 3733 +f 3730 605 3732 +f 3733 3732 643 +f 3730 3732 3733 +f 647 3734 3624 +f 3734 449 3735 +f 3624 3735 714 +f 3734 3735 3624 +f 889 3736 3737 +f 3736 537 3318 +f 3737 3318 1088 +f 3736 3318 3737 +f 77 3738 3403 +f 3738 581 3739 +f 3403 3739 1091 +f 3738 3739 3403 +f 556 3740 3742 +f 3740 404 3741 +f 3742 3741 680 +f 3740 3741 3742 +f 404 3740 3633 +f 3740 556 3486 +f 3633 3486 1413 +f 3740 3486 3633 +f 581 3743 3739 +f 3743 321 3484 +f 3739 3484 1091 +f 3743 3484 3739 +f 379 3744 3202 +f 3744 972 3745 +f 3202 3745 1096 +f 3744 3745 3202 +f 73 3499 3328 +f 3499 857 3746 +f 3328 3746 1256 +f 3499 3746 3328 +f 363 3747 3048 +f 3747 489 3748 +f 3048 3748 651 +f 3747 3748 3048 +f 489 3749 3748 +f 3749 195 3641 +f 3748 3641 651 +f 3749 3641 3748 +f 472 3750 3642 +f 3750 977 3644 +f 3642 3644 1095 +f 3750 3644 3642 +f 489 3747 3751 +f 3747 363 3504 +f 3751 3504 941 +f 3747 3504 3751 +f 9 3507 3502 +f 3507 598 3752 +f 3502 3752 941 +f 3507 3752 3502 +f 808 3753 3754 +f 3753 350 3506 +f 3754 3506 1108 +f 3753 3506 3754 +f 364 3755 3659 +f 3755 685 3756 +f 3659 3756 1444 +f 3755 3756 3659 +f 826 3757 3759 +f 3757 63 3758 +f 3759 3758 833 +f 3757 3758 3759 +f 588 3760 3761 +f 3760 674 3669 +f 3761 3669 826 +f 3760 3669 3761 +f 412 3762 3764 +f 3762 662 3763 +f 3764 3763 1282 +f 3762 3763 3764 +f 648 3765 3767 +f 3765 396 3766 +f 3767 3766 1312 +f 3765 3766 3767 +f 396 3768 3766 +f 3768 984 3769 +f 3766 3769 1312 +f 3768 3769 3766 +f 674 3760 3771 +f 3760 588 3770 +f 3771 3770 1395 +f 3760 3770 3771 +f 366 3552 3773 +f 3552 1011 3772 +f 3773 3772 1354 +f 3552 3772 3773 +f 703 3774 3555 +f 3774 815 3775 +f 3555 3775 1472 +f 3774 3775 3555 +f 564 3776 3339 +f 3776 673 3777 +f 3339 3777 1380 +f 3776 3777 3339 +f 673 3778 3777 +f 3778 497 3779 +f 3777 3779 1380 +f 3778 3779 3777 +f 497 3780 3779 +f 3780 465 3558 +f 3779 3558 1380 +f 3780 3558 3779 +f 1157 3781 3342 +f 3781 310 3782 +f 3342 3782 1469 +f 3781 3782 3342 +f 825 3783 3563 +f 3783 314 3784 +f 3563 3784 1281 +f 3783 3784 3563 +f 553 3685 3785 +f 3685 281 3690 +f 3785 3690 1366 +f 3685 3690 3785 +f 1311 3571 3786 +f 3571 768 3694 +f 3786 3694 1437 +f 3571 3694 3786 +f 1065 3430 3788 +f 3430 545 3787 +f 3788 3787 1365 +f 3430 3787 3788 +f 146 3577 3789 +f 3577 1078 3428 +f 3789 3428 1353 +f 3577 3428 3789 +f 975 3790 3791 +f 3790 1065 3788 +f 3791 3788 1365 +f 3790 3788 3791 +f 1083 3432 3793 +f 3432 193 3792 +f 3793 3792 1441 +f 3432 3792 3793 +f 460 3794 3795 +f 3794 330 3356 +f 3795 3356 1183 +f 3794 3356 3795 +f 1065 3790 3695 +f 3790 975 3796 +f 3695 3796 1396 +f 3790 3796 3695 +f 460 3795 3797 +f 3795 1183 3591 +f 3797 3591 1487 +f 3795 3591 3797 +f 1083 3793 3588 +f 3793 1441 3798 +f 3588 3798 1454 +f 3793 3798 3588 +f 100 3799 3800 +f 3799 884 3703 +f 3800 3703 1396 +f 3799 3703 3800 +f 899 3801 3704 +f 3801 448 3802 +f 3704 3802 1191 +f 3801 3802 3704 +f 884 3803 3705 +f 3803 948 3804 +f 3705 3804 1181 +f 3803 3804 3705 +f 174 3805 3707 +f 3805 448 3801 +f 3707 3801 899 +f 3805 3801 3707 +f 855 3806 3807 +f 3806 502 3595 +f 3807 3595 1454 +f 3806 3595 3807 +f 1036 3712 3809 +f 3712 502 3808 +f 3809 3808 1290 +f 3712 3808 3809 +f 336 3810 3714 +f 3810 468 3597 +f 3714 3597 1145 +f 3810 3597 3714 +f 103 3440 3811 +f 3440 1036 3809 +f 3811 3809 1290 +f 3440 3809 3811 +f 600 3716 3812 +f 3716 103 3811 +f 3812 3811 1290 +f 3716 3811 3812 +f 123 3459 3608 +f 3459 1001 3813 +f 3608 3813 1025 +f 3459 3813 3608 +f 814 3460 3814 +f 3460 434 3455 +f 3814 3455 980 +f 3460 3455 3814 +f 814 3815 3464 +f 3815 701 3816 +f 3464 3816 1188 +f 3815 3816 3464 +f 701 3817 3816 +f 3817 349 3467 +f 3816 3467 1188 +f 3817 3467 3816 +f 293 3818 3819 +f 3818 184 3722 +f 3819 3722 349 +f 3818 3722 3819 +f 362 3614 3724 +f 3614 184 3820 +f 3724 3820 810 +f 3614 3820 3724 +f 482 3726 3822 +f 3726 670 3821 +f 3822 3821 1213 +f 3726 3821 3822 +f 608 3823 3825 +f 3823 616 3824 +f 3825 3824 882 +f 3823 3824 3825 +f 882 3824 3620 +f 3824 616 3622 +f 3620 3622 1237 +f 3824 3622 3620 +f 199 3621 3827 +f 3621 616 3826 +f 3827 3826 1033 +f 3621 3826 3827 +f 199 3828 3476 +f 3828 449 3734 +f 3476 3734 647 +f 3828 3734 3476 +f 643 3829 3831 +f 3829 869 3830 +f 3831 3830 1160 +f 3829 3830 3831 +f 643 3731 3829 +f 3731 373 3832 +f 3829 3832 869 +f 3731 3832 3829 +f 38 3833 3834 +f 3833 373 3625 +f 3834 3625 714 +f 3833 3625 3834 +f 373 3833 3832 +f 3833 38 3835 +f 3832 3835 869 +f 3833 3835 3832 +f 38 3834 3837 +f 3834 714 3836 +f 3837 3836 945 +f 3834 3836 3837 +f 177 3838 3840 +f 3838 383 3839 +f 3840 3839 1286 +f 3838 3839 3840 +f 487 3637 3842 +f 3637 1008 3841 +f 3842 3841 1190 +f 3637 3841 3842 +f 1008 3843 3841 +f 3843 694 3844 +f 3841 3844 1190 +f 3843 3844 3841 +f 597 3500 3410 +f 3500 694 3843 +f 3410 3843 1008 +f 3500 3843 3410 +f 379 3640 3744 +f 3640 195 3845 +f 3744 3845 972 +f 3640 3845 3744 +f 1256 3746 3847 +f 3746 857 3846 +f 3847 3846 1491 +f 3746 3846 3847 +f 410 3848 3849 +f 3848 694 3501 +f 3849 3501 1128 +f 3848 3501 3849 +f 598 3850 3752 +f 3850 685 3851 +f 3752 3851 941 +f 3850 3851 3752 +f 1376 3852 3853 +f 3852 978 3679 +f 3853 3679 1429 +f 3852 3679 3853 +f 465 3854 3557 +f 3854 352 3855 +f 3557 3855 1204 +f 3854 3855 3557 +f 360 3856 3857 +f 3856 156 3561 +f 3857 3561 1484 +f 3856 3561 3857 +f 156 3858 3560 +f 3858 310 3781 +f 3560 3781 1157 +f 3858 3781 3560 +f 1052 3859 3860 +f 3859 825 3562 +f 3860 3562 1195 +f 3859 3562 3860 +f 624 3861 3345 +f 3861 422 3862 +f 3345 3862 1195 +f 3861 3862 3345 +f 292 3564 3683 +f 3564 330 3863 +f 3683 3863 861 +f 3564 3863 3683 +f 838 3350 3427 +f 3350 1281 3864 +f 3427 3864 1353 +f 3350 3864 3427 +f 545 3568 3787 +f 3568 1245 3865 +f 3787 3865 1365 +f 3568 3865 3787 +f 547 3573 3866 +f 3573 168 3080 +f 3866 3080 1244 +f 3573 3080 3866 +f 380 3867 2942 +f 3867 1085 3868 +f 2942 3868 1244 +f 3867 3868 2942 +f 975 3869 3796 +f 3869 1087 3870 +f 3796 3870 1396 +f 3869 3870 3796 +f 1389 3871 3873 +f 3871 1116 3872 +f 3873 3872 1405 +f 3871 3872 3873 +f 1116 3871 3693 +f 3871 1389 3874 +f 3693 3874 1437 +f 3871 3874 3693 +f 1087 3875 3870 +f 3875 100 3800 +f 3870 3800 1396 +f 3875 3800 3870 +f 1116 3699 3872 +f 3699 1191 3876 +f 3872 3876 1405 +f 3699 3876 3872 +f 198 3877 2949 +f 3877 731 3878 +f 2949 3878 992 +f 3877 3878 2949 +f 528 3879 3880 +f 3879 288 3088 +f 3880 3088 992 +f 3879 3088 3880 +f 731 3881 3878 +f 3881 528 3880 +f 3878 3880 992 +f 3881 3880 3878 +f 884 3882 3803 +f 3882 272 3883 +f 3803 3883 948 +f 3882 3883 3803 +f 448 3805 3885 +f 3805 174 3884 +f 3885 3884 463 +f 3805 3884 3885 +f 174 3709 3884 +f 3709 203 3886 +f 3884 3886 463 +f 3709 3886 3884 +f 203 3711 3887 +f 3711 288 3879 +f 3887 3879 528 +f 3711 3879 3887 +f 468 3888 3593 +f 3888 382 3889 +f 3593 3889 1487 +f 3888 3889 3593 +f 502 3806 3808 +f 3806 855 3890 +f 3808 3890 1290 +f 3806 3890 3808 +f 336 3713 3892 +f 3713 54 3891 +f 3892 3891 1331 +f 3713 3891 3892 +f 54 3715 3893 +f 3715 530 3600 +f 3893 3600 628 +f 3715 3600 3893 +f 54 3893 3891 +f 3893 628 3894 +f 3891 3894 1331 +f 3893 3894 3891 +f 1001 3720 3813 +f 3720 428 3895 +f 3813 3895 1025 +f 3720 3895 3813 +f 814 3814 3896 +f 3814 980 3607 +f 3896 3607 1138 +f 3814 3607 3896 +f 279 3897 3721 +f 3897 428 3719 +f 3721 3719 534 +f 3897 3719 3721 +f 293 3819 3898 +f 3819 349 3817 +f 3898 3817 701 +f 3819 3817 3898 +f 184 3818 3820 +f 3818 293 3899 +f 3820 3899 810 +f 3818 3899 3820 +f 261 3729 3728 +f 3729 209 3900 +f 3728 3900 670 +f 3729 3900 3728 +f 449 3828 3901 +f 3828 199 3827 +f 3901 3827 1033 +f 3828 3827 3901 +f 449 3901 3903 +f 3901 1033 3902 +f 3903 3902 1293 +f 3901 3902 3903 +f 714 3735 3836 +f 3735 449 3904 +f 3836 3904 945 +f 3735 3904 3836 +f 945 3904 3905 +f 3904 449 3903 +f 3905 3903 1293 +f 3904 3903 3905 +f 869 3835 3906 +f 3835 38 3837 +f 3906 3837 945 +f 3835 3837 3906 +f 197 3907 3908 +f 3907 889 3737 +f 3908 3737 1088 +f 3907 3737 3908 +f 383 3488 3839 +f 3488 895 3909 +f 3839 3909 1286 +f 3488 3909 3839 +f 128 3910 3630 +f 3910 197 3908 +f 3630 3908 1088 +f 3910 3908 3630 +f 77 3626 3912 +f 3626 90 3911 +f 3912 3911 721 +f 3626 3911 3912 +f 581 3738 3913 +f 3738 77 3912 +f 3913 3912 721 +f 3738 3912 3913 +f 321 3914 3631 +f 3914 342 3915 +f 3631 3915 1370 +f 3914 3915 3631 +f 197 3910 3916 +f 3910 128 3636 +f 3916 3636 487 +f 3910 3636 3916 +f 82 3917 3918 +f 3917 1006 3490 +f 3918 3490 1370 +f 3917 3490 3918 +f 1096 3919 3496 +f 3919 807 3920 +f 3496 3920 1321 +f 3919 3920 3496 +f 82 3921 3917 +f 3921 798 3922 +f 3917 3922 1006 +f 3921 3922 3917 +f 798 3923 3922 +f 3923 6 3638 +f 3922 3638 1006 +f 3923 3638 3922 +f 972 3924 3745 +f 3924 807 3919 +f 3745 3919 1096 +f 3924 3919 3745 +f 538 3925 3926 +f 3925 857 3498 +f 3926 3498 1167 +f 3925 3498 3926 +f 6 3923 3639 +f 3923 798 3927 +f 3639 3927 1194 +f 3923 3927 3639 +f 1194 3927 3929 +f 3927 798 3928 +f 3929 3928 1233 +f 3927 3928 3929 +f 685 3930 3851 +f 3930 357 3931 +f 3851 3931 941 +f 3930 3931 3851 +f 933 3932 3934 +f 3932 506 3933 +f 3934 3933 1159 +f 3932 3933 3934 +f 685 3935 3937 +f 3935 648 3936 +f 3937 3936 1073 +f 3935 3936 3937 +f 662 3938 3940 +f 3938 577 3939 +f 3940 3939 864 +f 3938 3939 3940 +f 933 3934 3942 +f 3934 1159 3941 +f 3942 3941 1352 +f 3934 3941 3942 +f 588 3943 3770 +f 3943 845 3944 +f 3770 3944 1395 +f 3943 3944 3770 +f 1354 3772 3946 +f 3772 1011 3945 +f 3946 3945 1395 +f 3772 3945 3946 +f 1150 3947 3949 +f 3947 564 3948 +f 3949 3948 1159 +f 3947 3948 3949 +f 673 3776 3950 +f 3776 564 3947 +f 3950 3947 1150 +f 3776 3947 3950 +f 352 3951 3953 +f 3951 497 3952 +f 3953 3952 887 +f 3951 3952 3953 +f 352 3854 3951 +f 3854 465 3780 +f 3951 3780 497 +f 3854 3780 3951 +f 553 3954 3686 +f 3954 360 3857 +f 3686 3857 1484 +f 3954 3857 3686 +f 422 3955 3862 +f 3955 1052 3860 +f 3862 3860 1195 +f 3955 3860 3862 +f 310 3956 3782 +f 3956 1381 3957 +f 3782 3957 1469 +f 3956 3957 3782 +f 553 3785 3959 +f 3785 1366 3958 +f 3959 3958 1480 +f 3785 3958 3959 +f 452 3960 3687 +f 3960 422 3861 +f 3687 3861 624 +f 3960 3861 3687 +f 1281 3784 3962 +f 3784 314 3961 +f 3962 3961 1481 +f 3784 3961 3962 +f 330 3963 3863 +f 3963 62 3964 +f 3863 3964 861 +f 3963 3964 3863 +f 1353 3864 3965 +f 3864 1281 3962 +f 3965 3962 1481 +f 3864 3962 3965 +f 1204 3855 3967 +f 3855 352 3966 +f 3967 3966 1441 +f 3855 3966 3967 +f 193 3567 3792 +f 3567 1204 3967 +f 3792 3967 1441 +f 3567 3967 3792 +f 1368 3968 3969 +f 3968 1311 3786 +f 3969 3786 1437 +f 3968 3786 3969 +f 24 3970 3971 +f 3970 975 3791 +f 3971 3791 1365 +f 3970 3791 3971 +f 1203 3972 3973 +f 3972 460 3797 +f 3973 3797 1487 +f 3972 3797 3973 +f 1441 3974 3798 +f 3974 153 3975 +f 3798 3975 1454 +f 3974 3975 3798 +f 1389 3976 3874 +f 3976 1368 3969 +f 3874 3969 1437 +f 3976 3969 3874 +f 380 3438 3978 +f 3438 1385 3977 +f 3978 3977 1391 +f 3438 3977 3978 +f 153 3979 3975 +f 3979 855 3807 +f 3975 3807 1454 +f 3979 3807 3975 +f 1181 3980 3587 +f 3980 816 3981 +f 3587 3981 1385 +f 3980 3981 3587 +f 948 3982 3804 +f 3982 816 3980 +f 3804 3980 1181 +f 3982 3980 3804 +f 463 3886 3984 +f 3886 203 3983 +f 3984 3983 664 +f 3886 3983 3984 +f 203 3887 3983 +f 3887 528 3985 +f 3983 3985 664 +f 3887 3985 3983 +f 100 3986 3799 +f 3986 272 3882 +f 3799 3882 884 +f 3986 3882 3799 +f 998 3987 3988 +f 3987 100 3875 +f 3988 3875 1087 +f 3987 3875 3988 +f 382 3989 3889 +f 3989 1203 3973 +f 3889 3973 1487 +f 3989 3973 3889 +f 1191 3990 3876 +f 3990 479 3991 +f 3876 3991 1405 +f 3990 3991 3876 +f 448 3992 3802 +f 3992 479 3990 +f 3802 3990 1191 +f 3992 3990 3802 +f 936 3993 3995 +f 3993 1126 3994 +f 3995 3994 1206 +f 3993 3994 3995 +f 382 3996 3997 +f 3996 936 3995 +f 3997 3995 1206 +f 3996 3995 3997 +f 855 3998 4000 +f 3998 772 3999 +f 4000 3999 1501 +f 3998 3999 4000 +f 382 4001 3996 +f 4001 336 4002 +f 3996 4002 936 +f 4001 4002 3996 +f 336 4001 3810 +f 4001 382 3888 +f 3810 3888 468 +f 4001 3888 3810 +f 1290 3890 4003 +f 3890 855 4000 +f 4003 4000 1501 +f 3890 4000 4003 +f 939 4004 4006 +f 4004 484 4005 +f 4006 4005 1290 +f 4004 4005 4006 +f 30 4007 4009 +f 4007 701 4008 +f 4009 4008 1138 +f 4007 4008 4009 +f 1025 3895 3605 +f 3895 428 4010 +f 3605 4010 1408 +f 3895 4010 3605 +f 701 3815 4008 +f 3815 814 3896 +f 4008 3896 1138 +f 3815 3896 4008 +f 279 4011 3897 +f 4011 107 4012 +f 3897 4012 428 +f 4011 4012 3897 +f 107 4011 4013 +f 4011 279 3723 +f 4013 3723 1234 +f 4011 3723 4013 +f 461 4014 4016 +f 4014 608 4015 +f 4016 4015 810 +f 4014 4015 4016 +f 726 4017 4018 +f 4017 482 3822 +f 4018 3822 1213 +f 4017 3822 4018 +f 482 4017 3616 +f 4017 726 4019 +f 3616 4019 1234 +f 4017 4019 3616 +f 810 4015 3725 +f 4015 608 3825 +f 3725 3825 882 +f 4015 3825 3725 +f 1213 3821 4021 +f 3821 670 4020 +f 4021 4020 1340 +f 3821 4020 4021 +f 670 3900 4020 +f 3900 209 4022 +f 4020 4022 1340 +f 3900 4022 4020 +f 209 4023 4022 +f 4023 246 4024 +f 4022 4024 1340 +f 4023 4024 4022 +f 246 4023 4025 +f 4023 209 3733 +f 4025 3733 643 +f 4023 3733 4025 +f 246 4025 4026 +f 4025 643 3831 +f 4026 3831 1160 +f 4025 3831 4026 +f 869 3906 4028 +f 3906 945 4027 +f 4028 4027 1064 +f 3906 4027 4028 +f 90 3627 4029 +f 3627 537 3736 +f 4029 3736 889 +f 3627 3736 4029 +f 197 3916 4031 +f 3916 487 4030 +f 4031 4030 920 +f 3916 4030 4031 +f 265 4032 4033 +f 4032 581 3913 +f 4033 3913 721 +f 4032 3913 4033 +f 265 4034 4032 +f 4034 321 3743 +f 4032 3743 581 +f 4034 3743 4032 +f 404 3632 4036 +f 3632 681 4035 +f 4036 4035 1333 +f 3632 4035 4036 +f 983 4037 4038 +f 4037 404 4036 +f 4038 4036 1333 +f 4037 4036 4038 +f 177 4039 4041 +f 4039 704 4040 +f 4041 4040 1167 +f 4039 4040 4041 +f 383 3838 3491 +f 3838 177 4041 +f 3491 4041 1167 +f 3838 4041 3491 +f 920 4030 4042 +f 4030 487 3842 +f 4042 3842 1190 +f 4030 3842 4042 +f 704 4043 4040 +f 4043 538 3926 +f 4040 3926 1167 +f 4043 3926 4040 +f 857 3925 4045 +f 3925 538 4044 +f 4045 4044 1414 +f 3925 4044 4045 +f 694 4046 3844 +f 4046 53 4047 +f 3844 4047 1190 +f 4046 4047 3844 +f 857 4045 3846 +f 4045 1414 4048 +f 3846 4048 1491 +f 4045 4048 3846 +f 472 3643 4049 +f 3643 1194 3929 +f 4049 3929 1233 +f 3643 3929 4049 +f 195 3749 4051 +f 3749 489 4050 +f 4051 4050 559 +f 3749 4050 4051 +f 1313 4052 4054 +f 4052 410 4053 +f 4054 4053 1494 +f 4052 4053 4054 +f 1100 4055 4057 +f 4055 1073 4056 +f 4057 4056 1312 +f 4055 4056 4057 +f 577 4058 3939 +f 4058 407 4059 +f 3939 4059 864 +f 4058 4059 3939 +f 845 4060 3944 +f 4060 1354 3946 +f 3944 3946 1395 +f 4060 3946 3944 +f 1376 3853 4061 +f 3853 1429 3682 +f 4061 3682 1479 +f 3853 3682 4061 +f 861 4062 3681 +f 4062 49 4063 +f 3681 4063 1479 +f 4062 4063 3681 +f 310 3858 4065 +f 3858 156 4064 +f 4065 4064 1456 +f 3858 4064 4065 +f 314 3783 4067 +f 3783 825 4066 +f 4067 4066 971 +f 3783 4066 4067 +f 62 3963 4068 +f 3963 330 3794 +f 4068 3794 460 +f 3963 3794 4068 +f 1092 4069 4070 +f 4069 460 3972 +f 4070 3972 1203 +f 4069 3972 4070 +f 755 4071 4072 +f 4071 153 3974 +f 4072 3974 1441 +f 4071 3974 4072 +f 988 4073 4074 +f 4073 24 3971 +f 4074 3971 1365 +f 4073 3971 4074 +f 198 3700 3877 +f 3700 613 4075 +f 3877 4075 731 +f 3700 4075 3877 +f 975 3970 4076 +f 3970 24 4073 +f 4076 4073 988 +f 3970 4073 4076 +f 975 4076 3869 +f 4076 988 4077 +f 3869 4077 1087 +f 4076 4077 3869 +f 1087 4077 4079 +f 4077 988 4078 +f 4079 4078 1206 +f 4077 4078 4079 +f 988 4080 4078 +f 4080 541 4081 +f 4078 4081 1206 +f 4080 4081 4078 +f 541 4082 4081 +f 4082 1203 4083 +f 4081 4083 1206 +f 4082 4083 4081 +f 855 3979 4085 +f 3979 153 4084 +f 4085 4084 1023 +f 3979 4084 4085 +f 772 4086 4088 +f 4086 1023 4087 +f 4088 4087 1389 +f 4086 4087 4088 +f 1203 3989 4083 +f 3989 382 3997 +f 4083 3997 1206 +f 3989 3997 4083 +f 40 4089 4090 +f 4089 772 4088 +f 4090 4088 1389 +f 4089 4088 4090 +f 40 4090 4091 +f 4090 1389 3873 +f 4091 3873 1405 +f 4090 3873 4091 +f 1126 4092 3994 +f 4092 1087 4079 +f 3994 4079 1206 +f 4092 4079 3994 +f 772 3998 4086 +f 3998 855 4085 +f 4086 4085 1023 +f 3998 4085 4086 +f 272 3986 4093 +f 3986 100 3987 +f 4093 3987 998 +f 3986 3987 4093 +f 772 4094 3999 +f 4094 1405 4095 +f 3999 4095 1501 +f 4094 4095 3999 +f 772 4089 4094 +f 4089 40 4091 +f 4094 4091 1405 +f 4089 4091 4094 +f 998 3988 4096 +f 3988 1087 4092 +f 4096 4092 1126 +f 3988 4092 4096 +f 936 4097 3993 +f 4097 132 4098 +f 3993 4098 1126 +f 4097 4098 3993 +f 132 4097 4100 +f 4097 936 4099 +f 4100 4099 937 +f 4097 4099 4100 +f 936 4002 4099 +f 4002 336 4101 +f 4099 4101 937 +f 4002 4101 4099 +f 937 4101 4102 +f 4101 336 3892 +f 4102 3892 1331 +f 4101 3892 4102 +f 484 4103 4005 +f 4103 600 3812 +f 4005 3812 1290 +f 4103 3812 4005 +f 1331 3894 4104 +f 3894 628 3603 +f 4104 3603 1408 +f 3894 3603 4104 +f 484 4105 4103 +f 4105 30 4106 +f 4103 4106 600 +f 4105 4106 4103 +f 600 4106 3718 +f 4106 30 4009 +f 3718 4009 1138 +f 4106 4009 3718 +f 1408 4010 4108 +f 4010 428 4107 +f 4108 4107 1466 +f 4010 4107 4108 +f 461 4109 4110 +f 4109 293 3898 +f 4110 3898 701 +f 4109 3898 4110 +f 293 4109 3899 +f 4109 461 4016 +f 3899 4016 810 +f 4109 4016 3899 +f 726 4111 4019 +f 4111 107 4013 +f 4019 4013 1234 +f 4111 4013 4019 +f 1033 4112 3902 +f 4112 790 4113 +f 3902 4113 1293 +f 4112 4113 3902 +f 869 4114 3830 +f 4114 251 4115 +f 3830 4115 1160 +f 4114 4115 3830 +f 185 4116 4117 +f 4116 556 3742 +f 4117 3742 680 +f 4116 3742 4117 +f 571 4118 4119 +f 4118 177 3840 +f 4119 3840 1286 +f 4118 3840 4119 +f 680 3741 4120 +f 3741 404 4037 +f 4120 4037 983 +f 3741 4037 4120 +f 729 4121 4122 +f 4121 920 4042 +f 4122 4042 1190 +f 4121 4042 4122 +f 1414 4123 4048 +f 4123 642 4124 +f 4048 4124 1491 +f 4123 4124 4048 +f 472 4125 3750 +f 4125 586 4126 +f 3750 4126 977 +f 4125 4126 3750 +f 642 4127 4124 +f 4127 506 4128 +f 4124 4128 1491 +f 4127 4128 4124 +f 709 4129 4131 +f 4129 407 4130 +f 4131 4130 1372 +f 4129 4130 4131 +f 156 3856 4064 +f 3856 360 4132 +f 4064 4132 1456 +f 3856 4132 4064 +f 971 4066 4133 +f 4066 825 3859 +f 4133 3859 1052 +f 4066 3859 4133 +f 159 4134 4135 +f 4134 553 3959 +f 4135 3959 1480 +f 4134 3959 4135 +f 1381 4136 3957 +f 4136 1245 3570 +f 3957 3570 1469 +f 4136 3570 3957 +f 547 4137 3689 +f 4137 510 4138 +f 3689 4138 1366 +f 4137 4138 3689 +f 510 4137 4139 +f 4137 547 3866 +f 4139 3866 1244 +f 4137 3866 4139 +f 62 4068 4140 +f 4068 460 4069 +f 4140 4069 1092 +f 4068 4069 4140 +f 1003 4141 4142 +f 4141 62 4140 +f 4142 4140 1092 +f 4141 4140 4142 +f 1245 4143 3865 +f 4143 960 4144 +f 3865 4144 1365 +f 4143 4144 3865 +f 153 4071 4084 +f 4071 755 4145 +f 4084 4145 1023 +f 4071 4145 4084 +f 755 4146 4145 +f 4146 774 4147 +f 4145 4147 1023 +f 4146 4147 4145 +f 774 4148 4149 +f 4148 1368 3976 +f 4149 3976 1389 +f 4148 3976 4149 +f 960 4150 4144 +f 4150 988 4074 +f 4144 4074 1365 +f 4150 4074 4144 +f 960 4151 4150 +f 4151 541 4080 +f 4150 4080 988 +f 4151 4080 4150 +f 541 4152 4082 +f 4152 152 4153 +f 4082 4153 1203 +f 4152 4153 4082 +f 152 4154 4153 +f 4154 1092 4070 +f 4153 4070 1203 +f 4154 4070 4153 +f 1023 4147 4087 +f 4147 774 4149 +f 4087 4149 1389 +f 4147 4149 4087 +f 1385 3981 3977 +f 3981 816 4155 +f 3977 4155 1391 +f 3981 4155 3977 +f 528 4156 3985 +f 4156 478 4157 +f 3985 4157 664 +f 4156 4157 3985 +f 478 4156 4158 +f 4156 528 3881 +f 4158 3881 731 +f 4156 3881 4158 +f 463 3984 4160 +f 3984 664 4159 +f 4160 4159 821 +f 3984 4159 4160 +f 448 3885 3992 +f 3885 463 4161 +f 3992 4161 479 +f 3885 4161 3992 +f 132 4162 4098 +f 4162 998 4096 +f 4098 4096 1126 +f 4162 4096 4098 +f 1405 3991 4095 +f 3991 479 4163 +f 4095 4163 1501 +f 3991 4163 4095 +f 939 4006 4164 +f 4006 1290 4003 +f 4164 4003 1501 +f 4006 4003 4164 +f 1301 4165 4166 +f 4165 939 4164 +f 4166 4164 1501 +f 4165 4164 4166 +f 1117 4167 4168 +f 4167 937 4102 +f 4168 4102 1331 +f 4167 4102 4168 +f 1331 4104 4169 +f 4104 1408 4108 +f 4169 4108 1466 +f 4104 4108 4169 +f 701 4007 4171 +f 4007 30 4170 +f 4171 4170 1338 +f 4007 4170 4171 +f 428 4012 4107 +f 4012 107 4172 +f 4107 4172 1466 +f 4012 4172 4107 +f 616 3823 3826 +f 3823 608 4173 +f 3826 4173 1033 +f 3823 4173 3826 +f 860 4174 4175 +f 4174 246 4026 +f 4175 4026 1160 +f 4174 4026 4175 +f 1061 4176 4177 +f 4176 945 3905 +f 4177 3905 1293 +f 4176 3905 4177 +f 1061 4178 4180 +f 4178 420 4179 +f 4180 4179 1064 +f 4178 4179 4180 +f 945 4176 4027 +f 4176 1061 4180 +f 4027 4180 1064 +f 4176 4180 4027 +f 895 3485 3909 +f 3485 556 4181 +f 3909 4181 1286 +f 3485 4181 3909 +f 556 4116 4181 +f 4116 185 4182 +f 4181 4182 1286 +f 4116 4182 4181 +f 276 4183 4185 +f 4183 587 4184 +f 4185 4184 721 +f 4183 4184 4185 +f 587 4186 4184 +f 4186 265 4033 +f 4184 4033 721 +f 4186 4033 4184 +f 321 4034 3914 +f 4034 265 4187 +f 3914 4187 342 +f 4034 4187 3914 +f 53 4046 4189 +f 4046 694 4188 +f 4189 4188 1313 +f 4046 4188 4189 +f 582 4190 4191 +f 4190 978 3852 +f 4191 3852 1376 +f 4190 3852 4191 +f 878 4192 4193 +f 4192 1376 4061 +f 4193 4061 1479 +f 4192 4061 4193 +f 673 4194 4196 +f 4194 806 4195 +f 4196 4195 887 +f 4194 4195 4196 +f 497 3778 3952 +f 3778 673 4196 +f 3952 4196 887 +f 3778 4196 3952 +f 971 4133 4198 +f 4133 1052 4197 +f 4198 4197 1275 +f 4133 4197 4198 +f 159 4199 4134 +f 4199 360 3954 +f 4134 3954 553 +f 4199 3954 4134 +f 1381 3956 4200 +f 3956 310 4065 +f 4200 4065 1456 +f 3956 4065 4200 +f 49 4062 4202 +f 4062 861 4201 +f 4202 4201 1003 +f 4062 4201 4202 +f 422 4203 3955 +f 4203 496 4204 +f 3955 4204 1052 +f 4203 4204 3955 +f 314 4067 3961 +f 4067 971 4205 +f 3961 4205 1481 +f 4067 4205 3961 +f 861 3964 4201 +f 3964 62 4141 +f 4201 4141 1003 +f 3964 4141 4201 +f 1366 4138 3958 +f 4138 510 4206 +f 3958 4206 1480 +f 4138 4206 3958 +f 313 4207 4208 +f 4207 960 4143 +f 4208 4143 1245 +f 4207 4143 4208 +f 152 4209 4154 +f 4209 401 4210 +f 4154 4210 1092 +f 4209 4210 4154 +f 1066 4211 4212 +f 4211 1311 3968 +f 4212 3968 1368 +f 4211 3968 4212 +f 1085 4213 3868 +f 4213 603 4214 +f 3868 4214 1244 +f 4213 4214 3868 +f 442 4215 4216 +f 4215 541 4151 +f 4216 4151 960 +f 4215 4151 4216 +f 442 4217 4215 +f 4217 152 4152 +f 4215 4152 541 +f 4217 4152 4215 +f 774 4218 4148 +f 4218 1066 4212 +f 4148 4212 1368 +f 4218 4212 4148 +f 1085 3867 4219 +f 3867 380 3978 +f 4219 3978 1391 +f 3867 3978 4219 +f 948 3883 4220 +f 3883 272 4093 +f 4220 4093 998 +f 3883 4093 4220 +f 479 4161 4221 +f 4161 463 4160 +f 4221 4160 821 +f 4161 4160 4221 +f 132 4222 4162 +f 4222 763 4223 +f 4162 4223 998 +f 4222 4223 4162 +f 479 4224 4163 +f 4224 1301 4166 +f 4163 4166 1501 +f 4224 4166 4163 +f 763 4222 4225 +f 4222 132 4100 +f 4225 4100 937 +f 4222 4100 4225 +f 763 4225 4226 +f 4225 937 4167 +f 4226 4167 1117 +f 4225 4167 4226 +f 897 4227 4228 +f 4227 939 4165 +f 4228 4165 1301 +f 4227 4165 4228 +f 30 4105 4230 +f 4105 484 4229 +f 4230 4229 1134 +f 4105 4229 4230 +f 461 4110 4231 +f 4110 701 4171 +f 4231 4171 1338 +f 4110 4171 4231 +f 726 4018 4232 +f 4018 1213 4021 +f 4232 4021 1340 +f 4018 4021 4232 +f 608 4014 4234 +f 4014 461 4233 +f 4234 4233 1202 +f 4014 4233 4234 +f 1033 4173 4235 +f 4173 608 4234 +f 4235 4234 1202 +f 4173 4234 4235 +f 790 4112 4236 +f 4112 1033 4235 +f 4236 4235 1202 +f 4112 4235 4236 +f 246 4237 4024 +f 4237 264 4238 +f 4024 4238 1340 +f 4237 4238 4024 +f 790 4239 4113 +f 4239 441 4240 +f 4113 4240 1293 +f 4239 4240 4113 +f 1160 4115 4242 +f 4115 251 4241 +f 4242 4241 1223 +f 4115 4241 4242 +f 840 4243 4245 +f 4243 251 4244 +f 4245 4244 1064 +f 4243 4244 4245 +f 251 4114 4244 +f 4114 869 4028 +f 4244 4028 1064 +f 4114 4028 4244 +f 276 4246 4247 +f 4246 90 4029 +f 4247 4029 889 +f 4246 4029 4247 +f 889 3907 4248 +f 3907 197 4031 +f 4248 4031 920 +f 3907 4031 4248 +f 90 4246 3911 +f 4246 276 4185 +f 3911 4185 721 +f 4246 4185 3911 +f 681 3407 4250 +f 3407 1146 4249 +f 4250 4249 1288 +f 3407 4249 4250 +f 681 4250 4035 +f 4250 1288 4251 +f 4035 4251 1333 +f 4250 4251 4035 +f 177 4118 4253 +f 4118 571 4252 +f 4253 4252 1303 +f 4118 4252 4253 +f 704 4039 4254 +f 4039 177 4253 +f 4254 4253 1303 +f 4039 4253 4254 +f 515 4255 4256 +f 4255 82 3918 +f 4256 3918 1370 +f 4255 3918 4256 +f 53 4257 4047 +f 4257 850 4258 +f 4047 4258 1190 +f 4257 4258 4047 +f 195 4051 4260 +f 4051 559 4259 +f 4260 4259 1294 +f 4051 4259 4260 +f 972 3845 4261 +f 3845 195 4260 +f 4261 4260 1294 +f 3845 4260 4261 +f 777 4262 4263 +f 4262 642 4123 +f 4263 4123 1414 +f 4262 4123 4263 +f 705 4264 4266 +f 4264 873 4265 +f 4266 4265 1073 +f 4264 4265 4266 +f 586 4267 4269 +f 4267 758 4268 +f 4269 4268 1421 +f 4267 4268 4269 +f 845 4270 4060 +f 4270 346 4271 +f 4060 4271 1354 +f 4270 4271 4060 +f 161 4272 4274 +f 4272 1354 4273 +f 4274 4273 1420 +f 4272 4273 4274 +f 49 4275 4063 +f 4275 686 4276 +f 4063 4276 1479 +f 4275 4276 4063 +f 565 4277 4278 +f 4277 352 3953 +f 4278 3953 887 +f 4277 3953 4278 +f 352 4277 3966 +f 4277 565 4279 +f 3966 4279 1441 +f 4277 4279 3966 +f 496 4203 4281 +f 4203 422 4280 +f 4281 4280 1054 +f 4203 4280 4281 +f 302 4282 4283 +f 4282 1245 4136 +f 4283 4136 1381 +f 4282 4136 4283 +f 422 3960 4280 +f 3960 452 4284 +f 4280 4284 1054 +f 3960 4284 4280 +f 302 4285 4282 +f 4285 313 4208 +f 4282 4208 1245 +f 4285 4208 4282 +f 401 4286 4210 +f 4286 1003 4142 +f 4210 4142 1092 +f 4286 4142 4210 +f 284 4287 4288 +f 4287 755 4072 +f 4288 4072 1441 +f 4287 4072 4288 +f 755 4287 4290 +f 4287 284 4289 +f 4290 4289 1201 +f 4287 4289 4290 +f 565 4291 4279 +f 4291 284 4288 +f 4279 4288 1441 +f 4291 4288 4279 +f 1066 4292 4211 +f 4292 452 3691 +f 4211 3691 1311 +f 4292 3691 4211 +f 121 4293 4294 +f 4293 146 3789 +f 4294 3789 1353 +f 4293 3789 4294 +f 603 4295 4214 +f 4295 510 4139 +f 4214 4139 1244 +f 4295 4139 4214 +f 770 4296 4297 +f 4296 755 4290 +f 4297 4290 1201 +f 4296 4290 4297 +f 755 4296 4146 +f 4296 770 4298 +f 4146 4298 774 +f 4296 4298 4146 +f 146 4293 3575 +f 4293 121 4299 +f 3575 4299 613 +f 4293 4299 3575 +f 613 4299 4301 +f 4299 121 4300 +f 4301 4300 950 +f 4299 4300 4301 +f 886 4302 4303 +f 4302 1085 4219 +f 4303 4219 1391 +f 4302 4219 4303 +f 886 4303 4305 +f 4303 1391 4304 +f 4305 4304 1474 +f 4303 4304 4305 +f 130 4306 4307 +f 4306 816 3982 +f 4307 3982 948 +f 4306 3982 4307 +f 664 4308 4159 +f 4308 34 4309 +f 4159 4309 821 +f 4308 4309 4159 +f 478 4310 4157 +f 4310 34 4308 +f 4157 4308 664 +f 4310 4308 4157 +f 763 4311 4223 +f 4311 948 4220 +f 4223 4220 998 +f 4311 4220 4223 +f 479 4221 4224 +f 4221 821 4312 +f 4224 4312 1301 +f 4221 4312 4224 +f 897 4313 4227 +f 4313 484 4004 +f 4227 4004 939 +f 4313 4004 4227 +f 484 4313 4229 +f 4313 897 4314 +f 4229 4314 1134 +f 4313 4314 4229 +f 1242 4315 4316 +f 4315 1117 4168 +f 4316 4168 1331 +f 4315 4168 4316 +f 557 4317 4318 +f 4317 1242 4316 +f 4318 4316 1331 +f 4317 4316 4318 +f 1134 4319 4321 +f 4319 1136 4320 +f 4321 4320 1338 +f 4319 4320 4321 +f 30 4230 4170 +f 4230 1134 4321 +f 4170 4321 1338 +f 4230 4321 4170 +f 557 4318 4322 +f 4318 1331 4169 +f 4322 4169 1466 +f 4318 4169 4322 +f 107 4111 4172 +f 4111 726 4323 +f 4172 4323 1466 +f 4111 4323 4172 +f 726 4324 4323 +f 4324 789 4325 +f 4323 4325 1466 +f 4324 4325 4323 +f 789 4324 4326 +f 4324 726 4232 +f 4326 4232 1340 +f 4324 4232 4326 +f 239 4327 4328 +f 4327 790 4236 +f 4328 4236 1202 +f 4327 4236 4328 +f 264 4237 4329 +f 4237 246 4174 +f 4329 4174 860 +f 4237 4174 4329 +f 264 4329 4331 +f 4329 860 4330 +f 4331 4330 1438 +f 4329 4330 4331 +f 860 4175 4332 +f 4175 1160 4242 +f 4332 4242 1223 +f 4175 4242 4332 +f 441 4333 4240 +f 4333 1061 4177 +f 4240 4177 1293 +f 4333 4177 4240 +f 441 4334 4333 +f 4334 724 4335 +f 4333 4335 1061 +f 4334 4335 4333 +f 185 4336 4182 +f 4336 688 4337 +f 4182 4337 1286 +f 4336 4337 4182 +f 185 4117 4338 +f 4117 680 4120 +f 4338 4120 983 +f 4117 4120 4338 +f 955 4339 4340 +f 4339 1146 3322 +f 4340 3322 1321 +f 4339 3322 4340 +f 850 4341 4258 +f 4341 729 4122 +f 4258 4122 1190 +f 4341 4122 4258 +f 538 4342 4044 +f 4342 388 4343 +f 4044 4343 1414 +f 4342 4343 4044 +f 586 4125 4344 +f 4125 472 4049 +f 4344 4049 1233 +f 4125 4049 4344 +f 709 4345 4347 +f 4345 93 4346 +f 4347 4346 1313 +f 4345 4346 4347 +f 346 4270 4349 +f 4270 845 4348 +f 4349 4348 989 +f 4270 4348 4349 +f 686 4350 4276 +f 4350 878 4193 +f 4276 4193 1479 +f 4350 4193 4276 +f 804 4351 4352 +f 4351 565 4278 +f 4352 4278 887 +f 4351 4278 4352 +f 669 4353 4354 +f 4353 804 4352 +f 4354 4352 887 +f 4353 4352 4354 +f 360 4199 4356 +f 4199 159 4355 +f 4356 4355 1277 +f 4199 4355 4356 +f 1052 4204 4197 +f 4204 496 4357 +f 4197 4357 1275 +f 4204 4357 4197 +f 7 4358 4359 +f 4358 496 4281 +f 4359 4281 1054 +f 4358 4281 4359 +f 217 4360 4361 +f 4360 1353 3965 +f 4361 3965 1481 +f 4360 3965 4361 +f 2 4362 4364 +f 4362 1054 4363 +f 4364 4363 1066 +f 4362 4363 4364 +f 1054 4284 4363 +f 4284 452 4292 +f 4363 4292 1066 +f 4284 4292 4363 +f 217 4365 4360 +f 4365 121 4294 +f 4360 4294 1353 +f 4365 4294 4360 +f 313 4366 4207 +f 4366 728 4367 +f 4207 4367 960 +f 4366 4367 4207 +f 728 4368 4367 +f 4368 442 4216 +f 4367 4216 960 +f 4368 4216 4367 +f 152 4217 4369 +f 4217 442 4368 +f 4369 4368 728 +f 4217 4368 4369 +f 401 4209 4370 +f 4209 152 4369 +f 4370 4369 728 +f 4209 4369 4370 +f 774 4298 4218 +f 4298 770 4371 +f 4218 4371 1066 +f 4298 4371 4218 +f 770 4372 4371 +f 4372 2 4364 +f 4371 4364 1066 +f 4372 4364 4371 +f 1391 4155 4374 +f 4155 816 4373 +f 4374 4373 1403 +f 4155 4373 4374 +f 816 4306 4373 +f 4306 130 4375 +f 4373 4375 1403 +f 4306 4375 4373 +f 763 4376 4311 +f 4376 130 4307 +f 4311 4307 948 +f 4376 4307 4311 +f 951 4377 4378 +f 4377 763 4226 +f 4378 4226 1117 +f 4377 4226 4378 +f 951 4378 4379 +f 4378 1117 4315 +f 4379 4315 1242 +f 4378 4315 4379 +f 437 4380 4382 +f 4380 98 4381 +f 4382 4381 1338 +f 4380 4381 4382 +f 98 4383 4381 +f 4383 461 4231 +f 4381 4231 1338 +f 4383 4231 4381 +f 461 4383 4233 +f 4383 98 4384 +f 4233 4384 1202 +f 4383 4384 4233 +f 264 4385 4238 +f 4385 789 4326 +f 4238 4326 1340 +f 4385 4326 4238 +f 251 4243 4241 +f 4243 840 4386 +f 4241 4386 1223 +f 4243 4386 4241 +f 66 4387 4388 +f 4387 265 4186 +f 4388 4186 587 +f 4387 4186 4388 +f 265 4387 4187 +f 4387 66 4389 +f 4187 4389 342 +f 4387 4389 4187 +f 342 4390 3915 +f 4390 298 4391 +f 3915 4391 1370 +f 4390 4391 3915 +f 298 4392 4391 +f 4392 515 4256 +f 4391 4256 1370 +f 4392 4256 4391 +f 1146 4339 4249 +f 4339 955 4393 +f 4249 4393 1288 +f 4339 4393 4249 +f 361 4394 4395 +f 4394 704 4254 +f 4395 4254 1303 +f 4394 4254 4395 +f 850 4257 4396 +f 4257 53 4189 +f 4396 4189 1313 +f 4257 4189 4396 +f 559 4397 4259 +f 4397 873 4398 +f 4259 4398 1294 +f 4397 4398 4259 +f 586 4399 4267 +f 4399 230 4400 +f 4267 4400 758 +f 4399 4400 4267 +f 467 4401 4403 +f 4401 93 4402 +f 4403 4402 582 +f 4401 4402 4403 +f 346 4404 4406 +f 4404 630 4405 +f 4406 4405 1420 +f 4404 4405 4406 +f 806 4407 4409 +f 4407 1080 4408 +f 4409 4408 1471 +f 4407 4408 4409 +f 806 4410 4195 +f 4410 669 4354 +f 4195 4354 887 +f 4410 4354 4195 +f 686 4275 4411 +f 4275 49 4202 +f 4411 4202 1003 +f 4275 4202 4411 +f 360 4356 4132 +f 4356 1277 4412 +f 4132 4412 1456 +f 4356 4412 4132 +f 612 4413 4414 +f 4413 1381 4200 +f 4414 4200 1456 +f 4413 4200 4414 +f 459 4415 4416 +f 4415 971 4198 +f 4416 4198 1275 +f 4415 4198 4416 +f 1277 4355 4417 +f 4355 159 4135 +f 4417 4135 1480 +f 4355 4135 4417 +f 971 4415 4205 +f 4415 459 4418 +f 4205 4418 1481 +f 4415 4418 4205 +f 791 4419 4420 +f 4419 1277 4417 +f 4420 4417 1480 +f 4419 4417 4420 +f 510 4421 4206 +f 4421 791 4420 +f 4206 4420 1480 +f 4421 4420 4206 +f 284 4291 4422 +f 4291 565 4351 +f 4422 4351 804 +f 4291 4351 4422 +f 401 4370 4424 +f 4370 728 4423 +f 4424 4423 1356 +f 4370 4423 4424 +f 1003 4286 4425 +f 4286 401 4424 +f 4425 4424 1356 +f 4286 4424 4425 +f 728 4366 4427 +f 4366 313 4426 +f 4427 4426 1161 +f 4366 4426 4427 +f 478 4158 4429 +f 4158 731 4428 +f 4429 4428 1334 +f 4158 4428 4429 +f 1391 4374 4304 +f 4374 1403 4430 +f 4304 4430 1474 +f 4374 4430 4304 +f 34 4310 4431 +f 4310 478 4429 +f 4431 4429 1334 +f 4310 4429 4431 +f 130 4376 4432 +f 4376 763 4377 +f 4432 4377 951 +f 4376 4377 4432 +f 557 4433 4317 +f 4433 905 4434 +f 4317 4434 1242 +f 4433 4434 4317 +f 1136 4319 4436 +f 4319 1134 4435 +f 4436 4435 1164 +f 4319 4435 4436 +f 334 4437 4438 +f 4437 557 4322 +f 4438 4322 1466 +f 4437 4322 4438 +f 64 4439 4441 +f 4439 520 4440 +f 4441 4440 1466 +f 4439 4440 4441 +f 789 4442 4325 +f 4442 64 4441 +f 4325 4441 1466 +f 4442 4441 4325 +f 789 4385 4443 +f 4385 264 4331 +f 4443 4331 1438 +f 4385 4331 4443 +f 441 4239 4445 +f 4239 790 4444 +f 4445 4444 1350 +f 4239 4444 4445 +f 790 4327 4444 +f 4327 239 4446 +f 4444 4446 1350 +f 4327 4446 4444 +f 724 4334 4447 +f 4334 441 4445 +f 4447 4445 1350 +f 4334 4445 4447 +f 542 4448 4449 +f 4448 420 4178 +f 4449 4178 1061 +f 4448 4178 4449 +f 420 4450 4179 +f 4450 840 4245 +f 4179 4245 1064 +f 4450 4245 4179 +f 276 4247 4452 +f 4247 889 4451 +f 4452 4451 949 +f 4247 4451 4452 +f 920 4121 4454 +f 4121 729 4453 +f 4454 4453 1107 +f 4121 4453 4454 +f 82 4255 4456 +f 4255 515 4455 +f 4456 4455 663 +f 4255 4455 4456 +f 361 4457 4394 +f 4457 538 4043 +f 4394 4043 704 +f 4457 4043 4394 +f 82 4456 3921 +f 4456 663 4458 +f 3921 4458 798 +f 4456 4458 3921 +f 798 4458 3928 +f 4458 663 4459 +f 3928 4459 1233 +f 4458 4459 3928 +f 348 4460 4462 +f 4460 230 4461 +f 4462 4461 1233 +f 4460 4461 4462 +f 705 4463 4465 +f 4463 634 4464 +f 4465 4464 1205 +f 4463 4464 4465 +f 630 4466 4405 +f 4466 894 4467 +f 4405 4467 1420 +f 4466 4467 4405 +f 41 4468 4469 +f 4468 467 4403 +f 4469 4403 582 +f 4468 4403 4469 +f 878 4470 4192 +f 4470 582 4191 +f 4192 4191 1376 +f 4470 4191 4192 +f 698 4471 4472 +f 4471 669 4410 +f 4472 4410 806 +f 4471 4410 4472 +f 686 4473 4350 +f 4473 654 4474 +f 4350 4474 878 +f 4473 4474 4350 +f 1277 4475 4412 +f 4475 138 4476 +f 4412 4476 1456 +f 4475 4476 4412 +f 1275 4357 4478 +f 4357 496 4477 +f 4478 4477 1347 +f 4357 4477 4478 +f 612 4479 4413 +f 4479 402 4480 +f 4413 4480 1381 +f 4479 4480 4413 +f 402 4481 4480 +f 4481 302 4283 +f 4480 4283 1381 +f 4481 4283 4480 +f 1224 4482 4483 +f 4482 217 4361 +f 4483 4361 1481 +f 4482 4361 4483 +f 459 4484 4418 +f 4484 1224 4483 +f 4418 4483 1481 +f 4484 4483 4418 +f 313 4285 4426 +f 4285 302 4485 +f 4426 4485 1161 +f 4285 4485 4426 +f 302 4481 4485 +f 4481 402 4486 +f 4485 4486 1161 +f 4481 4486 4485 +f 105 4487 4489 +f 4487 1240 4488 +f 4489 4488 1356 +f 4487 4488 4489 +f 1240 4490 4488 +f 4490 1003 4425 +f 4488 4425 1356 +f 4490 4425 4488 +f 510 4295 4421 +f 4295 603 4491 +f 4421 4491 791 +f 4295 4491 4421 +f 728 4427 4423 +f 4427 1161 4492 +f 4423 4492 1356 +f 4427 4492 4423 +f 2 4372 4494 +f 4372 770 4493 +f 4494 4493 1017 +f 4372 4493 4494 +f 1017 4493 4495 +f 4493 770 4297 +f 4495 4297 1201 +f 4493 4297 4495 +f 2 4494 4362 +f 4494 1017 4496 +f 4362 4496 1054 +f 4494 4496 4362 +f 121 4365 4497 +f 4365 217 4482 +f 4497 4482 1224 +f 4365 4482 4497 +f 950 4300 4498 +f 4300 121 4497 +f 4498 4497 1224 +f 4300 4497 4498 +f 821 4309 4499 +f 4309 34 4431 +f 4499 4431 1334 +f 4309 4431 4499 +f 130 4432 4375 +f 4432 951 4500 +f 4375 4500 1403 +f 4432 4500 4375 +f 821 4501 4312 +f 4501 521 4502 +f 4312 4502 1301 +f 4501 4502 4312 +f 521 4501 4503 +f 4501 821 4499 +f 4503 4499 1334 +f 4501 4499 4503 +f 521 4504 4502 +f 4504 897 4228 +f 4502 4228 1301 +f 4504 4228 4502 +f 1134 4505 4435 +f 4505 521 4506 +f 4435 4506 1164 +f 4505 4506 4435 +f 897 4504 4314 +f 4504 521 4505 +f 4314 4505 1134 +f 4504 4505 4314 +f 1242 4434 4508 +f 4434 905 4507 +f 4508 4507 1470 +f 4434 4507 4508 +f 334 4509 4437 +f 4509 527 4510 +f 4437 4510 557 +f 4509 4510 4437 +f 1158 4511 4512 +f 4511 334 4438 +f 4512 4438 1466 +f 4511 4438 4512 +f 1461 4513 4514 +f 4513 1158 4512 +f 4514 4512 1466 +f 4513 4512 4514 +f 1185 4515 4516 +f 4515 437 4382 +f 4516 4382 1338 +f 4515 4382 4516 +f 520 4517 4440 +f 4517 1461 4514 +f 4440 4514 1466 +f 4517 4514 4440 +f 64 4518 4439 +f 4518 413 4519 +f 4439 4519 520 +f 4518 4519 4439 +f 98 4380 4521 +f 4380 437 4520 +f 4521 4520 1022 +f 4380 4520 4521 +f 98 4522 4384 +f 4522 239 4328 +f 4384 4328 1202 +f 4522 4328 4384 +f 840 4523 4386 +f 4523 820 4524 +f 4386 4524 1223 +f 4523 4524 4386 +f 420 4525 4450 +f 4525 163 4526 +f 4450 4526 840 +f 4525 4526 4450 +f 889 4527 4451 +f 4527 610 4528 +f 4451 4528 949 +f 4527 4528 4451 +f 276 4529 4183 +f 4529 423 4530 +f 4183 4530 587 +f 4529 4530 4183 +f 688 4531 4337 +f 4531 571 4119 +f 4337 4119 1286 +f 4531 4119 4337 +f 889 4248 4532 +f 4248 920 4454 +f 4532 4454 1107 +f 4248 4454 4532 +f 610 4527 4533 +f 4527 889 4532 +f 4533 4532 1107 +f 4527 4532 4533 +f 423 4534 4530 +f 4534 66 4388 +f 4530 4388 587 +f 4534 4388 4530 +f 298 4390 4536 +f 4390 342 4535 +f 4536 4535 809 +f 4390 4535 4536 +f 688 4336 4538 +f 4336 185 4537 +f 4538 4537 1373 +f 4336 4537 4538 +f 822 4539 4540 +f 4539 955 4340 +f 4540 4340 1321 +f 4539 4340 4540 +f 807 4541 3920 +f 4541 822 4540 +f 3920 4540 1321 +f 4541 4540 3920 +f 807 4542 4541 +f 4542 687 4543 +f 4541 4543 822 +f 4542 4543 4541 +f 687 4542 4544 +f 4542 807 3924 +f 4544 3924 972 +f 4542 3924 4544 +f 361 4545 4457 +f 4545 388 4342 +f 4457 4342 538 +f 4545 4342 4457 +f 1233 4459 4547 +f 4459 663 4546 +f 4547 4546 1317 +f 4459 4546 4547 +f 630 4548 4550 +f 4548 989 4549 +f 4550 4549 1475 +f 4548 4549 4550 +f 698 4472 4551 +f 4472 806 4409 +f 4551 4409 1471 +f 4472 4409 4551 +f 138 4552 4476 +f 4552 612 4414 +f 4476 4414 1456 +f 4552 4414 4476 +f 1030 4553 4554 +f 4553 1275 4478 +f 4554 4478 1347 +f 4553 4478 4554 +f 1030 4555 4553 +f 4555 459 4416 +f 4553 4416 1275 +f 4555 4416 4553 +f 496 4358 4477 +f 4358 7 4556 +f 4477 4556 1347 +f 4358 4556 4477 +f 417 4557 4559 +f 4557 592 4558 +f 4559 4558 804 +f 4557 4558 4559 +f 592 4560 4558 +f 4560 284 4422 +f 4558 4422 804 +f 4560 4422 4558 +f 284 4560 4289 +f 4560 592 4561 +f 4289 4561 1201 +f 4560 4561 4289 +f 1017 4562 4496 +f 4562 7 4359 +f 4496 4359 1054 +f 4562 4359 4496 +f 322 4563 4564 +f 4563 105 4489 +f 4564 4489 1356 +f 4563 4489 4564 +f 147 4565 4566 +f 4565 613 4301 +f 4566 4301 950 +f 4565 4301 4566 +f 613 4565 4075 +f 4565 147 4567 +f 4075 4567 731 +f 4565 4567 4075 +f 731 4568 4428 +f 4568 1297 4569 +f 4428 4569 1334 +f 4568 4569 4428 +f 1403 4570 4430 +f 4570 890 4571 +f 4430 4571 1474 +f 4570 4571 4430 +f 951 4572 4500 +f 4572 1014 4573 +f 4500 4573 1403 +f 4572 4573 4500 +f 589 4574 4576 +f 4574 250 4575 +f 4576 4575 1242 +f 4574 4575 4576 +f 250 4577 4575 +f 4577 951 4379 +f 4575 4379 1242 +f 4577 4379 4575 +f 589 4576 4578 +f 4576 1242 4508 +f 4578 4508 1470 +f 4576 4508 4578 +f 575 4579 4580 +f 4579 1136 4436 +f 4580 4436 1164 +f 4579 4436 4580 +f 557 4510 4582 +f 4510 527 4581 +f 4582 4581 900 +f 4510 4581 4582 +f 67 4583 4585 +f 4583 1089 4584 +f 4585 4584 1136 +f 4583 4584 4585 +f 1136 4584 4320 +f 4584 1089 4586 +f 4320 4586 1338 +f 4584 4586 4320 +f 1089 4587 4586 +f 4587 1185 4516 +f 4586 4516 1338 +f 4587 4516 4586 +f 1043 4588 4589 +f 4588 437 4515 +f 4589 4515 1185 +f 4588 4515 4589 +f 1022 4520 4590 +f 4520 437 4588 +f 4590 4588 1043 +f 4520 4588 4590 +f 520 4519 4592 +f 4519 413 4591 +f 4592 4591 847 +f 4519 4591 4592 +f 513 4593 4594 +f 4593 789 4443 +f 4594 4443 1438 +f 4593 4443 4594 +f 239 4595 4446 +f 4595 523 4596 +f 4446 4596 1350 +f 4595 4596 4446 +f 860 4597 4330 +f 4597 716 4598 +f 4330 4598 1438 +f 4597 4598 4330 +f 724 4599 4335 +f 4599 542 4449 +f 4335 4449 1061 +f 4599 4449 4335 +f 163 4525 4600 +f 4525 420 4448 +f 4600 4448 542 +f 4525 4448 4600 +f 342 4389 4602 +f 4389 66 4601 +f 4602 4601 1250 +f 4389 4601 4602 +f 809 4535 4603 +f 4535 342 4602 +f 4603 4602 1250 +f 4535 4602 4603 +f 983 4038 4605 +f 4038 1333 4604 +f 4605 4604 1373 +f 4038 4604 4605 +f 185 4338 4537 +f 4338 983 4605 +f 4537 4605 1373 +f 4338 4605 4537 +f 308 4606 4607 +f 4606 729 4341 +f 4607 4341 850 +f 4606 4341 4607 +f 942 4608 4610 +f 4608 308 4609 +f 4610 4609 1174 +f 4608 4609 4610 +f 687 4544 4611 +f 4544 972 4261 +f 4611 4261 1294 +f 4544 4261 4611 +f 912 4612 4613 +f 4612 687 4611 +f 4613 4611 1294 +f 4612 4611 4613 +f 348 4462 4614 +f 4462 1233 4547 +f 4614 4547 1317 +f 4462 4547 4614 +f 525 4615 4617 +f 4615 470 4616 +f 4617 4616 1294 +f 4615 4616 4617 +f 467 4618 4620 +f 4618 254 4619 +f 4620 4619 1174 +f 4618 4619 4620 +f 630 4621 4466 +f 4621 609 4622 +f 4466 4622 894 +f 4621 4622 4466 +f 467 4468 4624 +f 4468 41 4623 +f 4624 4623 1196 +f 4468 4623 4624 +f 41 4625 4627 +f 4625 878 4626 +f 4627 4626 1082 +f 4625 4626 4627 +f 878 4474 4626 +f 4474 654 4628 +f 4626 4628 1082 +f 4474 4628 4626 +f 617 4629 4630 +f 4629 669 4471 +f 4630 4471 698 +f 4629 4471 4630 +f 654 4473 4632 +f 4473 686 4631 +f 4632 4631 1240 +f 4473 4631 4632 +f 686 4411 4631 +f 4411 1003 4490 +f 4631 4490 1240 +f 4411 4490 4631 +f 263 4633 4634 +f 4633 417 4559 +f 4634 4559 804 +f 4633 4559 4634 +f 618 4635 4636 +f 4635 138 4475 +f 4636 4475 1277 +f 4635 4475 4636 +f 7 4637 4556 +f 4637 667 4638 +f 4556 4638 1347 +f 4637 4638 4556 +f 791 4639 4419 +f 4639 618 4636 +f 4419 4636 1277 +f 4639 4636 4419 +f 459 4555 4484 +f 4555 1030 4640 +f 4484 4640 1224 +f 4555 4640 4484 +f 1201 4561 4642 +f 4561 592 4641 +f 4642 4641 1326 +f 4561 4641 4642 +f 667 4637 4643 +f 4637 7 4562 +f 4643 4562 1017 +f 4637 4562 4643 +f 1161 4644 4492 +f 4644 322 4564 +f 4492 4564 1356 +f 4644 4564 4492 +f 786 4645 4646 +f 4645 322 4644 +f 4646 4644 1161 +f 4645 4644 4646 +f 1017 4495 4647 +f 4495 1201 4642 +f 4647 4642 1326 +f 4495 4642 4647 +f 667 4643 4648 +f 4643 1017 4647 +f 4648 4647 1326 +f 4643 4647 4648 +f 791 4491 4650 +f 4491 603 4649 +f 4650 4649 1253 +f 4491 4649 4650 +f 731 4567 4568 +f 4567 147 4651 +f 4568 4651 1297 +f 4567 4651 4568 +f 1297 4652 4569 +f 4652 17 4653 +f 4569 4653 1334 +f 4652 4653 4569 +f 940 4654 4655 +f 4654 521 4503 +f 4655 4503 1334 +f 4654 4503 4655 +f 1014 4656 4573 +f 4656 1024 4657 +f 4573 4657 1403 +f 4656 4657 4573 +f 743 4658 4659 +f 4658 521 4654 +f 4659 4654 940 +f 4658 4654 4659 +f 951 4577 4572 +f 4577 250 4660 +f 4572 4660 1014 +f 4577 4660 4572 +f 720 4661 4662 +f 4661 575 4580 +f 4662 4580 1164 +f 4661 4580 4662 +f 557 4582 4433 +f 4582 900 4663 +f 4433 4663 905 +f 4582 4663 4433 +f 900 4664 4663 +f 4664 216 4665 +f 4663 4665 905 +f 4664 4665 4663 +f 1136 4579 4667 +f 4579 575 4666 +f 4667 4666 1298 +f 4579 4666 4667 +f 67 4585 4668 +f 4585 1136 4667 +f 4668 4667 1298 +f 4585 4667 4668 +f 67 4668 4670 +f 4668 1298 4669 +f 4670 4669 1462 +f 4668 4669 4670 +f 1089 4583 4671 +f 4583 67 4670 +f 4671 4670 1462 +f 4583 4670 4671 +f 334 4672 4509 +f 4672 157 4673 +f 4509 4673 527 +f 4672 4673 4509 +f 157 4672 4674 +f 4672 334 4511 +f 4674 4511 1158 +f 4672 4511 4674 +f 46 4675 4676 +f 4675 1158 4513 +f 4676 4513 1461 +f 4675 4513 4676 +f 520 4592 4517 +f 4592 847 4677 +f 4517 4677 1461 +f 4592 4677 4517 +f 367 4678 4679 +f 4678 98 4521 +f 4679 4521 1022 +f 4678 4521 4679 +f 98 4678 4681 +f 4678 367 4680 +f 4681 4680 523 +f 4678 4680 4681 +f 513 4682 4593 +f 4682 64 4442 +f 4593 4442 789 +f 4682 4442 4593 +f 413 4518 4683 +f 4518 64 4682 +f 4683 4682 513 +f 4518 4682 4683 +f 239 4522 4595 +f 4522 98 4681 +f 4595 4681 523 +f 4522 4681 4595 +f 86 4684 4686 +f 4684 716 4685 +f 4686 4685 1223 +f 4684 4685 4686 +f 716 4597 4685 +f 4597 860 4332 +f 4685 4332 1223 +f 4597 4332 4685 +f 820 4687 4524 +f 4687 86 4686 +f 4524 4686 1223 +f 4687 4686 4524 +f 163 4688 4526 +f 4688 820 4523 +f 4526 4523 840 +f 4688 4523 4526 +f 423 4529 4689 +f 4529 276 4452 +f 4689 4452 949 +f 4529 4452 4689 +f 729 4690 4453 +f 4690 319 4691 +f 4453 4691 1107 +f 4690 4691 4453 +f 125 4692 4693 +f 4692 361 4395 +f 4693 4395 1303 +f 4692 4395 4693 +f 308 4694 4606 +f 4694 319 4690 +f 4606 4690 729 +f 4694 4690 4606 +f 765 4695 4696 +f 4695 348 4614 +f 4696 4614 1317 +f 4695 4614 4696 +f 684 4697 4698 +f 4697 630 4550 +f 4698 4550 1475 +f 4697 4550 4698 +f 634 4699 4464 +f 4699 800 4700 +f 4464 4700 1205 +f 4699 4700 4464 +f 41 4627 4623 +f 4627 1082 4701 +f 4623 4701 1196 +f 4627 4701 4623 +f 617 4702 4629 +f 4702 263 4703 +f 4629 4703 669 +f 4702 4703 4629 +f 669 4703 4353 +f 4703 263 4634 +f 4353 4634 804 +f 4703 4634 4353 +f 612 4552 4705 +f 4552 138 4704 +f 4705 4704 854 +f 4552 4704 4705 +f 1224 4640 4707 +f 4640 1030 4706 +f 4707 4706 1252 +f 4640 4706 4707 +f 592 4708 4641 +f 4708 877 4709 +f 4641 4709 1326 +f 4708 4709 4641 +f 749 4710 4712 +f 4710 322 4711 +f 4712 4711 796 +f 4710 4711 4712 +f 105 4563 4713 +f 4563 322 4710 +f 4713 4710 749 +f 4563 4710 4713 +f 322 4645 4711 +f 4645 786 4714 +f 4711 4714 796 +f 4645 4714 4711 +f 603 4213 4649 +f 4213 1085 4715 +f 4649 4715 1253 +f 4213 4715 4649 +f 1024 4716 4657 +f 4716 890 4570 +f 4657 4570 1403 +f 4716 4570 4657 +f 237 4717 4718 +f 4717 521 4658 +f 4718 4658 743 +f 4717 4658 4718 +f 164 4719 4720 +f 4719 250 4574 +f 4720 4574 589 +f 4719 4574 4720 +f 521 4717 4506 +f 4717 237 4721 +f 4506 4721 1164 +f 4717 4721 4506 +f 164 4720 4723 +f 4720 589 4722 +f 4723 4722 1076 +f 4720 4722 4723 +f 237 4724 4721 +f 4724 720 4662 +f 4721 4662 1164 +f 4724 4662 4721 +f 527 4673 4726 +f 4673 157 4725 +f 4726 4725 1045 +f 4673 4725 4726 +f 1089 4727 4587 +f 4727 189 4728 +f 4587 4728 1185 +f 4727 4728 4587 +f 189 4729 4728 +f 4729 1043 4589 +f 4728 4589 1185 +f 4729 4589 4728 +f 523 4730 4596 +f 4730 229 4731 +f 4596 4731 1350 +f 4730 4731 4596 +f 892 4732 4734 +f 4732 447 4733 +f 4734 4733 1350 +f 4732 4733 4734 +f 447 4735 4733 +f 4735 724 4447 +f 4733 4447 1350 +f 4735 4447 4733 +f 724 4735 4737 +f 4735 447 4736 +f 4737 4736 733 +f 4735 4736 4737 +f 542 4599 4738 +f 4599 724 4737 +f 4738 4737 733 +f 4599 4737 4738 +f 163 4600 4739 +f 4600 542 4738 +f 4739 4738 733 +f 4600 4738 4739 +f 66 4534 4601 +f 4534 423 4740 +f 4601 4740 1250 +f 4534 4740 4601 +f 1333 4741 4604 +f 4741 10 4742 +f 4604 4742 1373 +f 4741 4742 4604 +f 1288 4743 4251 +f 4743 10 4741 +f 4251 4741 1333 +f 4743 4741 4251 +f 823 4744 4745 +f 4744 610 4533 +f 4745 4533 1107 +f 4744 4533 4745 +f 388 4746 4748 +f 4746 125 4747 +f 4748 4747 408 +f 4746 4747 4748 +f 361 4692 4545 +f 4692 125 4746 +f 4545 4746 388 +f 4692 4746 4545 +f 388 4748 4750 +f 4748 408 4749 +f 4750 4749 732 +f 4748 4749 4750 +f 358 4751 4752 +f 4751 348 4695 +f 4752 4695 765 +f 4751 4695 4752 +f 492 4753 4754 +f 4753 684 4698 +f 4754 4698 1475 +f 4753 4698 4754 +f 654 4632 4756 +f 4632 1240 4755 +f 4756 4755 1457 +f 4632 4755 4756 +f 138 4635 4704 +f 4635 618 4757 +f 4704 4757 854 +f 4635 4757 4704 +f 278 4758 4759 +f 4758 612 4705 +f 4759 4705 854 +f 4758 4705 4759 +f 592 4557 4708 +f 4557 417 4760 +f 4708 4760 877 +f 4557 4760 4708 +f 278 4761 4758 +f 4761 402 4479 +f 4758 4479 612 +f 4761 4479 4758 +f 402 4761 4486 +f 4761 278 4762 +f 4486 4762 1161 +f 4761 4762 4486 +f 749 4763 4765 +f 4763 803 4764 +f 4765 4764 1240 +f 4763 4764 4765 +f 105 4713 4487 +f 4713 749 4765 +f 4487 4765 1240 +f 4713 4765 4487 +f 618 4639 4767 +f 4639 791 4766 +f 4767 4766 1477 +f 4639 4766 4767 +f 278 4768 4762 +f 4768 786 4646 +f 4762 4646 1161 +f 4768 4646 4762 +f 791 4650 4766 +f 4650 1253 4769 +f 4766 4769 1477 +f 4650 4769 4766 +f 507 4770 4771 +f 4770 950 4498 +f 4771 4498 1224 +f 4770 4498 4771 +f 89 4772 4773 +f 4772 147 4566 +f 4773 4566 950 +f 4772 4566 4773 +f 32 4774 4775 +f 4774 17 4652 +f 4775 4652 1297 +f 4774 4652 4775 +f 17 4776 4653 +f 4776 940 4655 +f 4653 4655 1334 +f 4776 4655 4653 +f 164 4777 4779 +f 4777 324 4778 +f 4779 4778 1014 +f 4777 4778 4779 +f 250 4719 4660 +f 4719 164 4779 +f 4660 4779 1014 +f 4719 4779 4660 +f 1076 4722 4780 +f 4722 589 4578 +f 4780 4578 1470 +f 4722 4578 4780 +f 922 4781 4783 +f 4781 720 4782 +f 4783 4782 1388 +f 4781 4782 4783 +f 575 4661 4784 +f 4661 720 4781 +f 4784 4781 922 +f 4661 4781 4784 +f 905 4785 4507 +f 4785 1316 4786 +f 4507 4786 1470 +f 4785 4786 4507 +f 905 4665 4785 +f 4665 216 4787 +f 4785 4787 1316 +f 4665 4787 4785 +f 575 4784 4666 +f 4784 922 4788 +f 4666 4788 1298 +f 4784 4788 4666 +f 216 4664 4790 +f 4664 900 4789 +f 4790 4789 1045 +f 4664 4789 4790 +f 900 4581 4789 +f 4581 527 4726 +f 4789 4726 1045 +f 4581 4726 4789 +f 847 4791 4677 +f 4791 52 4792 +f 4677 4792 1461 +f 4791 4792 4677 +f 52 4791 4794 +f 4791 847 4793 +f 4794 4793 1486 +f 4791 4793 4794 +f 1382 4795 4797 +f 4795 1043 4796 +f 4797 4796 1422 +f 4795 4796 4797 +f 1022 4590 4798 +f 4590 1043 4795 +f 4798 4795 1382 +f 4590 4795 4798 +f 317 4799 4800 +f 4799 367 4679 +f 4800 4679 1022 +f 4799 4679 4800 +f 317 4800 4801 +f 4800 1022 4798 +f 4801 4798 1382 +f 4800 4798 4801 +f 1433 4802 4803 +f 4802 513 4594 +f 4803 4594 1438 +f 4802 4594 4803 +f 716 4804 4598 +f 4804 1433 4803 +f 4598 4803 1438 +f 4804 4803 4598 +f 229 4805 4731 +f 4805 892 4734 +f 4731 4734 1350 +f 4805 4734 4731 +f 163 4739 4807 +f 4739 733 4806 +f 4807 4806 866 +f 4739 4806 4807 +f 423 4689 4740 +f 4689 949 4808 +f 4740 4808 1250 +f 4689 4808 4740 +f 10 4809 4742 +f 4809 494 4810 +f 4742 4810 1373 +f 4809 4810 4742 +f 955 4811 4393 +f 4811 723 4812 +f 4393 4812 1288 +f 4811 4812 4393 +f 494 4813 4810 +f 4813 688 4538 +f 4810 4538 1373 +f 4813 4538 4810 +f 454 4814 4815 +f 4814 571 4531 +f 4815 4531 688 +f 4814 4531 4815 +f 571 4814 4252 +f 4814 454 4816 +f 4252 4816 1303 +f 4814 4816 4252 +f 663 4455 4818 +f 4455 515 4817 +f 4818 4817 695 +f 4455 4817 4818 +f 663 4818 4546 +f 4818 695 4819 +f 4546 4819 1317 +f 4818 4819 4546 +f 358 4820 4821 +f 4820 492 4754 +f 4821 4754 1475 +f 4820 4754 4821 +f 800 4822 4700 +f 4822 759 4823 +f 4700 4823 1205 +f 4822 4823 4700 +f 800 4824 4826 +f 4824 894 4825 +f 4826 4825 1099 +f 4824 4825 4826 +f 285 4827 4829 +f 4827 677 4828 +f 4829 4828 1196 +f 4827 4828 4829 +f 1292 4830 4831 +f 4830 698 4551 +f 4831 4551 1471 +f 4830 4551 4831 +f 718 4832 4833 +f 4832 1292 4831 +f 4833 4831 1471 +f 4832 4831 4833 +f 617 4630 4834 +f 4630 698 4830 +f 4834 4830 1292 +f 4630 4830 4834 +f 618 4835 4757 +f 4835 136 4836 +f 4757 4836 854 +f 4835 4836 4757 +f 417 4837 4760 +f 4837 215 4838 +f 4760 4838 877 +f 4837 4838 4760 +f 667 4839 4638 +f 4839 958 4840 +f 4638 4840 1347 +f 4839 4840 4638 +f 877 4841 4709 +f 4841 1309 4842 +f 4709 4842 1326 +f 4841 4842 4709 +f 1253 4843 4769 +f 4843 392 4844 +f 4769 4844 1477 +f 4843 4844 4769 +f 1057 4845 4847 +f 4845 507 4846 +f 4847 4846 1252 +f 4845 4846 4847 +f 507 4771 4846 +f 4771 1224 4707 +f 4846 4707 1252 +f 4771 4707 4846 +f 507 4848 4770 +f 4848 89 4773 +f 4770 4773 950 +f 4848 4773 4770 +f 1085 4302 4715 +f 4302 886 4849 +f 4715 4849 1253 +f 4302 4849 4715 +f 147 4772 4651 +f 4772 89 4850 +f 4651 4850 1297 +f 4772 4850 4651 +f 493 4851 4852 +f 4851 886 4305 +f 4852 4305 1474 +f 4851 4305 4852 +f 890 4853 4571 +f 4853 108 4854 +f 4571 4854 1474 +f 4853 4854 4571 +f 17 4774 4776 +f 4774 32 4855 +f 4776 4855 940 +f 4774 4855 4776 +f 108 4853 4856 +f 4853 890 4716 +f 4856 4716 1024 +f 4853 4716 4856 +f 743 4659 4858 +f 4659 940 4857 +f 4858 4857 1496 +f 4659 4857 4858 +f 237 4718 4859 +f 4718 743 4858 +f 4859 4858 1496 +f 4718 4858 4859 +f 1388 4782 4861 +f 4782 720 4860 +f 4861 4860 1496 +f 4782 4860 4861 +f 720 4724 4860 +f 4724 237 4859 +f 4860 4859 1496 +f 4724 4859 4860 +f 761 4862 4863 +f 4862 1076 4780 +f 4863 4780 1470 +f 4862 4780 4863 +f 1118 4864 4865 +f 4864 761 4863 +f 4865 4863 1470 +f 4864 4863 4865 +f 1316 4866 4786 +f 4866 1118 4865 +f 4786 4865 1470 +f 4866 4865 4786 +f 922 4867 4788 +f 4867 182 4868 +f 4788 4868 1298 +f 4867 4868 4788 +f 216 4790 4787 +f 4790 1045 4869 +f 4787 4869 1316 +f 4790 4869 4787 +f 46 4870 4675 +f 4870 157 4674 +f 4675 4674 1158 +f 4870 4674 4675 +f 157 4870 4872 +f 4870 46 4871 +f 4872 4871 1458 +f 4870 4871 4872 +f 1043 4873 4796 +f 4873 827 4874 +f 4796 4874 1422 +f 4873 4874 4796 +f 189 4875 4729 +f 4875 827 4873 +f 4729 4873 1043 +f 4875 4873 4729 +f 1382 4797 4877 +f 4797 1422 4876 +f 4877 4876 1443 +f 4797 4876 4877 +f 523 4680 4879 +f 4680 367 4878 +f 4879 4878 708 +f 4680 4878 4879 +f 229 4730 4880 +f 4730 523 4879 +f 4880 4879 708 +f 4730 4879 4880 +f 86 4687 4882 +f 4687 820 4881 +f 4882 4881 916 +f 4687 4881 4882 +f 820 4688 4883 +f 4688 163 4807 +f 4883 4807 866 +f 4688 4807 4883 +f 475 4884 4885 +f 4884 298 4536 +f 4885 4536 809 +f 4884 4536 4885 +f 298 4884 4392 +f 4884 475 4886 +f 4392 4886 515 +f 4884 4886 4392 +f 183 4887 4888 +f 4887 723 4811 +f 4888 4811 955 +f 4887 4811 4888 +f 238 4889 4891 +f 4889 183 4890 +f 4891 4890 822 +f 4889 4890 4891 +f 822 4890 4539 +f 4890 183 4888 +f 4539 4888 955 +f 4890 4888 4539 +f 1303 4816 4893 +f 4816 454 4892 +f 4893 4892 1358 +f 4816 4892 4893 +f 319 4894 4691 +f 4894 823 4745 +f 4691 4745 1107 +f 4894 4745 4691 +f 695 4817 4896 +f 4817 515 4895 +f 4896 4895 753 +f 4817 4895 4896 +f 515 4886 4895 +f 4886 475 4897 +f 4895 4897 753 +f 4886 4897 4895 +f 319 4694 4899 +f 4694 308 4898 +f 4899 4898 1330 +f 4694 4898 4899 +f 745 4900 4902 +f 4900 492 4901 +f 4902 4901 765 +f 4900 4901 4902 +f 57 4903 4905 +f 4903 525 4904 +f 4905 4904 759 +f 4903 4904 4905 +f 1196 4701 4907 +f 4701 1082 4906 +f 4907 4906 1257 +f 4701 4906 4907 +f 1240 4764 4755 +f 4764 803 4908 +f 4755 4908 1457 +f 4764 4908 4755 +f 958 4909 4840 +f 4909 910 4910 +f 4840 4910 1347 +f 4909 4910 4840 +f 910 4911 4910 +f 4911 1030 4554 +f 4910 4554 1347 +f 4911 4554 4910 +f 1030 4911 4706 +f 4911 910 4912 +f 4706 4912 1252 +f 4911 4912 4706 +f 877 4913 4841 +f 4913 339 4914 +f 4841 4914 1309 +f 4913 4914 4841 +f 667 4915 4839 +f 4915 481 4916 +f 4839 4916 958 +f 4915 4916 4839 +f 786 4768 4917 +f 4768 278 4759 +f 4917 4759 854 +f 4768 4759 4917 +f 786 4917 4919 +f 4917 854 4918 +f 4919 4918 1114 +f 4917 4918 4919 +f 796 4714 4920 +f 4714 786 4919 +f 4920 4919 1114 +f 4714 4919 4920 +f 1309 4921 4842 +f 4921 481 4922 +f 4842 4922 1326 +f 4921 4922 4842 +f 481 4915 4922 +f 4915 667 4648 +f 4922 4648 1326 +f 4915 4648 4922 +f 89 4848 4924 +f 4848 507 4923 +f 4924 4923 1335 +f 4848 4923 4924 +f 886 4851 4849 +f 4851 493 4925 +f 4849 4925 1253 +f 4851 4925 4849 +f 89 4926 4850 +f 4926 961 4927 +f 4850 4927 1297 +f 4926 4927 4850 +f 108 4928 4854 +f 4928 493 4852 +f 4854 4852 1474 +f 4928 4852 4854 +f 961 4929 4927 +f 4929 32 4775 +f 4927 4775 1297 +f 4929 4775 4927 +f 940 4930 4857 +f 4930 1398 4931 +f 4857 4931 1496 +f 4930 4931 4857 +f 1014 4778 4656 +f 4778 324 4932 +f 4656 4932 1024 +f 4778 4932 4656 +f 532 4933 4935 +f 4933 324 4934 +f 4935 4934 1120 +f 4933 4934 4935 +f 324 4777 4934 +f 4777 164 4936 +f 4934 4936 1120 +f 4777 4936 4934 +f 164 4723 4936 +f 4723 1076 4937 +f 4936 4937 1120 +f 4723 4937 4936 +f 33 4938 4939 +f 4938 922 4783 +f 4939 4783 1388 +f 4938 4783 4939 +f 33 4940 4938 +f 4940 914 4941 +f 4938 4941 922 +f 4940 4941 4938 +f 1298 4868 4669 +f 4868 182 4942 +f 4669 4942 1462 +f 4868 4942 4669 +f 1045 4725 4943 +f 4725 157 4872 +f 4943 4872 1458 +f 4725 4872 4943 +f 189 4727 4944 +f 4727 1089 4671 +f 4944 4671 1462 +f 4727 4671 4944 +f 827 4875 4945 +f 4875 189 4944 +f 4945 4944 1462 +f 4875 4944 4945 +f 46 4946 4871 +f 4946 443 4947 +f 4871 4947 1458 +f 4946 4947 4871 +f 443 4946 4948 +f 4946 46 4676 +f 4948 4676 1461 +f 4946 4676 4948 +f 443 4949 4951 +f 4949 52 4950 +f 4951 4950 769 +f 4949 4950 4951 +f 52 4949 4792 +f 4949 443 4948 +f 4792 4948 1461 +f 4949 4948 4792 +f 769 4950 4952 +f 4950 52 4794 +f 4952 4794 1486 +f 4950 4794 4952 +f 847 4953 4793 +f 4953 432 4954 +f 4793 4954 1486 +f 4953 4954 4793 +f 413 4955 4591 +f 4955 432 4953 +f 4591 4953 847 +f 4955 4953 4591 +f 367 4799 4878 +f 4799 317 4956 +f 4878 4956 708 +f 4799 4956 4878 +f 413 4683 4957 +f 4683 513 4802 +f 4957 4802 1433 +f 4683 4802 4957 +f 432 4955 4958 +f 4955 413 4957 +f 4958 4957 1433 +f 4955 4957 4958 +f 229 4880 4960 +f 4880 708 4959 +f 4960 4959 1478 +f 4880 4959 4960 +f 716 4684 4961 +f 4684 86 4882 +f 4961 4882 916 +f 4684 4882 4961 +f 447 4732 4963 +f 4732 892 4962 +f 4963 4962 1377 +f 4732 4962 4963 +f 949 4964 4808 +f 4964 1132 4965 +f 4808 4965 1250 +f 4964 4965 4808 +f 1132 4966 4965 +f 4966 809 4603 +f 4965 4603 1250 +f 4966 4603 4965 +f 723 4967 4812 +f 4967 10 4743 +f 4812 4743 1288 +f 4967 4743 4812 +f 494 4809 4968 +f 4809 10 4967 +f 4968 4967 723 +f 4809 4967 4968 +f 949 4528 4964 +f 4528 610 4969 +f 4964 4969 1132 +f 4528 4969 4964 +f 494 4970 4813 +f 4970 454 4815 +f 4813 4815 688 +f 4970 4815 4813 +f 687 4971 4543 +f 4971 238 4891 +f 4543 4891 822 +f 4971 4891 4543 +f 238 4971 4973 +f 4971 687 4972 +f 4973 4972 702 +f 4971 4972 4973 +f 319 4974 4894 +f 4974 297 4975 +f 4894 4975 823 +f 4974 4975 4894 +f 125 4693 4976 +f 4693 1303 4893 +f 4976 4893 1358 +f 4693 4893 4976 +f 297 4974 4977 +f 4974 319 4899 +f 4977 4899 1330 +f 4974 4899 4977 +f 702 4972 4978 +f 4972 687 4612 +f 4978 4612 912 +f 4972 4612 4978 +f 942 4979 4981 +f 4979 677 4980 +f 4981 4980 1322 +f 4979 4980 4981 +f 684 4982 4984 +f 4982 745 4983 +f 4984 4983 1289 +f 4982 4983 4984 +f 745 4985 4983 +f 4985 640 4986 +f 4983 4986 1289 +f 4985 4986 4983 +f 560 4987 4988 +f 4987 800 4826 +f 4988 4826 1099 +f 4987 4826 4988 +f 81 4989 4990 +f 4989 560 4988 +f 4990 4988 1099 +f 4989 4988 4990 +f 285 4829 4992 +f 4829 1196 4991 +f 4992 4991 1409 +f 4829 4991 4992 +f 1292 4832 4994 +f 4832 718 4993 +f 4994 4993 1371 +f 4832 4993 4994 +f 1292 4994 4996 +f 4994 1371 4995 +f 4996 4995 1418 +f 4994 4995 4996 +f 1082 4628 4906 +f 4628 654 4997 +f 4906 4997 1257 +f 4628 4997 4906 +f 617 4834 4998 +f 4834 1292 4996 +f 4998 4996 1418 +f 4834 4996 4998 +f 263 4702 5000 +f 4702 617 4999 +f 5000 4999 1187 +f 4702 4999 5000 +f 154 5001 5002 +f 5001 654 4756 +f 5002 4756 1457 +f 5001 4756 5002 +f 803 5003 4908 +f 5003 957 5004 +f 4908 5004 1457 +f 5003 5004 4908 +f 215 4837 5006 +f 4837 417 5005 +f 5006 5005 1187 +f 4837 5005 5006 +f 417 4633 5005 +f 4633 263 5000 +f 5005 5000 1187 +f 4633 5000 5005 +f 803 4763 5008 +f 4763 749 5007 +f 5008 5007 985 +f 4763 5007 5008 +f 910 5009 4912 +f 5009 1057 4847 +f 4912 4847 1252 +f 5009 4847 4912 +f 749 4712 5007 +f 4712 796 5010 +f 5007 5010 985 +f 4712 5010 5007 +f 985 5010 5011 +f 5010 796 4920 +f 5011 4920 1114 +f 5010 4920 5011 +f 507 4845 4923 +f 4845 1057 5012 +f 4923 5012 1335 +f 4845 5012 4923 +f 493 5013 4925 +f 5013 392 4843 +f 4925 4843 1253 +f 5013 4843 4925 +f 961 4926 5014 +f 4926 89 4924 +f 5014 4924 1335 +f 4926 4924 5014 +f 493 4928 5016 +f 4928 108 5015 +f 5016 5015 692 +f 4928 5015 5016 +f 32 4929 5018 +f 4929 961 5017 +f 5018 5017 1398 +f 4929 5017 5018 +f 940 4855 4930 +f 4855 32 5018 +f 4930 5018 1398 +f 4855 5018 4930 +f 872 5019 5020 +f 5019 108 4856 +f 5020 4856 1024 +f 5019 4856 5020 +f 324 5021 4932 +f 5021 872 5020 +f 4932 5020 1024 +f 5021 5020 4932 +f 747 5022 5023 +f 5022 1388 4861 +f 5023 4861 1496 +f 5022 4861 5023 +f 997 5024 5025 +f 5024 1118 4866 +f 5025 4866 1316 +f 5024 4866 5025 +f 337 5026 5027 +f 5026 997 5025 +f 5027 5025 1316 +f 5026 5025 5027 +f 182 5028 5030 +f 5028 914 5029 +f 5030 5029 1013 +f 5028 5029 5030 +f 914 5028 4941 +f 5028 182 4867 +f 4941 4867 922 +f 5028 4867 4941 +f 1045 5031 4869 +f 5031 337 5027 +f 4869 5027 1316 +f 5031 5027 4869 +f 119 5032 5034 +f 5032 914 5033 +f 5034 5033 1276 +f 5032 5033 5034 +f 914 5035 5033 +f 5035 58 5036 +f 5033 5036 1276 +f 5035 5036 5033 +f 819 5037 5039 +f 5037 236 5038 +f 5039 5038 1443 +f 5037 5038 5039 +f 827 5040 4874 +f 5040 1362 5041 +f 4874 5041 1422 +f 5040 5041 4874 +f 115 5042 5044 +f 5042 562 5043 +f 5044 5043 1486 +f 5042 5043 5044 +f 317 4801 5045 +f 4801 1382 4877 +f 5045 4877 1443 +f 4801 4877 5045 +f 892 4805 5046 +f 4805 229 4960 +f 5046 4960 1478 +f 4805 4960 5046 +f 716 5047 4804 +f 5047 309 5048 +f 4804 5048 1433 +f 5047 5048 4804 +f 309 5047 5049 +f 5047 716 4961 +f 5049 4961 916 +f 5047 4961 5049 +f 733 4736 5050 +f 4736 447 4963 +f 5050 4963 1377 +f 4736 4963 5050 +f 820 5051 4881 +f 5051 851 5052 +f 4881 5052 916 +f 5051 5052 4881 +f 851 5051 5053 +f 5051 820 4883 +f 5053 4883 866 +f 5051 4883 5053 +f 866 4806 5054 +f 4806 733 5050 +f 5054 5050 1377 +f 4806 5050 5054 +f 454 5055 4892 +f 5055 551 5056 +f 4892 5056 1358 +f 5055 5056 4892 +f 305 5057 5058 +f 5057 238 4973 +f 5058 4973 702 +f 5057 4973 5058 +f 702 4978 5060 +f 4978 912 5059 +f 5060 5059 1173 +f 4978 5059 5060 +f 408 5061 5063 +f 5061 1358 5062 +f 5063 5062 1363 +f 5061 5062 5063 +f 408 4747 5061 +f 4747 125 4976 +f 5061 4976 1358 +f 4747 4976 5061 +f 1103 5064 5065 +f 5064 408 5063 +f 5065 5063 1363 +f 5064 5063 5065 +f 57 5066 5068 +f 5066 519 5067 +f 5068 5067 1173 +f 5066 5067 5068 +f 745 4902 5070 +f 4902 765 5069 +f 5070 5069 1200 +f 4902 5069 5070 +f 640 5071 4986 +f 5071 306 5072 +f 4986 5072 1289 +f 5071 5072 4986 +f 1287 5073 5074 +f 5073 285 4992 +f 5074 4992 1409 +f 5073 4992 5074 +f 1371 4993 5076 +f 4993 718 5075 +f 5076 5075 1435 +f 4993 5075 5076 +f 1196 4907 4991 +f 4907 1257 5077 +f 4991 5077 1409 +f 4907 5077 4991 +f 654 5001 4997 +f 5001 154 5078 +f 4997 5078 1257 +f 5001 5078 4997 +f 477 5079 5080 +f 5079 617 4998 +f 5080 4998 1418 +f 5079 4998 5080 +f 617 5079 4999 +f 5079 477 5081 +f 4999 5081 1187 +f 5079 5081 4999 +f 339 5082 5084 +f 5082 215 5083 +f 5084 5083 1241 +f 5082 5083 5084 +f 215 5082 4838 +f 5082 339 4913 +f 4838 4913 877 +f 5082 4913 4838 +f 136 4835 5085 +f 4835 618 4767 +f 5085 4767 1477 +f 4835 4767 5085 +f 136 5086 4836 +f 5086 143 5087 +f 4836 5087 854 +f 5086 5087 4836 +f 339 5088 4914 +f 5088 368 5089 +f 4914 5089 1309 +f 5088 5089 4914 +f 910 4909 5091 +f 4909 958 5090 +f 5091 5090 1040 +f 4909 5090 5091 +f 854 5087 4918 +f 5087 143 5092 +f 4918 5092 1114 +f 5087 5092 4918 +f 481 4921 5094 +f 4921 1309 5093 +f 5094 5093 1325 +f 4921 5093 5094 +f 958 4916 5095 +f 4916 481 5094 +f 5095 5094 1325 +f 4916 5094 5095 +f 918 5096 5097 +f 5096 985 5011 +f 5097 5011 1114 +f 5096 5011 5097 +f 392 5013 5099 +f 5013 493 5098 +f 5099 5098 927 +f 5013 5098 5099 +f 493 5016 5098 +f 5016 692 5100 +f 5098 5100 927 +f 5016 5100 5098 +f 692 5015 5101 +f 5015 108 5019 +f 5101 5019 872 +f 5015 5019 5101 +f 961 5102 5017 +f 5102 619 5103 +f 5017 5103 1398 +f 5102 5103 5017 +f 324 4933 5021 +f 4933 532 5104 +f 5021 5104 872 +f 4933 5104 5021 +f 1398 5105 4931 +f 5105 747 5023 +f 4931 5023 1496 +f 5105 5023 4931 +f 532 4935 5107 +f 4935 1120 5106 +f 5107 5106 1361 +f 4935 5106 5107 +f 747 5108 5022 +f 5108 1384 5109 +f 5022 5109 1388 +f 5108 5109 5022 +f 1120 4937 5111 +f 4937 1076 5110 +f 5111 5110 1123 +f 4937 5110 5111 +f 914 4940 5113 +f 4940 33 5112 +f 5113 5112 1130 +f 4940 5112 5113 +f 58 5035 5114 +f 5035 914 5113 +f 5114 5113 1130 +f 5035 5113 5114 +f 914 5032 5029 +f 5032 119 5115 +f 5029 5115 1013 +f 5032 5115 5029 +f 1013 5116 5118 +f 5116 1148 5117 +f 5118 5117 1462 +f 5116 5117 5118 +f 182 5030 4942 +f 5030 1013 5118 +f 4942 5118 1462 +f 5030 5118 4942 +f 337 5031 5119 +f 5031 1045 4943 +f 5119 4943 1458 +f 5031 4943 5119 +f 924 5120 5122 +f 5120 561 5121 +f 5122 5121 1118 +f 5120 5121 5122 +f 58 5123 5036 +f 5123 819 5124 +f 5036 5124 1276 +f 5123 5124 5036 +f 819 5125 5124 +f 5125 119 5034 +f 5124 5034 1276 +f 5125 5034 5124 +f 1148 5126 5117 +f 5126 827 4945 +f 5117 4945 1462 +f 5126 4945 5117 +f 562 5042 5128 +f 5042 115 5127 +f 5128 5127 924 +f 5042 5127 5128 +f 115 5129 5127 +f 5129 561 5120 +f 5127 5120 924 +f 5129 5120 5127 +f 58 5130 5123 +f 5130 236 5037 +f 5123 5037 819 +f 5130 5037 5123 +f 443 4951 4947 +f 4951 769 5131 +f 4947 5131 1458 +f 4951 5131 4947 +f 562 5132 5043 +f 5132 769 4952 +f 5043 4952 1486 +f 5132 4952 5043 +f 562 5133 5132 +f 5133 114 5134 +f 5132 5134 769 +f 5133 5134 5132 +f 1422 5041 4876 +f 5041 1362 5135 +f 4876 5135 1443 +f 5041 5135 4876 +f 1362 5136 5135 +f 5136 819 5039 +f 5135 5039 1443 +f 5136 5039 5135 +f 236 5137 5038 +f 5137 1264 5138 +f 5038 5138 1443 +f 5137 5138 5038 +f 421 5139 5140 +f 5139 115 5044 +f 5140 5044 1486 +f 5139 5044 5140 +f 1264 5141 5138 +f 5141 317 5045 +f 5138 5045 1443 +f 5141 5045 5138 +f 309 5142 5048 +f 5142 1397 5143 +f 5048 5143 1433 +f 5142 5143 5048 +f 262 5144 5146 +f 5144 1132 5145 +f 5146 5145 1426 +f 5144 5145 5146 +f 262 5147 5144 +f 5147 809 4966 +f 5144 4966 1132 +f 5147 4966 5144 +f 466 5148 5149 +f 5148 494 4968 +f 5149 4968 723 +f 5148 4968 5149 +f 466 5150 5148 +f 5150 454 4970 +f 5148 4970 494 +f 5150 4970 5148 +f 610 4744 5152 +f 4744 823 5151 +f 5152 5151 1426 +f 4744 5151 5152 +f 823 5153 5151 +f 5153 135 5154 +f 5151 5154 1426 +f 5153 5154 5151 +f 1132 4969 5145 +f 4969 610 5152 +f 5145 5152 1426 +f 4969 5152 5145 +f 475 5155 4897 +f 5155 262 5156 +f 4897 5156 753 +f 5155 5156 4897 +f 262 5155 5147 +f 5155 475 4885 +f 5147 4885 809 +f 5155 4885 5147 +f 723 4887 5158 +f 4887 183 5157 +f 5158 5157 1176 +f 4887 5157 5158 +f 183 4889 5157 +f 4889 238 5159 +f 5157 5159 1176 +f 4889 5159 5157 +f 238 5057 5159 +f 5057 305 5160 +f 5159 5160 1176 +f 5057 5160 5159 +f 695 4896 5162 +f 4896 753 5161 +f 5162 5161 1209 +f 4896 5161 5162 +f 1140 5163 5164 +f 5163 702 5060 +f 5164 5060 1173 +f 5163 5060 5164 +f 471 5165 5167 +f 5165 331 5166 +f 5167 5166 1289 +f 5165 5166 5167 +f 306 5168 5072 +f 5168 471 5167 +f 5072 5167 1289 +f 5168 5167 5072 +f 766 5169 5170 +f 5169 1287 5074 +f 5170 5074 1409 +f 5169 5074 5170 +f 828 5171 5172 +f 5171 154 5002 +f 5172 5002 1457 +f 5171 5002 5172 +f 455 5173 5175 +f 5173 190 5174 +f 5175 5174 803 +f 5173 5174 5175 +f 455 5175 5176 +f 5175 803 5008 +f 5176 5008 985 +f 5175 5008 5176 +f 1172 5177 5178 +f 5177 136 5085 +f 5178 5085 1477 +f 5177 5085 5178 +f 143 5086 5179 +f 5086 136 5177 +f 5179 5177 1172 +f 5086 5177 5179 +f 368 5088 5181 +f 5088 339 5180 +f 5181 5180 516 +f 5088 5180 5181 +f 927 5182 5183 +f 5182 1172 5178 +f 5183 5178 1477 +f 5182 5178 5183 +f 392 5099 4844 +f 5099 927 5183 +f 4844 5183 1477 +f 5099 5183 4844 +f 910 5091 5009 +f 5091 1040 5184 +f 5009 5184 1057 +f 5091 5184 5009 +f 143 5185 5092 +f 5185 918 5097 +f 5092 5097 1114 +f 5185 5097 5092 +f 918 5185 5186 +f 5185 143 5179 +f 5186 5179 1172 +f 5185 5179 5186 +f 1309 5089 5093 +f 5089 368 5187 +f 5093 5187 1325 +f 5089 5187 5093 +f 1040 5090 5188 +f 5090 958 5095 +f 5188 5095 1325 +f 5090 5095 5188 +f 1040 5189 5184 +f 5189 78 5190 +f 5184 5190 1057 +f 5189 5190 5184 +f 1057 5190 5012 +f 5190 78 5191 +f 5012 5191 1335 +f 5190 5191 5012 +f 927 5100 5193 +f 5100 692 5192 +f 5193 5192 1265 +f 5100 5192 5193 +f 78 5194 5191 +f 5194 619 5195 +f 5191 5195 1335 +f 5194 5195 5191 +f 619 5102 5195 +f 5102 961 5014 +f 5195 5014 1335 +f 5102 5014 5195 +f 692 5101 5192 +f 5101 872 5196 +f 5192 5196 1265 +f 5101 5196 5192 +f 1265 5196 5198 +f 5196 872 5197 +f 5198 5197 1361 +f 5196 5197 5198 +f 872 5104 5197 +f 5104 532 5107 +f 5197 5107 1361 +f 5104 5107 5197 +f 151 5199 5200 +f 5199 747 5105 +f 5200 5105 1398 +f 5199 5105 5200 +f 1120 5111 5106 +f 5111 1123 5201 +f 5106 5201 1361 +f 5111 5201 5106 +f 747 5199 5108 +f 5199 151 5202 +f 5108 5202 1384 +f 5199 5202 5108 +f 1384 5203 5109 +f 5203 1130 5204 +f 5109 5204 1388 +f 5203 5204 5109 +f 761 5205 4862 +f 5205 811 5206 +f 4862 5206 1076 +f 5205 5206 4862 +f 1076 5206 5110 +f 5206 811 5207 +f 5110 5207 1123 +f 5206 5207 5110 +f 1130 5112 5204 +f 5112 33 4939 +f 5204 4939 1388 +f 5112 4939 5204 +f 811 5205 5208 +f 5205 761 4864 +f 5208 4864 1118 +f 5205 4864 5208 +f 561 5209 5121 +f 5209 811 5208 +f 5121 5208 1118 +f 5209 5208 5121 +f 11 5210 5211 +f 5210 924 5122 +f 5211 5122 1118 +f 5210 5122 5211 +f 997 5212 5024 +f 5212 11 5211 +f 5024 5211 1118 +f 5212 5211 5024 +f 997 5026 5213 +f 5026 337 5119 +f 5213 5119 1458 +f 5026 5119 5213 +f 614 5214 5215 +f 5214 11 5212 +f 5215 5212 997 +f 5214 5212 5215 +f 11 5214 5210 +f 5214 614 5216 +f 5210 5216 924 +f 5214 5216 5210 +f 119 5217 5115 +f 5217 150 5218 +f 5115 5218 1013 +f 5217 5218 5115 +f 614 5215 5219 +f 5215 997 5213 +f 5219 5213 1458 +f 5215 5213 5219 +f 150 5217 5220 +f 5217 119 5125 +f 5220 5125 819 +f 5217 5125 5220 +f 614 5221 5216 +f 5221 562 5128 +f 5216 5128 924 +f 5221 5128 5216 +f 150 5220 5222 +f 5220 819 5136 +f 5222 5136 1362 +f 5220 5136 5222 +f 827 5126 5040 +f 5126 1148 5223 +f 5040 5223 1362 +f 5126 5223 5040 +f 114 5224 5134 +f 5224 614 5225 +f 5134 5225 769 +f 5224 5225 5134 +f 769 5225 5131 +f 5225 614 5219 +f 5131 5219 1458 +f 5225 5219 5131 +f 114 5133 5224 +f 5133 562 5221 +f 5224 5221 614 +f 5133 5221 5224 +f 236 5130 5226 +f 5130 58 5114 +f 5226 5114 1130 +f 5130 5114 5226 +f 432 5227 4954 +f 5227 421 5140 +f 4954 5140 1486 +f 5227 5140 4954 +f 1397 5228 5143 +f 5228 432 4958 +f 5143 4958 1433 +f 5228 4958 5143 +f 708 5229 4959 +f 5229 1355 5230 +f 4959 5230 1478 +f 5229 5230 4959 +f 354 5231 5232 +f 5231 866 5054 +f 5232 5054 1377 +f 5231 5054 5232 +f 354 5233 5231 +f 5233 851 5053 +f 5231 5053 866 +f 5233 5053 5231 +f 1192 5234 5235 +f 5234 262 5146 +f 5235 5146 1426 +f 5234 5146 5235 +f 1016 5236 5237 +f 5236 723 5158 +f 5237 5158 1176 +f 5236 5158 5237 +f 466 5149 5238 +f 5149 723 5236 +f 5238 5236 1016 +f 5149 5236 5238 +f 454 5150 5055 +f 5150 466 5239 +f 5055 5239 551 +f 5150 5239 5055 +f 262 5240 5156 +f 5240 282 5241 +f 5156 5241 753 +f 5240 5241 5156 +f 753 5241 5161 +f 5241 282 5242 +f 5161 5242 1209 +f 5241 5242 5161 +f 551 5243 5056 +f 5243 909 5244 +f 5056 5244 1358 +f 5243 5244 5056 +f 823 4975 5246 +f 4975 297 5245 +f 5246 5245 1416 +f 4975 5245 5246 +f 305 5058 5248 +f 5058 702 5247 +f 5248 5247 925 +f 5058 5247 5248 +f 305 5248 5160 +f 5248 925 5249 +f 5160 5249 1176 +f 5248 5249 5160 +f 1358 5244 5062 +f 5244 909 5250 +f 5062 5250 1363 +f 5244 5250 5062 +f 297 4977 5245 +f 4977 1330 5251 +f 5245 5251 1416 +f 4977 5251 5245 +f 925 5247 5252 +f 5247 702 5163 +f 5252 5163 1140 +f 5247 5163 5252 +f 1363 5250 5254 +f 5250 909 5253 +f 5254 5253 1364 +f 5250 5253 5254 +f 327 5255 5256 +f 5255 1363 5254 +f 5256 5254 1364 +f 5255 5254 5256 +f 782 5257 5258 +f 5257 745 5070 +f 5258 5070 1200 +f 5257 5070 5258 +f 578 5259 5261 +f 5259 327 5260 +f 5261 5260 1235 +f 5259 5260 5261 +f 640 5262 5264 +f 5262 771 5263 +f 5264 5263 986 +f 5262 5263 5264 +f 1235 5265 5267 +f 5265 576 5266 +f 5267 5266 1435 +f 5265 5266 5267 +f 306 5268 5270 +f 5268 986 5269 +f 5270 5269 1304 +f 5268 5269 5270 +f 307 5271 5272 +f 5271 1371 5076 +f 5272 5076 1435 +f 5271 5076 5272 +f 215 5006 5083 +f 5006 1187 5273 +f 5083 5273 1241 +f 5006 5273 5083 +f 1187 5274 5273 +f 5274 1101 5275 +f 5273 5275 1241 +f 5274 5275 5273 +f 803 5174 5003 +f 5174 190 5276 +f 5003 5276 957 +f 5174 5276 5003 +f 516 5180 5277 +f 5180 339 5084 +f 5277 5084 1241 +f 5180 5084 5277 +f 122 5278 5279 +f 5278 516 5277 +f 5279 5277 1241 +f 5278 5277 5279 +f 750 5280 5281 +f 5280 455 5176 +f 5281 5176 985 +f 5280 5176 5281 +f 918 5282 5096 +f 5282 750 5281 +f 5096 5281 985 +f 5282 5281 5096 +f 455 5280 5284 +f 5280 750 5283 +f 5284 5283 1489 +f 5280 5283 5284 +f 368 5181 5286 +f 5181 516 5285 +f 5286 5285 1259 +f 5181 5285 5286 +f 927 5287 5182 +f 5287 1007 5288 +f 5182 5288 1172 +f 5287 5288 5182 +f 222 5289 5290 +f 5289 918 5186 +f 5290 5186 1172 +f 5289 5186 5290 +f 222 5291 5289 +f 5291 750 5282 +f 5289 5282 918 +f 5291 5282 5289 +f 368 5286 5187 +f 5286 1259 5292 +f 5187 5292 1325 +f 5286 5292 5187 +f 78 5293 5194 +f 5293 359 5294 +f 5194 5294 619 +f 5293 5294 5194 +f 359 5293 5295 +f 5293 78 5189 +f 5295 5189 1040 +f 5293 5189 5295 +f 1007 5287 5296 +f 5287 927 5193 +f 5296 5193 1265 +f 5287 5193 5296 +f 1007 5297 5288 +f 5297 222 5290 +f 5288 5290 1172 +f 5297 5290 5288 +f 750 5291 5298 +f 5291 222 5297 +f 5298 5297 1007 +f 5291 5297 5298 +f 1259 5299 5292 +f 5299 359 5300 +f 5292 5300 1325 +f 5299 5300 5292 +f 359 5295 5300 +f 5295 1040 5188 +f 5300 5188 1325 +f 5295 5188 5300 +f 526 5301 5302 +f 5301 359 5299 +f 5302 5299 1259 +f 5301 5299 5302 +f 750 5298 5283 +f 5298 1007 5303 +f 5283 5303 1489 +f 5298 5303 5283 +f 359 5301 5294 +f 5301 526 5304 +f 5294 5304 619 +f 5301 5304 5294 +f 526 5302 5306 +f 5302 1259 5305 +f 5306 5305 1384 +f 5302 5305 5306 +f 1007 5307 5303 +f 5307 1361 5308 +f 5303 5308 1489 +f 5307 5308 5303 +f 1007 5296 5307 +f 5296 1265 5198 +f 5307 5198 1361 +f 5296 5198 5307 +f 526 5309 5304 +f 5309 151 5310 +f 5304 5310 619 +f 5309 5310 5304 +f 151 5309 5202 +f 5309 526 5306 +f 5202 5306 1384 +f 5309 5306 5202 +f 619 5310 5103 +f 5310 151 5200 +f 5103 5200 1398 +f 5310 5200 5103 +f 561 5311 5209 +f 5311 304 5312 +f 5209 5312 811 +f 5311 5312 5209 +f 1013 5218 5116 +f 5218 150 5313 +f 5116 5313 1148 +f 5218 5313 5116 +f 1148 5313 5223 +f 5313 150 5222 +f 5223 5222 1362 +f 5313 5222 5223 +f 115 5314 5129 +f 5314 304 5311 +f 5129 5311 561 +f 5314 5311 5129 +f 236 5226 5137 +f 5226 1130 5315 +f 5137 5315 1264 +f 5226 5315 5137 +f 304 5314 5316 +f 5314 115 5139 +f 5316 5139 421 +f 5314 5139 5316 +f 304 5316 5318 +f 5316 421 5317 +f 5318 5317 921 +f 5316 5317 5318 +f 421 5227 5317 +f 5227 432 5319 +f 5317 5319 921 +f 5227 5319 5317 +f 708 4956 5229 +f 4956 317 5320 +f 5229 5320 1355 +f 4956 5320 5229 +f 1377 4962 5321 +f 4962 892 5046 +f 5321 5046 1478 +f 4962 5046 5321 +f 406 5322 5323 +f 5322 1377 5321 +f 5323 5321 1478 +f 5322 5321 5323 +f 200 5324 5325 +f 5324 309 5049 +f 5325 5049 916 +f 5324 5049 5325 +f 406 5326 5322 +f 5326 354 5232 +f 5322 5232 1377 +f 5326 5232 5322 +f 135 5327 5154 +f 5327 1192 5235 +f 5154 5235 1426 +f 5327 5235 5154 +f 551 5239 5328 +f 5239 466 5238 +f 5328 5238 1016 +f 5239 5238 5328 +f 282 5329 5331 +f 5329 1192 5330 +f 5331 5330 1424 +f 5329 5330 5331 +f 282 5240 5329 +f 5240 262 5234 +f 5329 5234 1192 +f 5240 5234 5329 +f 135 5153 5332 +f 5153 823 5246 +f 5332 5246 1416 +f 5153 5246 5332 +f 1192 5327 5333 +f 5327 135 5332 +f 5333 5332 1416 +f 5327 5332 5333 +f 1416 5334 5336 +f 5334 341 5335 +f 5336 5335 1450 +f 5334 5335 5336 +f 418 5337 5338 +f 5337 925 5252 +f 5338 5252 1140 +f 5337 5252 5338 +f 771 5339 5263 +f 5339 583 5340 +f 5263 5340 986 +f 5339 5340 5263 +f 766 5341 5169 +f 5341 928 5342 +f 5169 5342 1287 +f 5341 5342 5169 +f 1084 5343 5345 +f 5343 331 5344 +f 5345 5344 1284 +f 5343 5344 5345 +f 48 5346 5347 +f 5346 307 5272 +f 5347 5272 1435 +f 5346 5272 5347 +f 576 5348 5266 +f 5348 48 5347 +f 5266 5347 1435 +f 5348 5347 5266 +f 75 5349 5350 +f 5349 766 5170 +f 5350 5170 1409 +f 5349 5170 5350 +f 307 5351 5271 +f 5351 1236 5352 +f 5271 5352 1371 +f 5351 5352 5271 +f 1371 5353 4995 +f 5353 267 5354 +f 4995 5354 1418 +f 5353 5354 4995 +f 444 5355 5356 +f 5355 190 5173 +f 5356 5173 455 +f 5355 5173 5356 +f 335 5357 5358 +f 5357 455 5284 +f 5358 5284 1489 +f 5357 5284 5358 +f 516 5278 5285 +f 5278 122 5359 +f 5285 5359 1259 +f 5278 5359 5285 +f 1229 5360 5362 +f 5360 435 5361 +f 5362 5361 1384 +f 5360 5361 5362 +f 122 5363 5364 +f 5363 1229 5362 +f 5364 5362 1384 +f 5363 5362 5364 +f 1259 5359 5305 +f 5359 122 5364 +f 5305 5364 1384 +f 5359 5364 5305 +f 1123 5365 5367 +f 5365 835 5366 +f 5367 5366 1489 +f 5365 5366 5367 +f 1361 5201 5308 +f 5201 1123 5367 +f 5308 5367 1489 +f 5201 5367 5308 +f 811 5368 5207 +f 5368 835 5365 +f 5207 5365 1123 +f 5368 5365 5207 +f 435 5369 5361 +f 5369 1315 5370 +f 5361 5370 1384 +f 5369 5370 5361 +f 1315 5371 5370 +f 5371 1130 5203 +f 5370 5203 1384 +f 5371 5203 5370 +f 1130 5372 5315 +f 5372 793 5373 +f 5315 5373 1264 +f 5372 5373 5315 +f 317 5141 5320 +f 5141 1264 5374 +f 5320 5374 1355 +f 5141 5374 5320 +f 1355 5375 5230 +f 5375 231 5376 +f 5230 5376 1478 +f 5375 5376 5230 +f 309 5377 5142 +f 5377 904 5378 +f 5142 5378 1397 +f 5377 5378 5142 +f 851 5379 5052 +f 5379 200 5325 +f 5052 5325 916 +f 5379 5325 5052 +f 374 5380 5381 +f 5380 200 5379 +f 5381 5379 851 +f 5380 5379 5381 +f 354 5382 5233 +f 5382 374 5381 +f 5233 5381 851 +f 5382 5381 5233 +f 1192 5333 5330 +f 5333 1416 5383 +f 5330 5383 1424 +f 5333 5383 5330 +f 1209 5242 5384 +f 5242 282 5331 +f 5384 5331 1424 +f 5242 5331 5384 +f 767 5385 5386 +f 5385 1016 5237 +f 5386 5237 1176 +f 5385 5237 5386 +f 925 5387 5249 +f 5387 767 5386 +f 5249 5386 1176 +f 5387 5386 5249 +f 767 5388 5385 +f 5388 909 5389 +f 5385 5389 1016 +f 5388 5389 5385 +f 909 5243 5389 +f 5243 551 5328 +f 5389 5328 1016 +f 5243 5328 5389 +f 909 5388 5391 +f 5388 767 5390 +f 5391 5390 1357 +f 5388 5390 5391 +f 500 5392 5393 +f 5392 1209 5384 +f 5393 5384 1424 +f 5392 5384 5393 +f 909 5391 5253 +f 5391 1357 5394 +f 5253 5394 1364 +f 5391 5394 5253 +f 925 5337 5396 +f 5337 418 5395 +f 5396 5395 1357 +f 5337 5395 5396 +f 341 5397 5335 +f 5397 1212 5398 +f 5335 5398 1450 +f 5397 5398 5335 +f 1212 5399 5398 +f 5399 326 5400 +f 5398 5400 1450 +f 5399 5400 5398 +f 186 5401 5403 +f 5401 83 5402 +f 5403 5402 1364 +f 5401 5402 5403 +f 500 5404 5406 +f 5404 326 5405 +f 5406 5405 1447 +f 5404 5405 5406 +f 782 5407 5409 +f 5407 637 5408 +f 5409 5408 1447 +f 5407 5408 5409 +f 186 5410 5412 +f 5410 158 5411 +f 5412 5411 1235 +f 5410 5411 5412 +f 583 5339 5414 +f 5339 771 5413 +f 5414 5413 782 +f 5339 5413 5414 +f 338 5415 5417 +f 5415 438 5416 +f 5417 5416 583 +f 5415 5416 5417 +f 338 5417 5419 +f 5417 583 5418 +f 5419 5418 1447 +f 5417 5418 5419 +f 901 5420 5421 +f 5420 576 5265 +f 5421 5265 1235 +f 5420 5265 5421 +f 257 5422 5424 +f 5422 901 5423 +f 5424 5423 1034 +f 5422 5423 5424 +f 451 5425 5427 +f 5425 783 5426 +f 5427 5426 928 +f 5425 5426 5427 +f 451 5428 5425 +f 5428 120 5429 +f 5425 5429 783 +f 5428 5429 5425 +f 901 5422 5431 +f 5422 257 5430 +f 5431 5430 911 +f 5422 5430 5431 +f 48 5432 5433 +f 5432 901 5431 +f 5433 5431 911 +f 5432 5431 5433 +f 764 5434 5435 +f 5434 1084 5345 +f 5435 5345 1284 +f 5434 5345 5435 +f 766 5436 5341 +f 5436 451 5427 +f 5341 5427 928 +f 5436 5427 5341 +f 471 5168 5437 +f 5168 306 5270 +f 5437 5270 1304 +f 5168 5270 5437 +f 331 5438 5344 +f 5438 775 5439 +f 5344 5439 1284 +f 5438 5439 5344 +f 331 5165 5438 +f 5165 471 5440 +f 5438 5440 775 +f 5165 5440 5438 +f 48 5433 5442 +f 5433 911 5441 +f 5442 5441 1236 +f 5433 5441 5442 +f 307 5346 5351 +f 5346 48 5442 +f 5351 5442 1236 +f 5346 5442 5351 +f 1257 5078 5444 +f 5078 154 5443 +f 5444 5443 1448 +f 5078 5443 5444 +f 149 5445 5446 +f 5445 477 5080 +f 5446 5080 1418 +f 5445 5080 5446 +f 477 5447 5081 +f 5447 291 5448 +f 5081 5448 1187 +f 5447 5448 5081 +f 957 5449 5004 +f 5449 828 5172 +f 5004 5172 1457 +f 5449 5172 5004 +f 335 5450 5357 +f 5450 444 5356 +f 5357 5356 455 +f 5450 5356 5357 +f 835 5451 5366 +f 5451 335 5358 +f 5366 5358 1489 +f 5451 5358 5366 +f 835 5368 5453 +f 5368 811 5452 +f 5453 5452 844 +f 5368 5452 5453 +f 304 5454 5312 +f 5454 486 5455 +f 5312 5455 811 +f 5454 5455 5312 +f 793 5372 5456 +f 5372 1130 5371 +f 5456 5371 1315 +f 5372 5371 5456 +f 921 5319 5457 +f 5319 432 5228 +f 5457 5228 1397 +f 5319 5228 5457 +f 231 5458 5376 +f 5458 1248 5459 +f 5376 5459 1478 +f 5458 5459 5376 +f 309 5324 5377 +f 5324 200 5460 +f 5377 5460 904 +f 5324 5460 5377 +f 1248 5461 5459 +f 5461 406 5323 +f 5459 5323 1478 +f 5461 5323 5459 +f 767 5387 5390 +f 5387 925 5396 +f 5390 5396 1357 +f 5387 5396 5390 +f 338 5462 5463 +f 5462 326 5399 +f 5463 5399 1212 +f 5462 5399 5463 +f 901 5464 5466 +f 5464 158 5465 +f 5466 5465 1261 +f 5464 5465 5466 +f 120 5467 5429 +f 5467 316 5468 +f 5429 5468 783 +f 5467 5468 5429 +f 986 5469 5269 +f 5469 316 5470 +f 5269 5470 1304 +f 5469 5470 5269 +f 257 5471 5472 +f 5471 764 5435 +f 5472 5435 1284 +f 5471 5435 5472 +f 911 5430 5473 +f 5430 257 5472 +f 5473 5472 1284 +f 5430 5472 5473 +f 120 5428 5475 +f 5428 451 5474 +f 5475 5474 1453 +f 5428 5474 5475 +f 316 5467 5476 +f 5467 120 5475 +f 5476 5475 1453 +f 5467 5475 5476 +f 1304 5470 5477 +f 5470 316 5476 +f 5477 5476 1453 +f 5470 5476 5477 +f 399 5478 5479 +f 5478 911 5473 +f 5479 5473 1284 +f 5478 5473 5479 +f 399 5480 5478 +f 5480 579 5481 +f 5478 5481 911 +f 5480 5481 5478 +f 911 5481 5441 +f 5481 579 5482 +f 5441 5482 1236 +f 5481 5482 5441 +f 741 5483 5484 +f 5483 451 5436 +f 5484 5436 766 +f 5483 5436 5484 +f 75 5485 5349 +f 5485 741 5484 +f 5349 5484 766 +f 5485 5484 5349 +f 76 5486 5487 +f 5486 1257 5444 +f 5487 5444 1448 +f 5486 5444 5487 +f 154 5171 5443 +f 5171 828 5488 +f 5443 5488 1448 +f 5171 5488 5443 +f 291 5447 5490 +f 5447 477 5489 +f 5490 5489 535 +f 5447 5489 5490 +f 957 5276 5492 +f 5276 190 5491 +f 5492 5491 1228 +f 5276 5491 5492 +f 580 5493 5494 +f 5493 122 5279 +f 5494 5279 1241 +f 5493 5279 5494 +f 122 5493 5363 +f 5493 580 5495 +f 5363 5495 1229 +f 5493 5495 5363 +f 102 5496 5497 +f 5496 335 5451 +f 5497 5451 835 +f 5496 5451 5497 +f 779 5498 5499 +f 5498 102 5497 +f 5499 5497 835 +f 5498 5497 5499 +f 435 5500 5369 +f 5500 425 5501 +f 5369 5501 1315 +f 5500 5501 5369 +f 286 5502 5503 +f 5502 835 5453 +f 5503 5453 844 +f 5502 5453 5503 +f 286 5504 5502 +f 5504 779 5499 +f 5502 5499 835 +f 5504 5499 5502 +f 425 5505 5501 +f 5505 737 5506 +f 5501 5506 1315 +f 5505 5506 5501 +f 811 5455 5452 +f 5455 486 5507 +f 5452 5507 844 +f 5455 5507 5452 +f 1270 5508 5509 +f 5508 921 5457 +f 5509 5457 1397 +f 5508 5457 5509 +f 200 5380 5511 +f 5380 374 5510 +f 5511 5510 875 +f 5380 5510 5511 +f 374 5382 5513 +f 5382 354 5512 +f 5513 5512 544 +f 5382 5512 5513 +f 544 5512 5515 +f 5512 354 5514 +f 5515 5514 1248 +f 5512 5514 5515 +f 354 5326 5514 +f 5326 406 5461 +f 5514 5461 1248 +f 5326 5461 5514 +f 451 5483 5474 +f 5483 741 5516 +f 5474 5516 1453 +f 5483 5516 5474 +f 1257 5517 5077 +f 5517 818 5518 +f 5077 5518 1409 +f 5517 5518 5077 +f 477 5445 5489 +f 5445 149 5519 +f 5489 5519 535 +f 5445 5519 5489 +f 828 5520 5488 +f 5520 160 5521 +f 5488 5521 1448 +f 5520 5521 5488 +f 1101 5522 5524 +f 5522 291 5523 +f 5524 5523 1485 +f 5522 5523 5524 +f 828 5449 5525 +f 5449 957 5492 +f 5525 5492 1228 +f 5449 5492 5525 +f 194 5526 5527 +f 5526 828 5525 +f 5527 5525 1228 +f 5526 5525 5527 +f 291 5522 5448 +f 5522 1101 5274 +f 5448 5274 1187 +f 5522 5274 5448 +f 190 5355 5491 +f 5355 444 5528 +f 5491 5528 1228 +f 5355 5528 5491 +f 1101 5529 5275 +f 5529 580 5494 +f 5275 5494 1241 +f 5529 5494 5275 +f 102 5530 5532 +f 5530 415 5531 +f 5532 5531 444 +f 5530 5531 5532 +f 580 5533 5495 +f 5533 1221 5534 +f 5495 5534 1229 +f 5533 5534 5495 +f 335 5496 5450 +f 5496 102 5532 +f 5450 5532 444 +f 5496 5532 5450 +f 102 5498 5536 +f 5498 779 5535 +f 5536 5535 1062 +f 5498 5535 5536 +f 1062 5535 5538 +f 5535 779 5537 +f 5538 5537 1151 +f 5535 5537 5538 +f 1151 5539 5541 +f 5539 425 5540 +f 5541 5540 1229 +f 5539 5540 5541 +f 1062 5538 5542 +f 5538 1151 5541 +f 5542 5541 1229 +f 5538 5541 5542 +f 425 5500 5540 +f 5500 435 5360 +f 5540 5360 1229 +f 5500 5360 5540 +f 286 5543 5545 +f 5543 255 5544 +f 5545 5544 1151 +f 5543 5544 5545 +f 779 5504 5537 +f 5504 286 5545 +f 5537 5545 1151 +f 5504 5545 5537 +f 255 5546 5544 +f 5546 737 5547 +f 5544 5547 1151 +f 5546 5547 5544 +f 737 5505 5547 +f 5505 425 5539 +f 5547 5539 1151 +f 5505 5539 5547 +f 286 5503 5549 +f 5503 844 5548 +f 5549 5548 976 +f 5503 5548 5549 +f 255 5543 5550 +f 5543 286 5549 +f 5550 5549 976 +f 5543 5549 5550 +f 737 5546 5552 +f 5546 255 5551 +f 5552 5551 813 +f 5546 5551 5552 +f 737 5553 5506 +f 5553 226 5554 +f 5506 5554 1315 +f 5553 5554 5506 +f 844 5507 5548 +f 5507 486 5555 +f 5548 5555 976 +f 5507 5555 5548 +f 226 5556 5554 +f 5556 793 5456 +f 5554 5456 1315 +f 5556 5456 5554 +f 486 5454 5558 +f 5454 304 5557 +f 5558 5557 574 +f 5454 5557 5558 +f 793 5559 5373 +f 5559 44 5560 +f 5373 5560 1264 +f 5559 5560 5373 +f 574 5557 5561 +f 5557 304 5318 +f 5561 5318 921 +f 5557 5318 5561 +f 904 5562 5378 +f 5562 1270 5509 +f 5378 5509 1397 +f 5562 5509 5378 +f 904 5460 5564 +f 5460 200 5563 +f 5564 5563 1394 +f 5460 5563 5564 +f 200 5511 5563 +f 5511 875 5565 +f 5563 5565 1394 +f 5511 5565 5563 +f 374 5513 5510 +f 5513 544 5566 +f 5510 5566 875 +f 5513 5566 5510 +f 775 5567 5439 +f 5567 399 5479 +f 5439 5479 1284 +f 5567 5479 5439 +f 1048 5568 5569 +f 5568 75 5350 +f 5569 5350 1409 +f 5568 5350 5569 +f 267 5570 5354 +f 5570 149 5446 +f 5354 5446 1418 +f 5570 5446 5354 +f 1005 5571 5572 +f 5571 194 5527 +f 5572 5527 1228 +f 5571 5527 5572 +f 444 5573 5528 +f 5573 903 5574 +f 5528 5574 1228 +f 5573 5574 5528 +f 580 5529 5576 +f 5529 1101 5575 +f 5576 5575 1482 +f 5529 5575 5576 +f 444 5531 5573 +f 5531 415 5577 +f 5573 5577 903 +f 5531 5577 5573 +f 415 5578 5580 +f 5578 1062 5579 +f 5580 5579 1221 +f 5578 5579 5580 +f 415 5530 5578 +f 5530 102 5536 +f 5578 5536 1062 +f 5530 5536 5578 +f 1221 5579 5534 +f 5579 1062 5542 +f 5534 5542 1229 +f 5579 5542 5534 +f 813 5551 5581 +f 5551 255 5550 +f 5581 5550 976 +f 5551 5550 5581 +f 226 5553 5582 +f 5553 737 5552 +f 5582 5552 813 +f 5553 5552 5582 +f 976 5555 5584 +f 5555 486 5583 +f 5584 5583 1476 +f 5555 5583 5584 +f 486 5558 5583 +f 5558 574 5585 +f 5583 5585 1476 +f 5558 5585 5583 +f 574 5561 5586 +f 5561 921 5508 +f 5586 5508 1270 +f 5561 5508 5586 +f 44 5587 5560 +f 5587 946 5588 +f 5560 5588 1264 +f 5587 5588 5560 +f 1264 5588 5374 +f 5588 946 5589 +f 5374 5589 1355 +f 5588 5589 5374 +f 231 5590 5592 +f 5590 946 5591 +f 5592 5591 1392 +f 5590 5591 5592 +f 946 5590 5589 +f 5590 231 5375 +f 5589 5375 1355 +f 5590 5375 5589 +f 1270 5562 5593 +f 5562 904 5564 +f 5593 5564 1394 +f 5562 5564 5593 +f 1248 5458 5594 +f 5458 231 5592 +f 5594 5592 1392 +f 5458 5592 5594 +f 544 5515 5595 +f 5515 1248 5594 +f 5595 5594 1392 +f 5515 5594 5595 +f 775 5440 5597 +f 5440 471 5596 +f 5597 5596 817 +f 5440 5596 5597 +f 818 5598 5518 +f 5598 1048 5569 +f 5518 5569 1409 +f 5598 5569 5518 +f 76 5599 5486 +f 5599 818 5517 +f 5486 5517 1257 +f 5599 5517 5486 +f 291 5600 5523 +f 5600 1020 5601 +f 5523 5601 1485 +f 5600 5601 5523 +f 291 5490 5600 +f 5490 535 5602 +f 5600 5602 1020 +f 5490 5602 5600 +f 1221 5533 5603 +f 5533 580 5576 +f 5603 5576 1482 +f 5533 5576 5603 +f 746 5604 5605 +f 5604 44 5559 +f 5605 5559 793 +f 5604 5559 5605 +f 44 5604 5587 +f 5604 746 5606 +f 5587 5606 946 +f 5604 5606 5587 +f 574 5586 5585 +f 5586 1270 5607 +f 5585 5607 1476 +f 5586 5607 5585 +f 544 5608 5566 +f 5608 202 5609 +f 5566 5609 875 +f 5608 5609 5566 +f 202 5608 5610 +f 5608 544 5595 +f 5610 5595 1392 +f 5608 5595 5610 +f 1247 5611 5612 +f 5611 1304 5477 +f 5612 5477 1453 +f 5611 5477 5612 +f 817 5596 5613 +f 5596 471 5437 +f 5613 5437 1304 +f 5596 5437 5613 +f 1247 5614 5611 +f 5614 817 5613 +f 5611 5613 1304 +f 5614 5613 5611 +f 715 5615 5616 +f 5615 399 5567 +f 5616 5567 775 +f 5615 5567 5616 +f 280 5617 5618 +f 5617 399 5615 +f 5618 5615 715 +f 5617 5615 5618 +f 715 5616 5619 +f 5616 775 5597 +f 5619 5597 817 +f 5616 5597 5619 +f 741 5485 5620 +f 5485 75 5568 +f 5620 5568 1048 +f 5485 5568 5620 +f 169 5621 5622 +f 5621 741 5620 +f 5622 5620 1048 +f 5621 5620 5622 +f 180 5623 5625 +f 5623 856 5624 +f 5625 5624 1236 +f 5623 5624 5625 +f 856 5626 5627 +f 5626 267 5353 +f 5627 5353 1371 +f 5626 5353 5627 +f 1236 5624 5352 +f 5624 856 5627 +f 5352 5627 1371 +f 5624 5627 5352 +f 149 5570 5629 +f 5570 267 5628 +f 5629 5628 849 +f 5570 5628 5629 +f 194 5630 5526 +f 5630 160 5520 +f 5526 5520 828 +f 5630 5520 5526 +f 160 5630 5632 +f 5630 194 5631 +f 5632 5631 1197 +f 5630 5631 5632 +f 1020 5633 5601 +f 5633 188 5634 +f 5601 5634 1485 +f 5633 5634 5601 +f 1482 5575 5635 +f 5575 1101 5524 +f 5635 5524 1485 +f 5575 5524 5635 +f 903 5636 5574 +f 5636 1005 5572 +f 5574 5572 1228 +f 5636 5572 5574 +f 415 5637 5577 +f 5637 400 5638 +f 5577 5638 903 +f 5637 5638 5577 +f 400 5637 5639 +f 5637 415 5580 +f 5639 5580 1221 +f 5637 5580 5639 +f 400 5639 5640 +f 5639 1221 5603 +f 5640 5603 1482 +f 5639 5603 5640 +f 746 5641 5642 +f 5641 226 5582 +f 5642 5582 813 +f 5641 5582 5642 +f 915 5643 5644 +f 5643 976 5584 +f 5644 5584 1476 +f 5643 5584 5644 +f 226 5641 5556 +f 5641 746 5605 +f 5556 5605 793 +f 5641 5605 5556 +f 1270 5593 5607 +f 5593 1394 5645 +f 5607 5645 1476 +f 5593 5645 5607 +f 1394 5646 5645 +f 5646 842 5647 +f 5645 5647 1476 +f 5646 5647 5645 +f 946 5648 5591 +f 5648 213 5649 +f 5591 5649 1392 +f 5648 5649 5591 +f 875 5650 5565 +f 5650 842 5646 +f 5565 5646 1394 +f 5650 5646 5565 +f 202 5651 5609 +f 5651 842 5650 +f 5609 5650 875 +f 5651 5650 5609 +f 213 5652 5649 +f 5652 202 5610 +f 5649 5610 1392 +f 5652 5610 5649 +f 296 5653 5654 +f 5653 1247 5612 +f 5654 5612 1453 +f 5653 5612 5654 +f 399 5617 5480 +f 5617 280 5655 +f 5480 5655 579 +f 5617 5655 5480 +f 741 5621 5516 +f 5621 169 5656 +f 5516 5656 1453 +f 5621 5656 5516 +f 169 5657 5656 +f 5657 296 5654 +f 5656 5654 1453 +f 5657 5654 5656 +f 715 5619 5659 +f 5619 817 5658 +f 5659 5658 1068 +f 5619 5658 5659 +f 579 5660 5482 +f 5660 180 5625 +f 5482 5625 1236 +f 5660 5625 5482 +f 849 5628 5661 +f 5628 267 5626 +f 5661 5626 856 +f 5628 5626 5661 +f 818 5599 5662 +f 5599 76 5487 +f 5662 5487 1448 +f 5599 5487 5662 +f 535 5519 5663 +f 5519 149 5629 +f 5663 5629 849 +f 5519 5629 5663 +f 194 5571 5631 +f 5571 1005 5664 +f 5631 5664 1197 +f 5571 5664 5631 +f 567 5665 5666 +f 5665 1482 5635 +f 5666 5635 1485 +f 5665 5635 5666 +f 95 5667 5669 +f 5667 813 5668 +f 5669 5668 915 +f 5667 5668 5669 +f 915 5668 5643 +f 5668 813 5581 +f 5643 5581 976 +f 5668 5581 5643 +f 95 5670 5667 +f 5670 746 5642 +f 5667 5642 813 +f 5670 5642 5667 +f 469 5671 5673 +f 5671 213 5672 +f 5673 5672 746 +f 5671 5672 5673 +f 746 5672 5606 +f 5672 213 5648 +f 5606 5648 946 +f 5672 5648 5606 +f 842 5674 5647 +f 5674 915 5644 +f 5647 5644 1476 +f 5674 5644 5647 +f 202 5675 5651 +f 5675 469 5676 +f 5651 5676 842 +f 5675 5676 5651 +f 202 5652 5675 +f 5652 213 5671 +f 5675 5671 469 +f 5652 5671 5675 +f 340 5677 5678 +f 5677 817 5614 +f 5678 5614 1247 +f 5677 5614 5678 +f 817 5677 5658 +f 5677 340 5679 +f 5658 5679 1068 +f 5677 5679 5658 +f 395 5680 5681 +f 5680 818 5662 +f 5681 5662 1448 +f 5680 5662 5681 +f 535 5663 5602 +f 5663 849 5682 +f 5602 5682 1020 +f 5663 5682 5602 +f 160 5632 5521 +f 5632 1197 5683 +f 5521 5683 1448 +f 5632 5683 5521 +f 1197 5664 5685 +f 5664 1005 5684 +f 5685 5684 1386 +f 5664 5684 5685 +f 1005 5636 5687 +f 5636 903 5686 +f 5687 5686 1412 +f 5636 5686 5687 +f 903 5638 5686 +f 5638 400 5688 +f 5686 5688 1412 +f 5638 5688 5686 +f 469 5689 5690 +f 5689 95 5669 +f 5690 5669 915 +f 5689 5669 5690 +f 95 5689 5670 +f 5689 469 5673 +f 5670 5673 746 +f 5689 5673 5670 +f 842 5676 5674 +f 5676 469 5690 +f 5674 5690 915 +f 5676 5690 5674 +f 974 5691 5692 +f 5691 169 5622 +f 5692 5622 1048 +f 5691 5622 5692 +f 79 5693 5695 +f 5693 849 5694 +f 5695 5694 1127 +f 5693 5694 5695 +f 849 5661 5694 +f 5661 856 5696 +f 5694 5696 1127 +f 5661 5696 5694 +f 188 5697 5634 +f 5697 963 5698 +f 5634 5698 1485 +f 5697 5698 5634 +f 963 5699 5698 +f 5699 567 5666 +f 5698 5666 1485 +f 5699 5666 5698 +f 296 5700 5653 +f 5700 488 5701 +f 5653 5701 1247 +f 5700 5701 5653 +f 926 5702 5703 +f 5702 715 5659 +f 5703 5659 1068 +f 5702 5659 5703 +f 224 5704 5705 +f 5704 715 5702 +f 5705 5702 926 +f 5704 5702 5705 +f 224 5706 5704 +f 5706 280 5618 +f 5704 5618 715 +f 5706 5618 5704 +f 280 5707 5655 +f 5707 180 5660 +f 5655 5660 579 +f 5707 5660 5655 +f 180 5707 5709 +f 5707 280 5708 +f 5709 5708 436 +f 5707 5708 5709 +f 180 5709 5711 +f 5709 436 5710 +f 5711 5710 1127 +f 5709 5710 5711 +f 856 5623 5696 +f 5623 180 5711 +f 5696 5711 1127 +f 5623 5711 5696 +f 974 5692 5713 +f 5692 1048 5712 +f 5713 5712 1086 +f 5692 5712 5713 +f 1048 5598 5712 +f 5598 818 5714 +f 5712 5714 1086 +f 5598 5714 5712 +f 818 5680 5714 +f 5680 395 5715 +f 5714 5715 1086 +f 5680 5715 5714 +f 79 5716 5718 +f 5716 693 5717 +f 5718 5717 1020 +f 5716 5717 5718 +f 849 5693 5682 +f 5693 79 5718 +f 5682 5718 1020 +f 5693 5718 5682 +f 1197 5719 5683 +f 5719 395 5681 +f 5683 5681 1448 +f 5719 5681 5683 +f 952 5720 5721 +f 5720 567 5699 +f 5721 5699 963 +f 5720 5699 5721 +f 400 5722 5688 +f 5722 56 5723 +f 5688 5723 1412 +f 5722 5723 5688 +f 56 5722 5724 +f 5722 400 5640 +f 5724 5640 1482 +f 5722 5640 5724 +f 567 5725 5665 +f 5725 56 5724 +f 5665 5724 1482 +f 5725 5724 5665 +f 280 5706 5708 +f 5706 224 5726 +f 5708 5726 436 +f 5706 5726 5708 +f 296 5657 5727 +f 5657 169 5691 +f 5727 5691 974 +f 5657 5691 5727 +f 488 5700 5728 +f 5700 296 5727 +f 5728 5727 974 +f 5700 5727 5728 +f 340 5678 5730 +f 5678 1247 5729 +f 5730 5729 1349 +f 5678 5729 5730 +f 104 5731 5732 +f 5731 340 5730 +f 5732 5730 1349 +f 5731 5730 5732 +f 340 5731 5679 +f 5731 104 5733 +f 5679 5733 1068 +f 5731 5733 5679 +f 917 5734 5735 +f 5734 926 5703 +f 5735 5703 1068 +f 5734 5703 5735 +f 104 5736 5733 +f 5736 917 5735 +f 5733 5735 1068 +f 5736 5735 5733 +f 693 5716 5737 +f 5716 79 5695 +f 5737 5695 1127 +f 5716 5695 5737 +f 606 5738 5739 +f 5738 395 5719 +f 5739 5719 1197 +f 5738 5719 5739 +f 606 5739 5740 +f 5739 1197 5685 +f 5740 5685 1386 +f 5739 5685 5740 +f 693 5741 5717 +f 5741 963 5742 +f 5717 5742 1020 +f 5741 5742 5717 +f 963 5697 5742 +f 5697 188 5633 +f 5742 5633 1020 +f 5697 5633 5742 +f 56 5743 5745 +f 5743 315 5744 +f 5745 5744 760 +f 5743 5744 5745 +f 1386 5684 5746 +f 5684 1005 5687 +f 5746 5687 1412 +f 5684 5687 5746 +f 722 5747 5748 +f 5747 1386 5746 +f 5748 5746 1412 +f 5747 5746 5748 +f 56 5745 5723 +f 5745 760 5749 +f 5723 5749 1412 +f 5745 5749 5723 +f 315 5743 5751 +f 5743 56 5750 +f 5751 5750 952 +f 5743 5750 5751 +f 56 5725 5750 +f 5725 567 5720 +f 5750 5720 952 +f 5725 5720 5750 +f 1247 5701 5729 +f 5701 488 5752 +f 5729 5752 1349 +f 5701 5752 5729 +f 436 5726 5754 +f 5726 224 5753 +f 5754 5753 1074 +f 5726 5753 5754 +f 917 5755 5734 +f 5755 853 5756 +f 5734 5756 926 +f 5755 5756 5734 +f 853 5757 5756 +f 5757 127 5758 +f 5756 5758 926 +f 5757 5758 5756 +f 436 5754 5710 +f 5754 1074 5759 +f 5710 5759 1127 +f 5754 5759 5710 +f 232 5760 5761 +f 5760 104 5732 +f 5761 5732 1349 +f 5760 5732 5761 +f 104 5760 5736 +f 5760 232 5762 +f 5736 5762 917 +f 5760 5762 5736 +f 1074 5763 5759 +f 5763 693 5737 +f 5759 5737 1127 +f 5763 5737 5759 +f 395 5738 5715 +f 5738 606 5764 +f 5715 5764 1086 +f 5738 5764 5715 +f 232 5765 5762 +f 5765 760 5766 +f 5762 5766 917 +f 5765 5766 5762 +f 693 5767 5741 +f 5767 952 5721 +f 5741 5721 963 +f 5767 5721 5741 +f 722 5768 5747 +f 5768 606 5740 +f 5747 5740 1386 +f 5768 5740 5747 +f 760 5744 5770 +f 5744 315 5769 +f 5770 5769 853 +f 5744 5769 5770 +f 488 5771 5752 +f 5771 148 5772 +f 5752 5772 1349 +f 5771 5772 5752 +f 224 5773 5753 +f 5773 127 5774 +f 5753 5774 1074 +f 5773 5774 5753 +f 127 5773 5758 +f 5773 224 5705 +f 5758 5705 926 +f 5773 5705 5758 +f 148 5771 5775 +f 5771 488 5728 +f 5775 5728 974 +f 5771 5728 5775 +f 148 5775 5776 +f 5775 974 5713 +f 5776 5713 1086 +f 5775 5713 5776 +f 148 5776 5778 +f 5776 1086 5777 +f 5778 5777 1155 +f 5776 5777 5778 +f 148 5778 5772 +f 5778 1155 5779 +f 5772 5779 1349 +f 5778 5779 5772 +f 1086 5764 5777 +f 5764 606 5780 +f 5777 5780 1155 +f 5764 5780 5777 +f 127 5781 5774 +f 5781 72 5782 +f 5774 5782 1074 +f 5781 5782 5774 +f 1155 5783 5779 +f 5783 232 5761 +f 5779 5761 1349 +f 5783 5761 5779 +f 72 5781 5784 +f 5781 127 5757 +f 5784 5757 853 +f 5781 5757 5784 +f 606 5768 5780 +f 5768 722 5785 +f 5780 5785 1155 +f 5768 5785 5780 +f 760 5770 5766 +f 5770 853 5755 +f 5766 5755 917 +f 5770 5755 5766 +f 72 5786 5782 +f 5786 693 5763 +f 5782 5763 1074 +f 5786 5763 5782 +f 760 5765 5787 +f 5765 232 5783 +f 5787 5783 1155 +f 5765 5783 5787 +f 315 5788 5769 +f 5788 72 5784 +f 5769 5784 853 +f 5788 5784 5769 +f 722 5789 5785 +f 5789 760 5787 +f 5785 5787 1155 +f 5789 5787 5785 +f 72 5788 5790 +f 5788 315 5751 +f 5790 5751 952 +f 5788 5751 5790 +f 693 5786 5767 +f 5786 72 5790 +f 5767 5790 952 +f 5786 5790 5767 +f 760 5789 5749 +f 5789 722 5748 +f 5749 5748 1412 +f 5789 5748 5749 +f 1046 3058 5791 +f 3058 196 2539 +f 5791 2539 1299 +f 3058 2539 5791 +f 540 2660 3335 +f 2660 196 3060 +f 3335 3060 1153 +f 2660 3060 3335 +f 665 3213 5792 +f 3213 552 3062 +f 5792 3062 1182 +f 3213 3062 5792 +f 668 5793 2802 +f 5793 1046 5791 +f 2802 5791 1299 +f 5793 5791 2802 +f 540 3334 2661 +f 3334 797 5794 +f 2661 5794 1399 +f 3334 5794 2661 +f 668 3214 5796 +f 3214 665 5795 +f 5796 5795 1227 +f 3214 5795 5796 +f 462 5797 3541 +f 5797 668 5796 +f 3541 5796 1227 +f 5797 5796 3541 +f 235 5798 5799 +f 5798 1077 2804 +f 5799 2804 1399 +f 5798 2804 5799 +f 596 5800 5801 +f 5800 483 3419 +f 5801 3419 1104 +f 5800 3419 5801 +f 639 5802 3521 +f 5802 740 5803 +f 3521 5803 908 +f 5802 5803 3521 +f 696 5804 5806 +f 5804 259 5805 +f 5806 5805 748 +f 5804 5805 5806 +f 696 5807 3523 +f 5807 398 5808 +f 3523 5808 1135 +f 5807 5808 3523 +f 398 5807 5809 +f 5807 696 5806 +f 5809 5806 748 +f 5807 5806 5809 +f 908 5803 3529 +f 5803 740 5810 +f 3529 5810 1451 +f 5803 5810 3529 +f 797 3545 5794 +f 3545 235 5799 +f 5794 5799 1399 +f 3545 5799 5794 +f 668 5797 5793 +f 5797 462 3554 +f 5793 3554 1046 +f 5797 3554 5793 +f 665 5811 5795 +f 5811 996 3549 +f 5795 3549 1227 +f 5811 3549 5795 +f 996 5811 5812 +f 5811 665 5792 +f 5812 5792 1182 +f 5811 5792 5812 +f 366 5813 3553 +f 5813 682 5814 +f 3553 5814 1046 +f 5813 5814 3553 +f 703 3216 5815 +f 3216 555 2918 +f 5815 2918 1077 +f 3216 2918 5815 +f 938 3505 3417 +f 3505 350 3651 +f 3417 3651 1402 +f 3505 3651 3417 +f 843 3646 3515 +f 3646 1128 3054 +f 3515 3054 1434 +f 3646 3054 3515 +f 483 5800 5816 +f 5800 596 3654 +f 5816 3654 1444 +f 5800 3654 5816 +f 598 3509 5817 +f 3509 483 5816 +f 5817 5816 1444 +f 3509 5816 5817 +f 88 3512 5818 +f 3512 621 3511 +f 5818 3511 933 +f 3512 3511 5818 +f 1402 5819 3414 +f 5819 134 3516 +f 3414 3516 1434 +f 5819 3516 3414 +f 88 5820 3513 +f 5820 596 5801 +f 3513 5801 1104 +f 5820 5801 3513 +f 258 5821 5822 +f 5821 259 5804 +f 5822 5804 696 +f 5821 5804 5822 +f 259 5823 5805 +f 5823 727 3525 +f 5805 3525 748 +f 5823 3525 5805 +f 259 5821 5823 +f 5821 258 5824 +f 5823 5824 727 +f 5821 5824 5823 +f 639 3520 5826 +f 3520 734 5825 +f 5826 5825 1216 +f 3520 5825 5826 +f 289 5827 5828 +f 5827 639 5826 +f 5828 5826 1216 +f 5827 5826 5828 +f 639 5827 5802 +f 5827 289 3662 +f 5802 3662 740 +f 5827 3662 5802 +f 611 5829 3528 +f 5829 364 3656 +f 3528 3656 908 +f 5829 3656 3528 +f 1135 5808 5830 +f 5808 398 3533 +f 5830 3533 1282 +f 5808 3533 5830 +f 635 3531 3535 +f 3531 398 5809 +f 3535 5809 748 +f 3531 5809 3535 +f 740 3664 5810 +f 3664 1352 5831 +f 5810 5831 1451 +f 3664 5831 5810 +f 815 3774 3543 +f 3774 703 5815 +f 3543 5815 1077 +f 3774 5815 3543 +f 235 5832 5798 +f 5832 566 3544 +f 5798 3544 1077 +f 5832 3544 5798 +f 566 5832 5833 +f 5832 235 3547 +f 5833 3547 984 +f 5832 3547 5833 +f 868 5834 3676 +f 5834 797 3336 +f 3676 3336 1153 +f 5834 3336 3676 +f 933 3510 5835 +f 3510 491 3329 +f 5835 3329 1256 +f 3510 3329 5835 +f 970 5836 3650 +f 5836 375 5837 +f 3650 5837 1402 +f 5836 5837 3650 +f 734 5838 5825 +f 5838 88 5839 +f 5825 5839 1216 +f 5838 5839 5825 +f 134 5840 5842 +f 5840 375 5841 +f 5842 5841 727 +f 5840 5841 5842 +f 375 5840 5837 +f 5840 134 5819 +f 5837 5819 1402 +f 5840 5819 5837 +f 596 5820 5843 +f 5820 88 5838 +f 5843 5838 734 +f 5820 5838 5843 +f 134 5844 3514 +f 5844 258 5845 +f 3514 5845 843 +f 5844 5845 3514 +f 258 5844 5824 +f 5844 134 5842 +f 5824 5842 727 +f 5844 5842 5824 +f 88 5818 5839 +f 5818 933 5846 +f 5839 5846 1216 +f 5818 5846 5839 +f 258 5822 5845 +f 5822 696 3522 +f 5845 3522 843 +f 5822 3522 5845 +f 727 5841 3657 +f 5841 375 5836 +f 3657 5836 970 +f 5841 5836 3657 +f 498 3652 3517 +f 3652 596 5843 +f 3517 5843 734 +f 3652 5843 3517 +f 289 5828 3663 +f 5828 1216 5847 +f 3663 5847 1352 +f 5828 5847 3663 +f 662 5848 3763 +f 5848 1135 5830 +f 3763 5830 1282 +f 5848 5830 3763 +f 63 3536 3758 +f 3536 748 3527 +f 3758 3527 833 +f 3536 3527 3758 +f 396 5849 5850 +f 5849 611 3530 +f 5850 3530 1451 +f 5849 3530 5850 +f 566 5851 3670 +f 5851 396 5850 +f 3670 5850 1451 +f 5851 5850 3670 +f 396 5851 3768 +f 5851 566 5833 +f 3768 5833 984 +f 5851 5833 3768 +f 797 5834 3546 +f 5834 868 5852 +f 3546 5852 984 +f 5834 5852 3546 +f 1186 3673 3666 +f 3673 412 3764 +f 3666 3764 1282 +f 3673 3764 3666 +f 996 5812 5853 +f 5812 1182 3422 +f 5853 3422 1372 +f 5812 3422 5853 +f 410 3849 4053 +f 3849 1128 3648 +f 4053 3648 1494 +f 3849 3648 4053 +f 506 3932 5854 +f 3932 933 5835 +f 5854 5835 1256 +f 3932 5835 5854 +f 506 5854 4128 +f 5854 1256 3847 +f 4128 3847 1491 +f 5854 3847 4128 +f 350 3753 3649 +f 3753 808 5855 +f 3649 5855 970 +f 3753 5855 3649 +f 364 5856 3755 +f 5856 648 3935 +f 3755 3935 685 +f 5856 3935 3755 +f 843 3660 3647 +f 3660 864 5857 +f 3647 5857 1494 +f 3660 5857 3647 +f 808 5858 5859 +f 5858 826 3759 +f 5859 3759 833 +f 5858 3759 5859 +f 808 5859 5855 +f 5859 833 3658 +f 5855 3658 970 +f 5859 3658 5855 +f 808 5860 5858 +f 5860 588 3761 +f 5858 3761 826 +f 5860 3761 5858 +f 364 5829 5856 +f 5829 611 5861 +f 5856 5861 648 +f 5829 5861 5856 +f 611 5849 5861 +f 5849 396 3765 +f 5861 3765 648 +f 5849 3765 5861 +f 635 3534 3667 +f 3534 63 3757 +f 3667 3757 826 +f 3534 3757 3667 +f 1352 5862 5831 +f 5862 815 3671 +f 5831 3671 1451 +f 5862 3671 5831 +f 984 5852 3769 +f 5852 868 5863 +f 3769 5863 1312 +f 5852 5863 3769 +f 868 3675 5865 +f 3675 682 5864 +f 5865 5864 1460 +f 3675 5864 5865 +f 577 5866 5867 +f 5866 412 3672 +f 5867 3672 996 +f 5866 3672 5867 +f 577 5867 5868 +f 5867 996 5853 +f 5868 5853 1372 +f 5867 5853 5868 +f 682 5813 5869 +f 5813 366 3773 +f 5869 3773 1354 +f 5813 3773 5869 +f 1046 5814 3059 +f 5814 682 3677 +f 3059 3677 1153 +f 5814 3677 3059 +f 977 5870 3645 +f 5870 808 3754 +f 3645 3754 1108 +f 5870 3754 3645 +f 685 3850 3756 +f 3850 598 5817 +f 3756 5817 1444 +f 3850 5817 3756 +f 1216 5846 5847 +f 5846 933 3942 +f 5847 3942 1352 +f 5846 3942 5847 +f 662 3940 5848 +f 3940 864 3661 +f 5848 3661 1135 +f 3940 3661 5848 +f 412 5866 3762 +f 5866 577 3938 +f 3762 3938 662 +f 5866 3938 3762 +f 1073 3936 4056 +f 3936 648 3767 +f 4056 3767 1312 +f 3936 3767 4056 +f 1352 3941 5872 +f 3941 1159 5871 +f 5872 5871 1472 +f 3941 5871 5872 +f 815 5862 3775 +f 5862 1352 5872 +f 3775 5872 1472 +f 5862 5872 3775 +f 1011 3674 3945 +f 3674 674 3771 +f 3945 3771 1395 +f 3674 3771 3945 +f 682 5873 5864 +f 5873 161 5874 +f 5864 5874 1460 +f 5873 5874 5864 +f 564 3424 3948 +f 3424 113 5875 +f 3948 5875 1159 +f 3424 5875 3948 +f 1159 5875 5871 +f 5875 113 3556 +f 5871 3556 1472 +f 5875 3556 5871 +f 586 5876 4126 +f 5876 416 5877 +f 4126 5877 977 +f 5876 5877 4126 +f 416 5878 5877 +f 5878 808 5870 +f 5877 5870 977 +f 5878 5870 5877 +f 357 3930 5879 +f 3930 685 3937 +f 5879 3937 1073 +f 3930 3937 5879 +f 588 5860 5881 +f 5860 808 5880 +f 5881 5880 1421 +f 5860 5880 5881 +f 1312 5863 5882 +f 5863 868 5865 +f 5882 5865 1460 +f 5863 5865 5882 +f 407 4058 4130 +f 4058 577 5868 +f 4130 5868 1372 +f 4058 5868 4130 +f 978 5883 5884 +f 5883 709 4131 +f 5884 4131 1372 +f 5883 4131 5884 +f 757 3678 3421 +f 3678 978 5884 +f 3421 5884 1372 +f 3678 5884 3421 +f 694 3848 4188 +f 3848 410 4052 +f 4188 4052 1313 +f 3848 4052 4188 +f 864 4059 5857 +f 4059 407 5885 +f 5857 5885 1494 +f 4059 5885 5857 +f 808 5878 5880 +f 5878 416 5886 +f 5880 5886 1421 +f 5878 5886 5880 +f 845 3943 5887 +f 3943 588 5881 +f 5887 5881 1421 +f 3943 5881 5887 +f 1100 4057 5888 +f 4057 1312 5882 +f 5888 5882 1460 +f 4057 5882 5888 +f 489 5889 4050 +f 5889 357 5890 +f 4050 5890 559 +f 5889 5890 4050 +f 357 5889 3931 +f 5889 489 3751 +f 3931 3751 941 +f 5889 3751 3931 +f 407 5891 5885 +f 5891 1313 4054 +f 5885 4054 1494 +f 5891 4054 5885 +f 506 4127 5893 +f 4127 642 5892 +f 5893 5892 1150 +f 4127 5892 5893 +f 416 5876 5886 +f 5876 586 4269 +f 5886 4269 1421 +f 5876 4269 5886 +f 506 5893 3933 +f 5893 1150 3949 +f 3933 3949 1159 +f 5893 3949 3933 +f 559 5890 4397 +f 5890 357 5894 +f 4397 5894 873 +f 5890 5894 4397 +f 873 5894 4265 +f 5894 357 5879 +f 4265 5879 1073 +f 5894 5879 4265 +f 642 5895 5892 +f 5895 1080 5896 +f 5892 5896 1150 +f 5895 5896 5892 +f 989 4348 5897 +f 4348 845 5887 +f 5897 5887 1421 +f 4348 5887 5897 +f 407 4129 5891 +f 4129 709 4347 +f 5891 4347 1313 +f 4129 4347 5891 +f 582 5898 4190 +f 5898 709 5883 +f 4190 5883 978 +f 5898 5883 4190 +f 1080 5899 5896 +f 5899 673 3950 +f 5896 3950 1150 +f 5899 3950 5896 +f 758 5900 4268 +f 5900 989 5897 +f 4268 5897 1421 +f 5900 5897 4268 +f 705 4266 5901 +f 4266 1073 4055 +f 5901 4055 1100 +f 4266 4055 5901 +f 582 4402 5898 +f 4402 93 4345 +f 5898 4345 709 +f 4402 4345 5898 +f 161 5873 4272 +f 5873 682 5869 +f 4272 5869 1354 +f 5873 5869 4272 +f 1354 4271 4273 +f 4271 346 4406 +f 4273 4406 1420 +f 4271 4406 4273 +f 634 4463 5902 +f 4463 705 5901 +f 5902 5901 1100 +f 4463 5901 5902 +f 1420 5903 5904 +f 5903 1100 5888 +f 5904 5888 1460 +f 5903 5888 5904 +f 161 4274 5874 +f 4274 1420 5904 +f 5874 5904 1460 +f 4274 5904 5874 +f 806 4194 4407 +f 4194 673 5899 +f 4407 5899 1080 +f 4194 5899 4407 +f 93 4401 5905 +f 4401 467 4620 +f 5905 4620 1174 +f 4401 4620 5905 +f 630 4404 4548 +f 4404 346 4349 +f 4548 4349 989 +f 4404 4349 4548 +f 634 5902 5906 +f 5902 1100 5903 +f 5906 5903 1420 +f 5902 5903 5906 +f 388 5907 4343 +f 5907 777 4263 +f 4343 4263 1414 +f 5907 4263 4343 +f 388 4750 5907 +f 4750 732 5908 +f 5907 5908 777 +f 4750 5908 5907 +f 93 5905 4346 +f 5905 1174 5909 +f 4346 5909 1313 +f 5905 5909 4346 +f 873 4264 5910 +f 4264 705 4465 +f 5910 4465 1205 +f 4264 4465 5910 +f 642 4262 5895 +f 4262 777 5911 +f 5895 5911 1080 +f 4262 5911 5895 +f 230 4399 4461 +f 4399 586 4344 +f 4461 4344 1233 +f 4399 4344 4461 +f 1080 5912 4408 +f 5912 1002 5913 +f 4408 5913 1471 +f 5912 5913 4408 +f 777 5914 5911 +f 5914 1002 5912 +f 5911 5912 1080 +f 5914 5912 5911 +f 894 5915 4467 +f 5915 634 5906 +f 4467 5906 1420 +f 5915 5906 4467 +f 41 4469 4625 +f 4469 582 4470 +f 4625 4470 878 +f 4469 4470 4625 +f 1174 5916 5909 +f 5916 850 4396 +f 5909 4396 1313 +f 5916 4396 5909 +f 777 5908 5914 +f 5908 732 5917 +f 5914 5917 1002 +f 5908 5917 5914 +f 230 4460 5918 +f 4460 348 4751 +f 5918 4751 358 +f 4460 4751 5918 +f 873 5919 4398 +f 5919 525 4617 +f 4398 4617 1294 +f 5919 4617 4398 +f 758 4400 5921 +f 4400 230 5920 +f 5921 5920 1475 +f 4400 5920 5921 +f 989 5900 4549 +f 5900 758 5921 +f 4549 5921 1475 +f 5900 5921 4549 +f 308 4607 4609 +f 4607 850 5916 +f 4609 5916 1174 +f 4607 5916 4609 +f 470 5922 4616 +f 5922 912 4613 +f 4616 4613 1294 +f 5922 4613 4616 +f 525 5919 5923 +f 5919 873 5910 +f 5923 5910 1205 +f 5919 5910 5923 +f 609 4621 5924 +f 4621 630 4697 +f 5924 4697 684 +f 4621 4697 5924 +f 254 4618 5925 +f 4618 467 4624 +f 5925 4624 1196 +f 4618 4624 5925 +f 230 5918 5920 +f 5918 358 4821 +f 5920 4821 1475 +f 5918 4821 5920 +f 800 4699 4824 +f 4699 634 5915 +f 4824 5915 894 +f 4699 5915 4824 +f 732 5926 5917 +f 5926 584 5927 +f 5917 5927 1002 +f 5926 5927 5917 +f 254 5928 4619 +f 5928 942 4610 +f 4619 4610 1174 +f 5928 4610 4619 +f 759 4904 4823 +f 4904 525 5923 +f 4823 5923 1205 +f 4904 5923 4823 +f 1002 5929 5913 +f 5929 718 4833 +f 5913 4833 1471 +f 5929 4833 5913 +f 308 4608 5930 +f 4608 942 4981 +f 5930 4981 1322 +f 4608 4981 5930 +f 308 5930 4898 +f 5930 1322 5931 +f 4898 5931 1330 +f 5930 5931 4898 +f 470 5932 5922 +f 5932 57 5933 +f 5922 5933 912 +f 5932 5933 5922 +f 254 5934 5928 +f 5934 677 4979 +f 5928 4979 942 +f 5934 4979 5928 +f 584 5935 5927 +f 5935 718 5929 +f 5927 5929 1002 +f 5935 5929 5927 +f 609 5924 5936 +f 5924 684 4984 +f 5936 4984 1289 +f 5924 4984 5936 +f 677 5934 4828 +f 5934 254 5925 +f 4828 5925 1196 +f 5934 5925 4828 +f 894 4622 5937 +f 4622 609 5936 +f 5937 5936 1289 +f 4622 5936 5937 +f 1099 4825 5938 +f 4825 894 5937 +f 5938 5937 1289 +f 4825 5937 5938 +f 732 4749 5939 +f 4749 408 5064 +f 5939 5064 1103 +f 4749 5064 5939 +f 584 5926 5940 +f 5926 732 5939 +f 5940 5939 1103 +f 5926 5939 5940 +f 57 5932 4903 +f 5932 470 4615 +f 4903 4615 525 +f 5932 4615 4903 +f 519 5066 5941 +f 5066 57 4905 +f 5941 4905 759 +f 5066 4905 5941 +f 492 4820 4901 +f 4820 358 4752 +f 4901 4752 765 +f 4820 4752 4901 +f 684 4753 4982 +f 4753 492 4900 +f 4982 4900 745 +f 4753 4900 4982 +f 560 5942 4987 +f 5942 759 4822 +f 4987 4822 800 +f 5942 4822 4987 +f 584 5943 5935 +f 5943 578 5944 +f 5935 5944 718 +f 5943 5944 5935 +f 912 5933 5059 +f 5933 57 5068 +f 5059 5068 1173 +f 5933 5068 5059 +f 1200 5069 5945 +f 5069 765 4696 +f 5945 4696 1317 +f 5069 4696 5945 +f 578 5943 5946 +f 5943 584 5940 +f 5946 5940 1103 +f 5943 5940 5946 +f 331 5947 5166 +f 5947 1099 5938 +f 5166 5938 1289 +f 5947 5938 5166 +f 695 5948 4819 +f 5948 1200 5945 +f 4819 5945 1317 +f 5948 5945 4819 +f 677 5949 4980 +f 5949 1267 5950 +f 4980 5950 1322 +f 5949 5950 4980 +f 677 4827 5949 +f 4827 285 5951 +f 5949 5951 1267 +f 4827 5951 5949 +f 560 5952 5942 +f 5952 519 5941 +f 5942 5941 759 +f 5952 5941 5942 +f 718 5944 5075 +f 5944 578 5953 +f 5075 5953 1435 +f 5944 5953 5075 +f 1267 5951 5954 +f 5951 285 5073 +f 5954 5073 1287 +f 5951 5073 5954 +f 1200 5948 5955 +f 5948 695 5162 +f 5955 5162 1209 +f 5948 5162 5955 +f 637 5956 5957 +f 5956 1200 5955 +f 5957 5955 1209 +f 5956 5955 5957 +f 1322 5958 5931 +f 5958 341 5959 +f 5931 5959 1330 +f 5958 5959 5931 +f 327 5960 5255 +f 5960 1103 5065 +f 5255 5065 1363 +f 5960 5065 5255 +f 1267 5961 5950 +f 5961 548 5962 +f 5950 5962 1322 +f 5961 5962 5950 +f 327 5259 5960 +f 5259 578 5946 +f 5960 5946 1103 +f 5259 5946 5960 +f 519 5952 5964 +f 5952 560 5963 +f 5964 5963 735 +f 5952 5963 5964 +f 331 5965 5947 +f 5965 81 4990 +f 5947 4990 1099 +f 5965 4990 5947 +f 81 5965 5966 +f 5965 331 5343 +f 5966 5343 1084 +f 5965 5343 5966 +f 1330 5959 5251 +f 5959 341 5334 +f 5251 5334 1416 +f 5959 5334 5251 +f 548 5967 5962 +f 5967 341 5958 +f 5962 5958 1322 +f 5967 5958 5962 +f 637 5407 5956 +f 5407 782 5258 +f 5956 5258 1200 +f 5407 5258 5956 +f 1173 5968 5970 +f 5968 735 5969 +f 5970 5969 1232 +f 5968 5969 5970 +f 519 5964 5067 +f 5964 735 5968 +f 5067 5968 1173 +f 5964 5968 5067 +f 771 5971 5413 +f 5971 745 5257 +f 5413 5257 782 +f 5971 5257 5413 +f 640 4985 5262 +f 4985 745 5971 +f 5262 5971 771 +f 4985 5971 5262 +f 560 4989 5972 +f 4989 81 5966 +f 5972 5966 1084 +f 4989 5966 5972 +f 735 5963 5973 +f 5963 560 5972 +f 5973 5972 1084 +f 5963 5972 5973 +f 764 5974 5434 +f 5974 735 5973 +f 5434 5973 1084 +f 5974 5973 5434 +f 306 5071 5268 +f 5071 640 5264 +f 5268 5264 986 +f 5071 5264 5268 +f 500 5975 5392 +f 5975 637 5957 +f 5392 5957 1209 +f 5975 5957 5392 +f 637 5975 5408 +f 5975 500 5406 +f 5408 5406 1447 +f 5975 5406 5408 +f 1140 5164 5976 +f 5164 1173 5970 +f 5976 5970 1232 +f 5164 5970 5976 +f 341 5967 5397 +f 5967 548 5977 +f 5397 5977 1212 +f 5967 5977 5397 +f 83 5978 5402 +f 5978 327 5256 +f 5402 5256 1364 +f 5978 5256 5402 +f 548 5979 5977 +f 5979 353 5980 +f 5977 5980 1212 +f 5979 5980 5977 +f 353 5979 5981 +f 5979 548 5961 +f 5981 5961 1267 +f 5979 5961 5981 +f 735 5982 5969 +f 5982 1034 5983 +f 5969 5983 1232 +f 5982 5983 5969 +f 578 5261 5953 +f 5261 1235 5267 +f 5953 5267 1435 +f 5261 5267 5953 +f 353 5981 5984 +f 5981 1267 5954 +f 5984 5954 1287 +f 5981 5954 5984 +f 928 5985 5342 +f 5985 353 5984 +f 5342 5984 1287 +f 5985 5984 5342 +f 500 5393 5987 +f 5393 1424 5986 +f 5987 5986 1450 +f 5393 5986 5987 +f 1424 5383 5986 +f 5383 1416 5336 +f 5986 5336 1450 +f 5383 5336 5986 +f 1357 5395 5394 +f 5395 418 5988 +f 5394 5988 1364 +f 5395 5988 5394 +f 1140 5976 5990 +f 5976 1232 5989 +f 5990 5989 1261 +f 5976 5989 5990 +f 326 5404 5400 +f 5404 500 5987 +f 5400 5987 1450 +f 5404 5987 5400 +f 186 5991 5993 +f 5991 418 5992 +f 5993 5992 1261 +f 5991 5992 5993 +f 418 5991 5988 +f 5991 186 5403 +f 5988 5403 1364 +f 5991 5403 5988 +f 418 5338 5992 +f 5338 1140 5990 +f 5992 5990 1261 +f 5338 5990 5992 +f 83 5401 5994 +f 5401 186 5412 +f 5994 5412 1235 +f 5401 5412 5994 +f 327 5978 5260 +f 5978 83 5994 +f 5260 5994 1235 +f 5978 5994 5260 +f 353 5995 5980 +f 5995 338 5463 +f 5980 5463 1212 +f 5995 5463 5980 +f 583 5414 5418 +f 5414 782 5409 +f 5418 5409 1447 +f 5414 5409 5418 +f 338 5995 5996 +f 5995 353 5985 +f 5996 5985 928 +f 5995 5985 5996 +f 438 5415 5997 +f 5415 338 5996 +f 5997 5996 928 +f 5415 5996 5997 +f 1232 5983 5989 +f 5983 1034 5998 +f 5989 5998 1261 +f 5983 5998 5989 +f 1034 5423 5998 +f 5423 901 5466 +f 5998 5466 1261 +f 5423 5466 5998 +f 158 5464 5411 +f 5464 901 5421 +f 5411 5421 1235 +f 5464 5421 5411 +f 735 5974 5982 +f 5974 764 5999 +f 5982 5999 1034 +f 5974 5999 5982 +f 764 5471 5999 +f 5471 257 5424 +f 5999 5424 1034 +f 5471 5424 5999 +f 583 5416 6001 +f 5416 438 6000 +f 6001 6000 783 +f 5416 6000 6001 +f 583 6001 5340 +f 6001 783 6002 +f 5340 6002 986 +f 6001 6002 5340 +f 783 6000 5426 +f 6000 438 5997 +f 5426 5997 928 +f 6000 5997 5426 +f 48 5348 5432 +f 5348 576 5420 +f 5432 5420 901 +f 5348 5420 5432 +f 783 5468 6002 +f 5468 316 5469 +f 6002 5469 986 +f 5468 5469 6002 +f 326 5462 5405 +f 5462 338 5419 +f 5405 5419 1447 +f 5462 5419 5405 +f 158 5410 5465 +f 5410 186 5993 +f 5465 5993 1261 +f 5410 5993 5465 \ No newline at end of file diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e71486e --- /dev/null +++ b/flake.nix @@ -0,0 +1,30 @@ + +{ + description = "A simple hybrid renderer"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + venv = ".venv"; + in { + devShells.default = pkgs.mkShell { + name = "kale"; + + packages = with pkgs; [ + sdl3 + glm + gcc + shaderc + gnumake + ]; + + }; + } + ); +} diff --git a/shaders/blit.frag b/shaders/blit.frag new file mode 100644 index 0000000..b6dff6b --- /dev/null +++ b/shaders/blit.frag @@ -0,0 +1,110 @@ +#version 450 + +layout(location = 0) in vec2 uv; +layout(location = 0) out vec4 out_color; +layout(set = 2, binding = 0) uniform sampler2D screen; + +layout(std140, set = 3, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + + +float road(float x) { return cos(x); } + +vec3 backup(vec2 uv) { + float x_scale = time * 12.0; + float y_scale = uv.x; + + uv.x *= x_scale; + uv.y *= 2.0; + uv.y -= 1.0; + uv.y /= 0.75; + uv.y /= y_scale; + + float y = road(uv.x); + + float dist = length(uv.y - y); + + vec3 col = vec3(cos(time / 10.0)) - vec3(exp(-dist), cos(dist), sin(dist)); + return (0.005 * (1.2 + abs(cos(time)))) / col; +} + +const int MAX_MARCH_STEPS = 64; +const float EPS_DIST = 1e-6; + +float sdf(vec3 point) { +// return length(point - vec3(6.0 * sin(time), 8.0*abs(sin(time * 0.7)*cos(time)), 5.0 * cos(time * 1.2))) - 0.4; + float size = 8.0 + (3.0* sin(time)); + vec3 s1_local = mod(point, vec3(size)) - vec3(size/2.0); + float s1 = length(s1_local) - 0.3; + return s1; +} + +vec3 getnormal(vec3 p) { + float e = EPS_DIST; + return normalize(vec3( + sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)), + sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)), + sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e)) + )); +} + + + +vec4 march(vec3 point, vec3 ray) { + float MAX_DEPTH = texture(screen, uv).w * 1000.0; + float totaldist = 0.0; + + int i; + for (i = 0; i < MAX_MARCH_STEPS && totaldist < MAX_DEPTH; i += 1) { + float h = sdf(point); + point += h * ray; + if (h < EPS_DIST) { + return vec4(point, totaldist + h); + } + + totaldist += h; + } + + return vec4(-1.0); +} + +vec3 camray() { + vec2 ndc = uv * 2.0 - 1.0; + ndc.y = -ndc.y; + vec4 clip = vec4(ndc, 1.0, 1.0); + vec4 view_pos = inverse(projection) * clip; + view_pos /= view_pos.w; + + vec3 ray_dir_view = normalize(view_pos.xyz); + + vec3 ray_dir_world = normalize((inverse(view) * vec4(ray_dir_view, 0.0)).xyz); + + return ray_dir_world; +} + +vec3 camorigin() { return (inverse(view) * vec4(0, 0, 0, 1)).xyz; } + +vec4 kernel() { + vec3 cam_pos = camorigin(); + vec3 cam_ray = camray(); + + return march(cam_pos, cam_ray); +} + +float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); } + +void main() { + + vec2 bg = (projection * view * vec4(uv, 1.0, 1.0)).xy; + vec3 b = backup(bg); + vec4 hit = kernel(); + if (hit.w > 0.0 && ((t(uv.x, uv.y) < 0.01) || (hit.w < (texture(screen, uv).w * 1000.0)))) { + out_color = vec4(getnormal(hit.xyz), 1.0); + } else { + out_color = texture(screen, uv); + } +} diff --git a/shaders/blit.vert b/shaders/blit.vert new file mode 100644 index 0000000..ee04010 --- /dev/null +++ b/shaders/blit.vert @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) out vec2 uv; + +void main() { + float x = float((gl_VertexIndex << 1) & 2); + float y = float(gl_VertexIndex & 2); + uv = vec2(x, y); + gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0); + gl_Position.y *= -1.0; +} diff --git a/shaders/post.frag b/shaders/post.frag new file mode 100644 index 0000000..30c978e --- /dev/null +++ b/shaders/post.frag @@ -0,0 +1,46 @@ +#version 450 + +layout(location = 0) in vec2 uv; +layout(location = 0) out vec4 out_color; +layout(set = 2, binding = 0) uniform sampler2D screen; + +layout(std140, set = 3, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + +float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); } + +mat3 neighborhood() { + vec2 d = 1.0 / vec2(textureSize(screen, 0)); + return mat3(t(uv.x - d.x, uv.y - d.y), t(uv.x + 0.0, uv.y - d.y), + t(uv.x + d.x, uv.y - d.y), t(uv.x - d.x, uv.y - 0.0), + t(uv.x + 0.0, uv.y + 0.0), t(uv.x + d.x, uv.y - 0.0), + t(uv.x - d.x, uv.y + d.y), t(uv.x + 0.0, uv.y + d.y), + t(uv.x + d.x, uv.y + d.y)); +} + +float sum3(mat3 m) { + float s = 0.0; + for (int c = 0; c < 3; ++c) { + vec3 col = m[c]; + s += col.x + col.y + col.z; + } + return s; +} + +float f(mat3 kernel) { + return abs(sum3(matrixCompMult(kernel, neighborhood()))); +} + + +void main() { + const mat3 sobelx = mat3(-1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0); + + const mat3 sobely = mat3(-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0); + + out_color = texture(screen, uv) + ((t(uv.x, uv.y) > 0.01)? + vec4(abs(f(sobelx) + f(sobely)), 0.0, 0.0, 1.0) : vec4(0.0)); +} \ No newline at end of file diff --git a/shaders/scene.frag b/shaders/scene.frag new file mode 100644 index 0000000..5e056f0 --- /dev/null +++ b/shaders/scene.frag @@ -0,0 +1,16 @@ +#version 460 +layout(location = 0) in vec4 v_color; +layout(location = 1) in float depth; +layout(location = 2) in vec3 v_normal_vs; + +layout(location = 0) out vec4 out_color; + +void main() { + vec3 light_dir = normalize(vec3(0.5, 1.0, 0.8)); + + float ambient = 0.2; + float diffuse = max(dot(v_normal_vs, light_dir), 0.0); + float lighting = ambient + (1.0 - ambient) * diffuse; + + out_color = vec4(v_color.rgb * lighting, v_color.a); +} diff --git a/shaders/scene.vert b/shaders/scene.vert new file mode 100644 index 0000000..b6faca0 --- /dev/null +++ b/shaders/scene.vert @@ -0,0 +1,26 @@ +#version 460 +layout(location = 0) in vec3 a_pos; +layout(location = 1) in vec4 a_color; +layout(location = 2) in vec3 a_normal; + +layout(location = 0) out vec4 v_color; +layout(location = 1) out float depth; +layout(location = 2) out vec3 v_normal_vs; // view-space normal + +layout(std140, set = 1, binding = 0) uniform UniformBlock { + mat4 model; + mat4 view; + mat4 projection; + float time; +}; + +void main() { + vec4 view_pos = view * model * vec4(a_pos, 1.0); + depth = -view_pos.z / 1000.0; + gl_Position = projection * view_pos; + v_color = a_color; + + // For uniform scale this shortcut is fine: + mat3 normal_mat = mat3(transpose(inverse(view * model))); + v_normal_vs = normalize(normal_mat * a_normal); +} diff --git a/src/camera.cpp b/src/camera.cpp new file mode 100644 index 0000000..94fb750 --- /dev/null +++ b/src/camera.cpp @@ -0,0 +1,65 @@ +#include "camera.h" + +vec3 Camera::dir() const { + return normalize(vec3( + cos(radians(yaw)) * cos(radians(pitch)), + sin(radians(pitch)), + sin(radians(yaw)) * cos(radians(pitch)) + )); +} + +void Camera::update() { + if (look_up) pitch += look_speed; + if (look_down) pitch -= look_speed; + if (look_left) yaw -= look_speed; + if (look_right) yaw += look_speed; + pitch = clamp(pitch, -89.0f, 89.0f); + + vec3 d = dir(); + vec3 right = normalize(cross(d, up)); + target = pos + d; + float shift_speed = shifted? 10.0 : 1.0; + float speed = move_speed * shift_speed; + + if (move_forward) { pos += d * speed; target += d * speed; } + if (move_backward) { pos -= d * speed; target -= d * speed; } + if (move_left) { pos -= right * speed; target -= right * speed; } + if (move_right) { pos += right * speed; target += right * speed; } + if (move_up) { pos += up * speed; target += up * speed; } + if (move_down) { pos -= up * speed; target -= up * speed; } +} + +void Camera::on_key(SDL_Scancode scancode, bool pressed) { + switch (scancode) { + case SDL_SCANCODE_W: move_forward = pressed; break; + case SDL_SCANCODE_S: move_backward = pressed; break; + case SDL_SCANCODE_A: move_left = pressed; break; + case SDL_SCANCODE_D: move_right = pressed; break; + case SDL_SCANCODE_SPACE: move_up = pressed; break; + case SDL_SCANCODE_LCTRL: move_down = pressed; break; + case SDL_SCANCODE_UP: look_up = pressed; break; + case SDL_SCANCODE_DOWN: look_down = pressed; break; + case SDL_SCANCODE_LEFT: look_left = pressed; break; + case SDL_SCANCODE_RIGHT: look_right = pressed; break; + case SDL_SCANCODE_LSHIFT: + case SDL_SCANCODE_RSHIFT: + shifted |= pressed; + break; + default: break; + } +} + +void Camera::on_mouse_motion(float dx, float dy) { + yaw += dx * look_speed * 0.1f; + pitch -= dy * look_speed * 0.1f; + pitch = clamp(pitch, -89.0f, 89.0f); +} + +CameraUBO Camera::ubo(float aspect) const { + return CameraUBO { + .model = mat4(1.0f), + .view = lookAt(pos, target, up), + .proj = perspective(radians(fov), aspect, 0.01f, 1000.0f), + .time = (float)SDL_GetTicks() / 1000.0f, + }; +} diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..2371ae0 --- /dev/null +++ b/src/camera.h @@ -0,0 +1,35 @@ +#pragma once +#include "types.h" +#include +#include + +struct Camera { + vec3 pos = vec3(0.0f, 0.0f, 2.0f); + vec3 target = vec3(0.0f, 0.0f, 0.0f); + vec3 up = vec3(0.0f, 1.0f, 0.0f); + float fov = 60.0f; + float move_speed = 0.05f; + float look_speed = 1.0f; + float pitch = 0.0f; + float yaw = -90.0f; + + bool move_forward = false; + bool move_backward = false; + bool move_left = false; + bool move_right = false; + bool move_up = false; + bool move_down = false; + bool look_up = false; + bool look_down = false; + bool look_left = false; + bool look_right = false; + bool shifted = false; + + void update(); + void on_key(SDL_Scancode scancode, bool pressed); + void on_mouse_motion(float dx, float dy); + CameraUBO ubo(float aspect) const; + +private: + vec3 dir() const; +}; diff --git a/src/gpu.cpp b/src/gpu.cpp new file mode 100644 index 0000000..e5a52d5 --- /dev/null +++ b/src/gpu.cpp @@ -0,0 +1,80 @@ +#include "gpu.h" +#include +#include + +SDL_GPUShader* load_shader(SDL_GPUDevice* dev, const char* path, SDL_GPUShaderStage stage, + uint32_t num_samplers, uint32_t num_uniform_buffers) { + size_t code_size; + void* code = SDL_LoadFile(path, &code_size); + if (!code) { + std::cerr << "Failed to load " << path << ": " << SDL_GetError() << std::endl; + return nullptr; + } + + SDL_GPUShaderCreateInfo info { + .code_size = code_size, + .code = (uint8_t*)code, + .entrypoint = "main", + .format = SDL_GPU_SHADERFORMAT_SPIRV, + .stage = stage, + .num_samplers = num_samplers, + .num_uniform_buffers = num_uniform_buffers, + }; + + SDL_GPUShader* shader = SDL_CreateGPUShader(dev, &info); + if (!shader) + std::cerr << "Shader creation failed (" << path << "): " << SDL_GetError() << std::endl; + SDL_free(code); + return shader; +} + +SDL_GPUTexture* create_render_texture(SDL_GPUDevice* dev, SDL_Window* win, + uint32_t w, uint32_t h) { + SDL_GPUTextureCreateInfo info { + .type = SDL_GPU_TEXTURETYPE_2D, + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + .usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, + .width = w, + .height = h, + .layer_count_or_depth = 1, + .num_levels = 1, + }; + + SDL_GPUTexture* tex = SDL_CreateGPUTexture(dev, &info); + if (!tex) + std::cerr << "Render texture creation failed: " << SDL_GetError() << std::endl; + return tex; +} + +SDL_GPUSampler* create_linear_sampler(SDL_GPUDevice* dev) { + SDL_GPUSamplerCreateInfo info { + .min_filter = SDL_GPU_FILTER_LINEAR, + .mag_filter = SDL_GPU_FILTER_LINEAR, + .address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE, + .address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE, + }; + return SDL_CreateGPUSampler(dev, &info); +} + +void upload_buffer(SDL_GPUDevice* dev, SDL_GPUBuffer* dst, const void* data, uint32_t size) { + SDL_GPUTransferBufferCreateInfo trans_info { + .usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, + .size = size, + }; + SDL_GPUTransferBuffer* trans = SDL_CreateGPUTransferBuffer(dev, &trans_info); + + void* mapped = SDL_MapGPUTransferBuffer(dev, trans, false); + memcpy(mapped, data, size); + SDL_UnmapGPUTransferBuffer(dev, trans); + + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(dev); + SDL_GPUCopyPass* copy = SDL_BeginGPUCopyPass(cmd); + + SDL_GPUTransferBufferLocation src { .transfer_buffer = trans, .offset = 0 }; + SDL_GPUBufferRegion reg { .buffer = dst, .offset = 0, .size = size }; + SDL_UploadToGPUBuffer(copy, &src, ®, true); + + SDL_EndGPUCopyPass(copy); + SDL_ReleaseGPUTransferBuffer(dev, trans); + SDL_SubmitGPUCommandBuffer(cmd); +} diff --git a/src/gpu.h b/src/gpu.h new file mode 100644 index 0000000..f09cc65 --- /dev/null +++ b/src/gpu.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include + +SDL_GPUShader* load_shader(SDL_GPUDevice* dev, const char* path, SDL_GPUShaderStage stage, + uint32_t num_samplers, uint32_t num_uniform_buffers); + +SDL_GPUTexture* create_render_texture(SDL_GPUDevice* dev, SDL_Window* win, + uint32_t w, uint32_t h); + +SDL_GPUSampler* create_linear_sampler(SDL_GPUDevice* dev); + +void upload_buffer(SDL_GPUDevice* dev, SDL_GPUBuffer* dst, const void* data, uint32_t size); diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..8666ce7 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,64 @@ +#include +#include +#define SDL_MAIN_USE_CALLBACKS +#include +#include + +#include "camera.h" +#include "renderer.h" + +static Camera camera; +static Renderer renderer; + +SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv) { + (void)appstate; + (void)argc; + (void)argv; + SDL_Window* win = SDL_CreateWindow("Kale", 960, 540, SDL_WINDOW_RESIZABLE); + SDL_SetWindowRelativeMouseMode(win, true); + + if (!renderer.init(win)) + return SDL_APP_FAILURE; + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void* appstate) { + (void)appstate; + camera.update(); + + uint32_t sw_w = renderer.render_w; + uint32_t sw_h = renderer.render_h; + CameraUBO ubo = camera.ubo((float)sw_w / (float)(sw_h ? sw_h : 1)); + + renderer.draw(ubo); + + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { + (void)appstate; + switch (event->type) { + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + case SDL_EVENT_QUIT: + return SDL_APP_SUCCESS; + + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: + if(event->key.scancode == SDL_SCANCODE_ESCAPE) + return SDL_APP_SUCCESS; + camera.on_key(event->key.scancode, event->type == SDL_EVENT_KEY_DOWN); + break; + case SDL_EVENT_MOUSE_MOTION: + camera.on_mouse_motion(event->motion.xrel, event->motion.yrel); + break; + } + return SDL_APP_CONTINUE; +} + +void SDL_AppQuit(void* appstate, SDL_AppResult result) { + (void)appstate; + (void)result; + renderer.destroy(); + SDL_DestroyWindow(renderer.win); +} diff --git a/src/pipelines.cpp b/src/pipelines.cpp new file mode 100644 index 0000000..cb535b1 --- /dev/null +++ b/src/pipelines.cpp @@ -0,0 +1,146 @@ +#include "pipelines.h" +#include "gpu.h" +#include "types.h" +#include + +void ScenePipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/scene.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 1); + frag = load_shader(dev, "shaders/scene.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 0, 0); + + SDL_GPUVertexBufferDescription vert_buf { + .slot = 0, + .pitch = sizeof(Vertex), + .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX, + .instance_step_rate = 0, + }; + + SDL_GPUVertexAttribute attrs[3] = { + { .location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0 }, + { .location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4, .offset = (uint32_t)offsetof(Vertex, color) }, + { .location = 2, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = (uint32_t)offsetof(Vertex, normal) }, + }; + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + .blend_state = { + .src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .color_blend_op = SDL_GPU_BLENDOP_ADD, + .src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA, + .dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + .alpha_blend_op = SDL_GPU_BLENDOP_ADD, + .enable_blend = false, + } + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = &vert_buf, + .num_vertex_buffers = 1, + .vertex_attributes = attrs, + .num_vertex_attributes = sizeof(attrs)/sizeof(attrs[0]), + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Scene pipeline failed: " << SDL_GetError() << std::endl; +} + +void ScenePipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} + +void BlitPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + frag = load_shader(dev, "shaders/blit.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = nullptr, + .num_vertex_buffers = 0, + .vertex_attributes = nullptr, + .num_vertex_attributes = 0, + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Blit pipeline failed: " << SDL_GetError() << std::endl; +} + +void BlitPipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} + +void PostPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + frag = load_shader(dev, "shaders/post.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); + + SDL_GPUColorTargetDescription color_tgt { + .format = SDL_GetGPUSwapchainTextureFormat(dev, win), + }; + + SDL_GPUGraphicsPipelineCreateInfo info { + .vertex_shader = vert, + .fragment_shader = frag, + .vertex_input_state = { + .vertex_buffer_descriptions = nullptr, + .num_vertex_buffers = 0, + .vertex_attributes = nullptr, + .num_vertex_attributes = 0, + }, + .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, + .rasterizer_state = { + .fill_mode = SDL_GPU_FILLMODE_FILL, + .cull_mode = SDL_GPU_CULLMODE_NONE, + .front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE, + }, + .target_info = { + .color_target_descriptions = &color_tgt, + .num_color_targets = 1, + }, + }; + + pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); + if (!pipeline) + std::cerr << "Post pipeline failed: " << SDL_GetError() << std::endl; +} + +void PostPipeline::destroy(SDL_GPUDevice* dev) { + if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); + if (vert) SDL_ReleaseGPUShader(dev, vert); + if (frag) SDL_ReleaseGPUShader(dev, frag); +} \ No newline at end of file diff --git a/src/pipelines.h b/src/pipelines.h new file mode 100644 index 0000000..12281c7 --- /dev/null +++ b/src/pipelines.h @@ -0,0 +1,29 @@ +#pragma once +#include + +struct ScenePipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; + +struct BlitPipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; + +struct PostPipeline { + SDL_GPUGraphicsPipeline* pipeline = nullptr; + SDL_GPUShader* vert = nullptr; + SDL_GPUShader* frag = nullptr; + + void create(SDL_GPUDevice* dev, SDL_Window* win); + void destroy(SDL_GPUDevice* dev); +}; \ No newline at end of file diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..adf235f --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,183 @@ +#include "renderer.h" +#include "gpu.h" +#include +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + + +bool Renderer::init(SDL_Window* w) { + win = w; + dev = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV, true, NULL); + if (!dev) { std::cerr << "GPU device failed: " << SDL_GetError() << std::endl; return false; } + + SDL_ClaimWindowForGPUDevice(dev, win); + + load_obj(); + + render_sampler = create_linear_sampler(dev); + resize_render_texture(960, 540); + + scene.create(dev, win); + blit.create(dev, win); + post.create(dev, win); + + return scene.pipeline && blit.pipeline; +} + +void Renderer::destroy() { + if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex); + if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex); + if (render_sampler) SDL_ReleaseGPUSampler(dev, render_sampler); + if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff); + scene.destroy(dev); + blit.destroy(dev); + post.destroy(dev); + SDL_DestroyGPUDevice(dev); +} + +bool Renderer::load_obj() { + const std::string& path = "assets/homer.obj"; + tinyobj::attrib_t attrib; + std::vector shapes; + std::vector materials; + std::string warn, err; + if(!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, path.c_str())) { + std::cerr << "OBJ fail: " << warn << err << std::endl; + return false; + } + + vertices.clear(); + for(const auto& shape : shapes) { + const auto& indices = shape.mesh.indices; + for(size_t i = 0; i < indices.size(); i += 3) { + // Use OBJ normals if present, otherwise compute face normal + vec3 pos[3]; + vec3 nor[3]; + bool has_normals = true; + + for(int v = 0; v < 3; v++) { + const auto& idx = indices[i + v]; + pos[v] = vec3( + attrib.vertices[3 * idx.vertex_index + 0], + attrib.vertices[3 * idx.vertex_index + 1], + attrib.vertices[3 * idx.vertex_index + 2] + ); + if(idx.normal_index >= 0) { + nor[v] = vec3( + attrib.normals[3 * idx.normal_index + 0], + attrib.normals[3 * idx.normal_index + 1], + attrib.normals[3 * idx.normal_index + 2] + ); + } else { + has_normals = false; + } + } + + if(!has_normals) { + vec3 face_normal = glm::normalize(glm::cross(pos[1] - pos[0], pos[2] - pos[0])); + nor[0] = nor[1] = nor[2] = face_normal; + } + + for(int v = 0; v < 3; v++) { + vertices.push_back(Vertex { + .pos = pos[v], + .color = vec4(abs(sin(pos[v].x)), abs(cos(pos[v].y)), abs(sin(pos[v].z) * cos(pos[v].y)), 1.0f), + .normal = nor[v], + }); + } + } + } + + SDL_GPUBufferCreateInfo info { + .usage = SDL_GPU_BUFFERUSAGE_VERTEX, + .size = static_cast(vertices.size() * sizeof(Vertex)), + }; + vert_buff = SDL_CreateGPUBuffer(dev, &info); + upload_buffer(dev, vert_buff, vertices.data(), info.size); + return true; +} + +void Renderer::resize_render_texture(uint32_t w, uint32_t h) { + SDL_WaitForGPUIdle(dev); + if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex); + if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex); + render_tex = create_render_texture(dev, win, w, h); + post_tex = create_render_texture(dev, win, w, h); + render_w = w; + render_h = h; +} + + +void Renderer::pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { + SDL_PushGPUVertexUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = render_tex, + .clear_color = { 0.0, 0.0, 0.0, 1.0}, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, scene.pipeline); + SDL_GPUBufferBinding binding { .buffer = vert_buff, .offset = 0 }; + SDL_BindGPUVertexBuffers(pass, 0, &binding, 1); + SDL_DrawGPUPrimitives(pass, vertices.size(), 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { + SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = post_tex, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, blit.pipeline); + SDL_GPUTextureSamplerBinding tex { .texture = render_tex, .sampler = render_sampler }; + SDL_BindGPUFragmentSamplers(pass, 0, &tex, 1); + SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo) { + SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo)); + + SDL_GPUColorTargetInfo tgt { + .texture = swapchain, + .load_op = SDL_GPU_LOADOP_CLEAR, + .store_op = SDL_GPU_STOREOP_STORE, + }; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL); + SDL_BindGPUGraphicsPipeline(pass, post.pipeline); + SDL_GPUTextureSamplerBinding tex { .texture = post_tex, .sampler = render_sampler }; + SDL_BindGPUFragmentSamplers(pass, 0, &tex, 1); + SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); + SDL_EndGPURenderPass(pass); +} + +void Renderer::draw(const CameraUBO& ubo) { + SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(dev); + + SDL_GPUTexture* swapchain; + uint32_t sw_w, sw_h; + SDL_WaitAndAcquireGPUSwapchainTexture(cmd, win, &swapchain, &sw_w, &sw_h); + + if (!swapchain) { + SDL_SubmitGPUCommandBuffer(cmd); + return; + } + + if (sw_w != render_w || sw_h != render_h) + resize_render_texture(sw_w, sw_h); + + pass_scene(cmd, ubo); + pass_blit(cmd, ubo); + pass_post(cmd, swapchain, ubo); + + SDL_SubmitGPUCommandBuffer(cmd); +} diff --git a/src/renderer.h b/src/renderer.h new file mode 100644 index 0000000..09f1ef1 --- /dev/null +++ b/src/renderer.h @@ -0,0 +1,34 @@ +#pragma once +#include "types.h" +#include "pipelines.h" +#include +#include + +struct Renderer { + SDL_GPUDevice* dev = nullptr; + SDL_Window* win = nullptr; + + ScenePipeline scene; + BlitPipeline blit; + PostPipeline post; + + SDL_GPUBuffer* vert_buff = nullptr; + SDL_GPUTexture* render_tex = nullptr; + SDL_GPUTexture* post_tex = nullptr; + SDL_GPUSampler* render_sampler = nullptr; + uint32_t render_w = 0, render_h = 0; + + std::vector vertices; + + bool init(SDL_Window* win); + void destroy(); + + void draw(const CameraUBO& ubo); + +private: + bool load_obj(); + void resize_render_texture(uint32_t w, uint32_t h); + void pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); + void pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); + void pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo); +}; diff --git a/src/tiny_obj_loader.h b/src/tiny_obj_loader.h new file mode 100644 index 0000000..2a949fd --- /dev/null +++ b/src/tiny_obj_loader.h @@ -0,0 +1,9267 @@ +/* +The MIT License (MIT) + +Copyright (c) 2012-Present, Syoyo Fujita and many contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// +// version 2.0.0 : Add new object oriented API. 1.x API is still provided. +// * Add python binding. +// * Support line primitive. +// * Support points primitive. +// * Support multiple search path for .mtl(v1 API). +// * Support vertex skinning weight `vw`(as an tinyobj +// extension). Note that this differs vertex weight([w] +// component in `v` line) +// * Support escaped whitespece in mtllib +// * Add robust triangulation using Mapbox +// earcut(TINYOBJLOADER_USE_MAPBOX_EARCUT). +// version 1.4.0 : Modifed ParseTextureNameAndOption API +// version 1.3.1 : Make ParseTextureNameAndOption API public +// version 1.3.0 : Separate warning and error message(breaking API of LoadObj) +// version 1.2.3 : Added color space extension('-colorspace') to tex opts. +// version 1.2.2 : Parse multiple group names. +// version 1.2.1 : Added initial support for line('l') primitive(PR #178) +// version 1.2.0 : Hardened implementation(#175) +// version 1.1.1 : Support smoothing groups(#162) +// version 1.1.0 : Support parsing vertex color(#144) +// version 1.0.8 : Fix parsing `g` tag just after `usemtl`(#138) +// version 1.0.7 : Support multiple tex options(#126) +// version 1.0.6 : Add TINYOBJLOADER_USE_DOUBLE option(#124) +// version 1.0.5 : Ignore `Tr` when `d` exists in MTL(#43) +// version 1.0.4 : Support multiple filenames for 'mtllib'(#112) +// version 1.0.3 : Support parsing texture options(#85) +// version 1.0.2 : Improve parsing speed by about a factor of 2 for large +// files(#105) +// version 1.0.1 : Fixes a shape is lost if obj ends with a 'usemtl'(#104) +// version 1.0.0 : Change data structure. Change license from BSD to MIT. +// + +// +// Use this in *one* .cc +// #define TINYOBJLOADER_IMPLEMENTATION +// #include "tiny_obj_loader.h" +// + +#ifndef TINY_OBJ_LOADER_H_ +#define TINY_OBJ_LOADER_H_ + +#include +#include +#include + +namespace tinyobj { + +// C++11 is now the minimum required standard. +#if __cplusplus < 201103L && (!defined(_MSVC_LANG) || _MSVC_LANG < 201103L) +#error "tinyobjloader requires C++11 or later. Compile with -std=c++11 or higher." +#endif +#define TINYOBJ_OVERRIDE override + +#ifdef __clang__ +#pragma clang diagnostic push +#if __has_warning("-Wzero-as-null-pointer-constant") +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif + +#pragma clang diagnostic ignored "-Wpadded" + +#endif + +// https://en.wikipedia.org/wiki/Wavefront_.obj_file says ... +// +// -blendu on | off # set horizontal texture blending +// (default on) +// -blendv on | off # set vertical texture blending +// (default on) +// -boost real_value # boost mip-map sharpness +// -mm base_value gain_value # modify texture map values (default +// 0 1) +// # base_value = brightness, +// gain_value = contrast +// -o u [v [w]] # Origin offset (default +// 0 0 0) +// -s u [v [w]] # Scale (default +// 1 1 1) +// -t u [v [w]] # Turbulence (default +// 0 0 0) +// -texres resolution # texture resolution to create +// -clamp on | off # only render texels in the clamped +// 0-1 range (default off) +// # When unclamped, textures are +// repeated across a surface, +// # when clamped, only texels which +// fall within the 0-1 +// # range are rendered. +// -bm mult_value # bump multiplier (for bump maps +// only) +// +// -imfchan r | g | b | m | l | z # specifies which channel of the file +// is used to +// # create a scalar or bump texture. +// r:red, g:green, +// # b:blue, m:matte, l:luminance, +// z:z-depth.. +// # (the default for bump is 'l' and +// for decal is 'm') +// bump -imfchan r bumpmap.tga # says to use the red channel of +// bumpmap.tga as the bumpmap +// +// For reflection maps... +// +// -type sphere # specifies a sphere for a "refl" +// reflection map +// -type cube_top | cube_bottom | # when using a cube map, the texture +// file for each +// cube_front | cube_back | # side of the cube is specified +// separately +// cube_left | cube_right +// +// TinyObjLoader extension. +// +// -colorspace SPACE # Color space of the texture. e.g. +// 'sRGB` or 'linear' +// + +#ifdef TINYOBJLOADER_USE_DOUBLE +//#pragma message "using double" +typedef double real_t; +#else +//#pragma message "using float" +typedef float real_t; +#endif + +typedef enum { + TEXTURE_TYPE_NONE, // default + TEXTURE_TYPE_SPHERE, + TEXTURE_TYPE_CUBE_TOP, + TEXTURE_TYPE_CUBE_BOTTOM, + TEXTURE_TYPE_CUBE_FRONT, + TEXTURE_TYPE_CUBE_BACK, + TEXTURE_TYPE_CUBE_LEFT, + TEXTURE_TYPE_CUBE_RIGHT +} texture_type_t; + +struct texture_option_t { + texture_type_t type; // -type (default TEXTURE_TYPE_NONE) + real_t sharpness; // -boost (default 1.0?) + real_t brightness; // base_value in -mm option (default 0) + real_t contrast; // gain_value in -mm option (default 1) + real_t origin_offset[3]; // -o u [v [w]] (default 0 0 0) + real_t scale[3]; // -s u [v [w]] (default 1 1 1) + real_t turbulence[3]; // -t u [v [w]] (default 0 0 0) + int texture_resolution; // -texres resolution (No default value in the spec. + // We'll use -1) + bool clamp; // -clamp (default false) + char imfchan; // -imfchan (the default for bump is 'l' and for decal is 'm') + bool blendu; // -blendu (default on) + bool blendv; // -blendv (default on) + real_t bump_multiplier; // -bm (for bump maps only, default 1.0) + + // extension + std::string colorspace; // Explicitly specify color space of stored texel + // value. Usually `sRGB` or `linear` (default empty). +}; + +struct material_t { + std::string name; + + real_t ambient[3]; + real_t diffuse[3]; + real_t specular[3]; + real_t transmittance[3]; + real_t emission[3]; + real_t shininess; + real_t ior; // index of refraction + real_t dissolve; // 1 == opaque; 0 == fully transparent + // illumination model (see http://www.fileformat.info/format/material/) + int illum; + + int dummy; // Suppress padding warning. + + std::string ambient_texname; // map_Ka. For ambient or ambient occlusion. + std::string diffuse_texname; // map_Kd + std::string specular_texname; // map_Ks + std::string specular_highlight_texname; // map_Ns + std::string bump_texname; // map_bump, map_Bump, bump + std::string displacement_texname; // disp + std::string alpha_texname; // map_d + std::string reflection_texname; // refl + + texture_option_t ambient_texopt; + texture_option_t diffuse_texopt; + texture_option_t specular_texopt; + texture_option_t specular_highlight_texopt; + texture_option_t bump_texopt; + texture_option_t displacement_texopt; + texture_option_t alpha_texopt; + texture_option_t reflection_texopt; + + // PBR extension + // http://exocortex.com/blog/extending_wavefront_mtl_to_support_pbr + real_t roughness; // [0, 1] default 0 + real_t metallic; // [0, 1] default 0 + real_t sheen; // [0, 1] default 0 + real_t clearcoat_thickness; // [0, 1] default 0 + real_t clearcoat_roughness; // [0, 1] default 0 + real_t anisotropy; // aniso. [0, 1] default 0 + real_t anisotropy_rotation; // anisor. [0, 1] default 0 + real_t pad0; + std::string roughness_texname; // map_Pr + std::string metallic_texname; // map_Pm + std::string sheen_texname; // map_Ps + std::string emissive_texname; // map_Ke + std::string normal_texname; // norm. For normal mapping. + + texture_option_t roughness_texopt; + texture_option_t metallic_texopt; + texture_option_t sheen_texopt; + texture_option_t emissive_texopt; + texture_option_t normal_texopt; + + int pad2; + + std::map unknown_parameter; + +#ifdef TINY_OBJ_LOADER_PYTHON_BINDING + // For pybind11 + std::array GetDiffuse() { + std::array values; + values[0] = double(diffuse[0]); + values[1] = double(diffuse[1]); + values[2] = double(diffuse[2]); + + return values; + } + + std::array GetSpecular() { + std::array values; + values[0] = double(specular[0]); + values[1] = double(specular[1]); + values[2] = double(specular[2]); + + return values; + } + + std::array GetTransmittance() { + std::array values; + values[0] = double(transmittance[0]); + values[1] = double(transmittance[1]); + values[2] = double(transmittance[2]); + + return values; + } + + std::array GetEmission() { + std::array values; + values[0] = double(emission[0]); + values[1] = double(emission[1]); + values[2] = double(emission[2]); + + return values; + } + + std::array GetAmbient() { + std::array values; + values[0] = double(ambient[0]); + values[1] = double(ambient[1]); + values[2] = double(ambient[2]); + + return values; + } + + void SetDiffuse(std::array &a) { + diffuse[0] = real_t(a[0]); + diffuse[1] = real_t(a[1]); + diffuse[2] = real_t(a[2]); + } + + void SetAmbient(std::array &a) { + ambient[0] = real_t(a[0]); + ambient[1] = real_t(a[1]); + ambient[2] = real_t(a[2]); + } + + void SetSpecular(std::array &a) { + specular[0] = real_t(a[0]); + specular[1] = real_t(a[1]); + specular[2] = real_t(a[2]); + } + + void SetTransmittance(std::array &a) { + transmittance[0] = real_t(a[0]); + transmittance[1] = real_t(a[1]); + transmittance[2] = real_t(a[2]); + } + + std::string GetCustomParameter(const std::string &key) { + std::map::const_iterator it = + unknown_parameter.find(key); + + if (it != unknown_parameter.end()) { + return it->second; + } + return std::string(); + } + +#endif +}; + +struct tag_t { + std::string name; + + std::vector intValues; + std::vector floatValues; + std::vector stringValues; +}; + +struct joint_and_weight_t { + int joint_id; + real_t weight; +}; + +struct skin_weight_t { + int vertex_id; // Corresponding vertex index in `attrib_t::vertices`. + // Compared to `index_t`, this index must be positive and + // start with 0(does not allow relative indexing) + std::vector weightValues; +}; + +// Index struct to support different indices for vtx/normal/texcoord. +// -1 means not used. +struct index_t { + int vertex_index; + int normal_index; + int texcoord_index; +}; + +struct mesh_t { + std::vector indices; + std::vector + num_face_vertices; // The number of vertices per + // face. 3 = triangle, 4 = quad, ... + std::vector material_ids; // per-face material ID + std::vector smoothing_group_ids; // per-face smoothing group + // ID(0 = off. positive value + // = group id) + std::vector tags; // SubD tag +}; + +// struct path_t { +// std::vector indices; // pairs of indices for lines +//}; + +struct lines_t { + // Linear flattened indices. + std::vector indices; // indices for vertices(poly lines) + std::vector num_line_vertices; // The number of vertices per line. +}; + +struct points_t { + std::vector indices; // indices for points +}; + +struct shape_t { + std::string name; + mesh_t mesh; + lines_t lines; + points_t points; +}; + +// Vertex attributes +struct attrib_t { + std::vector vertices; // 'v'(xyz) + + // For backward compatibility, we store vertex weight in separate array. + std::vector vertex_weights; // 'v'(w) + std::vector normals; // 'vn' + std::vector texcoords; // 'vt'(uv) + + // For backward compatibility, we store texture coordinate 'w' in separate + // array. + std::vector texcoord_ws; // 'vt'(w) + std::vector colors; // extension: vertex colors + + // + // TinyObj extension. + // + + // NOTE(syoyo): array index is based on the appearance order. + // To get a corresponding skin weight for a specific vertex id `vid`, + // Need to reconstruct a look up table: `skin_weight_t::vertex_id` == `vid` + // (e.g. using std::map, std::unordered_map) + std::vector skin_weights; + + attrib_t() {} + + // + // For pybind11 + // + const std::vector &GetVertices() const { return vertices; } + + const std::vector &GetVertexWeights() const { return vertex_weights; } +}; + +struct callback_t { + // W is optional and set to 1 if there is no `w` item in `v` line + void (*vertex_cb)(void *user_data, real_t x, real_t y, real_t z, real_t w); + void (*vertex_color_cb)(void *user_data, real_t x, real_t y, real_t z, + real_t r, real_t g, real_t b, bool has_color); + void (*normal_cb)(void *user_data, real_t x, real_t y, real_t z); + + // y and z are optional and set to 0 if there is no `y` and/or `z` item(s) in + // `vt` line. + void (*texcoord_cb)(void *user_data, real_t x, real_t y, real_t z); + + // called per 'f' line. num_indices is the number of face indices(e.g. 3 for + // triangle, 4 for quad) + // 0 will be passed for undefined index in index_t members. + void (*index_cb)(void *user_data, index_t *indices, int num_indices); + // `name` material name, `material_id` = the array index of material_t[]. -1 + // if + // a material not found in .mtl + void (*usemtl_cb)(void *user_data, const char *name, int material_id); + // `materials` = parsed material data. + void (*mtllib_cb)(void *user_data, const material_t *materials, + int num_materials); + // There may be multiple group names + void (*group_cb)(void *user_data, const char **names, int num_names); + void (*object_cb)(void *user_data, const char *name); + + callback_t() + : vertex_cb(NULL), + vertex_color_cb(NULL), + normal_cb(NULL), + texcoord_cb(NULL), + index_cb(NULL), + usemtl_cb(NULL), + mtllib_cb(NULL), + group_cb(NULL), + object_cb(NULL) {} +}; + +class MaterialReader { + public: + MaterialReader() {} + virtual ~MaterialReader(); + + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) = 0; +}; + +/// +/// Read .mtl from a file. +/// +class MaterialFileReader : public MaterialReader { + public: + // Path could contain separator(';' in Windows, ':' in Posix) + explicit MaterialFileReader(const std::string &mtl_basedir) + : m_mtlBaseDir(mtl_basedir) {} + virtual ~MaterialFileReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::string m_mtlBaseDir; +}; + +/// +/// Read .mtl from a stream. +/// +class MaterialStreamReader : public MaterialReader { + public: + explicit MaterialStreamReader(std::istream &inStream) + : m_inStream(inStream) {} + virtual ~MaterialStreamReader() TINYOBJ_OVERRIDE {} + virtual bool operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, std::string *warn, + std::string *err) TINYOBJ_OVERRIDE; + + private: + std::istream &m_inStream; +}; + +// v2 API +struct ObjReaderConfig { + bool triangulate; // triangulate polygon? + + // Currently not used. + // "simple" or empty: Create triangle fan + // "earcut": Use the algorithm based on Ear clipping + std::string triangulation_method; + + /// Parse vertex color. + /// If vertex color is not present, its filled with default value. + /// false = no vertex color + /// This will increase memory of parsed .obj + bool vertex_color; + + /// + /// Search path to .mtl file. + /// Default = "" = search from the same directory of .obj file. + /// Valid only when loading .obj from a file. + /// + std::string mtl_search_path; + + ObjReaderConfig() + : triangulate(true), triangulation_method("simple"), vertex_color(true) {} +}; + +/// +/// Wavefront .obj reader class(v2 API) +/// +class ObjReader { + public: + ObjReader() : valid_(false) {} + + /// + /// Load .obj and .mtl from a file. + /// + /// @param[in] filename wavefront .obj filename + /// @param[in] config Reader configuration + /// + bool ParseFromFile(const std::string &filename, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// Parse .obj from a text string. + /// Need to supply .mtl text string by `mtl_text`. + /// This function ignores `mtllib` line in .obj text. + /// + /// @param[in] obj_text wavefront .obj filename + /// @param[in] mtl_text wavefront .mtl filename + /// @param[in] config Reader configuration + /// + bool ParseFromString(const std::string &obj_text, const std::string &mtl_text, + const ObjReaderConfig &config = ObjReaderConfig()); + + /// + /// .obj was loaded or parsed correctly. + /// + bool Valid() const { return valid_; } + + const attrib_t &GetAttrib() const { return attrib_; } + + const std::vector &GetShapes() const { return shapes_; } + + const std::vector &GetMaterials() const { return materials_; } + + /// + /// Warning message(may be filled after `Load` or `Parse`) + /// + const std::string &Warning() const { return warning_; } + + /// + /// Error message(filled when `Load` or `Parse` failed) + /// + const std::string &Error() const { return error_; } + + private: + bool valid_; + + attrib_t attrib_; + std::vector shapes_; + std::vector materials_; + + std::string warning_; + std::string error_; +}; + +/// ==>>========= Legacy v1 API ============================================= + +/// Loads .obj from a file. +/// 'attrib', 'shapes' and 'materials' will be filled with parsed shape data +/// 'shapes' will be filled with parsed shape data +/// Returns true when loading .obj become success. +/// Returns warning message into `warn`, and error message into `err` +/// 'mtl_basedir' is optional, and used for base directory for .mtl file. +/// In default(`NULL'), .mtl file is searched from an application's working +/// directory. +/// 'triangulate' is optional, and used whether triangulate polygon face in .obj +/// or not. +/// Option 'default_vcols_fallback' specifies whether vertex colors should +/// always be defined, even if no colors are given (fallback to white). +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, + const char *mtl_basedir = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads .obj from a file with custom user callback. +/// .mtl is loaded as usual and parsed material_t data will be passed to +/// `callback.mtllib_cb`. +/// Returns true when loading .obj/.mtl become success. +/// Returns warning message into `warn`, and error message into `err` +/// See `examples/callback_api/` for how to use this function. +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data = NULL, + MaterialReader *readMatFn = NULL, + std::string *warn = NULL, std::string *err = NULL); + +/// Loads object from a std::istream, uses `readMatFn` to retrieve +/// std::istream for materials. +/// Returns true when loading .obj become success. +/// Returns warning and error message into `err` +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn = NULL, bool triangulate = true, + bool default_vcols_fallback = true); + +/// Loads materials into std::map +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err); + +/// +/// Parse texture name and texture option for custom texture parameter through +/// material::unknown_parameter +/// +/// @param[out] texname Parsed texture name +/// @param[out] texopt Parsed texopt +/// @param[in] linebuf Input string +/// +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf); + +/// =<<========== Legacy v1 API ============================================= + +} // namespace tinyobj + +#endif // TINY_OBJ_LOADER_H_ + +#ifdef TINYOBJLOADER_IMPLEMENTATION +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#endif + +#ifdef TINYOBJLOADER_USE_MMAP +#if !defined(_WIN32) +// POSIX headers for mmap +#include +#include +#include +#include +#endif +#endif // TINYOBJLOADER_USE_MMAP +#include +#include +#include + +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + +#ifdef TINYOBJLOADER_DONOT_INCLUDE_MAPBOX_EARCUT +// Assume earcut.hpp is included outside of tiny_obj_loader.h +#else + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Weverything" +#endif + +#include + +#include "mapbox/earcut.hpp" + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#endif + +#endif // TINYOBJLOADER_USE_MAPBOX_EARCUT + +#ifdef _WIN32 +// Converts a UTF-8 encoded string to a UTF-16 wide string for use with +// Windows file APIs that support Unicode paths (including paths longer than +// MAX_PATH when combined with the extended-length path prefix). +static std::wstring UTF8ToWchar(const std::string &str) { + if (str.empty()) return std::wstring(); + int size_needed = + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), + static_cast(str.size()), NULL, 0); + if (size_needed == 0) return std::wstring(); + std::wstring wstr(static_cast(size_needed), L'\0'); + int result = + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), + static_cast(str.size()), &wstr[0], size_needed); + if (result == 0) return std::wstring(); + return wstr; +} + +// Prepends the Windows extended-length path prefix ("\\?\") to an absolute +// path when the path length meets or exceeds MAX_PATH (260 characters). +// This allows Windows APIs to handle paths up to 32767 characters long. +// UNC paths (starting with "\\") are converted to "\\?\UNC\" form. +static std::wstring LongPathW(const std::wstring &wpath) { + const std::wstring kLongPathPrefix = L"\\\\?\\"; + const std::wstring kUNCPrefix = L"\\\\"; + const std::wstring kLongUNCPathPrefix = L"\\\\?\\UNC\\"; + + // Already has the extended-length prefix; return as-is. + if (wpath.size() >= kLongPathPrefix.size() && + wpath.substr(0, kLongPathPrefix.size()) == kLongPathPrefix) { + return wpath; + } + + // Only add the prefix when the path is long enough to require it. + if (wpath.size() < MAX_PATH) { + return wpath; + } + + // Normalize forward slashes to backslashes: the extended-length "\\?\" + // prefix requires backslash separators only. + std::wstring normalized = wpath; + for (std::wstring::size_type i = 0; i < normalized.size(); ++i) { + if (normalized[i] == L'/') normalized[i] = L'\\'; + } + + // UNC path: "\\server\share\..." -> "\\?\UNC\server\share\..." + if (normalized.size() >= kUNCPrefix.size() && + normalized.substr(0, kUNCPrefix.size()) == kUNCPrefix) { + return kLongUNCPathPrefix + normalized.substr(kUNCPrefix.size()); + } + + // Absolute path with drive letter: "C:\..." -> "\\?\C:\..." + if (normalized.size() >= 2 && normalized[1] == L':') { + return kLongPathPrefix + normalized; + } + + return normalized; +} +#endif // _WIN32 + +// -------------------------------------------------------------------------- +// Embedded fast_float v8.0.2 for high-performance, bit-exact float parsing. +// Disable by defining TINYOBJLOADER_DISABLE_FAST_FLOAT before including +// this file with TINYOBJLOADER_IMPLEMENTATION. +// -------------------------------------------------------------------------- +#ifndef TINYOBJLOADER_DISABLE_FAST_FLOAT + +// Standard headers needed by the embedded fast_float. +#include +#include + +namespace tinyobj_ff { + +// --- integral_constant, true_type, false_type --- +template +struct integral_constant { + static const T value = V; + typedef T value_type; + typedef integral_constant type; + operator value_type() const { return value; } +}; +typedef integral_constant true_type; +typedef integral_constant false_type; + +// --- is_same --- +template struct is_same : false_type {}; +template struct is_same : true_type {}; + +// --- enable_if --- +template struct enable_if {}; +template struct enable_if { typedef T type; }; + +// --- conditional --- +template struct conditional { typedef T type; }; +template struct conditional { typedef F type; }; + +// --- is_integral --- +template struct is_integral : false_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; +template <> struct is_integral : true_type {}; + +// --- is_signed --- +template struct is_signed : integral_constant {}; + +// --- underlying_type (uses compiler builtin) --- +template struct underlying_type { + typedef __underlying_type(T) type; +}; + +// --- ff_errc (replaces std::errc, our own enum - no system_error needed) --- +enum class ff_errc { ok = 0, invalid_argument = 22, result_out_of_range = 34 }; + +// --- min_val (replaces std::min, avoids Windows min/max macro conflicts) --- +template +inline T min_val(T a, T b) { return (b < a) ? b : a; } + +// --- copy_n --- +template +inline OutputIt copy_n(InputIt first, Size count, OutputIt result) { + for (Size i = 0; i < count; ++i) *result++ = *first++; + return result; +} + +// --- copy_backward --- +template +inline BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) { + while (first != last) *(--d_last) = *(--last); + return d_last; +} + +// --- fill --- +template +inline void fill(ForwardIt first, ForwardIt last, const T &value) { + for (; first != last; ++first) *first = value; +} + +// --- distance --- +template +inline typename conditional::type +distance(It first, It last) { + return last - first; +} + +} // namespace tinyobj_ff + +// --- Begin embedded fast_float v8.0.2 (MIT / Apache-2.0 / BSL-1.0) --- +// https://github.com/fastfloat/fast_float +// fast_float by Daniel Lemire +// fast_float by João Paulo Magalhaes +// +// +// with contributions from Eugene Golushkov +// with contributions from Maksim Kita +// with contributions from Marcin Wojdyr +// with contributions from Neal Richardson +// with contributions from Tim Paine +// with contributions from Fabio Pellacini +// with contributions from Lénárd Szolnoki +// with contributions from Jan Pharago +// with contributions from Maya Warrier +// with contributions from Taha Khokhar +// with contributions from Anders Dalvander +// +// +// Licensed under the Apache License, Version 2.0, or the +// MIT License or the Boost License. This file may not be copied, +// modified, or distributed except according to those terms. +// +// MIT License Notice +// +// MIT License +// +// Copyright (c) 2021 The fast_float authors +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// Apache License (Version 2.0) Notice +// +// Copyright 2021 The fast_float authors +// Licensed 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 +// +// BOOST License Notice +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + +#ifndef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H +#define FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifdef __has_include +#if __has_include() +#include +#endif +#endif + +// Testing for https://wg21.link/N3652, adopted in C++14 +#if defined(__cpp_constexpr) && __cpp_constexpr >= 201304 +#define FASTFLOAT_CONSTEXPR14 constexpr +#else +#define FASTFLOAT_CONSTEXPR14 +#endif + +#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L +#define FASTFLOAT_HAS_BIT_CAST 1 +#else +#define FASTFLOAT_HAS_BIT_CAST 0 +#endif + +#if defined(__cpp_lib_is_constant_evaluated) && \ + __cpp_lib_is_constant_evaluated >= 201811L +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 1 +#else +#define FASTFLOAT_HAS_IS_CONSTANT_EVALUATED 0 +#endif + +#if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L +#define FASTFLOAT_IF_CONSTEXPR17(x) if constexpr (x) +#else +#define FASTFLOAT_IF_CONSTEXPR17(x) if (x) +#endif + +// Testing for relevant C++20 constexpr library features +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED && FASTFLOAT_HAS_BIT_CAST && \ + defined(__cpp_lib_constexpr_algorithms) && \ + __cpp_lib_constexpr_algorithms >= 201806L /*For std::copy and std::fill*/ +#define FASTFLOAT_CONSTEXPR20 constexpr +#define FASTFLOAT_IS_CONSTEXPR 1 +#else +#define FASTFLOAT_CONSTEXPR20 +#define FASTFLOAT_IS_CONSTEXPR 0 +#endif + +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 0 +#else +#define FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE 1 +#endif + +#endif // FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H + +#ifndef FASTFLOAT_FLOAT_COMMON_H +#define FASTFLOAT_FLOAT_COMMON_H + +#include +#include +#include +#ifdef __has_include +#if __has_include() && (__cplusplus > 202002L || (defined(_MSVC_LANG) && (_MSVC_LANG > 202002L))) +#include +#endif +#endif + +#define FASTFLOAT_VERSION_MAJOR 8 +#define FASTFLOAT_VERSION_MINOR 0 +#define FASTFLOAT_VERSION_PATCH 2 + +#define FASTFLOAT_STRINGIZE_IMPL(x) #x +#define FASTFLOAT_STRINGIZE(x) FASTFLOAT_STRINGIZE_IMPL(x) + +#define FASTFLOAT_VERSION_STR \ + FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MAJOR) \ + "." FASTFLOAT_STRINGIZE(FASTFLOAT_VERSION_MINOR) "." FASTFLOAT_STRINGIZE( \ + FASTFLOAT_VERSION_PATCH) + +#define FASTFLOAT_VERSION \ + (FASTFLOAT_VERSION_MAJOR * 10000 + FASTFLOAT_VERSION_MINOR * 100 + \ + FASTFLOAT_VERSION_PATCH) + +namespace fast_float { + +enum class chars_format : uint64_t; + +namespace detail { +constexpr chars_format basic_json_fmt = chars_format(1 << 5); +constexpr chars_format basic_fortran_fmt = chars_format(1 << 6); +} // namespace detail + +enum class chars_format : uint64_t { + scientific = 1 << 0, + fixed = 1 << 2, + hex = 1 << 3, + no_infnan = 1 << 4, + // RFC 8259: https://datatracker.ietf.org/doc/html/rfc8259#section-6 + json = uint64_t(detail::basic_json_fmt) | fixed | scientific | no_infnan, + // Extension of RFC 8259 where, e.g., "inf" and "nan" are allowed. + json_or_infnan = uint64_t(detail::basic_json_fmt) | fixed | scientific, + fortran = uint64_t(detail::basic_fortran_fmt) | fixed | scientific, + general = fixed | scientific, + allow_leading_plus = 1 << 7, + skip_white_space = 1 << 8, +}; + +template struct from_chars_result_t { + UC const *ptr; + tinyobj_ff::ff_errc ec; +}; + +using from_chars_result = from_chars_result_t; + +template struct parse_options_t { + constexpr explicit parse_options_t(chars_format fmt = chars_format::general, + UC dot = UC('.'), int b = 10) + : format(fmt), decimal_point(dot), base(b) {} + + /** Which number formats are accepted */ + chars_format format; + /** The character used as decimal point */ + UC decimal_point; + /** The base used for integers */ + int base; +}; + +using parse_options = parse_options_t; + +} // namespace fast_float + +#if FASTFLOAT_HAS_BIT_CAST +#include +#endif + +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \ + defined(__MINGW64__) || defined(__s390x__) || \ + (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || \ + defined(__PPC64LE__)) || \ + defined(__loongarch64)) +#define FASTFLOAT_64BIT 1 +#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__arm__) || defined(_M_ARM) || defined(__ppc__) || \ + defined(__MINGW32__) || defined(__EMSCRIPTEN__)) +#define FASTFLOAT_32BIT 1 +#else + // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow. +// We can never tell the register width, but the SIZE_MAX is a good +// approximation. UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max +// portability. +#if SIZE_MAX == 0xffff +#error Unknown platform (16-bit, unsupported) +#elif SIZE_MAX == 0xffffffff +#define FASTFLOAT_32BIT 1 +#elif SIZE_MAX == 0xffffffffffffffff +#define FASTFLOAT_64BIT 1 +#else +#error Unknown platform (not 32-bit, not 64-bit?) +#endif +#endif + +#if ((defined(_WIN32) || defined(_WIN64)) && !defined(__clang__)) || \ + (defined(_M_ARM64) && !defined(__MINGW32__)) +#include +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#define FASTFLOAT_VISUAL_STUDIO 1 +#endif + +#if defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#elif defined _WIN32 +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#if defined(__APPLE__) || defined(__FreeBSD__) +#include +#elif defined(sun) || defined(__sun) +#include +#elif defined(__MVS__) +#include +#else +#ifdef __has_include +#if __has_include() +#include +#endif //__has_include() +#endif //__has_include +#endif +# +#ifndef __BYTE_ORDER__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#ifndef __ORDER_LITTLE_ENDIAN__ +// safe choice +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#endif +# +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define FASTFLOAT_IS_BIG_ENDIAN 0 +#else +#define FASTFLOAT_IS_BIG_ENDIAN 1 +#endif +#endif + +#if defined(__SSE2__) || (defined(FASTFLOAT_VISUAL_STUDIO) && \ + (defined(_M_AMD64) || defined(_M_X64) || \ + (defined(_M_IX86_FP) && _M_IX86_FP == 2))) +#define FASTFLOAT_SSE2 1 +#endif + +#if defined(__aarch64__) || defined(_M_ARM64) +#define FASTFLOAT_NEON 1 +#endif + +#if defined(FASTFLOAT_SSE2) || defined(FASTFLOAT_NEON) +#define FASTFLOAT_HAS_SIMD 1 +#endif + +#if defined(__GNUC__) +// disable -Wcast-align=strict (GCC only) +#define FASTFLOAT_SIMD_DISABLE_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-align\"") +#else +#define FASTFLOAT_SIMD_DISABLE_WARNINGS +#endif + +#if defined(__GNUC__) +#define FASTFLOAT_SIMD_RESTORE_WARNINGS _Pragma("GCC diagnostic pop") +#else +#define FASTFLOAT_SIMD_RESTORE_WARNINGS +#endif + +#ifdef FASTFLOAT_VISUAL_STUDIO +#define fastfloat_really_inline __forceinline +#else +#define fastfloat_really_inline inline __attribute__((always_inline)) +#endif + +#ifndef FASTFLOAT_ASSERT +#define FASTFLOAT_ASSERT(x) \ + { ((void)(x)); } +#endif + +#ifndef FASTFLOAT_DEBUG_ASSERT +#define FASTFLOAT_DEBUG_ASSERT(x) \ + { ((void)(x)); } +#endif + +// rust style `try!()` macro, or `?` operator +#define FASTFLOAT_TRY(x) \ + { \ + if (!(x)) \ + return false; \ + } + +#define FASTFLOAT_ENABLE_IF(...) \ + typename tinyobj_ff::enable_if<(__VA_ARGS__), int>::type + +namespace fast_float { + +fastfloat_really_inline constexpr bool cpp20_and_in_constexpr() { +#if FASTFLOAT_HAS_IS_CONSTANT_EVALUATED + return std::is_constant_evaluated(); +#else + return false; +#endif +} + +template +struct is_supported_float_type + : tinyobj_ff::integral_constant< + bool, tinyobj_ff::is_same::value || tinyobj_ff::is_same::value +#ifdef __STDCPP_FLOAT64_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_FLOAT32_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_FLOAT16_T__ + || tinyobj_ff::is_same::value +#endif +#ifdef __STDCPP_BFLOAT16_T__ + || tinyobj_ff::is_same::value +#endif + > { +}; + +template +using equiv_uint_t = typename tinyobj_ff::conditional< + sizeof(T) == 1, uint8_t, + typename tinyobj_ff::conditional< + sizeof(T) == 2, uint16_t, + typename tinyobj_ff::conditional::type>::type>::type; + +template struct is_supported_integer_type : tinyobj_ff::is_integral {}; + +template +struct is_supported_char_type + : tinyobj_ff::integral_constant::value || + tinyobj_ff::is_same::value || + tinyobj_ff::is_same::value || + tinyobj_ff::is_same::value +#ifdef __cpp_char8_t + || tinyobj_ff::is_same::value +#endif + > { +}; + +// Compares two ASCII strings in a case insensitive manner. +template +inline FASTFLOAT_CONSTEXPR14 bool +fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase, + size_t length) { + for (size_t i = 0; i < length; ++i) { + UC const actual = actual_mixedcase[i]; + if ((actual < 256 ? actual | 32 : actual) != expected_lowercase[i]) { + return false; + } + } + return true; +} + +#ifndef FLT_EVAL_METHOD +#error "FLT_EVAL_METHOD should be defined, please include cfloat." +#endif + +// a pointer and a length to a contiguous block of memory +template struct span { + T const *ptr; + size_t length; + + constexpr span(T const *_ptr, size_t _length) : ptr(_ptr), length(_length) {} + + constexpr span() : ptr(nullptr), length(0) {} + + constexpr size_t len() const noexcept { return length; } + + FASTFLOAT_CONSTEXPR14 const T &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return ptr[index]; + } +}; + +struct value128 { + uint64_t low; + uint64_t high; + + constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {} + + constexpr value128() : low(0), high(0) {} +}; + +/* Helper C++14 constexpr generic implementation of leading_zeroes */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int +leading_zeroes_generic(uint64_t input_num, int last_bit = 0) { + if (input_num & uint64_t(0xffffffff00000000)) { + input_num >>= 32; + last_bit |= 32; + } + if (input_num & uint64_t(0xffff0000)) { + input_num >>= 16; + last_bit |= 16; + } + if (input_num & uint64_t(0xff00)) { + input_num >>= 8; + last_bit |= 8; + } + if (input_num & uint64_t(0xf0)) { + input_num >>= 4; + last_bit |= 4; + } + if (input_num & uint64_t(0xc)) { + input_num >>= 2; + last_bit |= 2; + } + if (input_num & uint64_t(0x2)) { /* input_num >>= 1; */ + last_bit |= 1; + } + return 63 - last_bit; +} + +/* result might be undefined when input_num is zero */ +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 int +leading_zeroes(uint64_t input_num) { + assert(input_num > 0); + if (cpp20_and_in_constexpr()) { + return leading_zeroes_generic(input_num); + } +#ifdef FASTFLOAT_VISUAL_STUDIO +#if defined(_M_X64) || defined(_M_ARM64) + unsigned long leading_zero = 0; + // Search the mask data from most significant bit (MSB) + // to least significant bit (LSB) for a set bit (1). + _BitScanReverse64(&leading_zero, input_num); + return (int)(63 - leading_zero); +#else + return leading_zeroes_generic(input_num); +#endif +#else + return __builtin_clzll(input_num); +#endif +} + +// slow emulation routine for 32-bit +fastfloat_really_inline constexpr uint64_t emulu(uint32_t x, uint32_t y) { + return x * (uint64_t)y; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +umul128_generic(uint64_t ab, uint64_t cd, uint64_t *hi) { + uint64_t ad = emulu((uint32_t)(ab >> 32), (uint32_t)cd); + uint64_t bd = emulu((uint32_t)ab, (uint32_t)cd); + uint64_t adbc = ad + emulu((uint32_t)ab, (uint32_t)(cd >> 32)); + uint64_t adbc_carry = (uint64_t)(adbc < ad); + uint64_t lo = bd + (adbc << 32); + *hi = emulu((uint32_t)(ab >> 32), (uint32_t)(cd >> 32)) + (adbc >> 32) + + (adbc_carry << 32) + (uint64_t)(lo < bd); + return lo; +} + +#ifdef FASTFLOAT_32BIT + +// slow emulation routine for 32-bit +#if !defined(__MINGW64__) +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t _umul128(uint64_t ab, + uint64_t cd, + uint64_t *hi) { + return umul128_generic(ab, cd, hi); +} +#endif // !__MINGW64__ + +#endif // FASTFLOAT_32BIT + +// compute 64-bit a*b +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +full_multiplication(uint64_t a, uint64_t b) { + if (cpp20_and_in_constexpr()) { + value128 answer; + answer.low = umul128_generic(a, b, &answer.high); + return answer; + } + value128 answer; +#if defined(_M_ARM64) && !defined(__MINGW32__) + // ARM64 has native support for 64-bit multiplications, no need to emulate + // But MinGW on ARM64 doesn't have native support for 64-bit multiplications + answer.high = __umulh(a, b); + answer.low = a * b; +#elif defined(FASTFLOAT_32BIT) || \ + (defined(_WIN64) && !defined(__clang__) && !defined(_M_ARM64)) + answer.low = _umul128(a, b, &answer.high); // _umul128 not available on ARM64 +#elif defined(FASTFLOAT_64BIT) && defined(__SIZEOF_INT128__) + __uint128_t r = ((__uint128_t)a) * b; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); +#else + answer.low = umul128_generic(a, b, &answer.high); +#endif + return answer; +} + +struct adjusted_mantissa { + uint64_t mantissa{0}; + int32_t power2{0}; // a negative value indicates an invalid result + adjusted_mantissa() = default; + + constexpr bool operator==(adjusted_mantissa const &o) const { + return mantissa == o.mantissa && power2 == o.power2; + } + + constexpr bool operator!=(adjusted_mantissa const &o) const { + return mantissa != o.mantissa || power2 != o.power2; + } +}; + +// Bias so we can get the real exponent with an invalid adjusted_mantissa. +constexpr static int32_t invalid_am_bias = -0x8000; + +// used for binary_format_lookup_tables::max_mantissa +constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; + +template struct binary_format_lookup_tables; + +template struct binary_format : binary_format_lookup_tables { + using equiv_uint = equiv_uint_t; + + static constexpr int mantissa_explicit_bits(); + static constexpr int minimum_exponent(); + static constexpr int infinite_power(); + static constexpr int sign_index(); + static constexpr int + min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST + static constexpr int max_exponent_fast_path(); + static constexpr int max_exponent_round_to_even(); + static constexpr int min_exponent_round_to_even(); + static constexpr uint64_t max_mantissa_fast_path(int64_t power); + static constexpr uint64_t + max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST + static constexpr int largest_power_of_ten(); + static constexpr int smallest_power_of_ten(); + static constexpr T exact_power_of_ten(int64_t power); + static constexpr size_t max_digits(); + static constexpr equiv_uint exponent_mask(); + static constexpr equiv_uint mantissa_mask(); + static constexpr equiv_uint hidden_bit_mask(); +}; + +template struct binary_format_lookup_tables { + static constexpr double powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + + // Largest integer value v so that (5**index * v) <= 1<<53. + // 0x20000000000000 == 1 << 53 + static constexpr uint64_t max_mantissa[] = { + 0x20000000000000, + 0x20000000000000 / 5, + 0x20000000000000 / (5 * 5), + 0x20000000000000 / (5 * 5 * 5), + 0x20000000000000 / (5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555), + 0x20000000000000 / (constant_55555 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x20000000000000 / + (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5), + 0x20000000000000 / (constant_55555 * constant_55555 * constant_55555 * + constant_55555 * 5 * 5 * 5 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr double binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template struct binary_format_lookup_tables { + static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, + 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + + // Largest integer value v so that (5**index * v) <= 1<<24. + // 0x1000000 == 1<<24 + static constexpr uint64_t max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr float binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -22; +#endif +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return 0; +#else + return -10; +#endif +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 52; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 23; +} + +template <> +inline constexpr int binary_format::max_exponent_round_to_even() { + return 10; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -4; +} + +template <> +inline constexpr int binary_format::min_exponent_round_to_even() { + return -17; +} + +template <> inline constexpr int binary_format::minimum_exponent() { + return -1023; +} + +template <> inline constexpr int binary_format::minimum_exponent() { + return -127; +} + +template <> inline constexpr int binary_format::infinite_power() { + return 0x7FF; +} + +template <> inline constexpr int binary_format::infinite_power() { + return 0xFF; +} + +template <> inline constexpr int binary_format::sign_index() { + return 63; +} + +template <> inline constexpr int binary_format::sign_index() { + return 31; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 22; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 10; +} + +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +// credit: Jakub Jelínek +#ifdef __STDCPP_FLOAT16_T__ +template struct binary_format_lookup_tables { + static constexpr std::float16_t powers_of_ten[] = {1e0f16, 1e1f16, 1e2f16, + 1e3f16, 1e4f16}; + + // Largest integer value v so that (5**index * v) <= 1<<11. + // 0x800 == 1<<11 + static constexpr uint64_t max_mantissa[] = {0x800, + 0x800 / 5, + 0x800 / (5 * 5), + 0x800 / (5 * 5 * 5), + 0x800 / (5 * 5 * 5 * 5), + 0x800 / (constant_55555)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr std::float16_t + binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t + binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr std::float16_t +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7C00; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x03FF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0400; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 4; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 10; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 4 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { + return 0; +} + +template <> +inline constexpr int +binary_format::max_exponent_round_to_even() { + return 5; +} + +template <> +inline constexpr int +binary_format::min_exponent_round_to_even() { + return -22; +} + +template <> +inline constexpr int binary_format::minimum_exponent() { + return -15; +} + +template <> +inline constexpr int binary_format::infinite_power() { + return 0x1F; +} + +template <> inline constexpr int binary_format::sign_index() { + return 15; +} + +template <> +inline constexpr int binary_format::largest_power_of_ten() { + return 4; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -27; +} + +template <> +inline constexpr size_t binary_format::max_digits() { + return 22; +} +#endif // __STDCPP_FLOAT16_T__ + +// credit: Jakub Jelínek +#ifdef __STDCPP_BFLOAT16_T__ +template struct binary_format_lookup_tables { + static constexpr std::bfloat16_t powers_of_ten[] = {1e0bf16, 1e1bf16, 1e2bf16, + 1e3bf16}; + + // Largest integer value v so that (5**index * v) <= 1<<8. + // 0x100 == 1<<8 + static constexpr uint64_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5), + 0x100 / (5 * 5 * 5), + 0x100 / (5 * 5 * 5 * 5)}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr std::bfloat16_t + binary_format_lookup_tables::powers_of_ten[]; + +template +constexpr uint64_t + binary_format_lookup_tables::max_mantissa[]; + +#endif + +template <> +inline constexpr std::bfloat16_t +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr int binary_format::max_exponent_fast_path() { + return 3; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7F80; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x007F; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0080; +} + +template <> +inline constexpr int binary_format::mantissa_explicit_bits() { + return 7; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path() { + return uint64_t(2) << mantissa_explicit_bits(); +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 3 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr int binary_format::min_exponent_fast_path() { + return 0; +} + +template <> +inline constexpr int +binary_format::max_exponent_round_to_even() { + return 3; +} + +template <> +inline constexpr int +binary_format::min_exponent_round_to_even() { + return -24; +} + +template <> +inline constexpr int binary_format::minimum_exponent() { + return -127; +} + +template <> +inline constexpr int binary_format::infinite_power() { + return 0xFF; +} + +template <> inline constexpr int binary_format::sign_index() { + return 15; +} + +template <> +inline constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -60; +} + +template <> +inline constexpr size_t binary_format::max_digits() { + return 98; +} +#endif // __STDCPP_BFLOAT16_T__ + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 22 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr uint64_t +binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 10 + // + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)max_mantissa[0], max_mantissa[power]; +} + +template <> +inline constexpr double +binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> +inline constexpr float binary_format::exact_power_of_ten(int64_t power) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + return (void)powers_of_ten[0], powers_of_ten[power]; +} + +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 308; +} + +template <> inline constexpr int binary_format::largest_power_of_ten() { + return 38; +} + +template <> +inline constexpr int binary_format::smallest_power_of_ten() { + return -342; +} + +template <> inline constexpr int binary_format::smallest_power_of_ten() { + return -64; +} + +template <> inline constexpr size_t binary_format::max_digits() { + return 769; +} + +template <> inline constexpr size_t binary_format::max_digits() { + return 114; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7F800000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::exponent_mask() { + return 0x7FF0000000000000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x007FFFFF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::mantissa_mask() { + return 0x000FFFFFFFFFFFFF; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x00800000; +} + +template <> +inline constexpr binary_format::equiv_uint +binary_format::hidden_bit_mask() { + return 0x0010000000000000; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +to_float(bool negative, adjusted_mantissa am, T &value) { + using equiv_uint = equiv_uint_t; + equiv_uint word = equiv_uint(am.mantissa); + word = equiv_uint(word | equiv_uint(am.power2) + << binary_format::mantissa_explicit_bits()); + word = + equiv_uint(word | equiv_uint(negative) << binary_format::sign_index()); +#if FASTFLOAT_HAS_BIT_CAST + value = std::bit_cast(word); +#else + ::memcpy(&value, &word, sizeof(T)); +#endif +} + +template struct space_lut { + static constexpr bool value[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr bool space_lut::value[]; + +#endif + +template constexpr bool is_space(UC c) { + return c < 256 && space_lut<>::value[uint8_t(c)]; +} + +template static constexpr uint64_t int_cmp_zeros() { + static_assert((sizeof(UC) == 1) || (sizeof(UC) == 2) || (sizeof(UC) == 4), + "Unsupported character size"); + return (sizeof(UC) == 1) ? 0x3030303030303030 + : (sizeof(UC) == 2) + ? (uint64_t(UC('0')) << 48 | uint64_t(UC('0')) << 32 | + uint64_t(UC('0')) << 16 | UC('0')) + : (uint64_t(UC('0')) << 32 | UC('0')); +} + +template static constexpr int int_cmp_len() { + return sizeof(uint64_t) / sizeof(UC); +} + +template constexpr UC const *str_const_nan(); + +template <> constexpr char const *str_const_nan() { return "nan"; } + +template <> constexpr wchar_t const *str_const_nan() { return L"nan"; } + +template <> constexpr char16_t const *str_const_nan() { + return u"nan"; +} + +template <> constexpr char32_t const *str_const_nan() { + return U"nan"; +} + +#ifdef __cpp_char8_t +template <> constexpr char8_t const *str_const_nan() { + return u8"nan"; +} +#endif + +template constexpr UC const *str_const_inf(); + +template <> constexpr char const *str_const_inf() { return "infinity"; } + +template <> constexpr wchar_t const *str_const_inf() { + return L"infinity"; +} + +template <> constexpr char16_t const *str_const_inf() { + return u"infinity"; +} + +template <> constexpr char32_t const *str_const_inf() { + return U"infinity"; +} + +#ifdef __cpp_char8_t +template <> constexpr char8_t const *str_const_inf() { + return u8"infinity"; +} +#endif + +template struct int_luts { + static constexpr uint8_t chdigit[] = { + 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, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, + 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 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, 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, 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, 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, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255}; + + static constexpr size_t maxdigits_u64[] = { + 64, 41, 32, 28, 25, 23, 22, 21, 20, 19, 18, 18, 17, 17, 16, 16, 16, 16, + 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13}; + + static constexpr uint64_t min_safe_u64[] = { + 9223372036854775808ull, 12157665459056928801ull, 4611686018427387904, + 7450580596923828125, 4738381338321616896, 3909821048582988049, + 9223372036854775808ull, 12157665459056928801ull, 10000000000000000000ull, + 5559917313492231481, 2218611106740436992, 8650415919381337933, + 2177953337809371136, 6568408355712890625, 1152921504606846976, + 2862423051509815793, 6746640616477458432, 15181127029874798299ull, + 1638400000000000000, 3243919932521508681, 6221821273427820544, + 11592836324538749809ull, 876488338465357824, 1490116119384765625, + 2481152873203736576, 4052555153018976267, 6502111422497947648, + 10260628712958602189ull, 15943230000000000000ull, 787662783788549761, + 1152921504606846976, 1667889514952984961, 2386420683693101056, + 3379220508056640625, 4738381338321616896}; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint8_t int_luts::chdigit[]; + +template constexpr size_t int_luts::maxdigits_u64[]; + +template constexpr uint64_t int_luts::min_safe_u64[]; + +#endif + +template +fastfloat_really_inline constexpr uint8_t ch_to_digit(UC c) { + return int_luts<>::chdigit[static_cast(c)]; +} + +fastfloat_really_inline constexpr size_t max_digits_u64(int base) { + return int_luts<>::maxdigits_u64[base - 2]; +} + +// If a u64 is exactly max_digits_u64() in length, this is +// the value below which it has definitely overflowed. +fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) { + return int_luts<>::min_safe_u64[base - 2]; +} + +static_assert(tinyobj_ff::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for double"); +static_assert(std::numeric_limits::is_iec559, + "double must fulfill the requirements of IEC 559 (IEEE 754)"); + +static_assert(tinyobj_ff::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for float"); +static_assert(std::numeric_limits::is_iec559, + "float must fulfill the requirements of IEC 559 (IEEE 754)"); + +#ifdef __STDCPP_FLOAT64_T__ +static_assert(tinyobj_ff::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for std::float64_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float64_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT64_T__ + +#ifdef __STDCPP_FLOAT32_T__ +static_assert(tinyobj_ff::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for std::float32_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float32_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT32_T__ + +#ifdef __STDCPP_FLOAT16_T__ +static_assert( + tinyobj_ff::is_same::equiv_uint, uint16_t>::value, + "equiv_uint should be uint16_t for std::float16_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::float16_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_FLOAT16_T__ + +#ifdef __STDCPP_BFLOAT16_T__ +static_assert( + tinyobj_ff::is_same::equiv_uint, uint16_t>::value, + "equiv_uint should be uint16_t for std::bfloat16_t"); +static_assert( + std::numeric_limits::is_iec559, + "std::bfloat16_t must fulfill the requirements of IEC 559 (IEEE 754)"); +#endif // __STDCPP_BFLOAT16_T__ + +constexpr chars_format operator~(chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(~static_cast(rhs)); +} + +constexpr chars_format operator&(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) & + static_cast(rhs)); +} + +constexpr chars_format operator|(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) | + static_cast(rhs)); +} + +constexpr chars_format operator^(chars_format lhs, chars_format rhs) noexcept { + using int_type = tinyobj_ff::underlying_type::type; + return static_cast(static_cast(lhs) ^ + static_cast(rhs)); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator&=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs & rhs); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator|=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs | rhs); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 chars_format & +operator^=(chars_format &lhs, chars_format rhs) noexcept { + return lhs = (lhs ^ rhs); +} + +namespace detail { +// adjust for deprecated feature macros +constexpr chars_format adjust_for_feature_macros(chars_format fmt) { + return fmt +#ifdef FASTFLOAT_ALLOWS_LEADING_PLUS + | chars_format::allow_leading_plus +#endif +#ifdef FASTFLOAT_SKIP_WHITE_SPACE + | chars_format::skip_white_space +#endif + ; +} +} // namespace detail + +} // namespace fast_float + +#endif + + +#ifndef FASTFLOAT_FAST_FLOAT_H +#define FASTFLOAT_FAST_FLOAT_H + + +namespace fast_float { +/** + * This function parses the character sequence [first,last) for a number. It + * parses floating-point numbers expecting a locale-indepent format equivalent + * to what is used by std::strtod in the default ("C") locale. The resulting + * floating-point value is the closest floating-point values (using either float + * or double), using the "round to even" convention for values that would + * otherwise fall right in-between two values. That is, we provide exact parsing + * according to the IEEE standard. + * + * Given a successful parse, the pointer (`ptr`) in the returned value is set to + * point right after the parsed number, and the `value` referenced is set to the + * parsed value. In case of error, the returned `ec` contains a representative + * error, otherwise the default (`tinyobj_ff::ff_errc()`) value is stored. + * + * The implementation does not throw and does not allocate memory (e.g., with + * `new` or `malloc`). + * + * Like the C++17 standard, the `fast_float::from_chars` functions take an + * optional last argument of the type `fast_float::chars_format`. It is a bitset + * value: we check whether `fmt & fast_float::chars_format::fixed` and `fmt & + * fast_float::chars_format::scientific` are set to determine whether we allow + * the fixed point and scientific notation respectively. The default is + * `fast_float::chars_format::general` which allows both `fixed` and + * `scientific`. + */ +template ::value)> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt = chars_format::general) noexcept; + +/** + * Like from_chars, but accepts an `options` argument to govern number parsing. + * Both for floating-point types and integer types. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept; + +/** + * from_chars for integer types. + */ +template ::value)> +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept; + +} // namespace fast_float + +#endif // FASTFLOAT_FAST_FLOAT_H + +#ifndef FASTFLOAT_ASCII_NUMBER_H +#define FASTFLOAT_ASCII_NUMBER_H + +#include +#include +#include + + +#ifdef FASTFLOAT_SSE2 +#include +#endif + +#ifdef FASTFLOAT_NEON +#include +#endif + +namespace fast_float { + +template fastfloat_really_inline constexpr bool has_simd_opt() { +#ifdef FASTFLOAT_HAS_SIMD + return tinyobj_ff::is_same::value; +#else + return false; +#endif +} + +// Next function can be micro-optimized, but compilers are entirely +// able to optimize it well. +template +fastfloat_really_inline constexpr bool is_integer(UC c) noexcept { + return !(c > UC('9') || c < UC('0')); +} + +fastfloat_really_inline constexpr uint64_t byteswap(uint64_t val) { + return (val & 0xFF00000000000000) >> 56 | (val & 0x00FF000000000000) >> 40 | + (val & 0x0000FF0000000000) >> 24 | (val & 0x000000FF00000000) >> 8 | + (val & 0x00000000FF000000) << 8 | (val & 0x0000000000FF0000) << 24 | + (val & 0x000000000000FF00) << 40 | (val & 0x00000000000000FF) << 56; +} + +// Read 8 UC into a u64. Truncates UC if not char. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +read8_to_u64(UC const *chars) { + if (cpp20_and_in_constexpr() || !tinyobj_ff::is_same::value) { + uint64_t val = 0; + for (int i = 0; i < 8; ++i) { + val |= uint64_t(uint8_t(*chars)) << (i * 8); + ++chars; + } + return val; + } + uint64_t val; + ::memcpy(&val, chars, sizeof(uint64_t)); +#if FASTFLOAT_IS_BIG_ENDIAN == 1 + // Need to read as-if the number was in little-endian order. + val = byteswap(val); +#endif + return val; +} + +#ifdef FASTFLOAT_SSE2 + +fastfloat_really_inline uint64_t simd_read8_to_u64(__m128i const data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + __m128i const packed = _mm_packus_epi16(data, data); +#ifdef FASTFLOAT_64BIT + return uint64_t(_mm_cvtsi128_si64(packed)); +#else + uint64_t value; + // Visual Studio + older versions of GCC don't support _mm_storeu_si64 + _mm_storel_epi64(reinterpret_cast<__m128i *>(&value), packed); + return value; +#endif + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#elif defined(FASTFLOAT_NEON) + +fastfloat_really_inline uint64_t simd_read8_to_u64(uint16x8_t const data) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + uint8x8_t utf8_packed = vmovn_u16(data); + return vget_lane_u64(vreinterpret_u64_u8(utf8_packed), 0); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +fastfloat_really_inline uint64_t simd_read8_to_u64(char16_t const *chars) { + FASTFLOAT_SIMD_DISABLE_WARNINGS + return simd_read8_to_u64( + vld1q_u16(reinterpret_cast(chars))); + FASTFLOAT_SIMD_RESTORE_WARNINGS +} + +#endif // FASTFLOAT_SSE2 + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +uint64_t simd_read8_to_u64(UC const *) { + return 0; +} + +// credit @aqrit +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint32_t +parse_eight_digits_unrolled(uint64_t val) { + uint64_t const mask = 0x000000FF000000FF; + uint64_t const mul1 = 0x000F424000000064; // 100 + (1000000ULL << 32) + uint64_t const mul2 = 0x0000271000000001; // 1 + (10000ULL << 32) + val -= 0x3030303030303030; + val = (val * 10) + (val >> 8); // val = (val * 2561) >> 8; + val = (((val & mask) * mul1) + (((val >> 16) & mask) * mul2)) >> 32; + return uint32_t(val); +} + +// Call this if chars are definitely 8 digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint32_t +parse_eight_digits_unrolled(UC const *chars) noexcept { + if (cpp20_and_in_constexpr() || !has_simd_opt()) { + return parse_eight_digits_unrolled(read8_to_u64(chars)); // truncation okay + } + return parse_eight_digits_unrolled(simd_read8_to_u64(chars)); +} + +// credit @aqrit +fastfloat_really_inline constexpr bool +is_made_of_eight_digits_fast(uint64_t val) noexcept { + return !((((val + 0x4646464646464646) | (val - 0x3030303030303030)) & + 0x8080808080808080)); +} + +#ifdef FASTFLOAT_HAS_SIMD + +// Call this if chars might not be 8 digits. +// Using this style (instead of is_made_of_eight_digits_fast() then +// parse_eight_digits_unrolled()) ensures we don't load SIMD registers twice. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +simd_parse_if_eight_digits_unrolled(char16_t const *chars, + uint64_t &i) noexcept { + if (cpp20_and_in_constexpr()) { + return false; + } +#ifdef FASTFLOAT_SSE2 + FASTFLOAT_SIMD_DISABLE_WARNINGS + __m128i const data = + _mm_loadu_si128(reinterpret_cast<__m128i const *>(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + __m128i const t0 = _mm_add_epi16(data, _mm_set1_epi16(32720)); + __m128i const t1 = _mm_cmpgt_epi16(t0, _mm_set1_epi16(-32759)); + + if (_mm_movemask_epi8(t1) == 0) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#elif defined(FASTFLOAT_NEON) + FASTFLOAT_SIMD_DISABLE_WARNINGS + uint16x8_t const data = vld1q_u16(reinterpret_cast(chars)); + + // (x - '0') <= 9 + // http://0x80.pl/articles/simd-parsing-int-sequences.html + uint16x8_t const t0 = vsubq_u16(data, vmovq_n_u16('0')); + uint16x8_t const mask = vcltq_u16(t0, vmovq_n_u16('9' - '0' + 1)); + + if (vminvq_u16(mask) == 0xFFFF) { + i = i * 100000000 + parse_eight_digits_unrolled(simd_read8_to_u64(data)); + return true; + } else + return false; + FASTFLOAT_SIMD_RESTORE_WARNINGS +#else + (void)chars; + (void)i; + return false; +#endif // FASTFLOAT_SSE2 +} + +#endif // FASTFLOAT_HAS_SIMD + +// MSVC SFINAE is broken pre-VS2017 +#if defined(_MSC_VER) && _MSC_VER <= 1900 +template +#else +template ()) = 0> +#endif +// dummy for compile +bool simd_parse_if_eight_digits_unrolled(UC const *, uint64_t &) { + return 0; +} + +template ::value) = 0> +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(UC const *&p, UC const *const pend, uint64_t &i) { + if (!has_simd_opt()) { + return; + } + while ((tinyobj_ff::distance(p, pend) >= 8) && + simd_parse_if_eight_digits_unrolled( + p, i)) { // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +loop_parse_if_eight_digits(char const *&p, char const *const pend, + uint64_t &i) { + // optimizes better than parse_if_eight_digits_unrolled() for UC = char. + while ((tinyobj_ff::distance(p, pend) >= 8) && + is_made_of_eight_digits_fast(read8_to_u64(p))) { + i = i * 100000000 + + parse_eight_digits_unrolled(read8_to_u64( + p)); // in rare cases, this will overflow, but that's ok + p += 8; + } +} + +enum class parse_error { + no_error, + // [JSON-only] The minus sign must be followed by an integer. + missing_integer_after_sign, + // A sign must be followed by an integer or dot. + missing_integer_or_dot_after_sign, + // [JSON-only] The integer part must not have leading zeros. + leading_zeros_in_integer_part, + // [JSON-only] The integer part must have at least one digit. + no_digits_in_integer_part, + // [JSON-only] If there is a decimal point, there must be digits in the + // fractional part. + no_digits_in_fractional_part, + // The mantissa must have at least one digit. + no_digits_in_mantissa, + // Scientific notation requires an exponential part. + missing_exponential_part, +}; + +template struct parsed_number_string_t { + int64_t exponent{0}; + uint64_t mantissa{0}; + UC const *lastmatch{nullptr}; + bool negative{false}; + bool valid{false}; + bool too_many_digits{false}; + // contains the range of the significant digits + span integer{}; // non-nullable + span fraction{}; // nullable + parse_error error{parse_error::no_error}; +}; + +using byte_span = span; +using parsed_number_string = parsed_number_string_t; + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +report_parse_error(UC const *p, parse_error error) { + parsed_number_string_t answer; + answer.valid = false; + answer.lastmatch = p; + answer.error = error; + return answer; +} + +// Assuming that you use no more than 19 digits, this will +// parse an ASCII string. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 parsed_number_string_t +parse_number_string(UC const *p, UC const *pend, + parse_options_t options) noexcept { + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + UC const decimal_point = options.decimal_point; + + parsed_number_string_t answer; + answer.valid = false; + answer.too_many_digits = false; + // assume p < pend, so dereference without checks; + answer.negative = (*p == UC('-')); + // C++17 20.19.3.(7.1) explicitly forbids '+' sign here + if ((*p == UC('-')) || (uint64_t(fmt & chars_format::allow_leading_plus) && + !basic_json_fmt && *p == UC('+'))) { + ++p; + if (p == pend) { + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + if (!is_integer(*p)) { // a sign must be followed by an integer + return report_parse_error(p, + parse_error::missing_integer_after_sign); + } + } + else { + if (!is_integer(*p) && + (*p != + decimal_point)) { // a sign must be followed by an integer or the dot + return report_parse_error( + p, parse_error::missing_integer_or_dot_after_sign); + } + } + } + UC const *const start_digits = p; + + uint64_t i = 0; // an unsigned int avoids signed overflows (which are bad) + + while ((p != pend) && is_integer(*p)) { + // a multiplication by 10 is cheaper than an arbitrary integer + // multiplication + i = 10 * i + + uint64_t(*p - + UC('0')); // might overflow, we will handle the overflow later + ++p; + } + UC const *const end_of_integer_part = p; + int64_t digit_count = int64_t(end_of_integer_part - start_digits); + answer.integer = span(start_digits, size_t(digit_count)); + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + // at least 1 digit in integer part, without leading zeros + if (digit_count == 0) { + return report_parse_error(p, parse_error::no_digits_in_integer_part); + } + if ((start_digits[0] == UC('0') && digit_count > 1)) { + return report_parse_error(start_digits, + parse_error::leading_zeros_in_integer_part); + } + } + + int64_t exponent = 0; + bool const has_decimal_point = (p != pend) && (*p == decimal_point); + if (has_decimal_point) { + ++p; + UC const *before = p; + // can occur at most twice without overflowing, but let it occur more, since + // for integers with many digits, digit parsing is the primary bottleneck. + loop_parse_if_eight_digits(p, pend, i); + + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + ++p; + i = i * 10 + digit; // in rare cases, this will overflow, but that's ok + } + exponent = before - p; + answer.fraction = span(before, size_t(p - before)); + digit_count -= exponent; + } + FASTFLOAT_IF_CONSTEXPR17(basic_json_fmt) { + // at least 1 digit in fractional part + if (has_decimal_point && exponent == 0) { + return report_parse_error(p, + parse_error::no_digits_in_fractional_part); + } + } + else if (digit_count == 0) { // we must have encountered at least one integer! + return report_parse_error(p, parse_error::no_digits_in_mantissa); + } + int64_t exp_number = 0; // explicit exponential part + if ((uint64_t(fmt & chars_format::scientific) && (p != pend) && + ((UC('e') == *p) || (UC('E') == *p))) || + (uint64_t(fmt & detail::basic_fortran_fmt) && (p != pend) && + ((UC('+') == *p) || (UC('-') == *p) || (UC('d') == *p) || + (UC('D') == *p)))) { + UC const *location_of_e = p; + if ((UC('e') == *p) || (UC('E') == *p) || (UC('d') == *p) || + (UC('D') == *p)) { + ++p; + } + bool neg_exp = false; + if ((p != pend) && (UC('-') == *p)) { + neg_exp = true; + ++p; + } else if ((p != pend) && + (UC('+') == + *p)) { // '+' on exponent is allowed by C++17 20.19.3.(7.1) + ++p; + } + if ((p == pend) || !is_integer(*p)) { + if (!uint64_t(fmt & chars_format::fixed)) { + // The exponential part is invalid for scientific notation, so it must + // be a trailing token for fixed notation. However, fixed notation is + // disabled, so report a scientific notation error. + return report_parse_error(p, parse_error::missing_exponential_part); + } + // Otherwise, we will be ignoring the 'e'. + p = location_of_e; + } else { + while ((p != pend) && is_integer(*p)) { + uint8_t digit = uint8_t(*p - UC('0')); + if (exp_number < 0x10000000) { + exp_number = 10 * exp_number + digit; + } + ++p; + } + if (neg_exp) { + exp_number = -exp_number; + } + exponent += exp_number; + } + } else { + // If it scientific and not fixed, we have to bail out. + if (uint64_t(fmt & chars_format::scientific) && + !uint64_t(fmt & chars_format::fixed)) { + return report_parse_error(p, parse_error::missing_exponential_part); + } + } + answer.lastmatch = p; + answer.valid = true; + + // If we frequently had to deal with long strings of digits, + // we could extend our code by using a 128-bit integer instead + // of a 64-bit integer. However, this is uncommon. + // + // We can deal with up to 19 digits. + if (digit_count > 19) { // this is uncommon + // It is possible that the integer had an overflow. + // We have to handle the case where we have 0.0000somenumber. + // We need to be mindful of the case where we only have zeroes... + // E.g., 0.000000000...000. + UC const *start = start_digits; + while ((start != pend) && (*start == UC('0') || *start == decimal_point)) { + if (*start == UC('0')) { + digit_count--; + } + start++; + } + + if (digit_count > 19) { + answer.too_many_digits = true; + // Let us start again, this time, avoiding overflows. + // We don't need to check if is_integer, since we use the + // pre-tokenized spans from above. + i = 0; + p = answer.integer.ptr; + UC const *int_end = p + answer.integer.len(); + uint64_t const minimal_nineteen_digit_integer{1000000000000000000}; + while ((i < minimal_nineteen_digit_integer) && (p != int_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + if (i >= minimal_nineteen_digit_integer) { // We have a big integers + exponent = end_of_integer_part - p + exp_number; + } else { // We have a value with a fractional component. + p = answer.fraction.ptr; + UC const *frac_end = p + answer.fraction.len(); + while ((i < minimal_nineteen_digit_integer) && (p != frac_end)) { + i = i * 10 + uint64_t(*p - UC('0')); + ++p; + } + exponent = answer.fraction.ptr - p + exp_number; + } + // We have now corrected both exponent and i, to a truncated value + } + } + answer.exponent = exponent; + answer.mantissa = i; + return answer; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 from_chars_result_t +parse_int_string(UC const *p, UC const *pend, T &value, + parse_options_t options) { + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + int const base = options.base; + + from_chars_result_t answer; + + UC const *const first = p; + + bool const negative = (*p == UC('-')); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +#pragma warning(disable : 4127) +#endif + if (!tinyobj_ff::is_signed::value && negative) { +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#endif + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + if ((*p == UC('-')) || + (uint64_t(fmt & chars_format::allow_leading_plus) && (*p == UC('+')))) { + ++p; + } + + UC const *const start_num = p; + + while (p != pend && *p == UC('0')) { + ++p; + } + + bool const has_leading_zeros = p > start_num; + + UC const *const start_digits = p; + + uint64_t i = 0; + if (base == 10) { + loop_parse_if_eight_digits(p, pend, i); // use SIMD if possible + } + while (p != pend) { + uint8_t digit = ch_to_digit(*p); + if (digit >= base) { + break; + } + i = uint64_t(base) * i + digit; // might overflow, check this later + p++; + } + + size_t digit_count = size_t(p - start_digits); + + if (digit_count == 0) { + if (has_leading_zeros) { + value = 0; + answer.ec = tinyobj_ff::ff_errc(); + answer.ptr = p; + } else { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + } + return answer; + } + + answer.ptr = p; + + // check u64 overflow + size_t max_digits = max_digits_u64(base); + if (digit_count > max_digits) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + // this check can be eliminated for all other types, but they will all require + // a max_digits(base) equivalent + if (digit_count == max_digits && i < min_safe_u64(base)) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + + // check other types overflow + if (!tinyobj_ff::is_same::value) { + if (i > uint64_t(std::numeric_limits::max()) + uint64_t(negative)) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + return answer; + } + } + + if (negative) { +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +#pragma warning(disable : 4146) +#endif + // this weird workaround is required because: + // - converting unsigned to signed when its value is greater than signed max + // is UB pre-C++23. + // - reinterpret_casting (~i + 1) would work, but it is not constexpr + // this is always optimized into a neg instruction (note: T is an integer + // type) + value = T(-std::numeric_limits::max() - + T(i - uint64_t(std::numeric_limits::max()))); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#endif + } else { + value = T(i); + } + + answer.ec = tinyobj_ff::ff_errc(); + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_FAST_TABLE_H +#define FASTFLOAT_FAST_TABLE_H + +namespace fast_float { + +/** + * When mapping numbers from decimal to binary, + * we go from w * 10^q to m * 2^p but we have + * 10^q = 5^q * 2^q, so effectively + * we are trying to match + * w * 2^q * 5^q to m * 2^p. Thus the powers of two + * are not a concern since they can be represented + * exactly using the binary notation, only the powers of five + * affect the binary significand. + */ + +/** + * The smallest non-zero float (binary64) is 2^-1074. + * We take as input numbers of the form w x 10^q where w < 2^64. + * We have that w * 10^-343 < 2^(64-344) 5^-343 < 2^-1076. + * However, we have that + * (2^64-1) * 10^-342 = (2^64-1) * 2^-342 * 5^-342 > 2^-1074. + * Thus it is possible for a number of the form w * 10^-342 where + * w is a 64-bit value to be a non-zero floating-point number. + ********* + * Any number of form w * 10^309 where w>= 1 is going to be + * infinite in binary64 so we never need to worry about powers + * of 5 greater than 308. + */ +template struct powers_template { + + constexpr static int smallest_power_of_five = + binary_format::smallest_power_of_ten(); + constexpr static int largest_power_of_five = + binary_format::largest_power_of_ten(); + constexpr static int number_of_entries = + 2 * (largest_power_of_five - smallest_power_of_five + 1); + // Powers of five from 5^-342 all the way to 5^308 rounded toward one. + constexpr static uint64_t power_of_five_128[number_of_entries] = { + 0xeef453d6923bd65a, 0x113faa2906a13b3f, + 0x9558b4661b6565f8, 0x4ac7ca59a424c507, + 0xbaaee17fa23ebf76, 0x5d79bcf00d2df649, + 0xe95a99df8ace6f53, 0xf4d82c2c107973dc, + 0x91d8a02bb6c10594, 0x79071b9b8a4be869, + 0xb64ec836a47146f9, 0x9748e2826cdee284, + 0xe3e27a444d8d98b7, 0xfd1b1b2308169b25, + 0x8e6d8c6ab0787f72, 0xfe30f0f5e50e20f7, + 0xb208ef855c969f4f, 0xbdbd2d335e51a935, + 0xde8b2b66b3bc4723, 0xad2c788035e61382, + 0x8b16fb203055ac76, 0x4c3bcb5021afcc31, + 0xaddcb9e83c6b1793, 0xdf4abe242a1bbf3d, + 0xd953e8624b85dd78, 0xd71d6dad34a2af0d, + 0x87d4713d6f33aa6b, 0x8672648c40e5ad68, + 0xa9c98d8ccb009506, 0x680efdaf511f18c2, + 0xd43bf0effdc0ba48, 0x212bd1b2566def2, + 0x84a57695fe98746d, 0x14bb630f7604b57, + 0xa5ced43b7e3e9188, 0x419ea3bd35385e2d, + 0xcf42894a5dce35ea, 0x52064cac828675b9, + 0x818995ce7aa0e1b2, 0x7343efebd1940993, + 0xa1ebfb4219491a1f, 0x1014ebe6c5f90bf8, + 0xca66fa129f9b60a6, 0xd41a26e077774ef6, + 0xfd00b897478238d0, 0x8920b098955522b4, + 0x9e20735e8cb16382, 0x55b46e5f5d5535b0, + 0xc5a890362fddbc62, 0xeb2189f734aa831d, + 0xf712b443bbd52b7b, 0xa5e9ec7501d523e4, + 0x9a6bb0aa55653b2d, 0x47b233c92125366e, + 0xc1069cd4eabe89f8, 0x999ec0bb696e840a, + 0xf148440a256e2c76, 0xc00670ea43ca250d, + 0x96cd2a865764dbca, 0x380406926a5e5728, + 0xbc807527ed3e12bc, 0xc605083704f5ecf2, + 0xeba09271e88d976b, 0xf7864a44c633682e, + 0x93445b8731587ea3, 0x7ab3ee6afbe0211d, + 0xb8157268fdae9e4c, 0x5960ea05bad82964, + 0xe61acf033d1a45df, 0x6fb92487298e33bd, + 0x8fd0c16206306bab, 0xa5d3b6d479f8e056, + 0xb3c4f1ba87bc8696, 0x8f48a4899877186c, + 0xe0b62e2929aba83c, 0x331acdabfe94de87, + 0x8c71dcd9ba0b4925, 0x9ff0c08b7f1d0b14, + 0xaf8e5410288e1b6f, 0x7ecf0ae5ee44dd9, + 0xdb71e91432b1a24a, 0xc9e82cd9f69d6150, + 0x892731ac9faf056e, 0xbe311c083a225cd2, + 0xab70fe17c79ac6ca, 0x6dbd630a48aaf406, + 0xd64d3d9db981787d, 0x92cbbccdad5b108, + 0x85f0468293f0eb4e, 0x25bbf56008c58ea5, + 0xa76c582338ed2621, 0xaf2af2b80af6f24e, + 0xd1476e2c07286faa, 0x1af5af660db4aee1, + 0x82cca4db847945ca, 0x50d98d9fc890ed4d, + 0xa37fce126597973c, 0xe50ff107bab528a0, + 0xcc5fc196fefd7d0c, 0x1e53ed49a96272c8, + 0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7a, + 0x9faacf3df73609b1, 0x77b191618c54e9ac, + 0xc795830d75038c1d, 0xd59df5b9ef6a2417, + 0xf97ae3d0d2446f25, 0x4b0573286b44ad1d, + 0x9becce62836ac577, 0x4ee367f9430aec32, + 0xc2e801fb244576d5, 0x229c41f793cda73f, + 0xf3a20279ed56d48a, 0x6b43527578c1110f, + 0x9845418c345644d6, 0x830a13896b78aaa9, + 0xbe5691ef416bd60c, 0x23cc986bc656d553, + 0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa8, + 0x94b3a202eb1c3f39, 0x7bf7d71432f3d6a9, + 0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc53, + 0xe858ad248f5c22c9, 0xd1b3400f8f9cff68, + 0x91376c36d99995be, 0x23100809b9c21fa1, + 0xb58547448ffffb2d, 0xabd40a0c2832a78a, + 0xe2e69915b3fff9f9, 0x16c90c8f323f516c, + 0x8dd01fad907ffc3b, 0xae3da7d97f6792e3, + 0xb1442798f49ffb4a, 0x99cd11cfdf41779c, + 0xdd95317f31c7fa1d, 0x40405643d711d583, + 0x8a7d3eef7f1cfc52, 0x482835ea666b2572, + 0xad1c8eab5ee43b66, 0xda3243650005eecf, + 0xd863b256369d4a40, 0x90bed43e40076a82, + 0x873e4f75e2224e68, 0x5a7744a6e804a291, + 0xa90de3535aaae202, 0x711515d0a205cb36, + 0xd3515c2831559a83, 0xd5a5b44ca873e03, + 0x8412d9991ed58091, 0xe858790afe9486c2, + 0xa5178fff668ae0b6, 0x626e974dbe39a872, + 0xce5d73ff402d98e3, 0xfb0a3d212dc8128f, + 0x80fa687f881c7f8e, 0x7ce66634bc9d0b99, + 0xa139029f6a239f72, 0x1c1fffc1ebc44e80, + 0xc987434744ac874e, 0xa327ffb266b56220, + 0xfbe9141915d7a922, 0x4bf1ff9f0062baa8, + 0x9d71ac8fada6c9b5, 0x6f773fc3603db4a9, + 0xc4ce17b399107c22, 0xcb550fb4384d21d3, + 0xf6019da07f549b2b, 0x7e2a53a146606a48, + 0x99c102844f94e0fb, 0x2eda7444cbfc426d, + 0xc0314325637a1939, 0xfa911155fefb5308, + 0xf03d93eebc589f88, 0x793555ab7eba27ca, + 0x96267c7535b763b5, 0x4bc1558b2f3458de, + 0xbbb01b9283253ca2, 0x9eb1aaedfb016f16, + 0xea9c227723ee8bcb, 0x465e15a979c1cadc, + 0x92a1958a7675175f, 0xbfacd89ec191ec9, + 0xb749faed14125d36, 0xcef980ec671f667b, + 0xe51c79a85916f484, 0x82b7e12780e7401a, + 0x8f31cc0937ae58d2, 0xd1b2ecb8b0908810, + 0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa15, + 0xdfbdcece67006ac9, 0x67a791e093e1d49a, + 0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e0, + 0xaecc49914078536d, 0x58fae9f773886e18, + 0xda7f5bf590966848, 0xaf39a475506a899e, + 0x888f99797a5e012d, 0x6d8406c952429603, + 0xaab37fd7d8f58178, 0xc8e5087ba6d33b83, + 0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a64, + 0x855c3be0a17fcd26, 0x5cf2eea09a55067f, + 0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481e, + 0xd0601d8efc57b08b, 0xf13b94daf124da26, + 0x823c12795db6ce57, 0x76c53d08d6b70858, + 0xa2cb1717b52481ed, 0x54768c4b0c64ca6e, + 0xcb7ddcdda26da268, 0xa9942f5dcf7dfd09, + 0xfe5d54150b090b02, 0xd3f93b35435d7c4c, + 0x9efa548d26e5a6e1, 0xc47bc5014a1a6daf, + 0xc6b8e9b0709f109a, 0x359ab6419ca1091b, + 0xf867241c8cc6d4c0, 0xc30163d203c94b62, + 0x9b407691d7fc44f8, 0x79e0de63425dcf1d, + 0xc21094364dfb5636, 0x985915fc12f542e4, + 0xf294b943e17a2bc4, 0x3e6f5b7b17b2939d, + 0x979cf3ca6cec5b5a, 0xa705992ceecf9c42, + 0xbd8430bd08277231, 0x50c6ff782a838353, + 0xece53cec4a314ebd, 0xa4f8bf5635246428, + 0x940f4613ae5ed136, 0x871b7795e136be99, + 0xb913179899f68584, 0x28e2557b59846e3f, + 0xe757dd7ec07426e5, 0x331aeada2fe589cf, + 0x9096ea6f3848984f, 0x3ff0d2c85def7621, + 0xb4bca50b065abe63, 0xfed077a756b53a9, + 0xe1ebce4dc7f16dfb, 0xd3e8495912c62894, + 0x8d3360f09cf6e4bd, 0x64712dd7abbbd95c, + 0xb080392cc4349dec, 0xbd8d794d96aacfb3, + 0xdca04777f541c567, 0xecf0d7a0fc5583a0, + 0x89e42caaf9491b60, 0xf41686c49db57244, + 0xac5d37d5b79b6239, 0x311c2875c522ced5, + 0xd77485cb25823ac7, 0x7d633293366b828b, + 0x86a8d39ef77164bc, 0xae5dff9c02033197, + 0xa8530886b54dbdeb, 0xd9f57f830283fdfc, + 0xd267caa862a12d66, 0xd072df63c324fd7b, + 0x8380dea93da4bc60, 0x4247cb9e59f71e6d, + 0xa46116538d0deb78, 0x52d9be85f074e608, + 0xcd795be870516656, 0x67902e276c921f8b, + 0x806bd9714632dff6, 0xba1cd8a3db53b6, + 0xa086cfcd97bf97f3, 0x80e8a40eccd228a4, + 0xc8a883c0fdaf7df0, 0x6122cd128006b2cd, + 0xfad2a4b13d1b5d6c, 0x796b805720085f81, + 0x9cc3a6eec6311a63, 0xcbe3303674053bb0, + 0xc3f490aa77bd60fc, 0xbedbfc4411068a9c, + 0xf4f1b4d515acb93b, 0xee92fb5515482d44, + 0x991711052d8bf3c5, 0x751bdd152d4d1c4a, + 0xbf5cd54678eef0b6, 0xd262d45a78a0635d, + 0xef340a98172aace4, 0x86fb897116c87c34, + 0x9580869f0e7aac0e, 0xd45d35e6ae3d4da0, + 0xbae0a846d2195712, 0x8974836059cca109, + 0xe998d258869facd7, 0x2bd1a438703fc94b, + 0x91ff83775423cc06, 0x7b6306a34627ddcf, + 0xb67f6455292cbf08, 0x1a3bc84c17b1d542, + 0xe41f3d6a7377eeca, 0x20caba5f1d9e4a93, + 0x8e938662882af53e, 0x547eb47b7282ee9c, + 0xb23867fb2a35b28d, 0xe99e619a4f23aa43, + 0xdec681f9f4c31f31, 0x6405fa00e2ec94d4, + 0x8b3c113c38f9f37e, 0xde83bc408dd3dd04, + 0xae0b158b4738705e, 0x9624ab50b148d445, + 0xd98ddaee19068c76, 0x3badd624dd9b0957, + 0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d6, + 0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4c, + 0xd47487cc8470652b, 0x7647c3200069671f, + 0x84c8d4dfd2c63f3b, 0x29ecd9f40041e073, + 0xa5fb0a17c777cf09, 0xf468107100525890, + 0xcf79cc9db955c2cc, 0x7182148d4066eeb4, + 0x81ac1fe293d599bf, 0xc6f14cd848405530, + 0xa21727db38cb002f, 0xb8ada00e5a506a7c, + 0xca9cf1d206fdc03b, 0xa6d90811f0e4851c, + 0xfd442e4688bd304a, 0x908f4a166d1da663, + 0x9e4a9cec15763e2e, 0x9a598e4e043287fe, + 0xc5dd44271ad3cdba, 0x40eff1e1853f29fd, + 0xf7549530e188c128, 0xd12bee59e68ef47c, + 0x9a94dd3e8cf578b9, 0x82bb74f8301958ce, + 0xc13a148e3032d6e7, 0xe36a52363c1faf01, + 0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac1, + 0x96f5600f15a7b7e5, 0x29ab103a5ef8c0b9, + 0xbcb2b812db11a5de, 0x7415d448f6b6f0e7, + 0xebdf661791d60f56, 0x111b495b3464ad21, + 0x936b9fcebb25c995, 0xcab10dd900beec34, + 0xb84687c269ef3bfb, 0x3d5d514f40eea742, + 0xe65829b3046b0afa, 0xcb4a5a3112a5112, + 0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ab, + 0xb3f4e093db73a093, 0x59ed216765690f56, + 0xe0f218b8d25088b8, 0x306869c13ec3532c, + 0x8c974f7383725573, 0x1e414218c73a13fb, + 0xafbd2350644eeacf, 0xe5d1929ef90898fa, + 0xdbac6c247d62a583, 0xdf45f746b74abf39, + 0x894bc396ce5da772, 0x6b8bba8c328eb783, + 0xab9eb47c81f5114f, 0x66ea92f3f326564, + 0xd686619ba27255a2, 0xc80a537b0efefebd, + 0x8613fd0145877585, 0xbd06742ce95f5f36, + 0xa798fc4196e952e7, 0x2c48113823b73704, + 0xd17f3b51fca3a7a0, 0xf75a15862ca504c5, + 0x82ef85133de648c4, 0x9a984d73dbe722fb, + 0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebba, + 0xcc963fee10b7d1b3, 0x318df905079926a8, + 0xffbbcfe994e5c61f, 0xfdf17746497f7052, + 0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa633, + 0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc0, + 0xf9bd690a1b68637b, 0x3dfdce7aa3c673b0, + 0x9c1661a651213e2d, 0x6bea10ca65c084e, + 0xc31bfa0fe5698db8, 0x486e494fcff30a62, + 0xf3e2f893dec3f126, 0x5a89dba3c3efccfa, + 0x986ddb5c6b3a76b7, 0xf89629465a75e01c, + 0xbe89523386091465, 0xf6bbb397f1135823, + 0xee2ba6c0678b597f, 0x746aa07ded582e2c, + 0x94db483840b717ef, 0xa8c2a44eb4571cdc, + 0xba121a4650e4ddeb, 0x92f34d62616ce413, + 0xe896a0d7e51e1566, 0x77b020baf9c81d17, + 0x915e2486ef32cd60, 0xace1474dc1d122e, + 0xb5b5ada8aaff80b8, 0xd819992132456ba, + 0xe3231912d5bf60e6, 0x10e1fff697ed6c69, + 0x8df5efabc5979c8f, 0xca8d3ffa1ef463c1, + 0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb2, + 0xddd0467c64bce4a0, 0xac7cb3f6d05ddbde, + 0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96b, + 0xad4ab7112eb3929d, 0x86c16c98d2c953c6, + 0xd89d64d57a607744, 0xe871c7bf077ba8b7, + 0x87625f056c7c4a8b, 0x11471cd764ad4972, + 0xa93af6c6c79b5d2d, 0xd598e40d3dd89bcf, + 0xd389b47879823479, 0x4aff1d108d4ec2c3, + 0x843610cb4bf160cb, 0xcedf722a585139ba, + 0xa54394fe1eedb8fe, 0xc2974eb4ee658828, + 0xce947a3da6a9273e, 0x733d226229feea32, + 0x811ccc668829b887, 0x806357d5a3f525f, + 0xa163ff802a3426a8, 0xca07c2dcb0cf26f7, + 0xc9bcff6034c13052, 0xfc89b393dd02f0b5, + 0xfc2c3f3841f17c67, 0xbbac2078d443ace2, + 0x9d9ba7832936edc0, 0xd54b944b84aa4c0d, + 0xc5029163f384a931, 0xa9e795e65d4df11, + 0xf64335bcf065d37d, 0x4d4617b5ff4a16d5, + 0x99ea0196163fa42e, 0x504bced1bf8e4e45, + 0xc06481fb9bcf8d39, 0xe45ec2862f71e1d6, + 0xf07da27a82c37088, 0x5d767327bb4e5a4c, + 0x964e858c91ba2655, 0x3a6a07f8d510f86f, + 0xbbe226efb628afea, 0x890489f70a55368b, + 0xeadab0aba3b2dbe5, 0x2b45ac74ccea842e, + 0x92c8ae6b464fc96f, 0x3b0b8bc90012929d, + 0xb77ada0617e3bbcb, 0x9ce6ebb40173744, + 0xe55990879ddcaabd, 0xcc420a6a101d0515, + 0x8f57fa54c2a9eab6, 0x9fa946824a12232d, + 0xb32df8e9f3546564, 0x47939822dc96abf9, + 0xdff9772470297ebd, 0x59787e2b93bc56f7, + 0x8bfbea76c619ef36, 0x57eb4edb3c55b65a, + 0xaefae51477a06b03, 0xede622920b6b23f1, + 0xdab99e59958885c4, 0xe95fab368e45eced, + 0x88b402f7fd75539b, 0x11dbcb0218ebb414, + 0xaae103b5fcd2a881, 0xd652bdc29f26a119, + 0xd59944a37c0752a2, 0x4be76d3346f0495f, + 0x857fcae62d8493a5, 0x6f70a4400c562ddb, + 0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb952, + 0xd097ad07a71f26b2, 0x7e2000a41346a7a7, + 0x825ecc24c873782f, 0x8ed400668c0c28c8, + 0xa2f67f2dfa90563b, 0x728900802f0f32fa, + 0xcbb41ef979346bca, 0x4f2b40a03ad2ffb9, + 0xfea126b7d78186bc, 0xe2f610c84987bfa8, + 0x9f24b832e6b0f436, 0xdd9ca7d2df4d7c9, + 0xc6ede63fa05d3143, 0x91503d1c79720dbb, + 0xf8a95fcf88747d94, 0x75a44c6397ce912a, + 0x9b69dbe1b548ce7c, 0xc986afbe3ee11aba, + 0xc24452da229b021b, 0xfbe85badce996168, + 0xf2d56790ab41c2a2, 0xfae27299423fb9c3, + 0x97c560ba6b0919a5, 0xdccd879fc967d41a, + 0xbdb6b8e905cb600f, 0x5400e987bbc1c920, + 0xed246723473e3813, 0x290123e9aab23b68, + 0x9436c0760c86e30b, 0xf9a0b6720aaf6521, + 0xb94470938fa89bce, 0xf808e40e8d5b3e69, + 0xe7958cb87392c2c2, 0xb60b1d1230b20e04, + 0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c2, + 0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af3, + 0xe2280b6c20dd5232, 0x25c6da63c38de1b0, + 0x8d590723948a535f, 0x579c487e5a38ad0e, + 0xb0af48ec79ace837, 0x2d835a9df0c6d851, + 0xdcdb1b2798182244, 0xf8e431456cf88e65, + 0x8a08f0f8bf0f156b, 0x1b8e9ecb641b58ff, + 0xac8b2d36eed2dac5, 0xe272467e3d222f3f, + 0xd7adf884aa879177, 0x5b0ed81dcc6abb0f, + 0x86ccbb52ea94baea, 0x98e947129fc2b4e9, + 0xa87fea27a539e9a5, 0x3f2398d747b36224, + 0xd29fe4b18e88640e, 0x8eec7f0d19a03aad, + 0x83a3eeeef9153e89, 0x1953cf68300424ac, + 0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd7, + 0xcdb02555653131b6, 0x3792f412cb06794d, + 0x808e17555f3ebf11, 0xe2bbd88bbee40bd0, + 0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec4, + 0xc8de047564d20a8b, 0xf245825a5a445275, + 0xfb158592be068d2e, 0xeed6e2f0f0d56712, + 0x9ced737bb6c4183d, 0x55464dd69685606b, + 0xc428d05aa4751e4c, 0xaa97e14c3c26b886, + 0xf53304714d9265df, 0xd53dd99f4b3066a8, + 0x993fe2c6d07b7fab, 0xe546a8038efe4029, + 0xbf8fdb78849a5f96, 0xde98520472bdd033, + 0xef73d256a5c0f77c, 0x963e66858f6d4440, + 0x95a8637627989aad, 0xdde7001379a44aa8, + 0xbb127c53b17ec159, 0x5560c018580d5d52, + 0xe9d71b689dde71af, 0xaab8f01e6e10b4a6, + 0x9226712162ab070d, 0xcab3961304ca70e8, + 0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d22, + 0xe45c10c42a2b3b05, 0x8cb89a7db77c506a, + 0x8eb98a7a9a5b04e3, 0x77f3608e92adb242, + 0xb267ed1940f1c61c, 0x55f038b237591ed3, + 0xdf01e85f912e37a3, 0x6b6c46dec52f6688, + 0x8b61313bbabce2c6, 0x2323ac4b3b3da015, + 0xae397d8aa96c1b77, 0xabec975e0a0d081a, + 0xd9c7dced53c72255, 0x96e7bd358c904a21, + 0x881cea14545c7575, 0x7e50d64177da2e54, + 0xaa242499697392d2, 0xdde50bd1d5d0b9e9, + 0xd4ad2dbfc3d07787, 0x955e4ec64b44e864, + 0x84ec3c97da624ab4, 0xbd5af13bef0b113e, + 0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58e, + 0xcfb11ead453994ba, 0x67de18eda5814af2, + 0x81ceb32c4b43fcf4, 0x80eacf948770ced7, + 0xa2425ff75e14fc31, 0xa1258379a94d028d, + 0xcad2f7f5359a3b3e, 0x96ee45813a04330, + 0xfd87b5f28300ca0d, 0x8bca9d6e188853fc, + 0x9e74d1b791e07e48, 0x775ea264cf55347e, + 0xc612062576589dda, 0x95364afe032a819e, + 0xf79687aed3eec551, 0x3a83ddbd83f52205, + 0x9abe14cd44753b52, 0xc4926a9672793543, + 0xc16d9a0095928a27, 0x75b7053c0f178294, + 0xf1c90080baf72cb1, 0x5324c68b12dd6339, + 0x971da05074da7bee, 0xd3f6fc16ebca5e04, + 0xbce5086492111aea, 0x88f4bb1ca6bcf585, + 0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6, + 0x9392ee8e921d5d07, 0x3aff322e62439fd0, + 0xb877aa3236a4b449, 0x9befeb9fad487c3, + 0xe69594bec44de15b, 0x4c2ebe687989a9b4, + 0x901d7cf73ab0acd9, 0xf9d37014bf60a11, + 0xb424dc35095cd80f, 0x538484c19ef38c95, + 0xe12e13424bb40e13, 0x2865a5f206b06fba, + 0x8cbccc096f5088cb, 0xf93f87b7442e45d4, + 0xafebff0bcb24aafe, 0xf78f69a51539d749, + 0xdbe6fecebdedd5be, 0xb573440e5a884d1c, + 0x89705f4136b4a597, 0x31680a88f8953031, + 0xabcc77118461cefc, 0xfdc20d2b36ba7c3e, + 0xd6bf94d5e57a42bc, 0x3d32907604691b4d, + 0x8637bd05af6c69b5, 0xa63f9a49c2c1b110, + 0xa7c5ac471b478423, 0xfcf80dc33721d54, + 0xd1b71758e219652b, 0xd3c36113404ea4a9, + 0x83126e978d4fdf3b, 0x645a1cac083126ea, + 0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4, + 0xcccccccccccccccc, 0xcccccccccccccccd, + 0x8000000000000000, 0x0, + 0xa000000000000000, 0x0, + 0xc800000000000000, 0x0, + 0xfa00000000000000, 0x0, + 0x9c40000000000000, 0x0, + 0xc350000000000000, 0x0, + 0xf424000000000000, 0x0, + 0x9896800000000000, 0x0, + 0xbebc200000000000, 0x0, + 0xee6b280000000000, 0x0, + 0x9502f90000000000, 0x0, + 0xba43b74000000000, 0x0, + 0xe8d4a51000000000, 0x0, + 0x9184e72a00000000, 0x0, + 0xb5e620f480000000, 0x0, + 0xe35fa931a0000000, 0x0, + 0x8e1bc9bf04000000, 0x0, + 0xb1a2bc2ec5000000, 0x0, + 0xde0b6b3a76400000, 0x0, + 0x8ac7230489e80000, 0x0, + 0xad78ebc5ac620000, 0x0, + 0xd8d726b7177a8000, 0x0, + 0x878678326eac9000, 0x0, + 0xa968163f0a57b400, 0x0, + 0xd3c21bcecceda100, 0x0, + 0x84595161401484a0, 0x0, + 0xa56fa5b99019a5c8, 0x0, + 0xcecb8f27f4200f3a, 0x0, + 0x813f3978f8940984, 0x4000000000000000, + 0xa18f07d736b90be5, 0x5000000000000000, + 0xc9f2c9cd04674ede, 0xa400000000000000, + 0xfc6f7c4045812296, 0x4d00000000000000, + 0x9dc5ada82b70b59d, 0xf020000000000000, + 0xc5371912364ce305, 0x6c28000000000000, + 0xf684df56c3e01bc6, 0xc732000000000000, + 0x9a130b963a6c115c, 0x3c7f400000000000, + 0xc097ce7bc90715b3, 0x4b9f100000000000, + 0xf0bdc21abb48db20, 0x1e86d40000000000, + 0x96769950b50d88f4, 0x1314448000000000, + 0xbc143fa4e250eb31, 0x17d955a000000000, + 0xeb194f8e1ae525fd, 0x5dcfab0800000000, + 0x92efd1b8d0cf37be, 0x5aa1cae500000000, + 0xb7abc627050305ad, 0xf14a3d9e40000000, + 0xe596b7b0c643c719, 0x6d9ccd05d0000000, + 0x8f7e32ce7bea5c6f, 0xe4820023a2000000, + 0xb35dbf821ae4f38b, 0xdda2802c8a800000, + 0xe0352f62a19e306e, 0xd50b2037ad200000, + 0x8c213d9da502de45, 0x4526f422cc340000, + 0xaf298d050e4395d6, 0x9670b12b7f410000, + 0xdaf3f04651d47b4c, 0x3c0cdd765f114000, + 0x88d8762bf324cd0f, 0xa5880a69fb6ac800, + 0xab0e93b6efee0053, 0x8eea0d047a457a00, + 0xd5d238a4abe98068, 0x72a4904598d6d880, + 0x85a36366eb71f041, 0x47a6da2b7f864750, + 0xa70c3c40a64e6c51, 0x999090b65f67d924, + 0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d, + 0x82818f1281ed449f, 0xbff8f10e7a8921a4, + 0xa321f2d7226895c7, 0xaff72d52192b6a0d, + 0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490, + 0xfee50b7025c36a08, 0x2f236d04753d5b4, + 0x9f4f2726179a2245, 0x1d762422c946590, + 0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5, + 0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2, + 0x9b934c3b330c8577, 0x63cc55f49f88eb2f, + 0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb, + 0xf316271c7fc3908a, 0x8bef464e3945ef7a, + 0x97edd871cfda3a56, 0x97758bf0e3cbb5ac, + 0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317, + 0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd, + 0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a, + 0xb975d6b6ee39e436, 0xb3e2fd538e122b44, + 0xe7d34c64a9c85d44, 0x60dbbca87196b616, + 0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd, + 0xb51d13aea4a488dd, 0x6babab6398bdbe41, + 0xe264589a4dcdab14, 0xc696963c7eed2dd1, + 0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2, + 0xb0de65388cc8ada8, 0x3b25a55f43294bcb, + 0xdd15fe86affad912, 0x49ef0eb713f39ebe, + 0x8a2dbf142dfcc7ab, 0x6e3569326c784337, + 0xacb92ed9397bf996, 0x49c2c37f07965404, + 0xd7e77a8f87daf7fb, 0xdc33745ec97be906, + 0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3, + 0xa8acd7c0222311bc, 0xc40832ea0d68ce0c, + 0xd2d80db02aabd62b, 0xf50a3fa490c30190, + 0x83c7088e1aab65db, 0x792667c6da79e0fa, + 0xa4b8cab1a1563f52, 0x577001b891185938, + 0xcde6fd5e09abcf26, 0xed4c0226b55e6f86, + 0x80b05e5ac60b6178, 0x544f8158315b05b4, + 0xa0dc75f1778e39d6, 0x696361ae3db1c721, + 0xc913936dd571c84c, 0x3bc3a19cd1e38e9, + 0xfb5878494ace3a5f, 0x4ab48a04065c723, + 0x9d174b2dcec0e47b, 0x62eb0d64283f9c76, + 0xc45d1df942711d9a, 0x3ba5d0bd324f8394, + 0xf5746577930d6500, 0xca8f44ec7ee36479, + 0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb, + 0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e, + 0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e, + 0x95d04aee3b80ece5, 0xbba1f1d158724a12, + 0xbb445da9ca61281f, 0x2a8a6e45ae8edc97, + 0xea1575143cf97226, 0xf52d09d71a3293bd, + 0x924d692ca61be758, 0x593c2626705f9c56, + 0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c, + 0xe498f455c38b997a, 0xb6dfb9c0f956447, + 0x8edf98b59a373fec, 0x4724bd4189bd5eac, + 0xb2977ee300c50fe7, 0x58edec91ec2cb657, + 0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed, + 0x8b865b215899f46c, 0xbd79e0d20082ee74, + 0xae67f1e9aec07187, 0xecd8590680a3aa11, + 0xda01ee641a708de9, 0xe80e6f4820cc9495, + 0x884134fe908658b2, 0x3109058d147fdcdd, + 0xaa51823e34a7eede, 0xbd4b46f0599fd415, + 0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a, + 0x850fadc09923329e, 0x3e2cf6bc604ddb0, + 0xa6539930bf6bff45, 0x84db8346b786151c, + 0xcfe87f7cef46ff16, 0xe612641865679a63, + 0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e, + 0xa26da3999aef7749, 0xe3be5e330f38f09d, + 0xcb090c8001ab551c, 0x5cadf5bfd3072cc5, + 0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6, + 0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa, + 0xc646d63501a1511d, 0xb281e1fd541501b8, + 0xf7d88bc24209a565, 0x1f225a7ca91a4226, + 0x9ae757596946075f, 0x3375788de9b06958, + 0xc1a12d2fc3978937, 0x52d6b1641c83ae, + 0xf209787bb47d6b84, 0xc0678c5dbd23a49a, + 0x9745eb4d50ce6332, 0xf840b7ba963646e0, + 0xbd176620a501fbff, 0xb650e5a93bc3d898, + 0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe, + 0x93ba47c980e98cdf, 0xc66f336c36b10137, + 0xb8a8d9bbe123f017, 0xb80b0047445d4184, + 0xe6d3102ad96cec1d, 0xa60dc059157491e5, + 0x9043ea1ac7e41392, 0x87c89837ad68db2f, + 0xb454e4a179dd1877, 0x29babe4598c311fb, + 0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a, + 0x8ce2529e2734bb1d, 0x1899e4a65f58660c, + 0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f, + 0xdc21a1171d42645d, 0x76707543f4fa1f73, + 0x899504ae72497eba, 0x6a06494a791c53a8, + 0xabfa45da0edbde69, 0x487db9d17636892, + 0xd6f8d7509292d603, 0x45a9d2845d3c42b6, + 0x865b86925b9bc5c2, 0xb8a2392ba45a9b2, + 0xa7f26836f282b732, 0x8e6cac7768d7141e, + 0xd1ef0244af2364ff, 0x3207d795430cd926, + 0x8335616aed761f1f, 0x7f44e6bd49e807b8, + 0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6, + 0xcd036837130890a1, 0x36dba887c37a8c0f, + 0x802221226be55a64, 0xc2494954da2c9789, + 0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c, + 0xc83553c5c8965d3d, 0x6f92829494e5acc7, + 0xfa42a8b73abbf48c, 0xcb772339ba1f17f9, + 0x9c69a97284b578d7, 0xff2a760414536efb, + 0xc38413cf25e2d70d, 0xfef5138519684aba, + 0xf46518c2ef5b8cd1, 0x7eb258665fc25d69, + 0x98bf2f79d5993802, 0xef2f773ffbd97a61, + 0xbeeefb584aff8603, 0xaafb550ffacfd8fa, + 0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38, + 0x952ab45cfa97a0b2, 0xdd945a747bf26183, + 0xba756174393d88df, 0x94f971119aeef9e4, + 0xe912b9d1478ceb17, 0x7a37cd5601aab85d, + 0x91abb422ccb812ee, 0xac62e055c10ab33a, + 0xb616a12b7fe617aa, 0x577b986b314d6009, + 0xe39c49765fdf9d94, 0xed5a7e85fda0b80b, + 0x8e41ade9fbebc27d, 0x14588f13be847307, + 0xb1d219647ae6b31c, 0x596eb2d8ae258fc8, + 0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb, + 0x8aec23d680043bee, 0x25de7bb9480d5854, + 0xada72ccc20054ae9, 0xaf561aa79a10ae6a, + 0xd910f7ff28069da4, 0x1b2ba1518094da04, + 0x87aa9aff79042286, 0x90fb44d2f05d0842, + 0xa99541bf57452b28, 0x353a1607ac744a53, + 0xd3fa922f2d1675f2, 0x42889b8997915ce8, + 0x847c9b5d7c2e09b7, 0x69956135febada11, + 0xa59bc234db398c25, 0x43fab9837e699095, + 0xcf02b2c21207ef2e, 0x94f967e45e03f4bb, + 0x8161afb94b44f57d, 0x1d1be0eebac278f5, + 0xa1ba1ba79e1632dc, 0x6462d92a69731732, + 0xca28a291859bbf93, 0x7d7b8f7503cfdcfe, + 0xfcb2cb35e702af78, 0x5cda735244c3d43e, + 0x9defbf01b061adab, 0x3a0888136afa64a7, + 0xc56baec21c7a1916, 0x88aaa1845b8fdd0, + 0xf6c69a72a3989f5b, 0x8aad549e57273d45, + 0x9a3c2087a63f6399, 0x36ac54e2f678864b, + 0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd, + 0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5, + 0x969eb7c47859e743, 0x9f644ae5a4b1b325, + 0xbc4665b596706114, 0x873d5d9f0dde1fee, + 0xeb57ff22fc0c7959, 0xa90cb506d155a7ea, + 0x9316ff75dd87cbd8, 0x9a7f12442d588f2, + 0xb7dcbf5354e9bece, 0xc11ed6d538aeb2f, + 0xe5d3ef282a242e81, 0x8f1668c8a86da5fa, + 0x8fa475791a569d10, 0xf96e017d694487bc, + 0xb38d92d760ec4455, 0x37c981dcc395a9ac, + 0xe070f78d3927556a, 0x85bbe253f47b1417, + 0x8c469ab843b89562, 0x93956d7478ccec8e, + 0xaf58416654a6babb, 0x387ac8d1970027b2, + 0xdb2e51bfe9d0696a, 0x6997b05fcc0319e, + 0x88fcf317f22241e2, 0x441fece3bdf81f03, + 0xab3c2fddeeaad25a, 0xd527e81cad7626c3, + 0xd60b3bd56a5586f1, 0x8a71e223d8d3b074, + 0x85c7056562757456, 0xf6872d5667844e49, + 0xa738c6bebb12d16c, 0xb428f8ac016561db, + 0xd106f86e69d785c7, 0xe13336d701beba52, + 0x82a45b450226b39c, 0xecc0024661173473, + 0xa34d721642b06084, 0x27f002d7f95d0190, + 0xcc20ce9bd35c78a5, 0x31ec038df7b441f4, + 0xff290242c83396ce, 0x7e67047175a15271, + 0x9f79a169bd203e41, 0xf0062c6e984d386, + 0xc75809c42c684dd1, 0x52c07b78a3e60868, + 0xf92e0c3537826145, 0xa7709a56ccdf8a82, + 0x9bbcc7a142b17ccb, 0x88a66076400bb691, + 0xc2abf989935ddbfe, 0x6acff893d00ea435, + 0xf356f7ebf83552fe, 0x583f6b8c4124d43, + 0x98165af37b2153de, 0xc3727a337a8b704a, + 0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c, + 0xeda2ee1c7064130c, 0x1162def06f79df73, + 0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8, + 0xb9a74a0637ce2ee1, 0x6d953e2bd7173692, + 0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437, + 0x910ab1d4db9914a0, 0x1d9c9892400a22a2, + 0xb54d5e4a127f59c8, 0x2503beb6d00cab4b, + 0xe2a0b5dc971f303a, 0x2e44ae64840fd61d, + 0x8da471a9de737e24, 0x5ceaecfed289e5d2, + 0xb10d8e1456105dad, 0x7425a83e872c5f47, + 0xdd50f1996b947518, 0xd12f124e28f77719, + 0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f, + 0xace73cbfdc0bfb7b, 0x636cc64d1001550b, + 0xd8210befd30efa5a, 0x3c47f7e05401aa4e, + 0x8714a775e3e95c78, 0x65acfaec34810a71, + 0xa8d9d1535ce3b396, 0x7f1839a741a14d0d, + 0xd31045a8341ca07c, 0x1ede48111209a050, + 0x83ea2b892091e44d, 0x934aed0aab460432, + 0xa4e4b66b68b65d60, 0xf81da84d5617853f, + 0xce1de40642e3f4b9, 0x36251260ab9d668e, + 0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019, + 0xa1075a24e4421730, 0xb24cf65b8612f81f, + 0xc94930ae1d529cfc, 0xdee033f26797b627, + 0xfb9b7cd9a4a7443c, 0x169840ef017da3b1, + 0x9d412e0806e88aa5, 0x8e1f289560ee864e, + 0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2, + 0xf5b5d7ec8acb58a2, 0xae10af696774b1db, + 0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29, + 0xbff610b0cc6edd3f, 0x17fd090a58d32af3, + 0xeff394dcff8a948e, 0xddfc4b4cef07f5b0, + 0x95f83d0a1fb69cd9, 0x4abdaf101564f98e, + 0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1, + 0xea53df5fd18d5513, 0x84c86189216dc5ed, + 0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4, + 0xb7118682dbb66a77, 0x3fbc8c33221dc2a1, + 0xe4d5e82392a40515, 0xfabaf3feaa5334a, + 0x8f05b1163ba6832d, 0x29cb4d87f2a7400e, + 0xb2c71d5bca9023f8, 0x743e20e9ef511012, + 0xdf78e4b2bd342cf6, 0x914da9246b255416, + 0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e, + 0xae9672aba3d0c320, 0xa184ac2473b529b1, + 0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e, + 0x8865899617fb1871, 0x7e2fa67c7a658892, + 0xaa7eebfb9df9de8d, 0xddbb901b98feeab7, + 0xd51ea6fa85785631, 0x552a74227f3ea565, + 0x8533285c936b35de, 0xd53a88958f87275f, + 0xa67ff273b8460356, 0x8a892abaf368f137, + 0xd01fef10a657842c, 0x2d2b7569b0432d85, + 0x8213f56a67f6b29b, 0x9c3b29620e29fc73, + 0xa298f2c501f45f42, 0x8349f3ba91b47b8f, + 0xcb3f2f7642717713, 0x241c70a936219a73, + 0xfe0efb53d30dd4d7, 0xed238cd383aa0110, + 0x9ec95d1463e8a506, 0xf4363804324a40aa, + 0xc67bb4597ce2ce48, 0xb143c6053edcd0d5, + 0xf81aa16fdc1b81da, 0xdd94b7868e94050a, + 0x9b10a4e5e9913128, 0xca7cf2b4191c8326, + 0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0, + 0xf24a01a73cf2dccf, 0xbc633b39673c8cec, + 0x976e41088617ca01, 0xd5be0503e085d813, + 0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18, + 0xec9c459d51852ba2, 0xddf8e7d60ed1219e, + 0x93e1ab8252f33b45, 0xcabb90e5c942b503, + 0xb8da1662e7b00a17, 0x3d6a751f3b936243, + 0xe7109bfba19c0c9d, 0xcc512670a783ad4, + 0x906a617d450187e2, 0x27fb2b80668b24c5, + 0xb484f9dc9641e9da, 0xb1f9f660802dedf6, + 0xe1a63853bbd26451, 0x5e7873f8a0396973, + 0x8d07e33455637eb2, 0xdb0b487b6423e1e8, + 0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62, + 0xdc5c5301c56b75f7, 0x7641a140cc7810fb, + 0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d, + 0xac2820d9623bf429, 0x546345fa9fbdcd44, + 0xd732290fbacaf133, 0xa97c177947ad4095, + 0x867f59a9d4bed6c0, 0x49ed8eabcccc485d, + 0xa81f301449ee8c70, 0x5c68f256bfff5a74, + 0xd226fc195c6a2f8c, 0x73832eec6fff3111, + 0x83585d8fd9c25db7, 0xc831fd53c5ff7eab, + 0xa42e74f3d032f525, 0xba3e7ca8b77f5e55, + 0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb, + 0x80444b5e7aa7cf85, 0x7980d163cf5b81b3, + 0xa0555e361951c366, 0xd7e105bcc332621f, + 0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7, + 0xfa856334878fc150, 0xb14f98f6f0feb951, + 0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3, + 0xc3b8358109e84f07, 0xa862f80ec4700c8, + 0xf4a642e14c6262c8, 0xcd27bb612758c0fa, + 0x98e7e9cccfbd7dbd, 0x8038d51cb897789c, + 0xbf21e44003acdd2c, 0xe0470a63e6bd56c3, + 0xeeea5d5004981478, 0x1858ccfce06cac74, + 0x95527a5202df0ccb, 0xf37801e0c43ebc8, + 0xbaa718e68396cffd, 0xd30560258f54e6ba, + 0xe950df20247c83fd, 0x47c6b82ef32a2069, + 0x91d28b7416cdd27e, 0x4cdc331d57fa5441, + 0xb6472e511c81471d, 0xe0133fe4adf8e952, + 0xe3d8f9e563a198e5, 0x58180fddd97723a6, + 0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648, + }; +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template +constexpr uint64_t + powers_template::power_of_five_128[number_of_entries]; + +#endif + +using powers = powers_template<>; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DECIMAL_TO_BINARY_H +#define FASTFLOAT_DECIMAL_TO_BINARY_H + +#include +#include +#include + +namespace fast_float { + +// This will compute or rather approximate w * 5**q and return a pair of 64-bit +// words approximating the result, with the "high" part corresponding to the +// most significant bits and the low part corresponding to the least significant +// bits. +// +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 +compute_product_approximation(int64_t q, uint64_t w) { + int const index = 2 * int(q - powers::smallest_power_of_five); + // For small values of q, e.g., q in [0,27], the answer is always exact + // because The line value128 firstproduct = full_multiplication(w, + // power_of_five_128[index]); gives the exact answer. + value128 firstproduct = + full_multiplication(w, powers::power_of_five_128[index]); + static_assert((bit_precision >= 0) && (bit_precision <= 64), + " precision should be in (0,64]"); + constexpr uint64_t precision_mask = + (bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision) + : uint64_t(0xFFFFFFFFFFFFFFFF); + if ((firstproduct.high & precision_mask) == + precision_mask) { // could further guard with (lower + w < lower) + // regarding the second product, we only need secondproduct.high, but our + // expectation is that the compiler will optimize this extra work away if + // needed. + value128 secondproduct = + full_multiplication(w, powers::power_of_five_128[index + 1]); + firstproduct.low += secondproduct.high; + if (secondproduct.high > firstproduct.low) { + firstproduct.high++; + } + } + return firstproduct; +} + +namespace detail { +/** + * For q in (0,350), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * floor(p) + q + * where + * p = log(5**q)/log(2) = q * log(5)/log(2) + * + * For negative values of q in (-400,0), we have that + * f = (((152170 + 65536) * q ) >> 16); + * is equal to + * -ceil(p) + q + * where + * p = log(5**-q)/log(2) = -q * log(5)/log(2) + */ +constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { + return (((152170 + 65536) * q) >> 16) + 63; +} +} // namespace detail + +// create an adjusted mantissa, biased by the invalid power2 +// for significant digits already multiplied by 10 ** q. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa +compute_error_scaled(int64_t q, uint64_t w, int lz) noexcept { + int hilz = int(w >> 63) ^ 1; + adjusted_mantissa answer; + answer.mantissa = w << hilz; + int bias = binary::mantissa_explicit_bits() - binary::minimum_exponent(); + answer.power2 = int32_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + + invalid_am_bias); + return answer; +} + +// w * 10 ** q, without rounding the representation up. +// the power2 in the exponent will be adjusted by invalid_am_bias. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_error(int64_t q, uint64_t w) noexcept { + int lz = leading_zeroes(w); + w <<= lz; + value128 product = + compute_product_approximation(q, w); + return compute_error_scaled(q, product.high, lz); +} + +// Computers w * 10 ** q. +// The returned value should be a valid number that simply needs to be +// packed. However, in some very rare cases, the computation will fail. In such +// cases, we return an adjusted_mantissa with a negative power of 2: the caller +// should recompute in such cases. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +compute_float(int64_t q, uint64_t w) noexcept { + adjusted_mantissa answer; + if ((w == 0) || (q < binary::smallest_power_of_ten())) { + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + if (q > binary::largest_power_of_ten()) { + // we want to get infinity: + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + return answer; + } + // At this point in time q is in [powers::smallest_power_of_five, + // powers::largest_power_of_five]. + + // We want the most significant bit of i to be 1. Shift if needed. + int lz = leading_zeroes(w); + w <<= lz; + + // The required precision is binary::mantissa_explicit_bits() + 3 because + // 1. We need the implicit bit + // 2. We need an extra bit for rounding purposes + // 3. We might lose a bit due to the "upperbit" routine (result too small, + // requiring a shift) + + value128 product = + compute_product_approximation(q, w); + // The computed 'product' is always sufficient. + // Mathematical proof: + // Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to + // appear) See script/mushtak_lemire.py + + // The "compute_product_approximation" function can be slightly slower than a + // branchless approach: value128 product = compute_product(q, w); but in + // practice, we can win big with the compute_product_approximation if its + // additional branch is easily predicted. Which is best is data specific. + int upperbit = int(product.high >> 63); + int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3; + + answer.mantissa = product.high >> shift; + + answer.power2 = int32_t(detail::power(int32_t(q)) + upperbit - lz - + binary::minimum_exponent()); + if (answer.power2 <= 0) { // we have a subnormal? + // Here have that answer.power2 <= 0 so -answer.power2 >= 0 + if (-answer.power2 + 1 >= + 64) { // if we have more than 64 bits below the minimum exponent, you + // have a zero for sure. + answer.power2 = 0; + answer.mantissa = 0; + // result should be zero + return answer; + } + // next line is safe because -answer.power2 + 1 < 64 + answer.mantissa >>= -answer.power2 + 1; + // Thankfully, we can't have both "round-to-even" and subnormals because + // "round-to-even" only occurs for powers close to 0 in the 32-bit and + // and 64-bit case (with no more than 19 digits). + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + // There is a weird scenario where we don't have a subnormal but just. + // Suppose we start with 2.2250738585072013e-308, we end up + // with 0x3fffffffffffff x 2^-1023-53 which is technically subnormal + // whereas 0x40000000000000 x 2^-1023-53 is normal. Now, we need to round + // up 0x3fffffffffffff x 2^-1023-53 and once we do, we are no longer + // subnormal, but we can only know this after rounding. + // So we only declare a subnormal if we are smaller than the threshold. + answer.power2 = + (answer.mantissa < (uint64_t(1) << binary::mantissa_explicit_bits())) + ? 0 + : 1; + return answer; + } + + // usually, we round *up*, but if we fall right in between and and we have an + // even basis, we need to round down + // We are only concerned with the cases where 5**q fits in single 64-bit word. + if ((product.low <= 1) && (q >= binary::min_exponent_round_to_even()) && + (q <= binary::max_exponent_round_to_even()) && + ((answer.mantissa & 3) == 1)) { // we may fall between two floats! + // To be in-between two floats we need that in doing + // answer.mantissa = product.high >> (upperbit + 64 - + // binary::mantissa_explicit_bits() - 3); + // ... we dropped out only zeroes. But if this happened, then we can go + // back!!! + if ((answer.mantissa << shift) == product.high) { + answer.mantissa &= ~uint64_t(1); // flip it so that we do not round up + } + } + + answer.mantissa += (answer.mantissa & 1); // round up + answer.mantissa >>= 1; + if (answer.mantissa >= (uint64_t(2) << binary::mantissa_explicit_bits())) { + answer.mantissa = (uint64_t(1) << binary::mantissa_explicit_bits()); + answer.power2++; // undo previous addition + } + + answer.mantissa &= ~(uint64_t(1) << binary::mantissa_explicit_bits()); + if (answer.power2 >= binary::infinite_power()) { // infinity + answer.power2 = binary::infinite_power(); + answer.mantissa = 0; + } + return answer; +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_BIGINT_H +#define FASTFLOAT_BIGINT_H + +#include + + +namespace fast_float { + +// the limb width: we want efficient multiplication of double the bits in +// limb, or for 64-bit limbs, at least 64-bit multiplication where we can +// extract the high and low parts efficiently. this is every 64-bit +// architecture except for sparc, which emulates 128-bit multiplication. +// we might have platforms where `CHAR_BIT` is not 8, so let's avoid +// doing `8 * sizeof(limb)`. +#if defined(FASTFLOAT_64BIT) && !defined(__sparc) +#define FASTFLOAT_64BIT_LIMB 1 +typedef uint64_t limb; +constexpr size_t limb_bits = 64; +#else +#define FASTFLOAT_32BIT_LIMB +typedef uint32_t limb; +constexpr size_t limb_bits = 32; +#endif + +typedef span limb_span; + +// number of bits in a bigint. this needs to be at least the number +// of bits required to store the largest bigint, which is +// `log2(10**(digits + max_exp))`, or `log2(10**(767 + 342))`, or +// ~3600 bits, so we round to 4000. +constexpr size_t bigint_bits = 4000; +constexpr size_t bigint_limbs = bigint_bits / limb_bits; + +// vector-like type that is allocated on the stack. the entire +// buffer is pre-allocated, and only the length changes. +template struct stackvec { + limb data[size]; + // we never need more than 150 limbs + uint16_t length{0}; + + stackvec() = default; + stackvec(stackvec const &) = delete; + stackvec &operator=(stackvec const &) = delete; + stackvec(stackvec &&) = delete; + stackvec &operator=(stackvec &&other) = delete; + + // create stack vector from existing limb span. + FASTFLOAT_CONSTEXPR20 stackvec(limb_span s) { + FASTFLOAT_ASSERT(try_extend(s)); + } + + FASTFLOAT_CONSTEXPR14 limb &operator[](size_t index) noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + + FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + return data[index]; + } + + // index from the end of the container + FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept { + FASTFLOAT_DEBUG_ASSERT(index < length); + size_t rindex = length - index - 1; + return data[rindex]; + } + + // set the length, without bounds checking. + FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept { + length = uint16_t(len); + } + + constexpr size_t len() const noexcept { return length; } + + constexpr bool is_empty() const noexcept { return length == 0; } + + constexpr size_t capacity() const noexcept { return size; } + + // append item to vector, without bounds checking + FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept { + data[length] = value; + length++; + } + + // append item to vector, returning if item was added + FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept { + if (len() < capacity()) { + push_unchecked(value); + return true; + } else { + return false; + } + } + + // add items to the vector, from a span, without bounds checking + FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept { + limb *ptr = data + length; + tinyobj_ff::copy_n(s.ptr, s.len(), ptr); + set_len(len() + s.len()); + } + + // try to add items to the vector, returning if items were added + FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept { + if (len() + s.len() <= capacity()) { + extend_unchecked(s); + return true; + } else { + return false; + } + } + + // resize the vector, without bounds checking + // if the new size is longer than the vector, assign value to each + // appended item. + FASTFLOAT_CONSTEXPR20 + void resize_unchecked(size_t new_len, limb value) noexcept { + if (new_len > len()) { + size_t count = new_len - len(); + limb *first = data + len(); + limb *last = first + count; + tinyobj_ff::fill(first, last, value); + set_len(new_len); + } else { + set_len(new_len); + } + } + + // try to resize the vector, returning if the vector was resized. + FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept { + if (new_len > capacity()) { + return false; + } else { + resize_unchecked(new_len, value); + return true; + } + } + + // check if any limbs are non-zero after the given index. + // this needs to be done in reverse order, since the index + // is relative to the most significant limbs. + FASTFLOAT_CONSTEXPR14 bool nonzero(size_t index) const noexcept { + while (index < len()) { + if (rindex(index) != 0) { + return true; + } + index++; + } + return false; + } + + // normalize the big integer, so most-significant zero limbs are removed. + FASTFLOAT_CONSTEXPR14 void normalize() noexcept { + while (len() > 0 && rindex(0) == 0) { + length--; + } + } +}; + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 uint64_t +empty_hi64(bool &truncated) noexcept { + truncated = false; + return 0; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, bool &truncated) noexcept { + truncated = false; + int shl = leading_zeroes(r0); + return r0 << shl; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint64_hi64(uint64_t r0, uint64_t r1, bool &truncated) noexcept { + int shl = leading_zeroes(r0); + if (shl == 0) { + truncated = r1 != 0; + return r0; + } else { + int shr = 64 - shl; + truncated = (r1 << shl) != 0; + return (r0 << shl) | (r1 >> shr); + } +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, bool &truncated) noexcept { + return uint64_hi64(r0, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + return uint64_hi64((x0 << 32) | x1, truncated); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 uint64_t +uint32_hi64(uint32_t r0, uint32_t r1, uint32_t r2, bool &truncated) noexcept { + uint64_t x0 = r0; + uint64_t x1 = r1; + uint64_t x2 = r2; + return uint64_hi64(x0, (x1 << 32) | x2, truncated); +} + +// add two small integers, checking for overflow. +// we want an efficient operation. for msvc, where +// we don't have built-in intrinsics, this is still +// pretty fast. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_add(limb x, limb y, bool &overflow) noexcept { + limb z; +// gcc and clang +#if defined(__has_builtin) +#if __has_builtin(__builtin_add_overflow) + if (!cpp20_and_in_constexpr()) { + overflow = __builtin_add_overflow(x, y, &z); + return z; + } +#endif +#endif + + // generic, this still optimizes correctly on MSVC. + z = x + y; + overflow = z < x; + return z; +} + +// multiply two small integers, getting both the high and low bits. +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 limb +scalar_mul(limb x, limb y, limb &carry) noexcept { +#ifdef FASTFLOAT_64BIT_LIMB +#if defined(__SIZEOF_INT128__) + // GCC and clang both define it as an extension. + __uint128_t z = __uint128_t(x) * __uint128_t(y) + __uint128_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#else + // fallback, no native 128-bit integer multiplication with carry. + // on msvc, this optimizes identically, somehow. + value128 z = full_multiplication(x, y); + bool overflow; + z.low = scalar_add(z.low, carry, overflow); + z.high += uint64_t(overflow); // cannot overflow + carry = z.high; + return z.low; +#endif +#else + uint64_t z = uint64_t(x) * uint64_t(y) + uint64_t(carry); + carry = limb(z >> limb_bits); + return limb(z); +#endif +} + +// add scalar value to bigint starting from offset. +// used in grade school multiplication +template +inline FASTFLOAT_CONSTEXPR20 bool small_add_from(stackvec &vec, limb y, + size_t start) noexcept { + size_t index = start; + limb carry = y; + bool overflow; + while (carry != 0 && index < vec.len()) { + vec[index] = scalar_add(vec[index], carry, overflow); + carry = limb(overflow); + index += 1; + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add scalar value to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +small_add(stackvec &vec, limb y) noexcept { + return small_add_from(vec, y, 0); +} + +// multiply bigint by scalar value. +template +inline FASTFLOAT_CONSTEXPR20 bool small_mul(stackvec &vec, + limb y) noexcept { + limb carry = 0; + for (size_t index = 0; index < vec.len(); index++) { + vec[index] = scalar_mul(vec[index], y, carry); + } + if (carry != 0) { + FASTFLOAT_TRY(vec.try_push(carry)); + } + return true; +} + +// add bigint to bigint starting from index. +// used in grade school multiplication +template +FASTFLOAT_CONSTEXPR20 bool large_add_from(stackvec &x, limb_span y, + size_t start) noexcept { + // the effective x buffer is from `xstart..x.len()`, so exit early + // if we can't get that current range. + if (x.len() < start || y.len() > x.len() - start) { + FASTFLOAT_TRY(x.try_resize(y.len() + start, 0)); + } + + bool carry = false; + for (size_t index = 0; index < y.len(); index++) { + limb xi = x[index + start]; + limb yi = y[index]; + bool c1 = false; + bool c2 = false; + xi = scalar_add(xi, yi, c1); + if (carry) { + xi = scalar_add(xi, 1, c2); + } + x[index + start] = xi; + carry = c1 | c2; + } + + // handle overflow + if (carry) { + FASTFLOAT_TRY(small_add_from(x, 1, y.len() + start)); + } + return true; +} + +// add bigint to bigint. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +large_add_from(stackvec &x, limb_span y) noexcept { + return large_add_from(x, y, 0); +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool long_mul(stackvec &x, limb_span y) noexcept { + limb_span xs = limb_span(x.data, x.len()); + stackvec z(xs); + limb_span zs = limb_span(z.data, z.len()); + + if (y.len() != 0) { + limb y0 = y[0]; + FASTFLOAT_TRY(small_mul(x, y0)); + for (size_t index = 1; index < y.len(); index++) { + limb yi = y[index]; + stackvec zi; + if (yi != 0) { + // re-use the same buffer throughout + zi.set_len(0); + FASTFLOAT_TRY(zi.try_extend(zs)); + FASTFLOAT_TRY(small_mul(zi, yi)); + limb_span zis = limb_span(zi.data, zi.len()); + FASTFLOAT_TRY(large_add_from(x, zis, index)); + } + } + } + + x.normalize(); + return true; +} + +// grade-school multiplication algorithm +template +FASTFLOAT_CONSTEXPR20 bool large_mul(stackvec &x, limb_span y) noexcept { + if (y.len() == 1) { + FASTFLOAT_TRY(small_mul(x, y[0])); + } else { + FASTFLOAT_TRY(long_mul(x, y)); + } + return true; +} + +template struct pow5_tables { + static constexpr uint32_t large_step = 135; + static constexpr uint64_t small_power_of_5[] = { + 1UL, + 5UL, + 25UL, + 125UL, + 625UL, + 3125UL, + 15625UL, + 78125UL, + 390625UL, + 1953125UL, + 9765625UL, + 48828125UL, + 244140625UL, + 1220703125UL, + 6103515625UL, + 30517578125UL, + 152587890625UL, + 762939453125UL, + 3814697265625UL, + 19073486328125UL, + 95367431640625UL, + 476837158203125UL, + 2384185791015625UL, + 11920928955078125UL, + 59604644775390625UL, + 298023223876953125UL, + 1490116119384765625UL, + 7450580596923828125UL, + }; +#ifdef FASTFLOAT_64BIT_LIMB + constexpr static limb large_power_of_5[] = { + 1414648277510068013UL, 9180637584431281687UL, 4539964771860779200UL, + 10482974169319127550UL, 198276706040285095UL}; +#else + constexpr static limb large_power_of_5[] = { + 4279965485U, 329373468U, 4020270615U, 2137533757U, 4287402176U, + 1057042919U, 1071430142U, 2440757623U, 381945767U, 46164893U}; +#endif +}; + +#if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE + +template constexpr uint32_t pow5_tables::large_step; + +template constexpr uint64_t pow5_tables::small_power_of_5[]; + +template constexpr limb pow5_tables::large_power_of_5[]; + +#endif + +// big integer type. implements a small subset of big integer +// arithmetic, using simple algorithms since asymptotically +// faster algorithms are slower for a small number of limbs. +// all operations assume the big-integer is normalized. +struct bigint : pow5_tables<> { + // storage of the limbs, in little-endian order. + stackvec vec; + + FASTFLOAT_CONSTEXPR20 bigint() : vec() {} + + bigint(bigint const &) = delete; + bigint &operator=(bigint const &) = delete; + bigint(bigint &&) = delete; + bigint &operator=(bigint &&other) = delete; + + FASTFLOAT_CONSTEXPR20 bigint(uint64_t value) : vec() { +#ifdef FASTFLOAT_64BIT_LIMB + vec.push_unchecked(value); +#else + vec.push_unchecked(uint32_t(value)); + vec.push_unchecked(uint32_t(value >> 32)); +#endif + vec.normalize(); + } + + // get the high 64 bits from the vector, and if bits were truncated. + // this is to get the significant digits for the float. + FASTFLOAT_CONSTEXPR20 uint64_t hi64(bool &truncated) const noexcept { +#ifdef FASTFLOAT_64BIT_LIMB + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint64_hi64(vec.rindex(0), truncated); + } else { + uint64_t result = uint64_hi64(vec.rindex(0), vec.rindex(1), truncated); + truncated |= vec.nonzero(2); + return result; + } +#else + if (vec.len() == 0) { + return empty_hi64(truncated); + } else if (vec.len() == 1) { + return uint32_hi64(vec.rindex(0), truncated); + } else if (vec.len() == 2) { + return uint32_hi64(vec.rindex(0), vec.rindex(1), truncated); + } else { + uint64_t result = + uint32_hi64(vec.rindex(0), vec.rindex(1), vec.rindex(2), truncated); + truncated |= vec.nonzero(3); + return result; + } +#endif + } + + // compare two big integers, returning the large value. + // assumes both are normalized. if the return value is + // negative, other is larger, if the return value is + // positive, this is larger, otherwise they are equal. + // the limbs are stored in little-endian order, so we + // must compare the limbs in ever order. + FASTFLOAT_CONSTEXPR20 int compare(bigint const &other) const noexcept { + if (vec.len() > other.vec.len()) { + return 1; + } else if (vec.len() < other.vec.len()) { + return -1; + } else { + for (size_t index = vec.len(); index > 0; index--) { + limb xi = vec[index - 1]; + limb yi = other.vec[index - 1]; + if (xi > yi) { + return 1; + } else if (xi < yi) { + return -1; + } + } + return 0; + } + } + + // shift left each limb n bits, carrying over to the new limb + // returns true if we were able to shift all the digits. + FASTFLOAT_CONSTEXPR20 bool shl_bits(size_t n) noexcept { + // Internally, for each item, we shift left by n, and add the previous + // right shifted limb-bits. + // For example, we transform (for u8) shifted left 2, to: + // b10100100 b01000010 + // b10 b10010001 b00001000 + FASTFLOAT_DEBUG_ASSERT(n != 0); + FASTFLOAT_DEBUG_ASSERT(n < sizeof(limb) * 8); + + size_t shl = n; + size_t shr = limb_bits - shl; + limb prev = 0; + for (size_t index = 0; index < vec.len(); index++) { + limb xi = vec[index]; + vec[index] = (xi << shl) | (prev >> shr); + prev = xi; + } + + limb carry = prev >> shr; + if (carry != 0) { + return vec.try_push(carry); + } + return true; + } + + // move the limbs left by `n` limbs. + FASTFLOAT_CONSTEXPR20 bool shl_limbs(size_t n) noexcept { + FASTFLOAT_DEBUG_ASSERT(n != 0); + if (n + vec.len() > vec.capacity()) { + return false; + } else if (!vec.is_empty()) { + // move limbs + limb *dst = vec.data + n; + limb const *src = vec.data; + tinyobj_ff::copy_backward(src, src + vec.len(), dst + vec.len()); + // fill in empty limbs + limb *first = vec.data; + limb *last = first + n; + tinyobj_ff::fill(first, last, 0); + vec.set_len(n + vec.len()); + return true; + } else { + return true; + } + } + + // move the limbs left by `n` bits. + FASTFLOAT_CONSTEXPR20 bool shl(size_t n) noexcept { + size_t rem = n % limb_bits; + size_t div = n / limb_bits; + if (rem != 0) { + FASTFLOAT_TRY(shl_bits(rem)); + } + if (div != 0) { + FASTFLOAT_TRY(shl_limbs(div)); + } + return true; + } + + // get the number of leading zeros in the bigint. + FASTFLOAT_CONSTEXPR20 int ctlz() const noexcept { + if (vec.is_empty()) { + return 0; + } else { +#ifdef FASTFLOAT_64BIT_LIMB + return leading_zeroes(vec.rindex(0)); +#else + // no use defining a specialized leading_zeroes for a 32-bit type. + uint64_t r0 = vec.rindex(0); + return leading_zeroes(r0 << 32); +#endif + } + } + + // get the number of bits in the bigint. + FASTFLOAT_CONSTEXPR20 int bit_length() const noexcept { + int lz = ctlz(); + return int(limb_bits * vec.len()) - lz; + } + + FASTFLOAT_CONSTEXPR20 bool mul(limb y) noexcept { return small_mul(vec, y); } + + FASTFLOAT_CONSTEXPR20 bool add(limb y) noexcept { return small_add(vec, y); } + + // multiply as if by 2 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow2(uint32_t exp) noexcept { return shl(exp); } + + // multiply as if by 5 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow5(uint32_t exp) noexcept { + // multiply by a power of 5 + size_t large_length = sizeof(large_power_of_5) / sizeof(limb); + limb_span large = limb_span(large_power_of_5, large_length); + while (exp >= large_step) { + FASTFLOAT_TRY(large_mul(vec, large)); + exp -= large_step; + } +#ifdef FASTFLOAT_64BIT_LIMB + uint32_t small_step = 27; + limb max_native = 7450580596923828125UL; +#else + uint32_t small_step = 13; + limb max_native = 1220703125U; +#endif + while (exp >= small_step) { + FASTFLOAT_TRY(small_mul(vec, max_native)); + exp -= small_step; + } + if (exp != 0) { + // Work around clang bug https://godbolt.org/z/zedh7rrhc + // This is similar to https://github.com/llvm/llvm-project/issues/47746, + // except the workaround described there don't work here + FASTFLOAT_TRY(small_mul( + vec, limb(((void)small_power_of_5[0], small_power_of_5[exp])))); + } + + return true; + } + + // multiply as if by 10 raised to a power. + FASTFLOAT_CONSTEXPR20 bool pow10(uint32_t exp) noexcept { + FASTFLOAT_TRY(pow5(exp)); + return pow2(exp); + } +}; + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_DIGIT_COMPARISON_H +#define FASTFLOAT_DIGIT_COMPARISON_H + +#include + + +namespace fast_float { + +// 1e0 to 1e19 +constexpr static uint64_t powers_of_ten_uint64[] = {1UL, + 10UL, + 100UL, + 1000UL, + 10000UL, + 100000UL, + 1000000UL, + 10000000UL, + 100000000UL, + 1000000000UL, + 10000000000UL, + 100000000000UL, + 1000000000000UL, + 10000000000000UL, + 100000000000000UL, + 1000000000000000UL, + 10000000000000000UL, + 100000000000000000UL, + 1000000000000000000UL, + 10000000000000000000UL}; + +// calculate the exponent, in scientific notation, of the number. +// this algorithm is not even close to optimized, but it has no practical +// effect on performance: in order to have a faster algorithm, we'd need +// to slow down performance for faster algorithms, and this is still fast. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int32_t +scientific_exponent(parsed_number_string_t &num) noexcept { + uint64_t mantissa = num.mantissa; + int32_t exponent = int32_t(num.exponent); + while (mantissa >= 10000) { + mantissa /= 10000; + exponent += 4; + } + while (mantissa >= 100) { + mantissa /= 100; + exponent += 2; + } + while (mantissa >= 10) { + mantissa /= 10; + exponent += 1; + } + return exponent; +} + +// this converts a native floating-point number to an extended-precision float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended(T value) noexcept { + using equiv_uint = equiv_uint_t; + constexpr equiv_uint exponent_mask = binary_format::exponent_mask(); + constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); + constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); + + adjusted_mantissa am; + int32_t bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + equiv_uint bits; +#if FASTFLOAT_HAS_BIT_CAST + bits = std::bit_cast(value); +#else + ::memcpy(&bits, &value, sizeof(T)); +#endif + if ((bits & exponent_mask) == 0) { + // denormal + am.power2 = 1 - bias; + am.mantissa = bits & mantissa_mask; + } else { + // normal + am.power2 = int32_t((bits & exponent_mask) >> + binary_format::mantissa_explicit_bits()); + am.power2 -= bias; + am.mantissa = (bits & mantissa_mask) | hidden_bit_mask; + } + + return am; +} + +// get the extended precision value of the halfway point between b and b+u. +// we are given a native float that represents b, so we need to adjust it +// halfway between b and b+u. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +to_extended_halfway(T value) noexcept { + adjusted_mantissa am = to_extended(value); + am.mantissa <<= 1; + am.mantissa += 1; + am.power2 -= 1; + return am; +} + +// round an extended-precision float to the nearest machine float. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am, + callback cb) noexcept { + int32_t mantissa_shift = 64 - binary_format::mantissa_explicit_bits() - 1; + if (-am.power2 >= mantissa_shift) { + // have a denormal float + int32_t shift = -am.power2 + 1; + cb(am, tinyobj_ff::min_val(shift, 64)); + // check for round-up: if rounding-nearest carried us to the hidden bit. + am.power2 = (am.mantissa < + (uint64_t(1) << binary_format::mantissa_explicit_bits())) + ? 0 + : 1; + return; + } + + // have a normal float, use the default shift. + cb(am, mantissa_shift); + + // check for carry + if (am.mantissa >= + (uint64_t(2) << binary_format::mantissa_explicit_bits())) { + am.mantissa = (uint64_t(1) << binary_format::mantissa_explicit_bits()); + am.power2++; + } + + // check for infinite: we could have carried to an infinite power + am.mantissa &= ~(uint64_t(1) << binary_format::mantissa_explicit_bits()); + if (am.power2 >= binary_format::infinite_power()) { + am.power2 = binary_format::infinite_power(); + am.mantissa = 0; + } +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_nearest_tie_even(adjusted_mantissa &am, int32_t shift, + callback cb) noexcept { + uint64_t const mask = (shift == 64) ? UINT64_MAX : (uint64_t(1) << shift) - 1; + uint64_t const halfway = (shift == 0) ? 0 : uint64_t(1) << (shift - 1); + uint64_t truncated_bits = am.mantissa & mask; + bool is_above = truncated_bits > halfway; + bool is_halfway = truncated_bits == halfway; + + // shift digits into position + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; + + bool is_odd = (am.mantissa & 1) == 1; + am.mantissa += uint64_t(cb(is_odd, is_halfway, is_above)); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +round_down(adjusted_mantissa &am, int32_t shift) noexcept { + if (shift == 64) { + am.mantissa = 0; + } else { + am.mantissa >>= shift; + } + am.power2 += shift; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +skip_zeros(UC const *&first, UC const *last) noexcept { + uint64_t val; + while (!cpp20_and_in_constexpr() && + tinyobj_ff::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + break; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + break; + } + first++; + } +} + +// determine if any non-zero digits were truncated. +// all characters must be valid digits. +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(UC const *first, UC const *last) noexcept { + // do 8-bit optimizations, can just compare to 8 literal 0s. + uint64_t val; + while (!cpp20_and_in_constexpr() && + tinyobj_ff::distance(first, last) >= int_cmp_len()) { + ::memcpy(&val, first, sizeof(uint64_t)); + if (val != int_cmp_zeros()) { + return true; + } + first += int_cmp_len(); + } + while (first != last) { + if (*first != UC('0')) { + return true; + } + ++first; + } + return false; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool +is_truncated(span s) noexcept { + return is_truncated(s.ptr, s.ptr + s.len()); +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +parse_eight_digits(UC const *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 100000000 + parse_eight_digits_unrolled(p); + p += 8; + counter += 8; + count += 8; +} + +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void +parse_one_digit(UC const *&p, limb &value, size_t &counter, + size_t &count) noexcept { + value = value * 10 + limb(*p - UC('0')); + p++; + counter++; + count++; +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +add_native(bigint &big, limb power, limb value) noexcept { + big.mul(power); + big.add(value); +} + +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +round_up_bigint(bigint &big, size_t &count) noexcept { + // need to round-up the digits, but need to avoid rounding + // ....9999 to ...10000, which could cause a false halfway point. + add_native(big, 10, 1); + count++; +} + +// parse the significant digits into a big integer +template +inline FASTFLOAT_CONSTEXPR20 void +parse_mantissa(bigint &result, parsed_number_string_t &num, + size_t max_digits, size_t &digits) noexcept { + // try to minimize the number of big integer and scalar multiplication. + // therefore, try to parse 8 digits at a time, and multiply by the largest + // scalar value (9 or 19 digits) for each step. + size_t counter = 0; + digits = 0; + limb value = 0; +#ifdef FASTFLOAT_64BIT_LIMB + size_t step = 19; +#else + size_t step = 9; +#endif + + // process all integer digits. + UC const *p = num.integer.ptr; + UC const *pend = p + num.integer.len(); + skip_zeros(p, pend); + // process all digits, in increments of step per loop + while (p != pend) { + while ((tinyobj_ff::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (num.fraction.ptr != nullptr) { + truncated |= is_truncated(num.fraction); + } + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + + // add our fraction digits, if they're available. + if (num.fraction.ptr != nullptr) { + p = num.fraction.ptr; + pend = p + num.fraction.len(); + if (digits == 0) { + skip_zeros(p, pend); + } + // process all digits, in increments of step per loop + while (p != pend) { + while ((tinyobj_ff::distance(p, pend) >= 8) && (step - counter >= 8) && + (max_digits - digits >= 8)) { + parse_eight_digits(p, value, counter, digits); + } + while (counter < step && p != pend && digits < max_digits) { + parse_one_digit(p, value, counter, digits); + } + if (digits == max_digits) { + // add the temporary value, then check if we've truncated any digits + add_native(result, limb(powers_of_ten_uint64[counter]), value); + bool truncated = is_truncated(p, pend); + if (truncated) { + round_up_bigint(result, digits); + } + return; + } else { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + counter = 0; + value = 0; + } + } + } + + if (counter != 0) { + add_native(result, limb(powers_of_ten_uint64[counter]), value); + } +} + +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { + FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent))); + adjusted_mantissa answer; + bool truncated; + answer.mantissa = bigmant.hi64(truncated); + int bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); + answer.power2 = bigmant.bit_length() - 64 + bias; + + round(answer, [truncated](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, + [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool { + return is_above || (is_halfway && truncated) || + (is_odd && is_halfway); + }); + }); + + return answer; +} + +// the scaling here is quite simple: we have, for the real digits `m * 10^e`, +// and for the theoretical digits `n * 2^f`. Since `e` is always negative, +// to scale them identically, we do `n * 2^f * 5^-f`, so we now have `m * 2^e`. +// we then need to scale by `2^(f- e)`, and then the two significant digits +// are of the same magnitude. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa negative_digit_comp( + bigint &bigmant, adjusted_mantissa am, int32_t exponent) noexcept { + bigint &real_digits = bigmant; + int32_t real_exp = exponent; + + // get the value of `b`, rounded down, and get a bigint representation of b+h + adjusted_mantissa am_b = am; + // gcc7 buf: use a lambda to remove the noexcept qualifier bug with + // -Wnoexcept-type. + round(am_b, + [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); }); + T b; + to_float(false, am_b, b); + adjusted_mantissa theor = to_extended_halfway(b); + bigint theor_digits(theor.mantissa); + int32_t theor_exp = theor.power2; + + // scale real digits and theor digits to be same power. + int32_t pow2_exp = theor_exp - real_exp; + uint32_t pow5_exp = uint32_t(-real_exp); + if (pow5_exp != 0) { + FASTFLOAT_ASSERT(theor_digits.pow5(pow5_exp)); + } + if (pow2_exp > 0) { + FASTFLOAT_ASSERT(theor_digits.pow2(uint32_t(pow2_exp))); + } else if (pow2_exp < 0) { + FASTFLOAT_ASSERT(real_digits.pow2(uint32_t(-pow2_exp))); + } + + // compare digits, and use it to director rounding + int ord = real_digits.compare(theor_digits); + adjusted_mantissa answer = am; + round(answer, [ord](adjusted_mantissa &a, int32_t shift) { + round_nearest_tie_even( + a, shift, [ord](bool is_odd, bool _, bool __) -> bool { + (void)_; // not needed, since we've done our comparison + (void)__; // not needed, since we've done our comparison + if (ord > 0) { + return true; + } else if (ord < 0) { + return false; + } else { + return is_odd; + } + }); + }); + + return answer; +} + +// parse the significant digits as a big integer to unambiguously round the +// the significant digits. here, we are trying to determine how to round +// an extended float representation close to `b+h`, halfway between `b` +// (the float rounded-down) and `b+u`, the next positive float. this +// algorithm is always correct, and uses one of two approaches. when +// the exponent is positive relative to the significant digits (such as +// 1234), we create a big-integer representation, get the high 64-bits, +// determine if any lower bits are truncated, and use that to direct +// rounding. in case of a negative exponent relative to the significant +// digits (such as 1.2345), we create a theoretical representation of +// `b` as a big-integer type, scaled to the same binary exponent as +// the actual digits. we then compare the big integer representations +// of both, and use that to direct rounding. +template +inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa +digit_comp(parsed_number_string_t &num, adjusted_mantissa am) noexcept { + // remove the invalid exponent bias + am.power2 -= invalid_am_bias; + + int32_t sci_exp = scientific_exponent(num); + size_t max_digits = binary_format::max_digits(); + size_t digits = 0; + bigint bigmant; + parse_mantissa(bigmant, num, max_digits, digits); + // can't underflow, since digits is at most max_digits. + int32_t exponent = sci_exp + 1 - int32_t(digits); + if (exponent >= 0) { + return positive_digit_comp(bigmant, exponent); + } else { + return negative_digit_comp(bigmant, am, exponent); + } +} + +} // namespace fast_float + +#endif + +#ifndef FASTFLOAT_PARSE_NUMBER_H +#define FASTFLOAT_PARSE_NUMBER_H + + +#include +#include +#include + +namespace fast_float { + +namespace detail { +/** + * Special case +inf, -inf, nan, infinity, -infinity. + * The case comparisons could be made much faster given that we know that the + * strings a null-free and fixed. + **/ +template +from_chars_result_t + FASTFLOAT_CONSTEXPR14 parse_infnan(UC const *first, UC const *last, + T &value, chars_format fmt) noexcept { + from_chars_result_t answer{}; + answer.ptr = first; + answer.ec = tinyobj_ff::ff_errc(); // be optimistic + // assume first < last, so dereference without checks; + bool const minusSign = (*first == UC('-')); + // C++17 20.19.3.(7.1) explicitly forbids '+' sign here + if ((*first == UC('-')) || + (uint64_t(fmt & chars_format::allow_leading_plus) && + (*first == UC('+')))) { + ++first; + } + if (last - first >= 3) { + if (fastfloat_strncasecmp(first, str_const_nan(), 3)) { + answer.ptr = (first += 3); + value = minusSign ? -std::numeric_limits::quiet_NaN() + : std::numeric_limits::quiet_NaN(); + // Check for possible nan(n-char-seq-opt), C++17 20.19.3.7, + // C11 7.20.1.3.3. At least MSVC produces nan(ind) and nan(snan). + if (first != last && *first == UC('(')) { + for (UC const *ptr = first + 1; ptr != last; ++ptr) { + if (*ptr == UC(')')) { + answer.ptr = ptr + 1; // valid nan(n-char-seq-opt) + break; + } else if (!((UC('a') <= *ptr && *ptr <= UC('z')) || + (UC('A') <= *ptr && *ptr <= UC('Z')) || + (UC('0') <= *ptr && *ptr <= UC('9')) || *ptr == UC('_'))) + break; // forbidden char, not nan(n-char-seq-opt) + } + } + return answer; + } + if (fastfloat_strncasecmp(first, str_const_inf(), 3)) { + if ((last - first >= 8) && + fastfloat_strncasecmp(first + 3, str_const_inf() + 3, 5)) { + answer.ptr = first + 8; + } else { + answer.ptr = first + 3; + } + value = minusSign ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity(); + return answer; + } + } + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + return answer; +} + +/** + * Returns true if the floating-pointing rounding mode is to 'nearest'. + * It is the default on most system. This function is meant to be inexpensive. + * Credit : @mwalcott3 + */ +fastfloat_really_inline bool rounds_to_nearest() noexcept { + // https://lemire.me/blog/2020/06/26/gcc-not-nearest/ +#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) + return false; +#endif + // See + // A fast function to check your floating-point rounding mode + // https://lemire.me/blog/2022/11/16/a-fast-function-to-check-your-floating-point-rounding-mode/ + // + // This function is meant to be equivalent to : + // prior: #include + // return fegetround() == FE_TONEAREST; + // However, it is expected to be much faster than the fegetround() + // function call. + // + // The volatile keyword prevents the compiler from computing the function + // at compile-time. + // There might be other ways to prevent compile-time optimizations (e.g., + // asm). The value does not need to be std::numeric_limits::min(), any + // small value so that 1 + x should round to 1 would do (after accounting for + // excess precision, as in 387 instructions). + static float volatile fmin = std::numeric_limits::min(); + float fmini = fmin; // we copy it so that it gets loaded at most once. +// +// Explanation: +// Only when fegetround() == FE_TONEAREST do we have that +// fmin + 1.0f == 1.0f - fmin. +// +// FE_UPWARD: +// fmin + 1.0f > 1 +// 1.0f - fmin == 1 +// +// FE_DOWNWARD or FE_TOWARDZERO: +// fmin + 1.0f == 1 +// 1.0f - fmin < 1 +// +// Note: This may fail to be accurate if fast-math has been +// enabled, as rounding conventions may not apply. +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(push) +// todo: is there a VS warning? +// see +// https://stackoverflow.com/questions/46079446/is-there-a-warning-for-floating-point-equality-checking-in-visual-studio-2013 +#elif defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfloat-equal" +#elif defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + return (fmini + 1.0f == 1.0f - fmini); +#ifdef FASTFLOAT_VISUAL_STUDIO +#pragma warning(pop) +#elif defined(__clang__) +#pragma clang diagnostic pop +#elif defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +} + +} // namespace detail + +template struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_advanced(first, last, value, options); + } +}; + +#ifdef __STDCPP_FLOAT32_T__ +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float32_t &value, + parse_options_t options) noexcept { + // if std::float32_t is defined, and we are in C++23 mode; macro set for + // float32; set value to float due to equivalence between float and + // float32_t + float val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +#ifdef __STDCPP_FLOAT64_T__ +template <> struct from_chars_caller { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, std::float64_t &value, + parse_options_t options) noexcept { + // if std::float64_t is defined, and we are in C++23 mode; macro set for + // float64; set value as double due to equivalence between double and + // float64_t + double val; + auto ret = from_chars_advanced(first, last, val, options); + value = val; + return ret; + } +}; +#endif + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, + chars_format fmt /*= chars_format::general*/) noexcept { + return from_chars_caller::call(first, last, value, + parse_options_t(fmt)); +} + +/** + * This function overload takes parsed_number_string_t structure that is created + * and populated either by from_chars_advanced function taking chars range and + * parsing options or other parsing custom function implemented by user. + */ +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(parsed_number_string_t &pns, T &value) noexcept { + + static_assert(is_supported_float_type::value, + "only some floating-point types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + from_chars_result_t answer; + + answer.ec = tinyobj_ff::ff_errc(); // be optimistic + answer.ptr = pns.lastmatch; + // The implementation of the Clinger's fast path is convoluted because + // we want round-to-nearest in all cases, irrespective of the rounding mode + // selected on the thread. + // We proceed optimistically, assuming that detail::rounds_to_nearest() + // returns true. + if (binary_format::min_exponent_fast_path() <= pns.exponent && + pns.exponent <= binary_format::max_exponent_fast_path() && + !pns.too_many_digits) { + // Unfortunately, the conventional Clinger's fast path is only possible + // when the system rounds to the nearest float. + // + // We expect the next branch to almost always be selected. + // We could check it first (before the previous branch), but + // there might be performance advantages at having the check + // be last. + if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) { + // We have that fegetround() == FE_TONEAREST. + // Next is Clinger's fast path. + if (pns.mantissa <= binary_format::max_mantissa_fast_path()) { + value = T(pns.mantissa); + if (pns.exponent < 0) { + value = value / binary_format::exact_power_of_ten(-pns.exponent); + } else { + value = value * binary_format::exact_power_of_ten(pns.exponent); + } + if (pns.negative) { + value = -value; + } + return answer; + } + } else { + // We do not have that fegetround() == FE_TONEAREST. + // Next is a modified Clinger's fast path, inspired by Jakub Jelínek's + // proposal + if (pns.exponent >= 0 && + pns.mantissa <= + binary_format::max_mantissa_fast_path(pns.exponent)) { +#if defined(__clang__) || defined(FASTFLOAT_32BIT) + // Clang may map 0 to -0.0 when fegetround() == FE_DOWNWARD + if (pns.mantissa == 0) { + value = pns.negative ? T(-0.) : T(0.); + return answer; + } +#endif + value = T(pns.mantissa) * + binary_format::exact_power_of_ten(pns.exponent); + if (pns.negative) { + value = -value; + } + return answer; + } + } + } + adjusted_mantissa am = + compute_float>(pns.exponent, pns.mantissa); + if (pns.too_many_digits && am.power2 >= 0) { + if (am != compute_float>(pns.exponent, pns.mantissa + 1)) { + am = compute_error>(pns.exponent, pns.mantissa); + } + } + // If we called compute_float>(pns.exponent, pns.mantissa) + // and we have an invalid power (am.power2 < 0), then we need to go the long + // way around again. This is very uncommon. + if (am.power2 < 0) { + am = digit_comp(pns, am); + } + to_float(pns.negative, am, value); + // Test for over/underflow. + if ((pns.mantissa != 0 && am.mantissa == 0 && am.power2 == 0) || + am.power2 == binary_format::infinite_power()) { + answer.ec = tinyobj_ff::ff_errc::result_out_of_range; + } + return answer; +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_float_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + + static_assert(is_supported_float_type::value, + "only some floating-point types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + + from_chars_result_t answer; + if (uint64_t(fmt & chars_format::skip_white_space)) { + while ((first != last) && fast_float::is_space(*first)) { + first++; + } + } + if (first == last) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + parsed_number_string_t pns = + uint64_t(fmt & detail::basic_json_fmt) + ? parse_number_string(first, last, options) + : parse_number_string(first, last, options); + if (!pns.valid) { + if (uint64_t(fmt & chars_format::no_infnan)) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } else { + return detail::parse_infnan(first, last, value, fmt); + } + } + + // call overload that takes parsed_number_string_t directly. + return from_chars_advanced(pns, value); +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars(UC const *first, UC const *last, T &value, int base) noexcept { + + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + parse_options_t options; + options.base = base; + return from_chars_advanced(first, last, value, options); +} + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_int_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + + static_assert(is_supported_integer_type::value, + "only integer types are supported"); + static_assert(is_supported_char_type::value, + "only char, wchar_t, char16_t and char32_t are supported"); + + chars_format const fmt = detail::adjust_for_feature_macros(options.format); + int const base = options.base; + + from_chars_result_t answer; + if (uint64_t(fmt & chars_format::skip_white_space)) { + while ((first != last) && fast_float::is_space(*first)) { + first++; + } + } + if (first == last || base < 2 || base > 36) { + answer.ec = tinyobj_ff::ff_errc::invalid_argument; + answer.ptr = first; + return answer; + } + + return parse_int_string(first, last, value, options); +} + +template struct from_chars_advanced_caller { + static_assert(TypeIx > 0, "unsupported type"); +}; + +template <> struct from_chars_advanced_caller<1> { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_float_advanced(first, last, value, options); + } +}; + +template <> struct from_chars_advanced_caller<2> { + template + FASTFLOAT_CONSTEXPR20 static from_chars_result_t + call(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_int_advanced(first, last, value, options); + } +}; + +template +FASTFLOAT_CONSTEXPR20 from_chars_result_t +from_chars_advanced(UC const *first, UC const *last, T &value, + parse_options_t options) noexcept { + return from_chars_advanced_caller< + size_t(is_supported_float_type::value) + + 2 * size_t(is_supported_integer_type::value)>::call(first, last, value, + options); +} + +} // namespace fast_float + +#endif + + +// --- End embedded fast_float --- + +// Clean up fast_float macros to avoid polluting the user's namespace. +#undef FASTFLOAT_32BIT +#undef FASTFLOAT_32BIT_LIMB +#undef FASTFLOAT_64BIT +#undef FASTFLOAT_64BIT_LIMB +#undef FASTFLOAT_ASCII_NUMBER_H +#undef FASTFLOAT_ASSERT +#undef FASTFLOAT_BIGINT_H +#undef FASTFLOAT_CONSTEXPR14 +#undef FASTFLOAT_CONSTEXPR20 +#undef FASTFLOAT_CONSTEXPR_FEATURE_DETECT_H +#undef FASTFLOAT_DEBUG_ASSERT +#undef FASTFLOAT_DECIMAL_TO_BINARY_H +#undef FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE +#undef FASTFLOAT_DIGIT_COMPARISON_H +#undef FASTFLOAT_ENABLE_IF +#undef FASTFLOAT_FAST_FLOAT_H +#undef FASTFLOAT_FAST_TABLE_H +#undef FASTFLOAT_FLOAT_COMMON_H +#undef FASTFLOAT_HAS_BIT_CAST +#undef FASTFLOAT_HAS_IS_CONSTANT_EVALUATED +#undef FASTFLOAT_HAS_SIMD +#undef FASTFLOAT_IF_CONSTEXPR17 +#undef FASTFLOAT_IS_BIG_ENDIAN +#undef FASTFLOAT_IS_CONSTEXPR +#undef FASTFLOAT_NEON +#undef FASTFLOAT_PARSE_NUMBER_H +#undef fastfloat_really_inline +#undef FASTFLOAT_SIMD_DISABLE_WARNINGS +#undef FASTFLOAT_SIMD_RESTORE_WARNINGS +#undef FASTFLOAT_SSE2 +#undef FASTFLOAT_STRINGIZE +#undef FASTFLOAT_STRINGIZE_IMPL +#undef FASTFLOAT_TRY +#undef FASTFLOAT_VERSION +#undef FASTFLOAT_VERSION_MAJOR +#undef FASTFLOAT_VERSION_MINOR +#undef FASTFLOAT_VERSION_PATCH +#undef FASTFLOAT_VERSION_STR +#undef FASTFLOAT_VISUAL_STUDIO + +#endif // TINYOBJLOADER_DISABLE_FAST_FLOAT + +namespace tinyobj { + +MaterialReader::~MaterialReader() {} + +// Byte-stream reader for bounds-checked text parsing. +// Replaces raw `const char*` token pointers with `(buf, len, idx)` triple. +// Every byte access is guarded by an EOF check. +class StreamReader { + public: +// Maximum number of bytes StreamReader will buffer from std::istream. +// Define this macro to a larger value if your application needs to parse +// very large streamed OBJ/MTL content. +#ifndef TINYOBJLOADER_STREAM_READER_MAX_BYTES +#define TINYOBJLOADER_STREAM_READER_MAX_BYTES (size_t(256) * size_t(1024) * size_t(1024)) +#endif + + StreamReader(const char *buf, size_t length) + : buf_(buf), length_(length), idx_(0), line_num_(1), col_num_(1) {} + + // Non-copyable, non-movable: buf_ may point into owned_buf_. + StreamReader(const StreamReader &) /* = delete */; + StreamReader &operator=(const StreamReader &) /* = delete */; + + // Build from std::istream by reading all content into an internal buffer. + explicit StreamReader(std::istream &is) : buf_(NULL), length_(0), idx_(0), line_num_(1), col_num_(1) { + const size_t max_stream_bytes = TINYOBJLOADER_STREAM_READER_MAX_BYTES; + std::streampos start_pos = is.tellg(); + bool can_seek = (start_pos != std::streampos(-1)); + if (can_seek) { + is.seekg(0, std::ios::end); + std::streampos end_pos = is.tellg(); + if (end_pos >= start_pos) { + std::streamoff remaining_off = static_cast(end_pos - start_pos); + is.seekg(start_pos); + unsigned long long remaining_ull = static_cast(remaining_off); + if (remaining_ull > static_cast((std::numeric_limits::max)())) { + std::stringstream ss; + ss << "input stream too large for this platform (" << remaining_ull + << " bytes exceeds size_t max " << (std::numeric_limits::max)() << ")\n"; + push_error(ss.str()); + buf_ = ""; + length_ = 0; + return; + } + size_t remaining_size = static_cast(remaining_ull); + if (remaining_size > max_stream_bytes) { + std::stringstream ss; + ss << "input stream too large (" << remaining_size + << " bytes exceeds limit " << max_stream_bytes << " bytes)\n"; + push_error(ss.str()); + buf_ = ""; + length_ = 0; + return; + } + owned_buf_.resize(remaining_size); + if (remaining_size > 0) { + is.read(&owned_buf_[0], static_cast(remaining_size)); + } + size_t actually_read = static_cast(is.gcount()); + owned_buf_.resize(actually_read); + } + } + if (!can_seek || owned_buf_.empty()) { + // Stream doesn't support seeking, or seek probing failed. + if (can_seek) is.seekg(start_pos); + is.clear(); + std::vector content; + char chunk[4096]; + size_t total_read = 0; + while (is.good()) { + is.read(chunk, static_cast(sizeof(chunk))); + std::streamsize nread = is.gcount(); + if (nread <= 0) break; + size_t n = static_cast(nread); + if (n > (max_stream_bytes - total_read)) { + std::stringstream ss; + ss << "input stream too large (exceeds limit " << max_stream_bytes + << " bytes)\n"; + push_error(ss.str()); + owned_buf_.clear(); + buf_ = ""; + length_ = 0; + return; + } + content.insert(content.end(), chunk, chunk + n); + total_read += n; + } + owned_buf_.swap(content); + } + buf_ = owned_buf_.empty() ? "" : &owned_buf_[0]; + length_ = owned_buf_.size(); + } + + bool eof() const { return idx_ >= length_; } + size_t tell() const { return idx_; } + size_t size() const { return length_; } + size_t line_num() const { return line_num_; } + size_t col_num() const { return col_num_; } + + char peek() const { + if (idx_ >= length_) return '\0'; + return buf_[idx_]; + } + + char get() { + if (idx_ >= length_) return '\0'; + char c = buf_[idx_++]; + if (c == '\n') { line_num_++; col_num_ = 1; } else { col_num_++; } + return c; + } + + void advance(size_t n) { + for (size_t i = 0; i < n && idx_ < length_; i++) { + if (buf_[idx_] == '\n') { line_num_++; col_num_ = 1; } else { col_num_++; } + idx_++; + } + } + + void skip_space() { + while (idx_ < length_ && (buf_[idx_] == ' ' || buf_[idx_] == '\t')) { + col_num_++; + idx_++; + } + } + + void skip_space_and_cr() { + while (idx_ < length_ && (buf_[idx_] == ' ' || buf_[idx_] == '\t' || buf_[idx_] == '\r')) { + col_num_++; + idx_++; + } + } + + void skip_line() { + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == '\n') { + idx_++; + line_num_++; + col_num_ = 1; + return; + } + if (c == '\r') { + idx_++; + if (idx_ < length_ && buf_[idx_] == '\n') { + idx_++; + } + line_num_++; + col_num_ = 1; + return; + } + col_num_++; + idx_++; + } + } + + bool at_line_end() const { + if (idx_ >= length_) return true; + char c = buf_[idx_]; + return (c == '\n' || c == '\r' || c == '\0'); + } + + std::string read_line() { + std::string result; + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == '\n' || c == '\r') break; + result += c; + col_num_++; + idx_++; + } + return result; + } + + // Reads a whitespace-delimited token. Used by tests and as a general utility. + std::string read_token() { + skip_space(); + std::string result; + while (idx_ < length_) { + char c = buf_[idx_]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + result += c; + col_num_++; + idx_++; + } + return result; + } + + bool match(const char *prefix, size_t len) const { + if (idx_ >= length_ || len > length_ - idx_) return false; + return (memcmp(buf_ + idx_, prefix, len) == 0); + } + + bool char_at(size_t offset, char c) const { + if (idx_ >= length_ || offset >= length_ - idx_) return false; + return buf_[idx_ + offset] == c; + } + + char peek_at(size_t offset) const { + if (idx_ >= length_ || offset >= length_ - idx_) return '\0'; + return buf_[idx_ + offset]; + } + + const char *current_ptr() const { + if (idx_ >= length_) return ""; + return buf_ + idx_; + } + + size_t remaining() const { + return (idx_ < length_) ? (length_ - idx_) : 0; + } + + // Returns the full text of the current line (for diagnostic display). + std::string current_line_text() const { + // Scan backward to find line start + size_t line_start = idx_; + while (line_start > 0 && buf_[line_start - 1] != '\n' && buf_[line_start - 1] != '\r') { + line_start--; + } + // Scan forward to find line end + size_t line_end = idx_; + while (line_end < length_ && buf_[line_end] != '\n' && buf_[line_end] != '\r') { + line_end++; + } + return std::string(buf_ + line_start, line_end - line_start); + } + + // Clang-style formatted error with file:line:col and caret. + std::string format_error(const std::string &filename, const std::string &msg) const { + std::stringstream line_ss, col_ss; + line_ss << line_num_; + col_ss << col_num_; + std::string result; + result += filename + ":" + line_ss.str() + ":" + col_ss.str() + ": error: " + msg + "\n"; + std::string line_text = current_line_text(); + result += line_text + "\n"; + // Build caret line preserving tab alignment + std::string caret; + size_t caret_pos = (col_num_ > 0) ? (col_num_ - 1) : 0; + for (size_t i = 0; i < caret_pos && i < line_text.size(); i++) { + caret += (line_text[i] == '\t') ? '\t' : ' '; + } + caret += "^"; + result += caret + "\n"; + return result; + } + + std::string format_error(const std::string &msg) const { + return format_error("", msg); + } + + // Error stack + void push_error(const std::string &msg) { + errors_.push_back(msg); + } + + void push_formatted_error(const std::string &filename, const std::string &msg) { + errors_.push_back(format_error(filename, msg)); + } + + bool has_errors() const { return !errors_.empty(); } + + std::string get_errors() const { + std::string result; + for (size_t i = 0; i < errors_.size(); i++) { + result += errors_[i]; + } + return result; + } + + const std::vector &error_stack() const { return errors_; } + + void clear_errors() { errors_.clear(); } + + private: + const char *buf_; + size_t length_; + size_t idx_; + size_t line_num_; + size_t col_num_; + std::vector owned_buf_; + std::vector errors_; +}; + +#ifdef TINYOBJLOADER_USE_MMAP +// RAII wrapper for memory-mapped file I/O. +// Opens a file and maps it into memory; the mapping is released on destruction. +// For empty files, data is set to "" and is_mapped remains false so close() +// will not attempt to unmap a string literal. +struct MappedFile { + const char *data; + size_t size; + bool is_mapped; // true when data points to an actual mapped region +#if defined(_WIN32) + HANDLE hFile; + HANDLE hMapping; +#else + void *mapped_ptr; +#endif + + MappedFile() : data(NULL), size(0), is_mapped(false) +#if defined(_WIN32) + , hFile(INVALID_HANDLE_VALUE), hMapping(NULL) +#else + , mapped_ptr(NULL) +#endif + {} + + // Opens and maps the file. Returns true on success. + bool open(const char *filepath) { +#if defined(_WIN32) + std::wstring wfilepath = LongPathW(UTF8ToWchar(std::string(filepath))); + hFile = CreateFileW(wfilepath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) return false; + LARGE_INTEGER fileSize; + if (!GetFileSizeEx(hFile, &fileSize)) { close(); return false; } + if (fileSize.QuadPart < 0) { close(); return false; } + unsigned long long fsize = static_cast(fileSize.QuadPart); + if (fsize > static_cast((std::numeric_limits::max)())) { + close(); + return false; + } + size = static_cast(fsize); + if (size == 0) { data = ""; return true; } // valid but empty; is_mapped stays false + hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hMapping == NULL) { close(); return false; } + data = static_cast(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)); + if (!data) { close(); return false; } + is_mapped = true; + return true; +#else + int fd = ::open(filepath, O_RDONLY); + if (fd == -1) return false; + struct stat sb; + if (fstat(fd, &sb) != 0) { ::close(fd); return false; } + if (sb.st_size < 0) { ::close(fd); return false; } + if (static_cast(sb.st_size) > + static_cast((std::numeric_limits::max)())) { + ::close(fd); + return false; + } + size = static_cast(sb.st_size); + if (size == 0) { ::close(fd); data = ""; return true; } // valid but empty + mapped_ptr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + ::close(fd); + if (mapped_ptr == MAP_FAILED) { mapped_ptr = NULL; size = 0; return false; } + data = static_cast(mapped_ptr); + is_mapped = true; + return true; +#endif + } + + void close() { +#if defined(_WIN32) + if (is_mapped && data) { UnmapViewOfFile(data); } + data = NULL; + is_mapped = false; + if (hMapping != NULL) { CloseHandle(hMapping); hMapping = NULL; } + if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE; } +#else + if (is_mapped && mapped_ptr && mapped_ptr != MAP_FAILED) { munmap(mapped_ptr, size); } + mapped_ptr = NULL; + data = NULL; + is_mapped = false; +#endif + size = 0; + } + + ~MappedFile() { close(); } + + private: + MappedFile(const MappedFile &); // non-copyable + MappedFile &operator=(const MappedFile &); // non-copyable +}; +#endif // TINYOBJLOADER_USE_MMAP + + +struct vertex_index_t { + int v_idx, vt_idx, vn_idx; + vertex_index_t() : v_idx(-1), vt_idx(-1), vn_idx(-1) {} + explicit vertex_index_t(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {} + vertex_index_t(int vidx, int vtidx, int vnidx) + : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {} +}; + +// Internal data structure for face representation +// index + smoothing group. +struct face_t { + unsigned int + smoothing_group_id; // smoothing group id. 0 = smoothing groupd is off. + int pad_; + std::vector vertex_indices; // face vertex indices. + + face_t() : smoothing_group_id(0), pad_(0) {} +}; + +// Internal data structure for line representation +struct __line_t { + // l v1/vt1 v2/vt2 ... + // In the specification, line primitrive does not have normal index, but + // TinyObjLoader allow it + std::vector vertex_indices; +}; + +// Internal data structure for points representation +struct __points_t { + // p v1 v2 ... + // In the specification, point primitrive does not have normal index and + // texture coord index, but TinyObjLoader allow it. + std::vector vertex_indices; +}; + +struct tag_sizes { + tag_sizes() : num_ints(0), num_reals(0), num_strings(0) {} + int num_ints; + int num_reals; + int num_strings; +}; + +struct obj_shape { + std::vector v; + std::vector vn; + std::vector vt; +}; + +// +// Manages group of primitives(face, line, points, ...) +struct PrimGroup { + std::vector faceGroup; + std::vector<__line_t> lineGroup; + std::vector<__points_t> pointsGroup; + + void clear() { + faceGroup.clear(); + lineGroup.clear(); + pointsGroup.clear(); + } + + bool IsEmpty() const { + return faceGroup.empty() && lineGroup.empty() && pointsGroup.empty(); + } + + // TODO(syoyo): bspline, surface, ... +}; + +// See +// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf +#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t')) +#define IS_DIGIT(x) \ + (static_cast((x) - '0') < static_cast(10)) +#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0')) + +template +static inline std::string toString(const T &t) { + std::stringstream ss; + ss << t; + return ss.str(); +} + +static inline std::string removeUtf8Bom(const std::string& input) { + // UTF-8 BOM = 0xEF,0xBB,0xBF + if (input.size() >= 3 && + static_cast(input[0]) == 0xEF && + static_cast(input[1]) == 0xBB && + static_cast(input[2]) == 0xBF) { + return input.substr(3); // Skip BOM + } + return input; +} + +// Trim trailing spaces and tabs from a string. +static inline std::string trimTrailingWhitespace(const std::string &s) { + size_t end = s.find_last_not_of(" \t"); + if (end == std::string::npos) return ""; + return s.substr(0, end + 1); +} + +struct warning_context { + std::string *warn; + size_t line_number; + std::string filename; +}; + +// Safely convert size_t to int, clamping at INT_MAX to prevent overflow. +static inline int size_to_int(size_t sz) { + return sz > static_cast(INT_MAX) ? INT_MAX : static_cast(sz); +} + +// Make index zero-base, and also support relative index. +static inline bool fixIndex(int idx, int n, int *ret, bool allow_zero, + const warning_context &context) { + if (!ret) { + return false; + } + + if (idx > 0) { + (*ret) = idx - 1; + return true; + } + + if (idx == 0) { + // zero is not allowed according to the spec. + if (context.warn) { + (*context.warn) += + context.filename + ":" + toString(context.line_number) + + ": warning: zero value index found (will have a value of -1 for " + "normal and tex indices)\n"; + } + + (*ret) = idx - 1; + return allow_zero; + } + + if (idx < 0) { + (*ret) = n + idx; // negative value = relative + if ((*ret) < 0) { + return false; // invalid relative index + } + return true; + } + + return false; // never reach here. +} + +static inline std::string parseString(const char **token) { + std::string s; + (*token) += strspn((*token), " \t"); + size_t e = strcspn((*token), " \t\r"); + s = std::string((*token), &(*token)[e]); + (*token) += e; + return s; +} + +static inline int parseInt(const char **token) { + (*token) += strspn((*token), " \t"); + int i = atoi((*token)); + (*token) += strcspn((*token), " \t\r"); + return i; +} + +#ifndef TINYOBJLOADER_DISABLE_FAST_FLOAT + +// ---- fast_float-based float parser (bit-exact with strtod, ~3x faster) ---- + +namespace detail_fp { + +// Case-insensitive prefix match. Returns pointer past matched prefix, or NULL. +static inline const char *match_iprefix(const char *p, const char *end, + const char *prefix) { + while (*prefix) { + if (p == end) return NULL; + char c = *p; + char e = *prefix; + if (c >= 'A' && c <= 'Z') c += 32; + if (e >= 'A' && e <= 'Z') e += 32; + if (c != e) return NULL; + ++p; + ++prefix; + } + return p; +} + +// Try to parse nan/inf. Returns true if matched, sets *result and *end_ptr. +static inline bool tryParseNanInf(const char *first, const char *last, + double *result, const char **end_ptr) { + if (first >= last) return false; + + const char *p = first; + bool negative = false; + + if (*p == '-') { + negative = true; + ++p; + } else if (*p == '+') { + ++p; + } + + if (p >= last) return false; + + // Try "nan" + const char *after = match_iprefix(p, last, "nan"); + if (after) { + *result = 0.0; // nan -> 0.0 for OBJ + *end_ptr = after; + return true; + } + + // Try "infinity" first (longer match), then "inf" + after = match_iprefix(p, last, "infinity"); + if (after) { + *result = negative ? std::numeric_limits::lowest() + : (std::numeric_limits::max)(); + *end_ptr = after; + return true; + } + + after = match_iprefix(p, last, "inf"); + if (after) { + *result = negative ? std::numeric_limits::lowest() + : (std::numeric_limits::max)(); + *end_ptr = after; + return true; + } + + return false; +} + +} // namespace detail_fp + +// Tries to parse a floating point number located at s. +// Uses fast_float::from_chars for bit-exact, high-performance parsing. +// Handles OBJ quirks: leading '+', nan/inf with replacement values. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (!s || !s_end || !result || s >= s_end) { + return false; + } + + // Check for nan/inf (starts with [nNiI] or [+-] followed by [nNiI]) + const char *p = s; + if (p < s_end && (*p == '+' || *p == '-')) ++p; + if (p < s_end) { + char fc = *p; + if (fc >= 'A' && fc <= 'Z') fc += 32; + if (fc == 'n' || fc == 'i') { + const char *end_ptr; + if (detail_fp::tryParseNanInf(s, s_end, result, &end_ptr)) { + return true; + } + } + } + + // Use allow_leading_plus so fast_float handles '+' natively. + double tmp; + auto r = fast_float::from_chars(s, s_end, tmp, + fast_float::chars_format::general | + fast_float::chars_format::allow_leading_plus); + if (r.ec == tinyobj_ff::ff_errc::ok) { + *result = tmp; + return true; + } + // On error (invalid_argument, result_out_of_range), *result is unchanged. + + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +#else // TINYOBJLOADER_DISABLE_FAST_FLOAT + +// ---- Legacy hand-written float parser (fallback) ---- + +// Tries to parse a floating point number located at s. +// +// s_end should be a location in the string where reading should absolutely +// stop. For example at the end of the string, to prevent buffer overflows. +// +// Parses the following EBNF grammar: +// sign = "+" | "-" ; +// END = ? anything not in digit ? +// digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +// integer = [sign] , digit , {digit} ; +// decimal = integer , ["." , integer] ; +// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; +// +// Valid strings are for example: +// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 +// +// If the parsing is a success, result is set to the parsed value and true +// is returned. +// +// The function is greedy and will parse until any of the following happens: +// - a non-conforming character is encountered. +// - s_end is reached. +// +// The following situations triggers a failure: +// - s >= s_end. +// - parse failure. +// +static bool tryParseDouble(const char *s, const char *s_end, double *result) { + if (s >= s_end) { + return false; + } + + double mantissa = 0.0; + // This exponent is base 2 rather than 10. + // However the exponent we parse is supposed to be one of ten, + // thus we must take care to convert the exponent/and or the + // mantissa to a * 2^E, where a is the mantissa and E is the + // exponent. + // To get the final double we will use ldexp, it requires the + // exponent to be in base 2. + int exponent = 0; + + // NOTE: THESE MUST BE DECLARED HERE SINCE WE ARE NOT ALLOWED + // TO JUMP OVER DEFINITIONS. + char sign = '+'; + char exp_sign = '+'; + char const *curr = s; + + // How many characters were read in a loop. + int read = 0; + // Tells whether a loop terminated due to reaching s_end. + bool end_not_reached = false; + bool leading_decimal_dots = false; + + /* + BEGIN PARSING. + */ + + // Find out what sign we've got. + if (*curr == '+' || *curr == '-') { + sign = *curr; + curr++; + if ((curr != s_end) && (*curr == '.')) { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else if (*curr == '.') { + // accept. Somethig like `.7e+2`, `-.5234` + leading_decimal_dots = true; + } else { + goto fail; + } + + // Read the integer part. + end_not_reached = (curr != s_end); + if (!leading_decimal_dots) { + while (end_not_reached && IS_DIGIT(*curr)) { + mantissa *= 10; + mantissa += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + + // We must make sure we actually got something. + if (read == 0) goto fail; + } + + // We allow numbers of form "#", "###" etc. + if (!end_not_reached) goto assemble; + + // Read the decimal part. + if (*curr == '.') { + curr++; + read = 1; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + static const double pow_lut[] = { + 1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001, 0.0000001, + }; + const int lut_entries = sizeof pow_lut / sizeof pow_lut[0]; + + // NOTE: Don't use powf here, it will absolutely murder precision. + mantissa += static_cast(*curr - 0x30) * + (read < lut_entries ? pow_lut[read] : std::pow(10.0, -read)); + read++; + curr++; + end_not_reached = (curr != s_end); + } + } else if (*curr == 'e' || *curr == 'E') { + } else { + goto assemble; + } + + if (!end_not_reached) goto assemble; + + // Read the exponent part. + if (*curr == 'e' || *curr == 'E') { + curr++; + // Figure out if a sign is present and if it is. + end_not_reached = (curr != s_end); + if (end_not_reached && (*curr == '+' || *curr == '-')) { + exp_sign = *curr; + curr++; + } else if (IS_DIGIT(*curr)) { /* Pass through. */ + } else { + // Empty E is not allowed. + goto fail; + } + + read = 0; + end_not_reached = (curr != s_end); + while (end_not_reached && IS_DIGIT(*curr)) { + // To avoid annoying MSVC's min/max macro definiton, + // Use hardcoded int max value + if (exponent > + ((2147483647 - 9) / 10)) { // (INT_MAX - 9) / 10, guards both multiply and add + // Integer overflow + goto fail; + } + exponent *= 10; + exponent += static_cast(*curr - 0x30); + curr++; + read++; + end_not_reached = (curr != s_end); + } + exponent *= (exp_sign == '+' ? 1 : -1); + if (read == 0) goto fail; + } + +assemble: + *result = (sign == '+' ? 1 : -1) * + (exponent ? std::ldexp(mantissa * std::pow(5.0, exponent), exponent) + : mantissa); + return true; +fail: + return false; +} + +static inline real_t parseReal(const char **token, double default_value = 0.0) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val = default_value; + tryParseDouble((*token), end, &val); + real_t f = static_cast(val); + (*token) = end; + return f; +} + +static inline bool parseReal(const char **token, real_t *out) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + double val; + bool ret = tryParseDouble((*token), end, &val); + if (ret) { + real_t f = static_cast(val); + (*out) = f; + } + (*token) = end; + return ret; +} + +#endif // TINYOBJLOADER_DISABLE_FAST_FLOAT + +static inline void parseReal2(real_t *x, real_t *y, const char **token, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); +} + +static inline void parseReal3(real_t *x, real_t *y, real_t *z, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); +} + +#if 0 // not used +static inline void parseV(real_t *x, real_t *y, real_t *z, real_t *w, + const char **token, const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0, + const double default_w = 1.0) { + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + (*w) = parseReal(token, default_w); +} +#endif + +// Extension: parse vertex with colors(6 items) +// Return 3: xyz, 4: xyzw, 6: xyzrgb +// `r`: red(case 6) or [w](case 4) +static inline int parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + const char **token, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + // TODO: Check error + (*x) = parseReal(token, default_x); + (*y) = parseReal(token, default_y); + (*z) = parseReal(token, default_z); + + // - 4 components(x, y, z, w) ot 6 components + bool has_r = parseReal(token, r); + + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = parseReal(token, g); + + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = parseReal(token, b); + + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; // treated as xyz + } + + return 6; +} + +static inline bool parseOnOff(const char **token, bool default_value = true) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + + bool ret = default_value; + if ((0 == strncmp((*token), "on", 2))) { + ret = true; + } else if ((0 == strncmp((*token), "off", 3))) { + ret = false; + } + + (*token) = end; + return ret; +} + +static inline texture_type_t parseTextureType( + const char **token, texture_type_t default_value = TEXTURE_TYPE_NONE) { + (*token) += strspn((*token), " \t"); + const char *end = (*token) + strcspn((*token), " \t\r"); + texture_type_t ty = default_value; + + if ((0 == strncmp((*token), "cube_top", strlen("cube_top")))) { + ty = TEXTURE_TYPE_CUBE_TOP; + } else if ((0 == strncmp((*token), "cube_bottom", strlen("cube_bottom")))) { + ty = TEXTURE_TYPE_CUBE_BOTTOM; + } else if ((0 == strncmp((*token), "cube_left", strlen("cube_left")))) { + ty = TEXTURE_TYPE_CUBE_LEFT; + } else if ((0 == strncmp((*token), "cube_right", strlen("cube_right")))) { + ty = TEXTURE_TYPE_CUBE_RIGHT; + } else if ((0 == strncmp((*token), "cube_front", strlen("cube_front")))) { + ty = TEXTURE_TYPE_CUBE_FRONT; + } else if ((0 == strncmp((*token), "cube_back", strlen("cube_back")))) { + ty = TEXTURE_TYPE_CUBE_BACK; + } else if ((0 == strncmp((*token), "sphere", strlen("sphere")))) { + ty = TEXTURE_TYPE_SPHERE; + } + + (*token) = end; + return ty; +} + +static tag_sizes parseTagTriple(const char **token) { + tag_sizes ts; + + (*token) += strspn((*token), " \t"); + ts.num_ints = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + + (*token)++; // Skip '/' + + (*token) += strspn((*token), " \t"); + ts.num_reals = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return ts; + } + (*token)++; // Skip '/' + + ts.num_strings = parseInt(token); + + return ts; +} + +// Parse triples with index offsets: i, i/j/k, i//k, i/j +static bool parseTriple(const char **token, int vsize, int vnsize, int vtsize, + vertex_index_t *ret, const warning_context &context) { + if (!ret) { + return false; + } + + vertex_index_t vi(-1); + + if (!fixIndex(atoi((*token)), vsize, &vi.v_idx, false, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(atoi((*token)), vtsize, &vi.vt_idx, true, context)) { + return false; + } + + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + (*token)++; // skip '/' + if (!fixIndex(atoi((*token)), vnsize, &vi.vn_idx, true, context)) { + return false; + } + (*token) += strcspn((*token), "/ \t\r"); + + (*ret) = vi; + + return true; +} + +// Parse raw triples: i, i/j/k, i//k, i/j +static vertex_index_t parseRawTriple(const char **token) { + vertex_index_t vi(static_cast(0)); // 0 is an invalid index in OBJ + + vi.v_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + (*token)++; + + // i//k + if ((*token)[0] == '/') { + (*token)++; + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + if ((*token)[0] != '/') { + return vi; + } + + // i/j/k + (*token)++; // skip '/' + vi.vn_idx = atoi((*token)); + (*token) += strcspn((*token), "/ \t\r"); + return vi; +} + +// --- Stream-based parse functions --- + +static inline std::string sr_parseString(StreamReader &sr) { + sr.skip_space(); + std::string s; + while (!sr.eof()) { + char c = sr.peek(); + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + s += c; + sr.advance(1); + } + return s; +} + +static inline int sr_parseInt(StreamReader &sr) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + int i = 0; + if (len > 0) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + if (copy_len != len) { + sr.advance(len); + return 0; + } + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + const bool has_error = + (errno == ERANGE || endptr == tmp || + val > (std::numeric_limits::max)() || + val < (std::numeric_limits::min)()); + if (!has_error) { + i = static_cast(val); + } + } + sr.advance(len); + return i; +} + +static inline real_t sr_parseReal(StreamReader &sr, double default_value = 0.0) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + double val = default_value; + if (len > 0) { + tryParseDouble(start, start + len, &val); + } + sr.advance(len); + return static_cast(val); +} + +static inline bool sr_parseReal(StreamReader &sr, real_t *out) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) return false; + double val; + bool ret = tryParseDouble(start, start + len, &val); + if (ret) { + (*out) = static_cast(val); + } + sr.advance(len); + return ret; +} + +static inline void sr_parseReal2(real_t *x, real_t *y, StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); +} + +static inline void sr_parseReal3(real_t *x, real_t *y, real_t *z, + StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); + (*z) = sr_parseReal(sr, default_z); +} + +static inline int sr_parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + StreamReader &sr, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + (*x) = sr_parseReal(sr, default_x); + (*y) = sr_parseReal(sr, default_y); + (*z) = sr_parseReal(sr, default_z); + + bool has_r = sr_parseReal(sr, r); + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = sr_parseReal(sr, g); + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = sr_parseReal(sr, b); + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + return 6; +} + +// --- Error-reporting overloads --- +// These overloads push clang-style diagnostics into `err` when parsing fails +// and return false so callers can early-return on unrecoverable parse errors. +// The original signatures are preserved above for backward compatibility. + +static inline bool sr_parseInt(StreamReader &sr, int *out, std::string *err, + const std::string &filename) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) { + if (err) { + (*err) += sr.format_error(filename, "expected integer value"); + } + *out = 0; + return false; + } + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + if (copy_len != len) { + if (err) { + (*err) += sr.format_error(filename, "integer value too long"); + } + *out = 0; + sr.advance(len); + return false; + } + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + if (errno == ERANGE || val > (std::numeric_limits::max)() || + val < (std::numeric_limits::min)()) { + if (err) { + (*err) += sr.format_error(filename, + "integer value out of range, got '" + std::string(tmp) + "'"); + } + *out = 0; + sr.advance(len); + return false; + } + if (endptr == tmp || (*endptr != '\0' && *endptr != ' ' && *endptr != '\t')) { + if (err) { + (*err) += sr.format_error(filename, + "expected integer, got '" + std::string(tmp) + "'"); + } + *out = 0; + sr.advance(len); + return false; + } + *out = static_cast(val); + sr.advance(len); + return true; +} + +static inline bool sr_parseReal(StreamReader &sr, real_t *out, + double default_value, + std::string *err, + const std::string &filename) { + sr.skip_space(); + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + while (len < rem) { + char c = start[len]; + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0') break; + len++; + } + if (len == 0) { + // No token to parse — not necessarily an error (e.g. optional component). + *out = static_cast(default_value); + return true; + } + double val; + if (!tryParseDouble(start, start + len, &val)) { + if (err) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + (*err) += sr.format_error(filename, + "expected number, got '" + std::string(tmp) + "'"); + } + *out = static_cast(default_value); + sr.advance(len); + return false; + } + *out = static_cast(val); + sr.advance(len); + return true; +} + +static inline bool sr_parseReal2(real_t *x, real_t *y, StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return false; + if (!sr_parseReal(sr, y, default_y, err, filename)) return false; + return true; +} + +static inline bool sr_parseReal3(real_t *x, real_t *y, real_t *z, + StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return false; + if (!sr_parseReal(sr, y, default_y, err, filename)) return false; + if (!sr_parseReal(sr, z, default_z, err, filename)) return false; + return true; +} + +// Returns number of components parsed (3, 4, or 6) on success, -1 on error. +static inline int sr_parseVertexWithColor(real_t *x, real_t *y, real_t *z, + real_t *r, real_t *g, real_t *b, + StreamReader &sr, + std::string *err, + const std::string &filename, + const double default_x = 0.0, + const double default_y = 0.0, + const double default_z = 0.0) { + if (!sr_parseReal(sr, x, default_x, err, filename)) return -1; + if (!sr_parseReal(sr, y, default_y, err, filename)) return -1; + if (!sr_parseReal(sr, z, default_z, err, filename)) return -1; + + bool has_r = sr_parseReal(sr, r); + if (!has_r) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + bool has_g = sr_parseReal(sr, g); + if (!has_g) { + (*g) = (*b) = 1.0; + return 4; + } + + bool has_b = sr_parseReal(sr, b); + if (!has_b) { + (*r) = (*g) = (*b) = 1.0; + return 3; + } + + return 6; +} + +static inline int sr_parseIntNoSkip(StreamReader &sr); + +// Advance past remaining characters in a tag triple field (stops at '/', whitespace, or line end). +static inline void sr_skipTagField(StreamReader &sr) { + while (!sr.eof() && !sr.at_line_end() && !IS_SPACE(sr.peek()) && + sr.peek() != '/') { + sr.advance(1); + } +} + +static tag_sizes sr_parseTagTriple(StreamReader &sr) { + tag_sizes ts; + + sr.skip_space(); + ts.num_ints = sr_parseIntNoSkip(sr); + sr_skipTagField(sr); + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + sr.skip_space(); + ts.num_reals = sr_parseIntNoSkip(sr); + sr_skipTagField(sr); + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + ts.num_strings = sr_parseInt(sr); + } + } + return ts; +} + +static inline int sr_parseIntNoSkip(StreamReader &sr) { + const char *start = sr.current_ptr(); + size_t rem = sr.remaining(); + size_t len = 0; + if (len < rem && (start[len] == '+' || start[len] == '-')) len++; + while (len < rem && start[len] >= '0' && start[len] <= '9') len++; + int i = 0; + if (len > 0) { + char tmp[64]; + size_t copy_len = len < 63 ? len : 63; + if (copy_len != len) { + sr.advance(len); + return 0; + } + memcpy(tmp, start, copy_len); + tmp[copy_len] = '\0'; + errno = 0; + char *endptr = NULL; + long val = strtol(tmp, &endptr, 10); + if (errno == 0 && endptr != tmp && *endptr == '\0' && + val <= (std::numeric_limits::max)() && + val >= (std::numeric_limits::min)()) { + i = static_cast(val); + } + } + sr.advance(len); + return i; +} + +static inline void sr_skipUntil(StreamReader &sr, const char *delims) { + while (!sr.eof()) { + char c = sr.peek(); + for (const char *d = delims; *d; d++) { + if (c == *d) return; + } + sr.advance(1); + } +} + +static bool sr_parseTriple(StreamReader &sr, int vsize, int vnsize, int vtsize, + vertex_index_t *ret, const warning_context &context) { + if (!ret) return false; + + vertex_index_t vi(-1); + + sr.skip_space(); + if (!fixIndex(sr_parseIntNoSkip(sr), vsize, &vi.v_idx, false, context)) { + return false; + } + + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') { + (*ret) = vi; + return true; + } + sr.advance(1); + + // i//k + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + if (!fixIndex(sr_parseIntNoSkip(sr), vnsize, &vi.vn_idx, true, context)) { + return false; + } + sr_skipUntil(sr, "/ \t\r\n"); + (*ret) = vi; + return true; + } + + // i/j/k or i/j + if (!fixIndex(sr_parseIntNoSkip(sr), vtsize, &vi.vt_idx, true, context)) { + return false; + } + + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') { + (*ret) = vi; + return true; + } + + // i/j/k + sr.advance(1); + if (!fixIndex(sr_parseIntNoSkip(sr), vnsize, &vi.vn_idx, true, context)) { + return false; + } + sr_skipUntil(sr, "/ \t\r\n"); + + (*ret) = vi; + return true; +} + +static vertex_index_t sr_parseRawTriple(StreamReader &sr) { + vertex_index_t vi(static_cast(0)); + + sr.skip_space(); + vi.v_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') return vi; + sr.advance(1); + + // i//k + if (!sr.eof() && sr.peek() == '/') { + sr.advance(1); + vi.vn_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + return vi; + } + + // i/j/k or i/j + vi.vt_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + if (sr.eof() || sr.peek() != '/') return vi; + + sr.advance(1); + vi.vn_idx = sr_parseIntNoSkip(sr); + sr_skipUntil(sr, "/ \t\r\n"); + return vi; +} + +bool ParseTextureNameAndOption(std::string *texname, texture_option_t *texopt, + const char *linebuf) { + // @todo { write more robust lexer and parser. } + bool found_texname = false; + std::string texture_name; + + const char *token = linebuf; // Assume line ends with NULL + + while (!IS_NEW_LINE((*token))) { + token += strspn(token, " \t"); // skip space + if ((0 == strncmp(token, "-blendu", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendu = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-blendv", 7)) && IS_SPACE((token[7]))) { + token += 8; + texopt->blendv = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-clamp", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->clamp = parseOnOff(&token, /* default */ true); + } else if ((0 == strncmp(token, "-boost", 6)) && IS_SPACE((token[6]))) { + token += 7; + texopt->sharpness = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-bm", 3)) && IS_SPACE((token[3]))) { + token += 4; + texopt->bump_multiplier = parseReal(&token, 1.0); + } else if ((0 == strncmp(token, "-o", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->origin_offset[0]), &(texopt->origin_offset[1]), + &(texopt->origin_offset[2]), &token); + } else if ((0 == strncmp(token, "-s", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->scale[0]), &(texopt->scale[1]), &(texopt->scale[2]), + &token, 1.0, 1.0, 1.0); + } else if ((0 == strncmp(token, "-t", 2)) && IS_SPACE((token[2]))) { + token += 3; + parseReal3(&(texopt->turbulence[0]), &(texopt->turbulence[1]), + &(texopt->turbulence[2]), &token); + } else if ((0 == strncmp(token, "-type", 5)) && IS_SPACE((token[5]))) { + token += 5; + texopt->type = parseTextureType((&token), TEXTURE_TYPE_NONE); + } else if ((0 == strncmp(token, "-texres", 7)) && IS_SPACE((token[7]))) { + token += 7; + // TODO(syoyo): Check if arg is int type. + texopt->texture_resolution = parseInt(&token); + } else if ((0 == strncmp(token, "-imfchan", 8)) && IS_SPACE((token[8]))) { + token += 9; + token += strspn(token, " \t"); + const char *end = token + strcspn(token, " \t\r"); + if ((end - token) == 1) { // Assume one char for -imfchan + texopt->imfchan = (*token); + } + token = end; + } else if ((0 == strncmp(token, "-mm", 3)) && IS_SPACE((token[3]))) { + token += 4; + parseReal2(&(texopt->brightness), &(texopt->contrast), &token, 0.0, 1.0); + } else if ((0 == strncmp(token, "-colorspace", 11)) && + IS_SPACE((token[11]))) { + token += 12; + texopt->colorspace = parseString(&token); + } else { +// Assume texture filename +#if 0 + size_t len = strcspn(token, " \t\r"); // untile next space + texture_name = std::string(token, token + len); + token += len; + + token += strspn(token, " \t"); // skip space +#else + // Read filename until line end to parse filename containing whitespace + // TODO(syoyo): Support parsing texture option flag after the filename. + texture_name = std::string(token); + token += texture_name.length(); +#endif + + found_texname = true; + } + } + + if (found_texname) { + (*texname) = texture_name; + return true; + } else { + return false; + } +} + +static void InitTexOpt(texture_option_t *texopt, const bool is_bump) { + if (is_bump) { + texopt->imfchan = 'l'; + } else { + texopt->imfchan = 'm'; + } + texopt->bump_multiplier = static_cast(1.0); + texopt->clamp = false; + texopt->blendu = true; + texopt->blendv = true; + texopt->sharpness = static_cast(1.0); + texopt->brightness = static_cast(0.0); + texopt->contrast = static_cast(1.0); + texopt->origin_offset[0] = static_cast(0.0); + texopt->origin_offset[1] = static_cast(0.0); + texopt->origin_offset[2] = static_cast(0.0); + texopt->scale[0] = static_cast(1.0); + texopt->scale[1] = static_cast(1.0); + texopt->scale[2] = static_cast(1.0); + texopt->turbulence[0] = static_cast(0.0); + texopt->turbulence[1] = static_cast(0.0); + texopt->turbulence[2] = static_cast(0.0); + texopt->texture_resolution = -1; + texopt->type = TEXTURE_TYPE_NONE; +} + +static void InitMaterial(material_t *material) { + InitTexOpt(&material->ambient_texopt, /* is_bump */ false); + InitTexOpt(&material->diffuse_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_texopt, /* is_bump */ false); + InitTexOpt(&material->specular_highlight_texopt, /* is_bump */ false); + InitTexOpt(&material->bump_texopt, /* is_bump */ true); + InitTexOpt(&material->displacement_texopt, /* is_bump */ false); + InitTexOpt(&material->alpha_texopt, /* is_bump */ false); + InitTexOpt(&material->reflection_texopt, /* is_bump */ false); + InitTexOpt(&material->roughness_texopt, /* is_bump */ false); + InitTexOpt(&material->metallic_texopt, /* is_bump */ false); + InitTexOpt(&material->sheen_texopt, /* is_bump */ false); + InitTexOpt(&material->emissive_texopt, /* is_bump */ false); + InitTexOpt(&material->normal_texopt, + /* is_bump */ false); // @fixme { is_bump will be true? } + material->name = ""; + material->ambient_texname = ""; + material->diffuse_texname = ""; + material->specular_texname = ""; + material->specular_highlight_texname = ""; + material->bump_texname = ""; + material->displacement_texname = ""; + material->reflection_texname = ""; + material->alpha_texname = ""; + for (int i = 0; i < 3; i++) { + material->ambient[i] = static_cast(0.0); + material->diffuse[i] = static_cast(0.0); + material->specular[i] = static_cast(0.0); + material->transmittance[i] = static_cast(0.0); + material->emission[i] = static_cast(0.0); + } + material->illum = 0; + material->dissolve = static_cast(1.0); + material->shininess = static_cast(1.0); + material->ior = static_cast(1.0); + + material->roughness = static_cast(0.0); + material->metallic = static_cast(0.0); + material->sheen = static_cast(0.0); + material->clearcoat_thickness = static_cast(0.0); + material->clearcoat_roughness = static_cast(0.0); + material->anisotropy_rotation = static_cast(0.0); + material->anisotropy = static_cast(0.0); + material->roughness_texname = ""; + material->metallic_texname = ""; + material->sheen_texname = ""; + material->emissive_texname = ""; + material->normal_texname = ""; + + material->unknown_parameter.clear(); +} + +// code from https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html +template +static int pnpoly(int nvert, T *vertx, T *verty, T testx, T testy) { + int i, j, c = 0; + for (i = 0, j = nvert - 1; i < nvert; j = i++) { + if (((verty[i] > testy) != (verty[j] > testy)) && + (testx < + (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + + vertx[i])) + c = !c; + } + return c; +} + +struct TinyObjPoint { + real_t x, y, z; + TinyObjPoint() : x(0), y(0), z(0) {} + TinyObjPoint(real_t x_, real_t y_, real_t z_) : x(x_), y(y_), z(z_) {} +}; + +inline TinyObjPoint cross(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return TinyObjPoint(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); +} + +inline real_t dot(const TinyObjPoint &v1, const TinyObjPoint &v2) { + return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); +} + +inline real_t GetLength(TinyObjPoint &e) { + return std::sqrt(e.x * e.x + e.y * e.y + e.z * e.z); +} + +inline TinyObjPoint Normalize(TinyObjPoint e) { + real_t len = GetLength(e); + if (len <= real_t(0)) return TinyObjPoint(real_t(0), real_t(0), real_t(0)); + real_t inv_length = real_t(1) / len; + return TinyObjPoint(e.x * inv_length, e.y * inv_length, e.z * inv_length); +} + +inline TinyObjPoint WorldToLocal(const TinyObjPoint &a, const TinyObjPoint &u, + const TinyObjPoint &v, const TinyObjPoint &w) { + return TinyObjPoint(dot(a, u), dot(a, v), dot(a, w)); +} + +// TODO(syoyo): refactor function. +static bool exportGroupsToShape(shape_t *shape, const PrimGroup &prim_group, + const std::vector &tags, + const int material_id, const std::string &name, + bool triangulate, const std::vector &v, + std::string *warn) { + if (prim_group.IsEmpty()) { + return false; + } + + shape->name = name; + + // polygon + if (!prim_group.faceGroup.empty()) { + // Flatten vertices and indices + for (size_t i = 0; i < prim_group.faceGroup.size(); i++) { + const face_t &face = prim_group.faceGroup[i]; + + size_t npolys = face.vertex_indices.size(); + + if (npolys < 3) { + // Face must have 3+ vertices. + if (warn) { + (*warn) += "Degenerated face found\n."; + } + continue; + } + + if (triangulate && npolys != 3) { + if (npolys == 4) { + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1 = face.vertex_indices[1]; + vertex_index_t i2 = face.vertex_indices[2]; + vertex_index_t i3 = face.vertex_indices[3]; + + if (i0.v_idx < 0 || i1.v_idx < 0 || i2.v_idx < 0 || i3.v_idx < 0) { + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + size_t vi3 = size_t(i3.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size()) || ((3 * vi3 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t v3x = v[vi3 * 3 + 0]; + real_t v3y = v[vi3 * 3 + 1]; + real_t v3z = v[vi3 * 3 + 2]; + + // There are two candidates to split the quad into two triangles. + // + // Choose the shortest edge. + // TODO: Is it better to determine the edge to split by calculating + // the area of each triangle? + // + // +---+ + // |\ | + // | \ | + // | \| + // +---+ + // + // +---+ + // | /| + // | / | + // |/ | + // +---+ + + real_t e02x = v2x - v0x; + real_t e02y = v2y - v0y; + real_t e02z = v2z - v0z; + real_t e13x = v3x - v1x; + real_t e13y = v3y - v1y; + real_t e13z = v3z - v1z; + + real_t sqr02 = e02x * e02x + e02y * e02y + e02z * e02z; + real_t sqr13 = e13x * e13x + e13y * e13y + e13z * e13z; + + index_t idx0, idx1, idx2, idx3; + + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + idx3.vertex_index = i3.v_idx; + idx3.normal_index = i3.vn_idx; + idx3.texcoord_index = i3.vt_idx; + + if (sqr02 < sqr13) { + // [0, 1, 2], [0, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } else { + // [0, 1, 3], [1, 2, 3] + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx3); + + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + shape->mesh.indices.push_back(idx3); + } + + // Two triangle faces + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.num_face_vertices.push_back(3); + + shape->mesh.material_ids.push_back(material_id); + shape->mesh.material_ids.push_back(material_id); + + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + shape->mesh.smoothing_group_ids.push_back(face.smoothing_group_id); + + } else { +#ifdef TINYOBJLOADER_USE_MAPBOX_EARCUT + // Validate all vertex indices before accessing the vertex array. + { + bool valid_poly = true; + for (size_t k = 0; k < npolys; ++k) { + size_t vi = size_t(face.vertex_indices[k].v_idx); + if ((3 * vi + 2) >= v.size()) { + valid_poly = false; + break; + } + } + if (!valid_poly) { + if (warn) { + (*warn) += "Face with invalid vertex index found.\n"; + } + continue; + } + } + + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i0_2 = i0; + + // TMW change: Find the normal axis of the polygon using Newell's + // method + TinyObjPoint n; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[k % npolys]; + size_t vi0 = size_t(i0.v_idx); + + size_t j = (k + 1) % npolys; + i0_2 = face.vertex_indices[j]; + size_t vi0_2 = size_t(i0_2.v_idx); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + real_t v0x_2 = v[vi0_2 * 3 + 0]; + real_t v0y_2 = v[vi0_2 * 3 + 1]; + real_t v0z_2 = v[vi0_2 * 3 + 2]; + + const TinyObjPoint point1(v0x, v0y, v0z); + const TinyObjPoint point2(v0x_2, v0y_2, v0z_2); + + TinyObjPoint a(point1.x - point2.x, point1.y - point2.y, + point1.z - point2.z); + TinyObjPoint b(point1.x + point2.x, point1.y + point2.y, + point1.z + point2.z); + + n.x += (a.y * b.z); + n.y += (a.z * b.x); + n.z += (a.x * b.y); + } + real_t length_n = GetLength(n); + // Check if zero length normal + if (length_n <= 0) { + continue; + } + // Negative is to flip the normal to the correct direction + real_t inv_length = -real_t(1.0) / length_n; + n.x *= inv_length; + n.y *= inv_length; + n.z *= inv_length; + + TinyObjPoint axis_w, axis_v, axis_u; + axis_w = n; + TinyObjPoint a; + if (std::fabs(axis_w.x) > real_t(0.9999999)) { + a = TinyObjPoint(0, 1, 0); + } else { + a = TinyObjPoint(1, 0, 0); + } + axis_v = Normalize(cross(axis_w, a)); + axis_u = cross(axis_w, axis_v); + using Point = std::array; + + // first polyline define the main polygon. + // following polylines define holes(not used in tinyobj). + std::vector > polygon; + + std::vector polyline; + + // TMW change: Find best normal and project v0x and v0y to those + // coordinates, instead of picking a plane aligned with an axis (which + // can flip polygons). + + // Fill polygon data(facevarying vertices). + for (size_t k = 0; k < npolys; k++) { + i0 = face.vertex_indices[k]; + size_t vi0 = size_t(i0.v_idx); + + assert(((3 * vi0 + 2) < v.size())); + + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + + TinyObjPoint polypoint(v0x, v0y, v0z); + TinyObjPoint loc = WorldToLocal(polypoint, axis_u, axis_v, axis_w); + + polyline.push_back({loc.x, loc.y}); + } + + polygon.push_back(polyline); + std::vector indices = mapbox::earcut(polygon); + // => result = 3 * faces, clockwise + + assert(indices.size() % 3 == 0); + + // Reconstruct vertex_index_t + for (size_t k = 0; k < indices.size() / 3; k++) { + { + index_t idx0, idx1, idx2; + idx0.vertex_index = face.vertex_indices[indices[3 * k + 0]].v_idx; + idx0.normal_index = + face.vertex_indices[indices[3 * k + 0]].vn_idx; + idx0.texcoord_index = + face.vertex_indices[indices[3 * k + 0]].vt_idx; + idx1.vertex_index = face.vertex_indices[indices[3 * k + 1]].v_idx; + idx1.normal_index = + face.vertex_indices[indices[3 * k + 1]].vn_idx; + idx1.texcoord_index = + face.vertex_indices[indices[3 * k + 1]].vt_idx; + idx2.vertex_index = face.vertex_indices[indices[3 * k + 2]].v_idx; + idx2.normal_index = + face.vertex_indices[indices[3 * k + 2]].vn_idx; + idx2.texcoord_index = + face.vertex_indices[indices[3 * k + 2]].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } + +#else // Built-in ear clipping triangulation + vertex_index_t i0 = face.vertex_indices[0]; + vertex_index_t i1(-1); + vertex_index_t i2 = face.vertex_indices[1]; + + // find the two axes to work in + size_t axes[2] = {1, 2}; + for (size_t k = 0; k < npolys; ++k) { + i0 = face.vertex_indices[(k + 0) % npolys]; + i1 = face.vertex_indices[(k + 1) % npolys]; + i2 = face.vertex_indices[(k + 2) % npolys]; + size_t vi0 = size_t(i0.v_idx); + size_t vi1 = size_t(i1.v_idx); + size_t vi2 = size_t(i2.v_idx); + + if (((3 * vi0 + 2) >= v.size()) || ((3 * vi1 + 2) >= v.size()) || + ((3 * vi2 + 2) >= v.size())) { + // Invalid triangle. + // FIXME(syoyo): Is it ok to simply skip this invalid triangle? + continue; + } + real_t v0x = v[vi0 * 3 + 0]; + real_t v0y = v[vi0 * 3 + 1]; + real_t v0z = v[vi0 * 3 + 2]; + real_t v1x = v[vi1 * 3 + 0]; + real_t v1y = v[vi1 * 3 + 1]; + real_t v1z = v[vi1 * 3 + 2]; + real_t v2x = v[vi2 * 3 + 0]; + real_t v2y = v[vi2 * 3 + 1]; + real_t v2z = v[vi2 * 3 + 2]; + real_t e0x = v1x - v0x; + real_t e0y = v1y - v0y; + real_t e0z = v1z - v0z; + real_t e1x = v2x - v1x; + real_t e1y = v2y - v1y; + real_t e1z = v2z - v1z; + real_t cx = std::fabs(e0y * e1z - e0z * e1y); + real_t cy = std::fabs(e0z * e1x - e0x * e1z); + real_t cz = std::fabs(e0x * e1y - e0y * e1x); + const real_t epsilon = std::numeric_limits::epsilon(); + // std::cout << "cx " << cx << ", cy " << cy << ", cz " << cz << + // "\n"; + if (cx > epsilon || cy > epsilon || cz > epsilon) { + // std::cout << "corner\n"; + // found a corner + if (cx > cy && cx > cz) { + // std::cout << "pattern0\n"; + } else { + // std::cout << "axes[0] = 0\n"; + axes[0] = 0; + if (cz > cx && cz > cy) { + // std::cout << "axes[1] = 1\n"; + axes[1] = 1; + } + } + break; + } + } + + face_t remainingFace = face; // copy + size_t guess_vert = 0; + vertex_index_t ind[3]; + real_t vx[3]; + real_t vy[3]; + + // How many iterations can we do without decreasing the remaining + // vertices. + size_t remainingIterations = face.vertex_indices.size(); + size_t previousRemainingVertices = + remainingFace.vertex_indices.size(); + + while (remainingFace.vertex_indices.size() > 3 && + remainingIterations > 0) { + // std::cout << "remainingIterations " << remainingIterations << + // "\n"; + + npolys = remainingFace.vertex_indices.size(); + if (guess_vert >= npolys) { + guess_vert -= npolys; + } + + if (previousRemainingVertices != npolys) { + // The number of remaining vertices decreased. Reset counters. + previousRemainingVertices = npolys; + remainingIterations = npolys; + } else { + // We didn't consume a vertex on previous iteration, reduce the + // available iterations. + remainingIterations--; + } + + for (size_t k = 0; k < 3; k++) { + ind[k] = remainingFace.vertex_indices[(guess_vert + k) % npolys]; + size_t vi = size_t(ind[k].v_idx); + if (((vi * 3 + axes[0]) >= v.size()) || + ((vi * 3 + axes[1]) >= v.size())) { + // ??? + vx[k] = static_cast(0.0); + vy[k] = static_cast(0.0); + } else { + vx[k] = v[vi * 3 + axes[0]]; + vy[k] = v[vi * 3 + axes[1]]; + } + } + + // + // area is calculated per face + // + real_t e0x = vx[1] - vx[0]; + real_t e0y = vy[1] - vy[0]; + real_t e1x = vx[2] - vx[1]; + real_t e1y = vy[2] - vy[1]; + real_t cross = e0x * e1y - e0y * e1x; + // std::cout << "axes = " << axes[0] << ", " << axes[1] << "\n"; + // std::cout << "e0x, e0y, e1x, e1y " << e0x << ", " << e0y << ", " + // << e1x << ", " << e1y << "\n"; + + real_t area = + (vx[0] * vy[1] - vy[0] * vx[1]) * static_cast(0.5); + // std::cout << "cross " << cross << ", area " << area << "\n"; + // if an internal angle + if (cross * area < static_cast(0.0)) { + // std::cout << "internal \n"; + guess_vert += 1; + // std::cout << "guess vert : " << guess_vert << "\n"; + continue; + } + + // check all other verts in case they are inside this triangle + bool overlap = false; + for (size_t otherVert = 3; otherVert < npolys; ++otherVert) { + size_t idx = (guess_vert + otherVert) % npolys; + + if (idx >= remainingFace.vertex_indices.size()) { + // std::cout << "???0\n"; + // ??? + continue; + } + + size_t ovi = size_t(remainingFace.vertex_indices[idx].v_idx); + + if (((ovi * 3 + axes[0]) >= v.size()) || + ((ovi * 3 + axes[1]) >= v.size())) { + // std::cout << "???1\n"; + // ??? + continue; + } + real_t tx = v[ovi * 3 + axes[0]]; + real_t ty = v[ovi * 3 + axes[1]]; + if (pnpoly(3, vx, vy, tx, ty)) { + // std::cout << "overlap\n"; + overlap = true; + break; + } + } + + if (overlap) { + // std::cout << "overlap2\n"; + guess_vert += 1; + continue; + } + + // this triangle is an ear + { + index_t idx0, idx1, idx2; + idx0.vertex_index = ind[0].v_idx; + idx0.normal_index = ind[0].vn_idx; + idx0.texcoord_index = ind[0].vt_idx; + idx1.vertex_index = ind[1].v_idx; + idx1.normal_index = ind[1].vn_idx; + idx1.texcoord_index = ind[1].vt_idx; + idx2.vertex_index = ind[2].v_idx; + idx2.normal_index = ind[2].vn_idx; + idx2.texcoord_index = ind[2].vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + + // remove v1 from the list + size_t removed_vert_index = (guess_vert + 1) % npolys; + while (removed_vert_index + 1 < npolys) { + remainingFace.vertex_indices[removed_vert_index] = + remainingFace.vertex_indices[removed_vert_index + 1]; + removed_vert_index += 1; + } + remainingFace.vertex_indices.pop_back(); + } + + // std::cout << "remainingFace.vi.size = " << + // remainingFace.vertex_indices.size() << "\n"; + if (remainingFace.vertex_indices.size() == 3) { + i0 = remainingFace.vertex_indices[0]; + i1 = remainingFace.vertex_indices[1]; + i2 = remainingFace.vertex_indices[2]; + { + index_t idx0, idx1, idx2; + idx0.vertex_index = i0.v_idx; + idx0.normal_index = i0.vn_idx; + idx0.texcoord_index = i0.vt_idx; + idx1.vertex_index = i1.v_idx; + idx1.normal_index = i1.vn_idx; + idx1.texcoord_index = i1.vt_idx; + idx2.vertex_index = i2.v_idx; + idx2.normal_index = i2.vn_idx; + idx2.texcoord_index = i2.vt_idx; + + shape->mesh.indices.push_back(idx0); + shape->mesh.indices.push_back(idx1); + shape->mesh.indices.push_back(idx2); + + shape->mesh.num_face_vertices.push_back(3); + shape->mesh.material_ids.push_back(material_id); + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); + } + } +#endif + } // npolys + } else { + for (size_t k = 0; k < npolys; k++) { + index_t idx; + idx.vertex_index = face.vertex_indices[k].v_idx; + idx.normal_index = face.vertex_indices[k].vn_idx; + idx.texcoord_index = face.vertex_indices[k].vt_idx; + shape->mesh.indices.push_back(idx); + } + + shape->mesh.num_face_vertices.push_back( + static_cast(npolys)); + shape->mesh.material_ids.push_back(material_id); // per face + shape->mesh.smoothing_group_ids.push_back( + face.smoothing_group_id); // per face + } + } + + shape->mesh.tags = tags; + } + + // line + if (!prim_group.lineGroup.empty()) { + // Flatten indices + for (size_t i = 0; i < prim_group.lineGroup.size(); i++) { + for (size_t j = 0; j < prim_group.lineGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.lineGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->lines.indices.push_back(idx); + } + + shape->lines.num_line_vertices.push_back( + int(prim_group.lineGroup[i].vertex_indices.size())); + } + } + + // points + if (!prim_group.pointsGroup.empty()) { + // Flatten & convert indices + for (size_t i = 0; i < prim_group.pointsGroup.size(); i++) { + for (size_t j = 0; j < prim_group.pointsGroup[i].vertex_indices.size(); + j++) { + const vertex_index_t &vi = prim_group.pointsGroup[i].vertex_indices[j]; + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + shape->points.indices.push_back(idx); + } + } + } + + return true; +} + +// Split a string with specified delimiter character and escape character. +// https://rosettacode.org/wiki/Tokenize_a_string_with_escaping#C.2B.2B +static void SplitString(const std::string &s, char delim, char escape, + std::vector &elems) { + std::string token; + + bool escaping = false; + for (size_t i = 0; i < s.size(); ++i) { + char ch = s[i]; + if (escaping) { + escaping = false; + } else if (ch == escape) { + if ((i + 1) < s.size()) { + const char next = s[i + 1]; + if ((next == delim) || (next == escape)) { + escaping = true; + continue; + } + } + } else if (ch == delim) { + if (!token.empty()) { + elems.push_back(token); + } + token.clear(); + continue; + } + token += ch; + } + + elems.push_back(token); +} + +static void RemoveEmptyTokens(std::vector *tokens) { + if (!tokens) return; + + const std::vector &src = *tokens; + std::vector filtered; + filtered.reserve(src.size()); + for (size_t i = 0; i < src.size(); i++) { + if (!src[i].empty()) { + filtered.push_back(src[i]); + } + } + tokens->swap(filtered); +} + +static std::string JoinPath(const std::string &dir, + const std::string &filename) { + if (dir.empty()) { + return filename; + } else { + // check '/' + char lastChar = *dir.rbegin(); + if (lastChar != '/') { + return dir + std::string("/") + filename; + } else { + return dir + filename; + } + } +} + +static bool LoadMtlInternal(std::map *material_map, + std::vector *materials, + StreamReader &sr, + std::string *warning, std::string *err, + const std::string &filename = "") { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + material_t material; + InitMaterial(&material); + + // Issue 43. `d` wins against `Tr` since `Tr` is not in the MTL specification. + bool has_d = false; + bool has_tr = false; + + // has_kd is used to set a default diffuse value when map_Kd is present + // and Kd is not. + bool has_kd = false; + + std::stringstream warn_ss; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + size_t line_num = sr.line_num(); + + // new mtl + if (sr.match("newmtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + // flush previous material. + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + InitMaterial(&material); + + has_d = false; + has_tr = false; + has_kd = false; + + sr.advance(7); + { + std::string namebuf = sr_parseString(sr); + if (namebuf.empty()) { + if (warning) { + (*warning) += "empty material name in `newmtl`\n"; + } + } + material.name = namebuf; + } + sr.skip_line(); + continue; + } + + // ambient + if (sr.peek() == 'K' && sr.peek_at(1) == 'a' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.ambient[0] = r; + material.ambient[1] = g; + material.ambient[2] = b; + sr.skip_line(); + continue; + } + + // diffuse + if (sr.peek() == 'K' && sr.peek_at(1) == 'd' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.diffuse[0] = r; + material.diffuse[1] = g; + material.diffuse[2] = b; + has_kd = true; + sr.skip_line(); + continue; + } + + // specular + if (sr.peek() == 'K' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.specular[0] = r; + material.specular[1] = g; + material.specular[2] = b; + sr.skip_line(); + continue; + } + + // transmittance + if ((sr.peek() == 'K' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) || + (sr.peek() == 'T' && sr.peek_at(1) == 'f' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t'))) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.transmittance[0] = r; + material.transmittance[1] = g; + material.transmittance[2] = b; + sr.skip_line(); + continue; + } + + // ior(index of refraction) + if (sr.peek() == 'N' && sr.peek_at(1) == 'i' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.ior, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // emission + if (sr.peek() == 'K' && sr.peek_at(1) == 'e' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + real_t r, g, b; + if (!sr_parseReal3(&r, &g, &b, sr, err, filename)) return false; + material.emission[0] = r; + material.emission[1] = g; + material.emission[2] = b; + sr.skip_line(); + continue; + } + + // shininess + if (sr.peek() == 'N' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.shininess, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // illum model + if (sr.match("illum", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + if (!sr_parseInt(sr, &material.illum, err, filename)) return false; + sr.skip_line(); + continue; + } + + // dissolve + if (sr.peek() == 'd' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(1); + if (!sr_parseReal(sr, &material.dissolve, 0.0, err, filename)) return false; + + if (has_tr) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_num + << " in .mtl.)\n"; + } + has_d = true; + sr.skip_line(); + continue; + } + if (sr.peek() == 'T' && sr.peek_at(1) == 'r' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (has_d) { + warn_ss << "Both `d` and `Tr` parameters defined for \"" + << material.name + << "\". Use the value of `d` for dissolve (line " << line_num + << " in .mtl.)\n"; + } else { + real_t tr_val; + if (!sr_parseReal(sr, &tr_val, 0.0, err, filename)) return false; + material.dissolve = static_cast(1.0) - tr_val; + } + has_tr = true; + sr.skip_line(); + continue; + } + + // PBR: roughness + if (sr.peek() == 'P' && sr.peek_at(1) == 'r' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.roughness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: metallic + if (sr.peek() == 'P' && sr.peek_at(1) == 'm' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.metallic, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: sheen + if (sr.peek() == 'P' && sr.peek_at(1) == 's' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.sheen, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: clearcoat thickness + if (sr.peek() == 'P' && sr.peek_at(1) == 'c' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(2); + if (!sr_parseReal(sr, &material.clearcoat_thickness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: clearcoat roughness + if (sr.match("Pcr", 3) && (sr.peek_at(3) == ' ' || sr.peek_at(3) == '\t')) { + sr.advance(4); + if (!sr_parseReal(sr, &material.clearcoat_roughness, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: anisotropy + if (sr.match("aniso", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + if (!sr_parseReal(sr, &material.anisotropy, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // PBR: anisotropy rotation + if (sr.match("anisor", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + if (!sr_parseReal(sr, &material.anisotropy_rotation, 0.0, err, filename)) return false; + sr.skip_line(); + continue; + } + + // For texture directives, read rest of line and delegate to + // ParseTextureNameAndOption (which uses the old const char* parse functions). + + // ambient or ambient occlusion texture + if (sr.match("map_Ka", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.ambient_texname), + &(material.ambient_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // diffuse texture + if (sr.match("map_Kd", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.diffuse_texname), + &(material.diffuse_texopt), line_rest.c_str()); + if (!has_kd) { + material.diffuse[0] = static_cast(0.6); + material.diffuse[1] = static_cast(0.6); + material.diffuse[2] = static_cast(0.6); + } + sr.skip_line(); + continue; + } + + // specular texture + if (sr.match("map_Ks", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.specular_texname), + &(material.specular_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // specular highlight texture + if (sr.match("map_Ns", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.specular_highlight_texname), + &(material.specular_highlight_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // bump texture + if ((sr.match("map_bump", 8) || sr.match("map_Bump", 8)) && + (sr.peek_at(8) == ' ' || sr.peek_at(8) == '\t')) { + sr.advance(9); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // bump texture (short form) + if (sr.match("bump", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.bump_texname), + &(material.bump_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // alpha texture + if (sr.match("map_d", 5) && (sr.peek_at(5) == ' ' || sr.peek_at(5) == '\t')) { + sr.advance(6); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.alpha_texname), + &(material.alpha_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // displacement texture + if ((sr.match("map_disp", 8) || sr.match("map_Disp", 8)) && + (sr.peek_at(8) == ' ' || sr.peek_at(8) == '\t')) { + sr.advance(9); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // displacement texture (short form) + if (sr.match("disp", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.displacement_texname), + &(material.displacement_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // reflection map + if (sr.match("refl", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.reflection_texname), + &(material.reflection_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: roughness texture + if (sr.match("map_Pr", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.roughness_texname), + &(material.roughness_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: metallic texture + if (sr.match("map_Pm", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.metallic_texname), + &(material.metallic_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: sheen texture + if (sr.match("map_Ps", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.sheen_texname), + &(material.sheen_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: emissive texture + if (sr.match("map_Ke", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(7); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.emissive_texname), + &(material.emissive_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // PBR: normal map texture + if (sr.match("norm", 4) && (sr.peek_at(4) == ' ' || sr.peek_at(4) == '\t')) { + sr.advance(5); + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + ParseTextureNameAndOption(&(material.normal_texname), + &(material.normal_texopt), line_rest.c_str()); + sr.skip_line(); + continue; + } + + // unknown parameter + { + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + const char *_lp = line_rest.c_str(); + const char *_space = strchr(_lp, ' '); + if (!_space) { + _space = strchr(_lp, '\t'); + } + if (_space) { + std::ptrdiff_t len = _space - _lp; + std::string key(_lp, static_cast(len)); + std::string value = _space + 1; + material.unknown_parameter.insert( + std::pair(key, value)); + } + } + sr.skip_line(); + } + // flush last material (only if it was actually defined). + if (!material.name.empty()) { + material_map->insert(std::pair( + material.name, static_cast(materials->size()))); + materials->push_back(material); + } + + if (warning) { + (*warning) += warn_ss.str(); + } + + return true; +} + +void LoadMtl(std::map *material_map, + std::vector *materials, std::istream *inStream, + std::string *warning, std::string *err) { + StreamReader sr(*inStream); + LoadMtlInternal(material_map, materials, sr, warning, err); +} + + +bool MaterialFileReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + if (!m_mtlBaseDir.empty()) { +#ifdef _WIN32 + char sep = ';'; +#else + char sep = ':'; +#endif + + // https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g + std::vector paths; + std::istringstream f(m_mtlBaseDir); + + std::string s; + while (getline(f, s, sep)) { + paths.push_back(s); + } + + for (size_t i = 0; i < paths.size(); i++) { + std::string filepath = JoinPath(paths[i], matId); + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (!mf.open(filepath.c_str())) continue; + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadMtlInternal(matMap, materials, sr, warn, err, filepath); + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream matIStream(LongPathW(UTF8ToWchar(filepath)).c_str()); +#else + std::ifstream matIStream(filepath.c_str()); +#endif + if (matIStream) { + StreamReader mtl_sr(matIStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, filepath); + } +#endif // TINYOBJLOADER_USE_MMAP + } + + std::stringstream ss; + ss << "Material file [ " << matId + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + + } else { + std::string filepath = matId; + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (mf.open(filepath.c_str())) { + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadMtlInternal(matMap, materials, sr, warn, err, filepath); + } + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream matIStream(LongPathW(UTF8ToWchar(filepath)).c_str()); +#else + std::ifstream matIStream(filepath.c_str()); +#endif + if (matIStream) { + StreamReader mtl_sr(matIStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, filepath); + } +#endif // TINYOBJLOADER_USE_MMAP + + std::stringstream ss; + ss << "Material file [ " << filepath + << " ] not found in a path : " << m_mtlBaseDir << "\n"; + if (warn) { + (*warn) += ss.str(); + } + + return false; + } +} + +bool MaterialStreamReader::operator()(const std::string &matId, + std::vector *materials, + std::map *matMap, + std::string *warn, std::string *err) { + (void)matId; + if (!m_inStream) { + std::stringstream ss; + ss << "Material stream in error state. \n"; + if (warn) { + (*warn) += ss.str(); + } + return false; + } + + StreamReader mtl_sr(m_inStream); + return LoadMtlInternal(matMap, materials, mtl_sr, warn, err, ""); +} + +static bool LoadObjInternal(attrib_t *attrib, std::vector *shapes, + std::vector *materials, + std::string *warn, std::string *err, + StreamReader &sr, + MaterialReader *readMatFn, bool triangulate, + bool default_vcols_fallback, + const std::string &filename = "") { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + std::vector v; + std::vector vertex_weights; + std::vector vn; + std::vector vt; + std::vector vt_w; // optional [w] component in `vt` + std::vector vc; + std::vector vw; + std::vector tags; + PrimGroup prim_group; + std::string name; + + // material + std::set material_filenames; + std::map material_map; + int material = -1; + + unsigned int current_smoothing_id = 0; + + int greatest_v_idx = -1; + int greatest_vn_idx = -1; + int greatest_vt_idx = -1; + + shape_t shape; + + bool found_all_colors = true; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + warning_context context; + context.warn = warn; + context.filename = filename; + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + size_t line_num = sr.line_num(); + + // vertex + if (sr.peek() == 'v' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + real_t x, y, z; + real_t r, g, b; + + int num_components = sr_parseVertexWithColor(&x, &y, &z, &r, &g, &b, sr, err, filename); + if (num_components < 0) return false; + found_all_colors &= (num_components == 6); + + v.push_back(x); + v.push_back(y); + v.push_back(z); + + vertex_weights.push_back(r); + + if ((num_components == 6) || default_vcols_fallback) { + vc.push_back(r); + vc.push_back(g); + vc.push_back(b); + } + + sr.skip_line(); + continue; + } + + // normal + if (sr.peek() == 'v' && sr.peek_at(1) == 'n' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + if (!sr_parseReal3(&x, &y, &z, sr, err, filename)) return false; + vn.push_back(x); + vn.push_back(y); + vn.push_back(z); + sr.skip_line(); + continue; + } + + // texcoord + if (sr.peek() == 'v' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y; + if (!sr_parseReal2(&x, &y, sr, err, filename)) return false; + vt.push_back(x); + vt.push_back(y); + + // Parse optional w component + real_t w = static_cast(0.0); + sr_parseReal(sr, &w); + vt_w.push_back(w); + + sr.skip_line(); + continue; + } + + // skin weight. tinyobj extension + if (sr.peek() == 'v' && sr.peek_at(1) == 'w' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + + int vid; + if (!sr_parseInt(sr, &vid, err, filename)) return false; + + skin_weight_t sw; + sw.vertex_id = vid; + + size_t vw_loop_max = sr.remaining() + 1; + size_t vw_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + vw_loop_iter < vw_loop_max) { + real_t j, w; + sr_parseReal2(&j, &w, sr, -1.0); + + if (j < static_cast(0)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `vw' line: joint_id is negative"); + } + return false; + } + + joint_and_weight_t jw; + jw.joint_id = int(j); + jw.weight = w; + + sw.weightValues.push_back(jw); + sr.skip_space_and_cr(); + vw_loop_iter++; + } + + vw.push_back(sw); + sr.skip_line(); + continue; + } + + context.line_number = line_num; + + // line + if (sr.peek() == 'l' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + + __line_t line; + + size_t l_loop_max = sr.remaining() + 1; + size_t l_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + l_loop_iter < l_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `l' line (invalid vertex index)"); + } + return false; + } + + line.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + l_loop_iter++; + } + + prim_group.lineGroup.push_back(line); + sr.skip_line(); + continue; + } + + // points + if (sr.peek() == 'p' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + + __points_t pts; + + size_t p_loop_max = sr.remaining() + 1; + size_t p_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + p_loop_iter < p_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `p' line (invalid vertex index)"); + } + return false; + } + + pts.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + p_loop_iter++; + } + + prim_group.pointsGroup.push_back(pts); + sr.skip_line(); + continue; + } + + // face + if (sr.peek() == 'f' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + sr.skip_space(); + + face_t face; + + face.smoothing_group_id = current_smoothing_id; + face.vertex_indices.reserve(3); + + size_t f_loop_max = sr.remaining() + 1; + size_t f_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + f_loop_iter < f_loop_max) { + vertex_index_t vi; + if (!sr_parseTriple(sr, size_to_int(v.size() / 3), + size_to_int(vn.size() / 3), + size_to_int(vt.size() / 2), &vi, context)) { + if (err) { + (*err) += sr.format_error(filename, + "failed to parse `f' line (invalid vertex index)"); + } + return false; + } + + greatest_v_idx = greatest_v_idx > vi.v_idx ? greatest_v_idx : vi.v_idx; + greatest_vn_idx = + greatest_vn_idx > vi.vn_idx ? greatest_vn_idx : vi.vn_idx; + greatest_vt_idx = + greatest_vt_idx > vi.vt_idx ? greatest_vt_idx : vi.vt_idx; + + face.vertex_indices.push_back(vi); + sr.skip_space_and_cr(); + f_loop_iter++; + } + + prim_group.faceGroup.push_back(face); + sr.skip_line(); + continue; + } + + // use mtl + if (sr.match("usemtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(6); + std::string namebuf = sr_parseString(sr); + + int newMaterialId = -1; + std::map::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + if (warn) { + (*warn) += "material [ '" + namebuf + "' ] not found in .mtl\n"; + } + } + + if (newMaterialId != material) { + exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + prim_group.faceGroup.clear(); + material = newMaterialId; + } + + sr.skip_line(); + continue; + } + + // load mtl + if (sr.match("mtllib", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + if (readMatFn) { + sr.advance(7); + + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + std::vector filenames; + SplitString(line_rest, ' ', '\\', filenames); + RemoveEmptyTokens(&filenames); + + if (filenames.empty()) { + if (warn) { + std::stringstream ss; + ss << "Looks like empty filename for mtllib. Use default " + "material (line " + << line_num << ".)\n"; + + (*warn) += ss.str(); + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), materials, + &material_map, &warn_mtl, &err_mtl); + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + material_filenames.insert(filenames[s]); + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } + } + } + + sr.skip_line(); + continue; + } + + // group name + if (sr.peek() == 'g' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; + + if (shape.mesh.indices.size() > 0) { + shapes->push_back(shape); + } + + shape = shape_t(); + + // material = -1; + prim_group.clear(); + + std::vector names; + + size_t g_loop_max = sr.remaining() + 1; + size_t g_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + g_loop_iter < g_loop_max) { + std::string str = sr_parseString(sr); + names.push_back(str); + sr.skip_space_and_cr(); + g_loop_iter++; + } + + // names[0] must be 'g' + + if (names.size() < 2) { + // 'g' with empty names + if (warn) { + std::stringstream ss; + ss << "Empty group name. line: " << line_num << "\n"; + (*warn) += ss.str(); + name = ""; + } + } else { + std::stringstream ss; + ss << names[1]; + + for (size_t i = 2; i < names.size(); i++) { + ss << " " << names[i]; + } + + name = ss.str(); + } + + sr.skip_line(); + continue; + } + + // object name + if (sr.peek() == 'o' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // flush previous face group. + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + (void)ret; + + if (shape.mesh.indices.size() > 0 || shape.lines.indices.size() > 0 || + shape.points.indices.size() > 0) { + shapes->push_back(shape); + } + + // material = -1; + prim_group.clear(); + shape = shape_t(); + + sr.advance(2); + std::string rest = sr.read_line(); + name = rest; + + sr.skip_line(); + continue; + } + + if (sr.peek() == 't' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + const int max_tag_nums = 8192; + tag_t tag; + + sr.advance(2); + + tag.name = sr_parseString(sr); + + tag_sizes ts = sr_parseTagTriple(sr); + + if (ts.num_ints < 0) { + ts.num_ints = 0; + } + if (ts.num_ints > max_tag_nums) { + ts.num_ints = max_tag_nums; + } + + if (ts.num_reals < 0) { + ts.num_reals = 0; + } + if (ts.num_reals > max_tag_nums) { + ts.num_reals = max_tag_nums; + } + + if (ts.num_strings < 0) { + ts.num_strings = 0; + } + if (ts.num_strings > max_tag_nums) { + ts.num_strings = max_tag_nums; + } + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = sr_parseInt(sr); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = sr_parseReal(sr); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = sr_parseString(sr); + } + + tags.push_back(tag); + + sr.skip_line(); + continue; + } + + if (sr.peek() == 's' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + // smoothing group id + sr.advance(2); + sr.skip_space(); + + if (sr.at_line_end()) { + sr.skip_line(); + continue; + } + + if (sr.peek() == '\r') { + sr.skip_line(); + continue; + } + + if (sr.remaining() >= 3 && sr.match("off", 3)) { + current_smoothing_id = 0; + } else { + int smGroupId = sr_parseInt(sr); + if (smGroupId < 0) { + current_smoothing_id = 0; + } else { + current_smoothing_id = static_cast(smGroupId); + } + } + + sr.skip_line(); + continue; + } + + // Ignore unknown command. + sr.skip_line(); + } + + // not all vertices have colors, no default colors desired? -> clear colors + if (!found_all_colors && !default_vcols_fallback) { + vc.clear(); + } + + if (greatest_v_idx >= size_to_int(v.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex indices out of bounds (line " << sr.line_num() << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vn_idx >= size_to_int(vn.size() / 3)) { + if (warn) { + std::stringstream ss; + ss << "Vertex normal indices out of bounds (line " << sr.line_num() + << ".)\n\n"; + (*warn) += ss.str(); + } + } + if (greatest_vt_idx >= size_to_int(vt.size() / 2)) { + if (warn) { + std::stringstream ss; + ss << "Vertex texcoord indices out of bounds (line " << sr.line_num() + << ".)\n\n"; + (*warn) += ss.str(); + } + } + + bool ret = exportGroupsToShape(&shape, prim_group, tags, material, name, + triangulate, v, warn); + if (ret || shape.mesh.indices.size()) { + shapes->push_back(shape); + } + prim_group.clear(); + + attrib->vertices.swap(v); + attrib->vertex_weights.swap(vertex_weights); + attrib->normals.swap(vn); + attrib->texcoords.swap(vt); + attrib->texcoord_ws.swap(vt_w); + attrib->colors.swap(vc); + attrib->skin_weights.swap(vw); + + return true; +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, const char *filename, const char *mtl_basedir, + bool triangulate, bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->vertex_weights.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->texcoord_ws.clear(); + attrib->colors.clear(); + attrib->skin_weights.clear(); + shapes->clear(); + + std::string baseDir = mtl_basedir ? mtl_basedir : ""; + if (!baseDir.empty()) { +#ifndef _WIN32 + const char dirsep = '/'; +#else + const char dirsep = '\\'; +#endif + if (baseDir[baseDir.length() - 1] != dirsep) baseDir += dirsep; + } + MaterialFileReader matFileReader(baseDir); + +#ifdef TINYOBJLOADER_USE_MMAP + { + MappedFile mf; + if (!mf.open(filename)) { + if (err) { + std::stringstream ss; + ss << "Cannot open file [" << filename << "]\n"; + (*err) = ss.str(); + } + return false; + } + if (mf.size > TINYOBJLOADER_STREAM_READER_MAX_BYTES) { + if (err) { + std::stringstream ss; + ss << "input stream too large (" << mf.size + << " bytes exceeds limit " + << TINYOBJLOADER_STREAM_READER_MAX_BYTES << " bytes)\n"; + (*err) += ss.str(); + } + return false; + } + StreamReader sr(mf.data, mf.size); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + &matFileReader, triangulate, default_vcols_fallback, + filename); + } +#else // !TINYOBJLOADER_USE_MMAP +#ifdef _WIN32 + std::ifstream ifs(LongPathW(UTF8ToWchar(filename)).c_str()); +#else + std::ifstream ifs(filename); +#endif + if (!ifs) { + if (err) { + std::stringstream ss; + ss << "Cannot open file [" << filename << "]\n"; + (*err) = ss.str(); + } + return false; + } + { + StreamReader sr(ifs); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + &matFileReader, triangulate, default_vcols_fallback, + filename); + } +#endif // TINYOBJLOADER_USE_MMAP +} + +bool LoadObj(attrib_t *attrib, std::vector *shapes, + std::vector *materials, std::string *warn, + std::string *err, std::istream *inStream, + MaterialReader *readMatFn /*= NULL*/, bool triangulate, + bool default_vcols_fallback) { + attrib->vertices.clear(); + attrib->vertex_weights.clear(); + attrib->normals.clear(); + attrib->texcoords.clear(); + attrib->texcoord_ws.clear(); + attrib->colors.clear(); + attrib->skin_weights.clear(); + shapes->clear(); + + StreamReader sr(*inStream); + return LoadObjInternal(attrib, shapes, materials, warn, err, sr, + readMatFn, triangulate, default_vcols_fallback); +} + + +static bool LoadObjWithCallbackInternal(StreamReader &sr, + const callback_t &callback, + void *user_data, + MaterialReader *readMatFn, + std::string *warn, + std::string *err) { + if (sr.has_errors()) { + if (err) { + (*err) += sr.get_errors(); + } + return false; + } + + // material + std::set material_filenames; + std::map material_map; + int material_id = -1; + + std::vector indices; + std::vector materials; + std::vector names; + names.reserve(2); + std::vector names_out; + + // Handle BOM + if (sr.remaining() >= 3 && + static_cast(sr.peek()) == 0xEF && + static_cast(sr.peek_at(1)) == 0xBB && + static_cast(sr.peek_at(2)) == 0xBF) { + sr.advance(3); + } + + while (!sr.eof()) { + sr.skip_space(); + if (sr.at_line_end()) { sr.skip_line(); continue; } + if (sr.peek() == '#') { sr.skip_line(); continue; } + + // vertex + if (sr.peek() == 'v' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + real_t x, y, z; + real_t r, g, b; + + int num_components = sr_parseVertexWithColor(&x, &y, &z, &r, &g, &b, sr, err, std::string()); + if (num_components < 0) { + return false; + } + if (callback.vertex_cb) { + callback.vertex_cb(user_data, x, y, z, r); + } + if (callback.vertex_color_cb) { + bool found_color = (num_components == 6); + callback.vertex_color_cb(user_data, x, y, z, r, g, b, found_color); + } + sr.skip_line(); + continue; + } + + // normal + if (sr.peek() == 'v' && sr.peek_at(1) == 'n' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + sr_parseReal3(&x, &y, &z, sr); + if (callback.normal_cb) { + callback.normal_cb(user_data, x, y, z); + } + sr.skip_line(); + continue; + } + + // texcoord + if (sr.peek() == 'v' && sr.peek_at(1) == 't' && (sr.peek_at(2) == ' ' || sr.peek_at(2) == '\t')) { + sr.advance(3); + real_t x, y, z; + sr_parseReal3(&x, &y, &z, sr); + if (callback.texcoord_cb) { + callback.texcoord_cb(user_data, x, y, z); + } + sr.skip_line(); + continue; + } + + // face + if (sr.peek() == 'f' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + sr.skip_space(); + + indices.clear(); + size_t cf_loop_max = sr.remaining() + 1; + size_t cf_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + cf_loop_iter < cf_loop_max) { + vertex_index_t vi = sr_parseRawTriple(sr); + + index_t idx; + idx.vertex_index = vi.v_idx; + idx.normal_index = vi.vn_idx; + idx.texcoord_index = vi.vt_idx; + + indices.push_back(idx); + sr.skip_space_and_cr(); + cf_loop_iter++; + } + + if (callback.index_cb && indices.size() > 0) { + callback.index_cb(user_data, &indices.at(0), + static_cast(indices.size())); + } + + sr.skip_line(); + continue; + } + + // use mtl + if (sr.match("usemtl", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + sr.advance(6); + std::string namebuf = sr_parseString(sr); + + int newMaterialId = -1; + std::map::const_iterator it = + material_map.find(namebuf); + if (it != material_map.end()) { + newMaterialId = it->second; + } else { + if (warn && (!callback.usemtl_cb)) { + (*warn) += "material [ " + namebuf + " ] not found in .mtl\n"; + } + } + + if (newMaterialId != material_id) { + material_id = newMaterialId; + } + + if (callback.usemtl_cb) { + callback.usemtl_cb(user_data, namebuf.c_str(), material_id); + } + + sr.skip_line(); + continue; + } + + // load mtl + if (sr.match("mtllib", 6) && (sr.peek_at(6) == ' ' || sr.peek_at(6) == '\t')) { + if (readMatFn) { + sr.advance(7); + + std::string line_rest = trimTrailingWhitespace(sr.read_line()); + std::vector filenames; + SplitString(line_rest, ' ', '\\', filenames); + RemoveEmptyTokens(&filenames); + + if (filenames.empty()) { + if (warn) { + (*warn) += + "Looks like empty filename for mtllib. Use default " + "material. \n"; + } + } else { + bool found = false; + for (size_t s = 0; s < filenames.size(); s++) { + if (material_filenames.count(filenames[s]) > 0) { + found = true; + continue; + } + + std::string warn_mtl; + std::string err_mtl; + bool ok = (*readMatFn)(filenames[s].c_str(), &materials, + &material_map, &warn_mtl, &err_mtl); + + if (warn && (!warn_mtl.empty())) { + (*warn) += warn_mtl; + } + + if (err && (!err_mtl.empty())) { + (*err) += err_mtl; + } + + if (ok) { + found = true; + material_filenames.insert(filenames[s]); + break; + } + } + + if (!found) { + if (warn) { + (*warn) += + "Failed to load material file(s). Use default " + "material.\n"; + } + } else { + if (callback.mtllib_cb && !materials.empty()) { + callback.mtllib_cb(user_data, &materials.at(0), + static_cast(materials.size())); + } + } + } + } + + sr.skip_line(); + continue; + } + + // group name + if (sr.peek() == 'g' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + names.clear(); + + size_t cg_loop_max = sr.remaining() + 1; + size_t cg_loop_iter = 0; + while (!sr.at_line_end() && sr.peek() != '#' && + cg_loop_iter < cg_loop_max) { + std::string str = sr_parseString(sr); + names.push_back(str); + sr.skip_space_and_cr(); + cg_loop_iter++; + } + + assert(names.size() > 0); + + if (callback.group_cb) { + if (names.size() > 1) { + names_out.resize(names.size() - 1); + for (size_t j = 0; j < names_out.size(); j++) { + names_out[j] = names[j + 1].c_str(); + } + callback.group_cb(user_data, &names_out.at(0), + static_cast(names_out.size())); + + } else { + callback.group_cb(user_data, NULL, 0); + } + } + + sr.skip_line(); + continue; + } + + // object name + if (sr.peek() == 'o' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + sr.advance(2); + std::string object_name = sr.read_line(); + + if (callback.object_cb) { + callback.object_cb(user_data, object_name.c_str()); + } + + sr.skip_line(); + continue; + } + +#if 0 // @todo + if (sr.peek() == 't' && (sr.peek_at(1) == ' ' || sr.peek_at(1) == '\t')) { + tag_t tag; + + sr.advance(2); + tag.name = sr_parseString(sr); + + tag_sizes ts = sr_parseTagTriple(sr); + + tag.intValues.resize(static_cast(ts.num_ints)); + + for (size_t i = 0; i < static_cast(ts.num_ints); ++i) { + tag.intValues[i] = sr_parseInt(sr); + } + + tag.floatValues.resize(static_cast(ts.num_reals)); + for (size_t i = 0; i < static_cast(ts.num_reals); ++i) { + tag.floatValues[i] = sr_parseReal(sr); + } + + tag.stringValues.resize(static_cast(ts.num_strings)); + for (size_t i = 0; i < static_cast(ts.num_strings); ++i) { + tag.stringValues[i] = sr_parseString(sr); + } + + tags.push_back(tag); + } +#endif + + // Ignore unknown command. + sr.skip_line(); + } + + return true; +} + +bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback, + void *user_data /*= NULL*/, + MaterialReader *readMatFn /*= NULL*/, + std::string *warn, /* = NULL*/ + std::string *err /*= NULL*/) { + StreamReader sr(inStream); + return LoadObjWithCallbackInternal(sr, callback, user_data, readMatFn, + warn, err); +} + +bool ObjReader::ParseFromFile(const std::string &filename, + const ObjReaderConfig &config) { + std::string mtl_search_path; + + if (config.mtl_search_path.empty()) { + // + // split at last '/'(for unixish system) or '\\'(for windows) to get + // the base directory of .obj file + // + size_t pos = filename.find_last_of("/\\"); + if (pos != std::string::npos) { + mtl_search_path = filename.substr(0, pos); + } + } else { + mtl_search_path = config.mtl_search_path; + } + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + filename.c_str(), mtl_search_path.c_str(), + config.triangulate, config.vertex_color); + + return valid_; +} + +bool ObjReader::ParseFromString(const std::string &obj_text, + const std::string &mtl_text, + const ObjReaderConfig &config) { + std::stringbuf obj_buf(obj_text); + std::stringbuf mtl_buf(mtl_text); + + std::istream obj_ifs(&obj_buf); + std::istream mtl_ifs(&mtl_buf); + + MaterialStreamReader mtl_ss(mtl_ifs); + + valid_ = LoadObj(&attrib_, &shapes_, &materials_, &warning_, &error_, + &obj_ifs, &mtl_ss, config.triangulate, config.vertex_color); + + return valid_; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +} // namespace tinyobj + +#endif \ No newline at end of file diff --git a/src/types.h b/src/types.h new file mode 100644 index 0000000..2315cbd --- /dev/null +++ b/src/types.h @@ -0,0 +1,17 @@ +#pragma once +#include + +using namespace glm; + +struct Vertex { + vec3 pos; + vec4 color; + vec3 normal; +}; + +struct CameraUBO { + mat4 model; + mat4 view; + mat4 proj; + float time; +};