diff --git a/.gitignore b/.gitignore
index a56a938..33ba5fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,6 @@
.godot/
/android/
/builds/
+
+# Blender backup files
+*.blend1
diff --git a/ASSET-LICENSE.md b/ASSET-LICENSE.md
new file mode 100644
index 0000000..50933b5
--- /dev/null
+++ b/ASSET-LICENSE.md
@@ -0,0 +1,135 @@
+# NETfishing Asset License 1.0
+
+Copyright © 2026 Woofmeow. All rights reserved except for the permissions
+expressly granted below.
+
+## 1. Scope
+
+This license applies to original NETfishing artwork, graphics, textures,
+models, animations, music, sound recordings, narrative content, visual
+designs, characters, and other creative assets owned by the NETfishing owners,
+publishing as Woofmeow (the **“NETfishing Assets”**).
+
+It does not apply to:
+
+- software source code identified as GPL-3.0-or-later;
+- third-party material identified in the source repository's
+ `docs/ATTRIBUTION.md` or the packaged `ATTRIBUTION.md` notice;
+- material accompanied by a different license; or
+- the NETfishing and Woofmeow names and logos, which are addressed in
+ `TRADEMARKS.md`.
+
+Repository location alone does not change third-party ownership or licensing.
+
+## 2. Definitions
+
+**Official NETfishing Software** means:
+
+- an unmodified binary release published by the NETfishing owners through an
+ official NETfishing distribution channel; or
+- a build made from an unmodified official NETfishing source release or tagged
+ revision.
+
+**Mod** means a non-standalone add-on created to operate with Official
+NETfishing Software. A Mod may add, replace, or alter content loaded by the
+Official NETfishing Software, but it may not redistribute a replacement copy
+of the game or represent a fork, clone, sequel, or separate game.
+
+## 3. Permission to use the official game
+
+You may reproduce NETfishing Assets as technically necessary to install, run,
+back up, and privately modify a lawfully obtained copy of Official NETfishing
+Software.
+
+You may capture, publish, and monetize screenshots, gameplay videos,
+livestreams, reviews, tutorials, and similar commentary showing a lawfully
+obtained copy of NETfishing. This permission does not authorize redistribution
+of the source asset files or imply endorsement.
+
+## 4. Community Mod license
+
+Subject to this license, you may create, modify, and distribute NETfishing
+Assets solely as part of a Mod for Official NETfishing Software.
+
+This permission is worldwide, nonexclusive, royalty-free, and available for
+as long as you comply with this license. It permits only the copies of
+NETfishing Assets reasonably necessary for the Mod to function. It does not
+permit distributing the original game, a substantially complete collection of
+its assets, or a general-purpose asset pack.
+
+A distributed Mod must:
+
+1. require a separately obtained copy of Official NETfishing Software;
+2. be presented as unofficial community content;
+3. include the following notice in its documentation or distribution page:
+
+ > Contains or adapts NETfishing assets © 2026 Woofmeow, used under the
+ > NETfishing Asset License 1.0. This Mod is unofficial and is not endorsed
+ > by Woofmeow.
+
+4. identify material created by the Mod author separately from NETfishing
+ Assets; and
+5. comply with `TRADEMARKS.md`.
+
+Mods may be shared without charge and may accept voluntary donations that do
+not purchase access, features, or preferential treatment. Selling a Mod,
+charging for access to it, licensing it commercially, or using NETfishing
+Assets in paid products requires separate written permission from both
+NETfishing owners.
+
+## 5. Uses not permitted
+
+Except with separate written permission from both NETfishing owners, you may
+not use or distribute NETfishing Assets:
+
+- in a fork, clone, remake, sequel, or standalone game;
+- with a modified distribution of the GPL-covered NETfishing code that is not
+ Official NETfishing Software;
+- in another game, application, asset library, template, or merchandise;
+- as a substantially complete asset extraction or archive;
+- in a way that implies sponsorship, endorsement, or official status;
+- to register a confusingly similar trademark, domain, account, or product
+ identity; or
+- under terms that claim ownership of the NETfishing Assets themselves.
+
+The GPL permits forks and redistribution of the GPL-covered code. This asset
+license does not permit those forks to carry NETfishing Assets. A code fork
+must remove or replace the NETfishing Assets and reserved branding unless both
+owners grant separate written permission.
+
+## 6. Ownership of Mods
+
+You retain ownership of your original Mod material. The NETfishing owners
+retain ownership of the NETfishing Assets and adaptations of those assets to
+the extent provided by applicable law.
+
+This license does not require you to assign your original Mod material to the
+NETfishing owners. It also does not grant you ownership of the underlying
+NETfishing Assets.
+
+## 7. Termination and cure
+
+Your permissions under this license terminate automatically if you violate
+its terms. They are reinstated provisionally when you stop the violation and
+permanently if both NETfishing owners do not notify you of the violation
+within sixty days after it has been cured.
+
+Termination does not limit remedies available for activity outside this
+license.
+
+## 8. No warranty
+
+THE NETFISHING ASSETS ARE PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE, TITLE, OR NON-INFRINGEMENT. TO THE MAXIMUM EXTENT
+PERMITTED BY LAW, THE OWNERS WILL NOT BE LIABLE FOR ANY CLAIM, DAMAGES, OR
+OTHER LIABILITY ARISING FROM THIS LICENSE OR USE OF THE NETFISHING ASSETS.
+
+## 9. Additional permission
+
+Uses not granted here require written permission from both NETfishing owners.
+A permission granted to one person or project does not amend this license for
+others.
+
+This is a custom asset license, not an open-source software license or a
+Creative Commons license.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8406c0a..62c7813 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,6 +4,12 @@ NETfishing is currently developed through focused changes on the repository's
active development branch. Coordinate scope with the project owner before
starting substantial work.
+By intentionally submitting material for inclusion, contributors agree to the
+applicable grants and representations in
+[`CONTRIBUTOR-TERMS.md`](CONTRIBUTOR-TERMS.md). Maintainers must preserve an
+affirmative record of that agreement. Contact the owners before submitting if
+separate written terms are needed.
+
## Change discipline
- Keep a change focused; avoid unrelated cleanup.
@@ -15,7 +21,10 @@ starting substantial work.
- Keep presentation-only systems out of save files and network messages.
- Store runtime assets under repository-owned paths; never reference a
workstation sync or temporary directory.
-- Record the source and license of newly imported assets.
+- Record the source and license of newly imported assets in
+ [`docs/ATTRIBUTION.md`](docs/ATTRIBUTION.md).
+- Do not assume the GPL code license applies to project assets; observe
+ [`ASSET-LICENSE.md`](ASSET-LICENSE.md) and third-party terms.
- Do not commit `.godot/`, test data, logs, captures, or build outputs.
## Before requesting review
@@ -26,7 +35,8 @@ scripts/run_validations.sh quick
git status --short
```
-Choose additional focused tests from [`docs/TESTING.md`](docs/TESTING.md).
+Choose additional focused tests from the validation section of
+[`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md#validation).
Changes involving networking should run the network suite and a real
two-process check. Visual changes still require graphical review; headless
tests are supporting evidence, not a replacement.
@@ -46,3 +56,7 @@ Follow the conventions already present in the surrounding GDScript, scene, and
resource files. Prefer typed values, named constants, shared resources, and
small domain-specific services. Avoid duplicating protocol definitions or
using display strings as persistent identifiers.
+
+New standalone source files should use `SPDX-License-Identifier:
+GPL-3.0-or-later` where the file format permits comments. Do not add that
+identifier to asset files governed by the NETfishing Asset License.
diff --git a/CONTRIBUTOR-TERMS.md b/CONTRIBUTOR-TERMS.md
new file mode 100644
index 0000000..8ef207e
--- /dev/null
+++ b/CONTRIBUTOR-TERMS.md
@@ -0,0 +1,94 @@
+# NETfishing contributor terms
+
+These terms apply to contributions intentionally submitted for inclusion in
+NETfishing after these terms are published. They do not retroactively change
+ownership of earlier work or replace a separately signed agreement.
+
+“Owners” means the two NETfishing co-owners who publish the Project as
+Woofmeow and are publicly credited as Voyager and Endeavour. “Project” means
+the official NETfishing game, its servers, tools, documentation, websites,
+ports, updates, and promotional materials.
+
+## 1. Your ownership and authority
+
+You retain copyright in your original contribution. By submitting it, you
+represent that:
+
+- you created it or otherwise have authority to grant these permissions;
+- its submission does not knowingly violate another party’s copyright,
+ patent, trademark, privacy, contract, or other rights;
+- you have disclosed relevant third-party material and license terms; and
+- if an employer or another organization controls the contribution, you have
+ obtained its permission before submitting.
+
+Do not submit confidential information, unlawfully obtained material, or
+content whose origin and permitted use cannot be documented.
+
+## 2. Code contributions
+
+You license an accepted software-code contribution under the GNU General
+Public License, version 3 or, at the recipient’s option, any later version
+(GPL-3.0-or-later).
+
+You also grant each recipient a perpetual, worldwide, nonexclusive,
+royalty-free patent license under patent claims you can license that are
+necessarily infringed by your contribution alone or by its combination with
+the Project as submitted. This patent license does not cover later
+combinations that are unrelated to your submitted contribution.
+
+## 3. Asset, writing, and documentation contributions
+
+For an accepted contribution consisting of artwork, models, animation, audio,
+music, writing, level content, branding material, or other non-code creative
+work, you grant the Owners a perpetual, worldwide, nonexclusive,
+royalty-free, transferable, and sublicensable license to:
+
+- use, reproduce, modify, adapt, translate, and create derivative works;
+- distribute, publicly display, publicly perform, transmit, and make
+ available the contribution;
+- include it in free and commercial Project releases, ports, updates,
+ merchandise, marketing, and archival materials; and
+- license it to Project users under `ASSET-LICENSE.md` or a later Project asset
+ license jointly approved by the Owners.
+
+This grant is limited to NETfishing, its promotion, and official successor or
+derived NETfishing products. It does not transfer your copyright or authorize
+the Owners to sell your contribution as an unrelated standalone asset.
+
+## 4. Documentation accompanying code
+
+Documentation submitted as an ordinary part of a code contribution may be
+distributed under GPL-3.0-or-later with that code. Project credits and
+provenance records may be reproduced in any medium needed to document the
+Project and its releases.
+
+## 5. Attribution
+
+Provide the name or pseudonym you want used for credit. The Owners will make a
+reasonable effort to preserve material attribution, subject to formatting,
+privacy, platform, and practical limitations.
+
+Attribution does not imply that a contributor endorses every Project change
+or release.
+
+## 6. No automatic ownership, employment, or payment
+
+Submitting a contribution does not provide ownership of NETfishing, create an
+employment, agency, partnership, or fiduciary relationship, or create a right
+to compensation. Any payment, ownership, or employment arrangement requires a
+separate written agreement signed by the appropriate parties.
+
+## 7. Acceptance
+
+A contribution is not accepted merely because it was posted, uploaded, or
+discussed. The Owners or their authorized maintainers may accept, modify,
+decline, or later remove it.
+
+By intentionally submitting a patch, pull request, asset, or other material
+for Project inclusion after receiving notice of these terms, you agree to the
+applicable grants above. Maintainers should record the contributor’s
+affirmative agreement in the pull request, issue, email, or another durable
+written record.
+
+If you cannot agree to these terms, do not submit the contribution; contact
+the Owners to discuss a separate written arrangement.
diff --git a/CREDITS.md b/CREDITS.md
deleted file mode 100644
index 8edbd4f..0000000
--- a/CREDITS.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Credits
-
-## Project direction
-
-NETfishing is designed, directed, reviewed, and released by its project
-creator. A public-facing creator or studio credit has not yet been recorded in
-this repository.
-
-## Development assistance
-
-Development has used automated coding assistance for implementation,
-investigation, testing, documentation, and review. Design choices, supplied
-artwork, acceptance decisions, repository operations, and releases remain
-human-controlled.
-
-This disclosure is intentionally about process. Commit style, code style, or
-repository metadata cannot reliably prove whether a particular change was
-written with or without assistance.
-
-## Fonts
-
-- Tuffy: Thatcher Ulrich, Karoly Barta, and Michael Evans. The bundled license
- dedicates the work to the public domain; see `ui/fonts/Tuffy-LICENSE.txt`.
-- Seattle Avenue: bundled as `ui/fonts/seattle_avenue.otf`. Author and
- redistribution terms still need to be recorded before public distribution.
-
-## Music
-
-- `audio/music/title/as_in_four_wolves.ogg`: original title/ambient music by
- the project owner.
-
-## Sound effects
-
-- “Spinning reel.wav” by tosha73, used as the source for the fishing fight and
- manual-reeling loops. Freesound sound 509902, Creative Commons Zero (CC0):
- https://freesound.org/s/509902/
-- “Gentle Ocean Waves Loop” by kkenny101, used for the saltwater shoreline
- ambience. Freesound sound 852826, Creative Commons Zero (CC0):
- https://freesound.org/s/852826/
-- “Quick Water Droplet” by qubodup, used for the bobber water-impact sound.
- Freesound sound 792931, Creative Commons Zero (CC0):
- https://freesound.org/s/792931/
-
-## Artwork
-
-- 2D artwork: Rheannon Eisworth, contributor.
-- 3D models: original work by the project owner.
-
-Asset categories and release-record requirements are listed in
-[`docs/ASSET-PROVENANCE.md`](docs/ASSET-PROVENANCE.md).
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f6cdd22
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,232 @@
+GNU GENERAL PUBLIC LICENSE
+Version 3, 29 June 2007
+
+Copyright © 2007 Free Software Foundation, Inc.
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+Preamble
+
+The GNU General Public License is a free, copyleft license for software and other kinds of works.
+
+The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
+
+To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
+
+Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
+
+Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+TERMS AND CONDITIONS
+
+0. Definitions.
+
+“This License” refers to version 3 of the GNU General Public License.
+
+“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
+
+“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.
+
+To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.
+
+A “covered work” means either the unmodified Program or a work based on the Program.
+
+To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
+
+To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
+
+An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
+
+1. Source Code.
+The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.
+
+A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
+
+The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
+
+The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
+
+The Corresponding Source for a work in source code form is that same work.
+
+2. Basic Permissions.
+All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
+
+3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
+
+When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
+
+4. Conveying Verbatim Copies.
+You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
+
+5. Conveying Modified Source Versions.
+You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
+
+ c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
+
+A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
+
+6. Conveying Non-Source Forms.
+You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
+
+ d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
+
+A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
+
+“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
+
+The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
+
+Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
+
+7. Additional Terms.
+“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
+
+Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
+
+All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
+
+8. Termination.
+You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
+
+However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
+
+Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
+
+9. Acceptance Not Required for Having Copies.
+You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
+
+10. Automatic Licensing of Downstream Recipients.
+Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.
+
+An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
+
+11. Patents.
+A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”.
+
+A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
+
+In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
+
+A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
+
+12. No Surrender of Others' Freedom.
+If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
+
+13. Use with the GNU Affero General Public License.
+Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
+
+14. Revised Versions of this License.
+The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
+
+Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
+
+15. Disclaimer of Warranty.
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. Limitation of Liability.
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+17. Interpretation of Sections 15 and 16.
+If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”.
+
+You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see .
+
+The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read .
diff --git a/README.md b/README.md
index af29cbc..b3d3e3f 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,9 @@ customization, jobs, and a controller-aware interface.
The project is under active development. Interfaces, balance, content, and
save migrations may continue to change before a stable release.
+NETfishing is developed and published by **Woofmeow**, the independent team of
+co-owners publicly credited as Voyager and Endeavour.
+
## Requirements
- Godot 4.7.x with the GL Compatibility renderer
@@ -35,8 +38,8 @@ Run the fast, deterministic suite before submitting a change:
scripts/run_validations.sh quick
```
-Additional suites and individual commands are documented in
-[`docs/TESTING.md`](docs/TESTING.md).
+Additional suites and individual commands are documented in the
+[`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md#validation) validation section.
## Building
@@ -65,18 +68,26 @@ scripts do not create or publish tags.
- `tests/`: focused Godot validation scripts
- `scripts/`: build, bake, and validation entry points
-See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) and
-[`world/README-WORLD-AUTHORING.md`](world/README-WORLD-AUTHORING.md) for more
-detail.
+All maintained project guidance starts at the
+[`docs/` documentation index](docs/README.md). Architecture, content policy,
+world and UI authoring, and testing are consolidated in
+[`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md).
-## Authorship and assets
+## Licensing
-NETfishing is human-directed and uses a mixture of human-authored assets and
-software-development assistance. The project records this plainly rather than
-claiming that repository history can prove how each line was produced. See
-[`CREDITS.md`](CREDITS.md) and
-[`docs/ASSET-PROVENANCE.md`](docs/ASSET-PROVENANCE.md).
+- Project-owned software code is licensed under
+ [GPL-3.0-or-later](LICENSE).
+- Project-owned artwork, models, music, and other creative assets are covered
+ by the [NETfishing Asset License](ASSET-LICENSE.md). It permits community
+ Mods for official NETfishing software, but not use in forks, clones, or
+ unrelated products.
+- The NETfishing and Woofmeow names and branding are reserved as described in
+ [TRADEMARKS.md](TRADEMARKS.md).
+- Third-party materials retain their own terms; see the consolidated
+ [credits, notices, and provenance record](docs/ATTRIBUTION.md).
+- Contributions are accepted under [CONTRIBUTOR-TERMS.md](CONTRIBUTOR-TERMS.md).
-No project-wide source license has been selected yet. Do not assume permission
-to redistribute the source or bundled assets beyond rights stated in their
-individual license records.
+Material boundaries and binary-release requirements are recorded in that same
+[`docs/ATTRIBUTION.md`](docs/ATTRIBUTION.md) reference.
+
+Copyright © 2026 Woofmeow.
diff --git a/TRADEMARKS.md b/TRADEMARKS.md
new file mode 100644
index 0000000..6848f47
--- /dev/null
+++ b/TRADEMARKS.md
@@ -0,0 +1,42 @@
+# NETfishing and Woofmeow branding
+
+The NETfishing and Woofmeow names, logos, icons, trade dress, and other source
+identifiers are reserved by the NETfishing owners, publishing as Woofmeow.
+Their presence in a GPL-licensed repository does not grant trademark rights or
+imply permission to represent another product as official.
+
+No trademark registration is asserted by this notice. Applicable rights may
+exist through use and other law.
+
+## Permitted references
+
+You may use the names NETfishing and Woofmeow truthfully to:
+
+- refer to the official game or development team;
+- state that software interoperates with or is a Mod for NETfishing;
+- link to an official repository or distribution page; and
+- discuss, review, criticize, or report on the Project.
+
+Use only the amount of branding reasonably necessary to identify the Project.
+Do not imply sponsorship, certification, endorsement, or official status.
+
+An unofficial Mod may use wording such as “Example Mod for NETfishing” if its
+name and presentation remain clearly distinct and it displays an unofficial
+notice.
+
+## Forks and redistributed code
+
+The GNU GPL permits forks and redistribution of covered code. A fork or
+modified distribution must:
+
+- use a distinct product name;
+- remove NETfishing and Woofmeow logos, icons, and official trade dress;
+- avoid confusingly similar names, domains, package identifiers, and account
+ names; and
+- clearly identify itself as independent and unofficial.
+
+These branding terms do not limit rights granted by the GPL to the software
+code or lawful nominative, descriptive, comparative, or fair use.
+
+Permission for broader branding use must be obtained in writing from both
+NETfishing owners.
diff --git a/addons/netfishing_shoreline_baker/plugin.cfg b/addons/netfishing_shoreline_baker/plugin.cfg
new file mode 100644
index 0000000..c8c4d06
--- /dev/null
+++ b/addons/netfishing_shoreline_baker/plugin.cfg
@@ -0,0 +1,7 @@
+[plugin]
+
+name="NETfishing Shoreline Auto-Baker"
+description="Rebuilds configured static shoreline ribbons after authored terrain reimports."
+author="woofmeow"
+version="1.0.0"
+script="shoreline_auto_baker.gd"
diff --git a/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd b/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd
new file mode 100644
index 0000000..18da4af
--- /dev/null
+++ b/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd
@@ -0,0 +1,66 @@
+@tool
+extends EditorPlugin
+
+const TERRAIN_RESOURCE := (
+ "res://art/exported/environment/terrain/starter_island.glb"
+)
+const REGION_SCENE := "res://world/regions/starter_island_region.tscn"
+
+var _bake_pending := false
+
+
+func _enter_tree() -> void:
+ var filesystem := get_editor_interface().get_resource_filesystem()
+ if not filesystem.resources_reimported.is_connected(_on_resources_reimported):
+ filesystem.resources_reimported.connect(_on_resources_reimported)
+
+
+func _exit_tree() -> void:
+ var filesystem := get_editor_interface().get_resource_filesystem()
+ if filesystem.resources_reimported.is_connected(_on_resources_reimported):
+ filesystem.resources_reimported.disconnect(_on_resources_reimported)
+
+
+func _on_resources_reimported(resources: PackedStringArray) -> void:
+ if not resources.has(TERRAIN_RESOURCE) or _bake_pending:
+ return
+ _bake_pending = true
+ call_deferred("_bake_configured_shorelines")
+
+
+func _bake_configured_shorelines() -> void:
+ _bake_pending = false
+ var packed_region := ResourceLoader.load(
+ REGION_SCENE,
+ "PackedScene",
+ ResourceLoader.CACHE_MODE_REPLACE,
+ ) as PackedScene
+ if packed_region == null:
+ push_error("Shoreline auto-bake could not load %s." % REGION_SCENE)
+ return
+ var region := packed_region.instantiate() as Node3D
+ add_child(region)
+ var baker := region.get_node_or_null(
+ "ShorelineRibbonBaker"
+ ) as ShorelineRibbonBaker
+ if baker == null:
+ push_error("Shoreline auto-bake found no configured baker.")
+ region.queue_free()
+ return
+ var results := baker.rebuild_all()
+ for result: Dictionary in results:
+ if result.get("skipped", false):
+ continue
+ var output_path: String = result.get("output_path", "")
+ if not output_path.is_empty():
+ ResourceLoader.load(
+ output_path,
+ "ArrayMesh",
+ ResourceLoader.CACHE_MODE_REPLACE,
+ )
+ print(
+ "Shoreline auto-bake: %s, %d loops, %d triangles"
+ % [output_path, result.loop_count, result.triangle_count]
+ )
+ region.queue_free()
+ get_editor_interface().get_resource_filesystem().scan()
diff --git a/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd.uid b/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd.uid
new file mode 100644
index 0000000..a143fcb
--- /dev/null
+++ b/addons/netfishing_shoreline_baker/shoreline_auto_baker.gd.uid
@@ -0,0 +1 @@
+uid://cbk4xpalei5v3
diff --git a/art/exported/characters/base/netfishing_base_character.glb b/art/exported/characters/base/netfishing_base_character.glb
index b4bb5d1..b7bc2f7 100644
Binary files a/art/exported/characters/base/netfishing_base_character.glb and b/art/exported/characters/base/netfishing_base_character.glb differ
diff --git a/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import
index 42a1604..4141bca 100644
--- a/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import
+++ b/art/exported/characters/base/netfishing_base_character_eyes_simple_shine.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/exported/characters/base/netfishing_base_character_mouth_three.png.import b/art/exported/characters/base/netfishing_base_character_mouth_three.png.import
index 5c94ab7..10d0721 100644
--- a/art/exported/characters/base/netfishing_base_character_mouth_three.png.import
+++ b/art/exported/characters/base/netfishing_base_character_mouth_three.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import
index 68c6e25..71d25b6 100644
--- a/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import
+++ b/art/exported/characters/base/netfishing_base_character_nose_dog_round.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/exported/characters/faces/README.md b/art/exported/characters/faces/README.md
deleted file mode 100644
index 06f3960..0000000
--- a/art/exported/characters/faces/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# Drop-in facial features
-
-Facial feature textures are discovered when the game starts. Put new PNGs in
-the matching directory, restart the game, and the option will appear in the
-Profile customization page.
-
-```text
-eyes/.png
-noses/.png
-mouth/.png
-```
-
-The category directory is authoritative. A category prefix is optional, so
-both `sleepy.png` and `eyes_sleepy.png` become the option ID `sleepy`.
-Filenames are normalized to lowercase snake_case. Use stable names because
-the resulting IDs are stored in appearance snapshots and sent to peers.
-
-Keep each PNG on the established facial-feature canvas with an RGBA
-transparent background. Godot imports the PNG automatically in the editor;
-the runtime registry ignores `.import` files and other non-PNG files.
-
-The current game bundles its facial assets under `res://`. Adding a file to a
-development checkout is picked up on the next startup. An exported build must
-be rebuilt to include newly added `res://` files in its package.
diff --git a/art/exported/characters/faces/eyes/eyes_alligator_extra.png b/art/exported/characters/faces/eyes/eyes_alligator_extra.png
new file mode 100644
index 0000000..e8c7be1
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_alligator_extra.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_alligator_extra.png.import b/art/exported/characters/faces/eyes/eyes_alligator_extra.png.import
new file mode 100644
index 0000000..c9348c7
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_alligator_extra.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c4rj1r1doawb4"
+path="res://.godot/imported/eyes_alligator_extra.png-30730001eeef37c24fac0158f6613bd7.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_alligator_extra.png"
+dest_files=["res://.godot/imported/eyes_alligator_extra.png-30730001eeef37c24fac0158f6613bd7.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_beady_extra.png b/art/exported/characters/faces/eyes/eyes_beady_extra.png
new file mode 100644
index 0000000..437d483
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_beady_extra.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_beady_extra.png.import b/art/exported/characters/faces/eyes/eyes_beady_extra.png.import
new file mode 100644
index 0000000..2951456
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_beady_extra.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bqgdrdc0hpi7s"
+path="res://.godot/imported/eyes_beady_extra.png-d07d79345b1d22e55a1cf140f7682248.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_beady_extra.png"
+dest_files=["res://.godot/imported/eyes_beady_extra.png-d07d79345b1d22e55a1cf140f7682248.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png b/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png
new file mode 100644
index 0000000..6c2a02b
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png.import b/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png.import
new file mode 100644
index 0000000..fe258f0
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_beady_extra_shine.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://mvjcdk84ko6f"
+path="res://.godot/imported/eyes_beady_extra_shine.png-c72a35f216a8c1a06122f7bd743ca6a4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_beady_extra_shine.png"
+dest_files=["res://.godot/imported/eyes_beady_extra_shine.png-c72a35f216a8c1a06122f7bd743ca6a4.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_cat_real.png b/art/exported/characters/faces/eyes/eyes_cat_real.png
new file mode 100644
index 0000000..365dd61
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_cat_real.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_cat_real.png.import b/art/exported/characters/faces/eyes/eyes_cat_real.png.import
new file mode 100644
index 0000000..2a4cbd3
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_cat_real.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://sbxopn55femq"
+path="res://.godot/imported/eyes_cat_real.png-13c9b6d280ac1000d177e74cbd33f07f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_cat_real.png"
+dest_files=["res://.godot/imported/eyes_cat_real.png-13c9b6d280ac1000d177e74cbd33f07f.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png b/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png
new file mode 100644
index 0000000..17e6c94
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png.import b/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png.import
new file mode 100644
index 0000000..9d9b065
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_cat_real_hunter.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cg1l01m0ae2oa"
+path="res://.godot/imported/eyes_cat_real_hunter.png-6eb486fc423d7e3fa84f71aa30ec04f3.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_cat_real_hunter.png"
+dest_files=["res://.godot/imported/eyes_cat_real_hunter.png-6eb486fc423d7e3fa84f71aa30ec04f3.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_closed.png b/art/exported/characters/faces/eyes/eyes_closed.png
new file mode 100644
index 0000000..d37f0a7
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_closed.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_closed.png.import b/art/exported/characters/faces/eyes/eyes_closed.png.import
new file mode 100644
index 0000000..af51540
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_closed.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b2ufsni8mnpmq"
+path="res://.godot/imported/eyes_closed.png-80789498475c2cfbcb6e3ac14e067a76.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_closed.png"
+dest_files=["res://.godot/imported/eyes_closed.png-80789498475c2cfbcb6e3ac14e067a76.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/eyes/eyes_punk_purple.png b/art/exported/characters/faces/eyes/eyes_punk_purple.png
new file mode 100644
index 0000000..2ab8a17
Binary files /dev/null and b/art/exported/characters/faces/eyes/eyes_punk_purple.png differ
diff --git a/art/exported/characters/faces/eyes/eyes_punk_purple.png.import b/art/exported/characters/faces/eyes/eyes_punk_purple.png.import
new file mode 100644
index 0000000..547a560
--- /dev/null
+++ b/art/exported/characters/faces/eyes/eyes_punk_purple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b2c784my766ag"
+path="res://.godot/imported/eyes_punk_purple.png-fc0ccb3a5f1d2c23f2f367bb306d1ada.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/eyes/eyes_punk_purple.png"
+dest_files=["res://.godot/imported/eyes_punk_purple.png-fc0ccb3a5f1d2c23f2f367bb306d1ada.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_buck teeth.png b/art/exported/characters/faces/mouth/mouth_buck teeth.png
new file mode 100644
index 0000000..9fde3c3
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_buck teeth.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_buck teeth.png.import b/art/exported/characters/faces/mouth/mouth_buck teeth.png.import
new file mode 100644
index 0000000..8909223
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_buck teeth.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dmvxpg0jbiyqw"
+path="res://.godot/imported/mouth_buck teeth.png-84be0f368b98b8640d5cc51d8a9b956f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_buck teeth.png"
+dest_files=["res://.godot/imported/mouth_buck teeth.png-84be0f368b98b8640d5cc51d8a9b956f.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_jowls.png b/art/exported/characters/faces/mouth/mouth_jowls.png
new file mode 100644
index 0000000..05ecbd1
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_jowls.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_jowls.png.import b/art/exported/characters/faces/mouth/mouth_jowls.png.import
new file mode 100644
index 0000000..1af65fe
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_jowls.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dyynmci0hf3vq"
+path="res://.godot/imported/mouth_jowls.png-88cd6159c02a5b4eee74b98dc8248dcd.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_jowls.png"
+dest_files=["res://.godot/imported/mouth_jowls.png-88cd6159c02a5b4eee74b98dc8248dcd.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_jowls_brock.png b/art/exported/characters/faces/mouth/mouth_jowls_brock.png
new file mode 100644
index 0000000..3b3d4a3
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_jowls_brock.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_jowls_brock.png.import b/art/exported/characters/faces/mouth/mouth_jowls_brock.png.import
new file mode 100644
index 0000000..d2ec5c4
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_jowls_brock.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://duajvlqrieray"
+path="res://.godot/imported/mouth_jowls_brock.png-de76cffdce72eb30289c44bcb2e68ce6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_jowls_brock.png"
+dest_files=["res://.godot/imported/mouth_jowls_brock.png-de76cffdce72eb30289c44bcb2e68ce6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_jowls_simple.png b/art/exported/characters/faces/mouth/mouth_jowls_simple.png
new file mode 100644
index 0000000..f96856e
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_jowls_simple.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_jowls_simple.png.import b/art/exported/characters/faces/mouth/mouth_jowls_simple.png.import
new file mode 100644
index 0000000..f6cf4a0
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_jowls_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c37gty8itl5oe"
+path="res://.godot/imported/mouth_jowls_simple.png-0586400ebfd9ef98c9067f0ebbe730be.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_jowls_simple.png"
+dest_files=["res://.godot/imported/mouth_jowls_simple.png-0586400ebfd9ef98c9067f0ebbe730be.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_kissy.png b/art/exported/characters/faces/mouth/mouth_kissy.png
new file mode 100644
index 0000000..65af5d9
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_kissy.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_kissy.png.import b/art/exported/characters/faces/mouth/mouth_kissy.png.import
new file mode 100644
index 0000000..ff0e1c1
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_kissy.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://druncaq416lvu"
+path="res://.godot/imported/mouth_kissy.png-52ec7a06301d8506497442f0ea0054a0.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_kissy.png"
+dest_files=["res://.godot/imported/mouth_kissy.png-52ec7a06301d8506497442f0ea0054a0.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_kissy_lips.png b/art/exported/characters/faces/mouth/mouth_kissy_lips.png
new file mode 100644
index 0000000..b20c0d1
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_kissy_lips.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_kissy_lips.png.import b/art/exported/characters/faces/mouth/mouth_kissy_lips.png.import
new file mode 100644
index 0000000..2141904
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_kissy_lips.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://babmei7rq8uaf"
+path="res://.godot/imported/mouth_kissy_lips.png-a90d7b9649dbba8cc17232f59291a2c8.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_kissy_lips.png"
+dest_files=["res://.godot/imported/mouth_kissy_lips.png-a90d7b9649dbba8cc17232f59291a2c8.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_open_ah.png b/art/exported/characters/faces/mouth/mouth_open_ah.png
new file mode 100644
index 0000000..b028f06
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_open_ah.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_open_ah.png.import b/art/exported/characters/faces/mouth/mouth_open_ah.png.import
new file mode 100644
index 0000000..5f8c2e7
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_open_ah.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://44cqu18imydc"
+path="res://.godot/imported/mouth_open_ah.png-2710d397264f57dbe8f9bac82dd4b0de.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_open_ah.png"
+dest_files=["res://.godot/imported/mouth_open_ah.png-2710d397264f57dbe8f9bac82dd4b0de.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_open_oh.png b/art/exported/characters/faces/mouth/mouth_open_oh.png
new file mode 100644
index 0000000..eba37ab
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_open_oh.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_open_oh.png.import b/art/exported/characters/faces/mouth/mouth_open_oh.png.import
new file mode 100644
index 0000000..e4602aa
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_open_oh.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c78hwv0t3ph47"
+path="res://.godot/imported/mouth_open_oh.png-10fc59160b782879c415074831421088.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_open_oh.png"
+dest_files=["res://.godot/imported/mouth_open_oh.png-10fc59160b782879c415074831421088.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_open_smile.png b/art/exported/characters/faces/mouth/mouth_open_smile.png
new file mode 100644
index 0000000..57675f8
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_open_smile.png differ
diff --git a/art/exported/characters/faces/mouth/mouth_open_smile.png.import b/art/exported/characters/faces/mouth/mouth_open_smile.png.import
new file mode 100644
index 0000000..06e410b
--- /dev/null
+++ b/art/exported/characters/faces/mouth/mouth_open_smile.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b12jrc4ao3r16"
+path="res://.godot/imported/mouth_open_smile.png-2561ffea934645e2eac40ab3a0a6395a.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/mouth/mouth_open_smile.png"
+dest_files=["res://.godot/imported/mouth_open_smile.png-2561ffea934645e2eac40ab3a0a6395a.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/faces/mouth/mouth_sad.png b/art/exported/characters/faces/mouth/mouth_sad.png
new file mode 100644
index 0000000..86687e0
Binary files /dev/null and b/art/exported/characters/faces/mouth/mouth_sad.png differ
diff --git a/art/exported/environment/textures/grass_heavy.png.import b/art/exported/characters/faces/mouth/mouth_sad.png.import
similarity index 72%
rename from art/exported/environment/textures/grass_heavy.png.import
rename to art/exported/characters/faces/mouth/mouth_sad.png.import
index d99e72b..bfe50b3 100644
--- a/art/exported/environment/textures/grass_heavy.png.import
+++ b/art/exported/characters/faces/mouth/mouth_sad.png.import
@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
-uid="uid://dusa52a3eghr7"
-path="res://.godot/imported/grass_heavy.png-ba7f679d1bc5402f8b0a3465ac6a44b8.ctex"
+uid="uid://camwvowsgxnlw"
+path="res://.godot/imported/mouth_sad.png-ced7361b391677e61acbb1877a8e7156.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://art/exported/environment/textures/grass_heavy.png"
-dest_files=["res://.godot/imported/grass_heavy.png-ba7f679d1bc5402f8b0a3465ac6a44b8.ctex"]
+source_file="res://art/exported/characters/faces/mouth/mouth_sad.png"
+dest_files=["res://.godot/imported/mouth_sad.png-ced7361b391677e61acbb1877a8e7156.ctex"]
[params]
diff --git a/art/exported/characters/faces/noses/nose_squidward.png b/art/exported/characters/faces/noses/nose_squidward.png
index ca71fc5..a878daa 100644
Binary files a/art/exported/characters/faces/noses/nose_squidward.png and b/art/exported/characters/faces/noses/nose_squidward.png differ
diff --git a/art/exported/characters/faces/noses/nose_squidward_wide.png b/art/exported/characters/faces/noses/nose_squidward_wide.png
new file mode 100644
index 0000000..1f55a69
Binary files /dev/null and b/art/exported/characters/faces/noses/nose_squidward_wide.png differ
diff --git a/art/exported/characters/faces/noses/nose_squidward_wide.png.import b/art/exported/characters/faces/noses/nose_squidward_wide.png.import
new file mode 100644
index 0000000..92d6c8a
--- /dev/null
+++ b/art/exported/characters/faces/noses/nose_squidward_wide.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dtisqywq2rv14"
+path="res://.godot/imported/nose_squidward_wide.png-fca231f913f03b97c273c870770f7948.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/faces/noses/nose_squidward_wide.png"
+dest_files=["res://.godot/imported/nose_squidward_wide.png-fca231f913f03b97c273c870770f7948.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/bengal/body_arms_bengal.png b/art/exported/characters/patterns/bengal/body_arms_bengal.png
new file mode 100644
index 0000000..dd4c735
Binary files /dev/null and b/art/exported/characters/patterns/bengal/body_arms_bengal.png differ
diff --git a/art/exported/characters/patterns/bengal/body_arms_bengal.png.import b/art/exported/characters/patterns/bengal/body_arms_bengal.png.import
new file mode 100644
index 0000000..8e98690
--- /dev/null
+++ b/art/exported/characters/patterns/bengal/body_arms_bengal.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b2e0uxfn187gu"
+path="res://.godot/imported/body_arms_bengal.png-350ed15f218f0efa6ae7573ad27d3c65.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/bengal/body_arms_bengal.png"
+dest_files=["res://.godot/imported/body_arms_bengal.png-350ed15f218f0efa6ae7573ad27d3c65.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/bengal/body_main_bengal.png b/art/exported/characters/patterns/bengal/body_main_bengal.png
new file mode 100644
index 0000000..c6eae5b
Binary files /dev/null and b/art/exported/characters/patterns/bengal/body_main_bengal.png differ
diff --git a/art/exported/characters/patterns/bengal/body_main_bengal.png.import b/art/exported/characters/patterns/bengal/body_main_bengal.png.import
new file mode 100644
index 0000000..389ec4f
--- /dev/null
+++ b/art/exported/characters/patterns/bengal/body_main_bengal.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cn71sswmj0tue"
+path="res://.godot/imported/body_main_bengal.png-59815350b807220c52317e683582847e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/bengal/body_main_bengal.png"
+dest_files=["res://.godot/imported/body_main_bengal.png-59815350b807220c52317e683582847e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/bengal/head_round_bengal.png b/art/exported/characters/patterns/bengal/head_round_bengal.png
new file mode 100644
index 0000000..d5326c4
Binary files /dev/null and b/art/exported/characters/patterns/bengal/head_round_bengal.png differ
diff --git a/art/exported/characters/patterns/bengal/head_round_bengal.png.import b/art/exported/characters/patterns/bengal/head_round_bengal.png.import
new file mode 100644
index 0000000..aa5113b
--- /dev/null
+++ b/art/exported/characters/patterns/bengal/head_round_bengal.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://rv36ws5wuakb"
+path="res://.godot/imported/head_round_bengal.png-dfa502a4514c1605f5c8aff839dd8765.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/bengal/head_round_bengal.png"
+dest_files=["res://.godot/imported/head_round_bengal.png-dfa502a4514c1605f5c8aff839dd8765.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/fox/body_arms_fox.png b/art/exported/characters/patterns/fox/body_arms_fox.png
new file mode 100644
index 0000000..aab265a
Binary files /dev/null and b/art/exported/characters/patterns/fox/body_arms_fox.png differ
diff --git a/art/exported/characters/patterns/fox/body_arms_fox.png.import b/art/exported/characters/patterns/fox/body_arms_fox.png.import
new file mode 100644
index 0000000..af10b42
--- /dev/null
+++ b/art/exported/characters/patterns/fox/body_arms_fox.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://p5cg2bwrxf7v"
+path="res://.godot/imported/body_arms_fox.png-91ab21ce544fdc29b8a0ebf3e54ef7cd.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/fox/body_arms_fox.png"
+dest_files=["res://.godot/imported/body_arms_fox.png-91ab21ce544fdc29b8a0ebf3e54ef7cd.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/fox/body_main_fox.png b/art/exported/characters/patterns/fox/body_main_fox.png
new file mode 100644
index 0000000..5c87bc5
Binary files /dev/null and b/art/exported/characters/patterns/fox/body_main_fox.png differ
diff --git a/art/exported/characters/patterns/fox/body_main_fox.png.import b/art/exported/characters/patterns/fox/body_main_fox.png.import
new file mode 100644
index 0000000..467c2b8
--- /dev/null
+++ b/art/exported/characters/patterns/fox/body_main_fox.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://wcsadkjjpaei"
+path="res://.godot/imported/body_main_fox.png-25e4fa03a48053f6b37b3bbadb1f01ba.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/fox/body_main_fox.png"
+dest_files=["res://.godot/imported/body_main_fox.png-25e4fa03a48053f6b37b3bbadb1f01ba.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/fox/head_pointy_fox.png b/art/exported/characters/patterns/fox/head_pointy_fox.png
new file mode 100644
index 0000000..71be5c3
Binary files /dev/null and b/art/exported/characters/patterns/fox/head_pointy_fox.png differ
diff --git a/art/exported/characters/patterns/fox/head_pointy_fox.png.import b/art/exported/characters/patterns/fox/head_pointy_fox.png.import
new file mode 100644
index 0000000..e3fa7e7
--- /dev/null
+++ b/art/exported/characters/patterns/fox/head_pointy_fox.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://c4vlbrp7qevvo"
+path="res://.godot/imported/head_pointy_fox.png-ef3535a6c05a49aae36fe5514844a3df.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/fox/head_pointy_fox.png"
+dest_files=["res://.godot/imported/head_pointy_fox.png-ef3535a6c05a49aae36fe5514844a3df.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/fox/head_round_fox.png b/art/exported/characters/patterns/fox/head_round_fox.png
new file mode 100644
index 0000000..2963975
Binary files /dev/null and b/art/exported/characters/patterns/fox/head_round_fox.png differ
diff --git a/art/exported/characters/patterns/fox/head_round_fox.png.import b/art/exported/characters/patterns/fox/head_round_fox.png.import
new file mode 100644
index 0000000..6d958dd
--- /dev/null
+++ b/art/exported/characters/patterns/fox/head_round_fox.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bwiwt76kyyevw"
+path="res://.godot/imported/head_round_fox.png-27dc2125a4e5b85a622291762225a303.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/fox/head_round_fox.png"
+dest_files=["res://.godot/imported/head_round_fox.png-27dc2125a4e5b85a622291762225a303.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/characters/patterns/fox/tails_fox_fox.png b/art/exported/characters/patterns/fox/tails_fox_fox.png
new file mode 100644
index 0000000..7283c2c
Binary files /dev/null and b/art/exported/characters/patterns/fox/tails_fox_fox.png differ
diff --git a/art/exported/characters/patterns/fox/tails_fox_fox.png.import b/art/exported/characters/patterns/fox/tails_fox_fox.png.import
new file mode 100644
index 0000000..46f6e60
--- /dev/null
+++ b/art/exported/characters/patterns/fox/tails_fox_fox.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cyr0wcavb1cmi"
+path="res://.godot/imported/tails_fox_fox.png-061a224c36e90f10b33d37e616ff7e94.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/characters/patterns/fox/tails_fox_fox.png"
+dest_files=["res://.godot/imported/tails_fox_fox.png-061a224c36e90f10b33d37e616ff7e94.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/environment/terrain/starter_island.glb b/art/exported/environment/terrain/starter_island.glb
index 5d8b6ce..e812b19 100644
Binary files a/art/exported/environment/terrain/starter_island.glb and b/art/exported/environment/terrain/starter_island.glb differ
diff --git a/art/exported/environment/textures/grass_lite.png.import b/art/exported/environment/textures/grass_lite.png.import
deleted file mode 100644
index a878153..0000000
--- a/art/exported/environment/textures/grass_lite.png.import
+++ /dev/null
@@ -1,42 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://crci2on30ctoc"
-path.s3tc="res://.godot/imported/grass_lite.png-f89cf6413257cd31582bd4f9f875ae85.s3tc.ctex"
-path.etc2="res://.godot/imported/grass_lite.png-f89cf6413257cd31582bd4f9f875ae85.etc2.ctex"
-metadata={
-"imported_formats": ["s3tc_bptc", "etc2_astc"],
-"vram_texture": true
-}
-
-[deps]
-
-source_file="res://art/exported/environment/textures/grass_lite.png"
-dest_files=["res://.godot/imported/grass_lite.png-f89cf6413257cd31582bd4f9f875ae85.s3tc.ctex", "res://.godot/imported/grass_lite.png-f89cf6413257cd31582bd4f9f875ae85.etc2.ctex"]
-
-[params]
-
-compress/mode=2
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=true
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=0
diff --git a/art/exported/environment/textures/grass_olive_tile.png.import b/art/exported/environment/textures/grass_olive_tile.png.import
deleted file mode 100644
index c880374..0000000
--- a/art/exported/environment/textures/grass_olive_tile.png.import
+++ /dev/null
@@ -1,42 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://btxhq3rdlum2"
-path.s3tc="res://.godot/imported/grass_olive_tile.png-72072a382d0948818df97773afa5493f.s3tc.ctex"
-path.etc2="res://.godot/imported/grass_olive_tile.png-72072a382d0948818df97773afa5493f.etc2.ctex"
-metadata={
-"imported_formats": ["s3tc_bptc", "etc2_astc"],
-"vram_texture": true
-}
-
-[deps]
-
-source_file="res://art/exported/environment/textures/grass_olive_tile.png"
-dest_files=["res://.godot/imported/grass_olive_tile.png-72072a382d0948818df97773afa5493f.s3tc.ctex", "res://.godot/imported/grass_olive_tile.png-72072a382d0948818df97773afa5493f.etc2.ctex"]
-
-[params]
-
-compress/mode=2
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=true
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=0
diff --git a/art/exported/environment/textures/sand.png.import b/art/exported/environment/textures/sand.png.import
deleted file mode 100644
index fdf8720..0000000
--- a/art/exported/environment/textures/sand.png.import
+++ /dev/null
@@ -1,42 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bnje415gq85nn"
-path.s3tc="res://.godot/imported/sand.png-41fc96c392119deeba43c2d4e49d88a5.s3tc.ctex"
-path.etc2="res://.godot/imported/sand.png-41fc96c392119deeba43c2d4e49d88a5.etc2.ctex"
-metadata={
-"imported_formats": ["s3tc_bptc", "etc2_astc"],
-"vram_texture": true
-}
-
-[deps]
-
-source_file="res://art/exported/environment/textures/sand.png"
-dest_files=["res://.godot/imported/sand.png-41fc96c392119deeba43c2d4e49d88a5.s3tc.ctex", "res://.godot/imported/sand.png-41fc96c392119deeba43c2d4e49d88a5.etc2.ctex"]
-
-[params]
-
-compress/mode=2
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=true
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=0
diff --git a/art/exported/system_icons/netfishing.ico b/art/exported/system_icons/netfishing.ico
new file mode 100644
index 0000000..dc5bdae
Binary files /dev/null and b/art/exported/system_icons/netfishing.ico differ
diff --git a/art/exported/system_icons/netfishing_1024.png b/art/exported/system_icons/netfishing_1024.png
new file mode 100644
index 0000000..a433e80
Binary files /dev/null and b/art/exported/system_icons/netfishing_1024.png differ
diff --git a/art/exported/system_icons/netfishing_1024.png.import b/art/exported/system_icons/netfishing_1024.png.import
new file mode 100644
index 0000000..08aa925
--- /dev/null
+++ b/art/exported/system_icons/netfishing_1024.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bkh5hw8wwu8pc"
+path="res://.godot/imported/netfishing_1024.png-7c53a099ed2743b4a623c258641b1d29.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/system_icons/netfishing_1024.png"
+dest_files=["res://.godot/imported/netfishing_1024.png-7c53a099ed2743b4a623c258641b1d29.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/exported/system_icons/netfishing_256.png b/art/exported/system_icons/netfishing_256.png
new file mode 100644
index 0000000..1e7be72
Binary files /dev/null and b/art/exported/system_icons/netfishing_256.png differ
diff --git a/art/exported/system_icons/netfishing_256.png.import b/art/exported/system_icons/netfishing_256.png.import
new file mode 100644
index 0000000..34d5d27
--- /dev/null
+++ b/art/exported/system_icons/netfishing_256.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cty16m8ydla06"
+path="res://.godot/imported/netfishing_256.png-d9dfc9c7871ac38bc73d09d00df679be.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://art/exported/system_icons/netfishing_256.png"
+dest_files=["res://.godot/imported/netfishing_256.png-d9dfc9c7871ac38bc73d09d00df679be.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/art/patterns/pattern_moneyfish.png b/art/patterns/pattern_moneyfish.png
index d223c44..6266f29 100644
Binary files a/art/patterns/pattern_moneyfish.png and b/art/patterns/pattern_moneyfish.png differ
diff --git a/art/source/characters/base/netfishing_base_character.blend1 b/art/source/characters/base/netfishing_base_character.blend1
deleted file mode 100644
index e9ee0bb..0000000
Binary files a/art/source/characters/base/netfishing_base_character.blend1 and /dev/null differ
diff --git a/art/source/characters/base/netfishing_character_source.blend b/art/source/characters/base/netfishing_character_source.blend
index 8fde03b..e75f254 100644
Binary files a/art/source/characters/base/netfishing_character_source.blend and b/art/source/characters/base/netfishing_character_source.blend differ
diff --git a/art/source/characters/base/netfishing_character_source.blend1 b/art/source/characters/base/netfishing_character_source.blend1
deleted file mode 100644
index e4808eb..0000000
Binary files a/art/source/characters/base/netfishing_character_source.blend1 and /dev/null differ
diff --git a/art/source/characters/base/netfishing_character_source.glb.import b/art/source/characters/base/netfishing_character_source.glb.import
new file mode 100644
index 0000000..61158c5
--- /dev/null
+++ b/art/source/characters/base/netfishing_character_source.glb.import
@@ -0,0 +1,45 @@
+[remap]
+
+importer="scene"
+importer_version=1
+type="PackedScene"
+uid="uid://3uq4cxiomttt"
+path="res://.godot/imported/netfishing_character_source.glb-9c98ee44b142c5b3d06f0838b7d2c9c4.scn"
+
+[deps]
+
+source_file="res://art/source/characters/base/netfishing_character_source.glb"
+dest_files=["res://.godot/imported/netfishing_character_source.glb-9c98ee44b142c5b3d06f0838b7d2c9c4.scn"]
+
+[params]
+
+nodes/root_type=""
+nodes/root_name=""
+nodes/root_script=null
+mesh_library/use_node_names_as_mesh_names=false
+array_mesh/deduplicate_surfaces=true
+nodes/apply_root_scale=true
+nodes/root_scale=1.0
+nodes/import_as_skeleton_bones=false
+nodes/use_name_suffixes=true
+nodes/use_node_type_suffixes=true
+meshes/ensure_tangents=true
+meshes/generate_lods=true
+meshes/create_shadow_meshes=true
+meshes/light_baking=1
+meshes/lightmap_texel_size=0.2
+meshes/force_disable_compression=false
+skins/use_named_skins=true
+animation/import=true
+animation/fps=30
+animation/trimming=false
+animation/remove_immutable_tracks=true
+animation/import_rest_as_RESET=false
+import_script/path=""
+materials/extract=0
+materials/extract_format=0
+materials/extract_path=""
+_subresources={}
+gltf/naming_version=2
+gltf/embedded_image_handling=1
+gltf/texture_map_mode=1
diff --git a/art/source/characters/base/netfishing_character_source_eyes1_eyebrows1.png.import b/art/source/characters/base/netfishing_character_source_eyes1_eyebrows1.png.import
index 4946a3c..e7aade1 100644
--- a/art/source/characters/base/netfishing_character_source_eyes1_eyebrows1.png.import
+++ b/art/source/characters/base/netfishing_character_source_eyes1_eyebrows1.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import
index e3894c9..e49d401 100644
--- a/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import
+++ b/art/source/characters/base/netfishing_character_source_eyes_simple_shine.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/characters/base/netfishing_character_source_mouth1.png.import b/art/source/characters/base/netfishing_character_source_mouth1.png.import
index e5394e7..8ff49a4 100644
--- a/art/source/characters/base/netfishing_character_source_mouth1.png.import
+++ b/art/source/characters/base/netfishing_character_source_mouth1.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/characters/base/netfishing_character_source_mouth_three.png.import b/art/source/characters/base/netfishing_character_source_mouth_three.png.import
index 4445b17..6abae09 100644
--- a/art/source/characters/base/netfishing_character_source_mouth_three.png.import
+++ b/art/source/characters/base/netfishing_character_source_mouth_three.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/characters/base/netfishing_character_source_nose1.2.png.import b/art/source/characters/base/netfishing_character_source_nose1.2.png.import
index 99bfef3..2fbb165 100644
--- a/art/source/characters/base/netfishing_character_source_nose1.2.png.import
+++ b/art/source/characters/base/netfishing_character_source_nose1.2.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import b/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import
index 9a8da06..12333e8 100644
--- a/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import
+++ b/art/source/characters/base/netfishing_character_source_nose_dog_round.png.import
@@ -28,7 +28,7 @@ compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
-mipmaps/generate=true
+mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
diff --git a/art/source/environment/terrain/starter_island.blend b/art/source/environment/terrain/starter_island.blend
index 9d3b513..8b82c4e 100644
Binary files a/art/source/environment/terrain/starter_island.blend and b/art/source/environment/terrain/starter_island.blend differ
diff --git a/art/exported/environment/textures/cliff_wall.png b/art/source/environment/textures/cliff_wall.png
similarity index 100%
rename from art/exported/environment/textures/cliff_wall.png
rename to art/source/environment/textures/cliff_wall.png
diff --git a/art/source/environment/textures/dirt.png b/art/source/environment/textures/dirt.png
new file mode 100644
index 0000000..588c8c6
Binary files /dev/null and b/art/source/environment/textures/dirt.png differ
diff --git a/art/source/environment/textures/dirt_light_wall.png b/art/source/environment/textures/dirt_light_wall.png
new file mode 100644
index 0000000..623dcd5
Binary files /dev/null and b/art/source/environment/textures/dirt_light_wall.png differ
diff --git a/art/exported/environment/textures/dirt_wall.png b/art/source/environment/textures/dirt_wall.png
similarity index 100%
rename from art/exported/environment/textures/dirt_wall.png
rename to art/source/environment/textures/dirt_wall.png
diff --git a/art/exported/environment/textures/grass.png b/art/source/environment/textures/grass.png
similarity index 100%
rename from art/exported/environment/textures/grass.png
rename to art/source/environment/textures/grass.png
diff --git a/art/exported/environment/textures/grass_heavy.png b/art/source/environment/textures/grass_heavy.png
similarity index 100%
rename from art/exported/environment/textures/grass_heavy.png
rename to art/source/environment/textures/grass_heavy.png
diff --git a/art/exported/environment/textures/grass_lite.png b/art/source/environment/textures/grass_lite.png
similarity index 100%
rename from art/exported/environment/textures/grass_lite.png
rename to art/source/environment/textures/grass_lite.png
diff --git a/art/exported/environment/textures/grass_olive_tile.png b/art/source/environment/textures/grass_olive_tile.png
similarity index 100%
rename from art/exported/environment/textures/grass_olive_tile.png
rename to art/source/environment/textures/grass_olive_tile.png
diff --git a/art/exported/environment/textures/sand.png b/art/source/environment/textures/sand.png
similarity index 100%
rename from art/exported/environment/textures/sand.png
rename to art/source/environment/textures/sand.png
diff --git a/art/source/environment/textures/sand_dark.png b/art/source/environment/textures/sand_dark.png
new file mode 100644
index 0000000..80633b5
Binary files /dev/null and b/art/source/environment/textures/sand_dark.png differ
diff --git a/art/source/environment/textures/sand_lite.png b/art/source/environment/textures/sand_lite.png
new file mode 100644
index 0000000..06f807a
Binary files /dev/null and b/art/source/environment/textures/sand_lite.png differ
diff --git a/art/source/environment/textures/sandstone_heavy.png b/art/source/environment/textures/sandstone_heavy.png
new file mode 100644
index 0000000..1bb282c
Binary files /dev/null and b/art/source/environment/textures/sandstone_heavy.png differ
diff --git a/art/source/environment/textures/sandstone_lite.png b/art/source/environment/textures/sandstone_lite.png
new file mode 100644
index 0000000..c329585
Binary files /dev/null and b/art/source/environment/textures/sandstone_lite.png differ
diff --git a/audio/ambience/rain_loop_ontario.ogg b/audio/ambience/rain_loop_ontario.ogg
new file mode 100644
index 0000000..179987b
Binary files /dev/null and b/audio/ambience/rain_loop_ontario.ogg differ
diff --git a/audio/ambience/rain_loop_ontario.ogg.import b/audio/ambience/rain_loop_ontario.ogg.import
new file mode 100644
index 0000000..280fc22
--- /dev/null
+++ b/audio/ambience/rain_loop_ontario.ogg.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="oggvorbisstr"
+type="AudioStreamOggVorbis"
+uid="uid://cfqskba5j2iig"
+path="res://.godot/imported/rain_loop_ontario.ogg-c206e8a7ee5398c9fdc6d59462050964.oggvorbisstr"
+
+[deps]
+
+source_file="res://audio/ambience/rain_loop_ontario.ogg"
+dest_files=["res://.godot/imported/rain_loop_ontario.ogg-c206e8a7ee5398c9fdc6d59462050964.oggvorbisstr"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/audio/music/world/craft.mp3 b/audio/music/world/craft.mp3
new file mode 100644
index 0000000..b73cd15
Binary files /dev/null and b/audio/music/world/craft.mp3 differ
diff --git a/audio/music/world/craft.mp3.import b/audio/music/world/craft.mp3.import
new file mode 100644
index 0000000..b8e054c
--- /dev/null
+++ b/audio/music/world/craft.mp3.import
@@ -0,0 +1,19 @@
+[remap]
+
+importer="mp3"
+type="AudioStreamMP3"
+uid="uid://c4y8puv0n6xk8"
+path="res://.godot/imported/craft.mp3-ba8d0c0c16ba90585f5d8eb4f37eb87d.mp3str"
+
+[deps]
+
+source_file="res://audio/music/world/craft.mp3"
+dest_files=["res://.godot/imported/craft.mp3-ba8d0c0c16ba90585f5d8eb4f37eb87d.mp3str"]
+
+[params]
+
+loop=false
+loop_offset=0
+bpm=0
+beat_count=0
+bar_beats=4
diff --git a/default_bus_layout.tres b/default_bus_layout.tres
index 665b0e9..d780a19 100644
--- a/default_bus_layout.tres
+++ b/default_bus_layout.tres
@@ -19,3 +19,9 @@ bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"
+bus/3/name = &"Environment"
+bus/3/solo = false
+bus/3/mute = false
+bus/3/bypass_fx = false
+bus/3/volume_db = 0.0
+bus/3/send = &"Master"
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
deleted file mode 100644
index 373c800..0000000
--- a/docs/ARCHITECTURE.md
+++ /dev/null
@@ -1,72 +0,0 @@
-# Architecture
-
-## Composition
-
-`main/main.tscn` is the application composition root. It owns long-lived
-services, the active world, player container, save/settings managers, and the
-pixelated UI viewport. Services are scene-owned rather than global autoloads,
-which makes their dependencies visible in the main scene and allows focused
-tests to instantiate the same composition.
-
-The main script coordinates title, session, world, and UI lifecycle. Domain
-logic remains in typed resources and services rather than being stored solely
-in controls.
-
-## Domain boundaries
-
-- `fish/` defines species, availability, catches, pools, quality, and selection.
-- `fishing/` owns cast/chase state and resolves authoritative fishing surfaces.
-- `inventory/`, `items/`, `economy/`, `progression/`, and `jobs/` own persistent
- player-facing game state.
-- `world/` owns authored map composition and presentation. Water type is a
- shared typed definition used by water bodies, fish habitat, fishing
- validation, Logbook classification, and saltwater shoreline presentation.
-- `ui/` observes and invokes domain services. It does not define stable item or
- fish identity.
-
-Resource files (`.tres`) are authored data. Stable IDs, not display names or
-node names, connect persistent and networked state to that data.
-
-## Networking
-
-`NetworkSession` owns ENet session lifecycle and peer registration. Dedicated
-network services validate and replicate bounded domains such as fishing,
-sales, shops, item use, profiles, jobs, mail, chat, drawings, time, and weather.
-
-The host is authoritative. Clients submit requests or evidence; the host
-derives trusted context from registered peers, authoritative regions, and
-server-owned state before mutating inventory, wallet, progression, or shared
-world state. See [`decisions/0001-host-authority.md`](decisions/0001-host-authority.md).
-
-Protocol compatibility is defined in `network/network_protocol.gd`. A visible
-release version is not a reason to change the protocol number.
-
-## Persistence
-
-`PlayerDataRoot` selects and validates a portable data root. Stores receive
-paths from that owner rather than inventing unrelated locations. Progression is
-written by `PlayerSaveManager`; device settings and social/identity stores have
-separate formats and lifecycles.
-
-Save migrations are sequential and explicit. Existing catches and ownership
-are keyed by stable IDs so authored metadata can evolve without rewriting
-historical records. Current source constants—not documentation—are
-authoritative for format versions.
-
-## Presentation
-
-Gameplay is rendered in 3D with the GL Compatibility renderer. The main UI is
-presented through a uniformly scaled SubViewport. Shared UI components and
-palette resources prevent page-specific geometry and style drift.
-
-World presentation systems (time/weather visuals, procedural sky and water,
-shoreline ribbons, player blob shadows) do not own gameplay collision or
-network authority. Generated shoreline meshes are deterministic presentation
-resources baked from explicitly configured static terrain.
-
-## Validation
-
-Tests are executable Godot `SceneTree` scripts. Some are pure content/domain
-checks, some instantiate the main scene, and multiplayer checks run paired host
-and client processes on loopback. The repository runner provides isolation and
-consistent entry points; see [`TESTING.md`](TESTING.md).
diff --git a/docs/ASSET-PROVENANCE.md b/docs/ASSET-PROVENANCE.md
deleted file mode 100644
index 9c3bc76..0000000
--- a/docs/ASSET-PROVENANCE.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Asset provenance
-
-This document records where runtime assets came from and what must be verified
-before redistribution. A Git commit proves when bytes entered this repository;
-it does not by itself prove authorship or licensing.
-
-## Intake policy
-
-For every new external or supplied asset, record:
-
-- creator or supplying party;
-- original source location or delivery channel;
-- source filename and repository destination;
-- source and destination SHA-256 when copied without modification;
-- license or explicit permission;
-- any permitted transformations;
-- the importing commit or release.
-
-Runtime resources must use `res://` paths. Workstation Sync folders are intake
-locations only and must never appear in scenes or resources.
-
-## Current inventory
-
-| Asset family | Repository location | Recorded provenance |
-| --- | --- | --- |
-| Fish art and portraits | `fish/species/`, `art/exported/fish/` | 2D artwork by contributor Rheannon Eisworth. |
-| Item icons | `items/icons/` | 2D artwork by contributor Rheannon Eisworth. |
-| Inventory notepad | `art/ui/ui_notepad.png` | 2D artwork by contributor Rheannon Eisworth; integrated without a runtime external path. |
-| Environment textures | `art/exported/environment/textures/` | 2D artwork by contributor Rheannon Eisworth. |
-| UI patterns | `art/patterns/` | 2D artwork by contributor Rheannon Eisworth. |
-| Character and world models | `art/exported/` | Original 3D models by the project owner. Any embedded 2D artwork is by Rheannon Eisworth. |
-| Tuffy font | `ui/fonts/Tuffy_Bold.otf` | Public-domain dedication in `ui/fonts/Tuffy-LICENSE.txt`. |
-| Seattle Avenue font | `ui/fonts/seattle_avenue.otf` | License and attribution not present; resolve before public distribution. |
-| Title music | `audio/music/title/as_in_four_wolves.ogg` | Original music composed and owned by the project owner. |
-| Fishing fight loop | `audio/sfx/fishing/fighting.wav` | Edited from “Spinning reel.wav” by Freesound user tosha73, sound 509902, CC0. |
-| Manual-reeling loop | `audio/sfx/fishing/reeling.wav` | Edited from the same CC0 “Spinning reel.wav” source. |
-| Saltwater wave ambience | `audio/ambience/waves.wav` | “Gentle Ocean Waves Loop” by Freesound user kkenny101, sound 852826, CC0. |
-| Bobber water impact | `audio/sfx/fishing/bobber.wav` | “Quick Water Droplet” by Freesound user qubodup, sound 792931, CC0. |
-
-### Fishing fight loop source record
-
-- Source page: https://freesound.org/s/509902/
-- Creator: tosha73
-- Source title: `Spinning reel.wav`
-- License: Creative Commons Zero (CC0)
-- Downloaded source filename: `509902__tosha73__spinning-reel.wav`
-- Downloaded source SHA-256:
- `9741afdb1ec9c73f5e039f0e5ac174998cb0a1f737b626531e63919d4d232fad`
-- Audacity working project: `fighting.aup3`
-- Audacity project SHA-256:
- `9928f077ecf48d01416f8d05700707e1b07d0f731846db80e27116f5b82dbbf5`
-- Runtime edit source/destination SHA-256:
- `b6f3f2f94bfaf9254ac04dd96b1fd28c15e1011a1db44bb3e70eeaa95de3c212`
-- Runtime format: 48 kHz, 16-bit, stereo PCM WAV; 2.593479 seconds;
- configured as a forward loop by the fishing presentation.
-- Manual-reeling Audacity project: `reeling.aup3`
-- Manual-reeling Audacity project SHA-256:
- `20ad52f6bdd16ae6561f06f8355fe309e95023e815053fd5dfbd5a5ce3c1f9f9`
-- Manual-reeling runtime source/destination SHA-256:
- `e403d5b7c8af1da4b28599cc0f51de3eda70d9e9296db27852fe7dc95617a29d`
-- Manual-reeling runtime format: 48 kHz, 16-bit, stereo PCM WAV;
- 2.388083 seconds; configured as a forward loop.
-- The downloaded source and Audacity projects remain in the project owner's
- source-work archive; only the finished runtime edits ship in the game.
-
-### Saltwater wave ambience source record
-
-- Source page: https://freesound.org/s/852826/
-- Creator: kkenny101
-- Source title: `Gentle Ocean Waves Loop`
-- License: Creative Commons Zero (CC0)
-- Downloaded source filename:
- `852826__kkenny101__gentle-ocean-waves-loop.wav`
-- Downloaded source and runtime source/destination SHA-256:
- `f93e9890583f072ac52cf197b8b5942397d3d5e889fbdb9112a0776142f50229`
-- Runtime format: 48 kHz, 24-bit, mono PCM WAV; 21.769917 seconds;
- configured as a forward loop.
-- The downloaded source remains in the project owner's source-work archive;
- only the finished runtime loop ships in the game.
-
-### Bobber water-impact source record
-
-- Source page: https://freesound.org/s/792931/
-- Creator: qubodup
-- Source title: `Quick Water Droplet`
-- License: Creative Commons Zero (CC0)
-- Downloaded source filename: `792931__qubodup__quick-water-droplet.wav`
-- Downloaded source and runtime source/destination SHA-256:
- `aef0d16384efed4a7b071c4d80c21597617f882f4e0c1d5295ac194d315eafb7`
-- Runtime format: 48 kHz, 16-bit, mono PCM WAV; 0.197146 seconds; one-shot.
-- The downloaded source remains in the project owner's source-work archive;
- only the finished runtime sound ships in the game.
-
-## Generated resources
-
-Godot `.import` sidecars and deterministic shoreline `.tres` meshes are derived
-repository resources, not original artwork. `.godot/imported/`, editor caches,
-captures, exports, and temporary test data are not tracked.
-
-## Release gate
-
-Before a public binary or source release:
-
-1. Resolve the Seattle Avenue font license and attribution gap above.
-2. Record the public owner/studio credit and the contributor's redistribution
- permission in the chosen project license or release records.
-3. Confirm the project-wide source/content license selected by the owner.
-4. Search exported resources for external filesystem paths.
-5. Preserve required third-party notices with the package.
diff --git a/docs/ATTRIBUTION.md b/docs/ATTRIBUTION.md
new file mode 100644
index 0000000..321b73d
--- /dev/null
+++ b/docs/ATTRIBUTION.md
@@ -0,0 +1,327 @@
+# Attribution, licensing, and asset provenance
+
+This is the authoritative project record for ownership, credits, license
+boundaries, third-party notices, asset provenance, and redistribution checks.
+A Git commit proves when bytes entered the repository; it does not by itself
+prove authorship or licensing.
+
+## Ownership and credits
+
+NETfishing is jointly owned, developed, and published by its creators,
+publicly credited as Voyager and Endeavour and operating collectively as the
+independent team Woofmeow.
+
+- Voyager: co-owner, developer, project director, creator of the game's 3D
+ art, and composer of the original title/ambient track
+ `audio/music/title/as_in_four_wolves.ogg`, world track
+ `audio/music/world/craft.mp3`, and animalese placeholder tones.
+- Endeavour: co-owner, developer, and creator of the game's 2D art, including
+ the original fish, environment, UI, and other artwork.
+- chillnfill: contributor of original 3D models for the character bodies and
+ arms, ears and tails, and multiple world props and decorative assets,
+ including trees and bridges. The contributor requested to be credited as
+ `chillnfill`.
+- Tekgator: creator of the cooler-capacity, reel-speed, and barrier-power shop
+ icons.
+
+Voyager is also the original catalog porter credit in PortMaster metadata.
+Third-party creators are credited with their individual records below. Those
+credits do not imply endorsement of NETfishing, Woofmeow, or its owners.
+
+## License map
+
+Do not describe the complete repository as covered only by the GPL.
+
+| Material | Governing terms |
+| --- | --- |
+| Project-owned software code, shaders, code-oriented scene/resource configuration, tests, build tooling, and server software | GPL-3.0-or-later; source-root `LICENSE` and packaged `GPL-3.0-or-later.txt` |
+| Project-owned artwork, textures, models, animation, music, audio, narrative content, characters, and other creative assets | Source-root or packaged `ASSET-LICENSE.md` |
+| NETfishing and Woofmeow names, logos, icons, and official identity | Source-root or packaged `TRADEMARKS.md` |
+| Third-party engines, fonts, sounds, and other external material | Their original terms, recorded below and in adjacent license texts where applicable |
+| New outside contributions | Source-root `CONTRIBUTOR-TERMS.md` plus any separately signed agreement |
+
+Generated Godot import metadata and deterministic generated resources follow
+the terms of their source material or generating code. Repository location
+alone does not relicense third-party material.
+
+The GPL permits study, modification, redistribution, and forks of covered
+code. It does not grant rights to NETfishing creative assets or branding. The
+NETfishing Asset License separately permits qualifying noncommercial add-on
+Mods for official NETfishing software; it does not permit those assets to
+accompany code forks, clones, standalone games, unrelated products, or
+general-purpose asset packs. A GPL fork must replace NETfishing assets and
+reserved branding with independently licensed material and a distinct
+identity.
+
+Project-wide code, asset, branding, or contributor-license changes require
+written approval from both NETfishing owners under their private joint
+ownership agreement.
+
+## Godot Engine notice
+
+NETfishing uses Godot Engine under the MIT License:
+
+> Copyright (c) 2014-present Godot Engine contributors.
+> Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
+>
+> 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.
+
+Godot licensing and bundled third-party-component notices are available at
+https://godotengine.org/license/ and
+https://github.com/godotengine/godot/blob/master/COPYRIGHT.txt. Godot uses
+FreeType for font rendering; portions are copyright The FreeType Project
+(https://www.freetype.org) under its applicable license.
+
+## Font notices
+
+- **Tuffy Bold** — Thatcher Ulrich, Karoly Barta, and Michael Evans; dedicated
+ to the public domain. Runtime file: `ui/fonts/Tuffy_Bold.otf`; original notice:
+ `ui/fonts/Tuffy-LICENSE.txt`.
+- **Seattle Avenue** — JLH Fonts; dedicated to the public domain by the creator.
+ Runtime file: `ui/fonts/seattle_avenue.otf`; source, hash, and original notice:
+ `ui/fonts/Seattle-Avenue-LICENSE.txt`.
+
+Public-domain fonts are not governed by the NETfishing Asset License.
+
+## Intake policy
+
+For every new external or supplied asset, record:
+
+- creator or supplying party;
+- original source location or delivery channel;
+- source filename and repository destination;
+- source and destination SHA-256 when copied without modification;
+- license or explicit permission;
+- any permitted transformations;
+- the importing commit or release.
+
+Maintainers must also obtain affirmative agreement to the source-root
+`CONTRIBUTOR-TERMS.md` before accepting an outside contribution and retain
+that agreement in a durable pull request, issue, email, or signed document.
+
+Runtime resources must use `res://` paths. Workstation Sync folders are intake
+locations only and must never appear in scenes or resources.
+
+## Asset inventory and provenance
+
+| Asset family | Repository location | Recorded provenance |
+| --- | --- | --- |
+| Fish art and portraits | `fish/species/`, `art/exported/fish/` | Original 2D artwork by co-owner Endeavour. |
+| Item icons | `items/icons/` | Original 2D artwork by co-owner Endeavour except where separately credited below. |
+| Cooler-capacity shop icon | `items/icons/equipment/64_cooler_plus.png` | Original artwork by Tekgator. Repository SHA-256: `b63705be5b78915753c068170323781a90e22b555b57a5b2ca9466e2726539f7`. |
+| Reel-speed shop icon | `items/icons/shop/64_speed_plus.png` | Original artwork by Tekgator. Repository SHA-256: `938452798f2be505e06ce3fbef178f52459331fd3bced8763fbc2a80157125ca`. |
+| Barrier-power shop icon | `items/icons/shop/64_power_plus.png` | Original artwork by Tekgator. Repository SHA-256: `164d34ce152aa6d75de79b69f0be2d9074f7891057de9636678889028ff98ae7`. |
+| Inventory notepad | `art/ui/ui_notepad.png` | Original 2D artwork by co-owner Endeavour; integrated without a runtime external path. |
+| Environment textures | `art/exported/environment/textures/` | Original 2D artwork by co-owner Endeavour. |
+| UI patterns | `art/patterns/` | Original 2D artwork by co-owner Endeavour. |
+| Fur customization channel maps | `art/exported/characters/patterns/` | Original 2D channel-map artwork by co-owner Endeavour. Exact file hashes are recorded below. |
+| Character base meshes and appendages | `art/source/characters/base/`, `art/exported/characters/base/`, and derived character resources | Original body and arm models and original ear and tail models by chillnfill. Any embedded original 2D artwork is by Endeavour. |
+| World and decorative prop models | `art/source/environment/`, `art/exported/environment/`, and derived world resources | Original prop and decorative models by chillnfill, including trees and bridges. Any embedded original 2D artwork is by Endeavour. |
+| Tuffy font | `ui/fonts/Tuffy_Bold.otf` | Public-domain dedication in `ui/fonts/Tuffy-LICENSE.txt`. |
+| Seattle Avenue font | `ui/fonts/seattle_avenue.otf` | Public-domain font by JLH Fonts; source record and hash in `ui/fonts/Seattle-Avenue-LICENSE.txt`. |
+| Title music | `audio/music/title/as_in_four_wolves.ogg` | Original music composed and owned by co-owner Voyager. |
+| Dusk music | `audio/music/world/craft.mp3` | Original music composed and owned by co-owner Voyager. |
+| Fishing fight loop | `audio/sfx/fishing/fighting.wav` | Edited from “Spinning reel.wav” by Freesound user tosha73, sound 509902, CC0. |
+| Manual-reeling loop | `audio/sfx/fishing/reeling.wav` | Edited from the same CC0 “Spinning reel.wav” source. |
+| Saltwater wave ambience | `audio/ambience/waves.wav` | “Gentle Ocean Waves Loop” by Freesound user kkenny101, sound 852826, CC0. |
+| Bobber water impact | `audio/sfx/fishing/bobber.wav` | “Quick Water Droplet” by Freesound user qubodup, sound 792931, CC0. |
+| Rain ambience | `audio/ambience/rain_loop_ontario.ogg` | Converted from “Rain Loop Ontario” by Freesound user Ayton, sound 212799, CC BY 3.0. |
+| Character bark call | `sound/dialogue/calls/bark.wav` | Edited from `Dog_Bark.wav` by Freesound user ivolipa, sound 328729, CC0. |
+| Character meow call | `sound/dialogue/calls/meow.wav` | Edited from `Cat meow.m4a` by Freesound user Christyboy100, sound 495694, Attribution 3.0. |
+| Animalese placeholder tones | `sound/dialogue/animalese/placeholder/` | Original tones composed and owned by co-owner Voyager without third-party samples. |
+
+Creative Commons Zero information:
+https://creativecommons.org/publicdomain/zero/1.0/. Creative Commons
+Attribution 3.0 legal text:
+https://creativecommons.org/licenses/by/3.0/legalcode.
+
+### chillnfill 3D model contribution record
+
+- Requested credit: `chillnfill`.
+- Original contribution families: character bodies and arms; character ears
+ and tails; and multiple world props and decorative assets, including trees
+ and bridges.
+- Repository mapping: character contributions are incorporated into the
+ character source/export families identified above. Prop contributions may
+ be incorporated into combined environment source and export files rather
+ than retained as one file per originally supplied model.
+- Permission record: because these historical contributions predate the
+ current `CONTRIBUTOR-TERMS.md`, retain the original permission record or a
+ later written confirmation covering Project use, modification,
+ distribution, commercial release, and applicable sublicensing.
+
+### Fur customization channel-map record
+
+Original channel-map artwork by Endeavour. Repository paths preserve the
+authored `mesh_style.png` filenames.
+
+| Style and mesh | Source filename | Repository file | SHA-256 |
+| --- | --- | --- | --- |
+| Bengal spots, body and arms | `body_arms_bengal.png` | `art/exported/characters/patterns/bengal/body_arms_bengal.png` | `fa90bd4e74b0b770ce97bf69d069676f5d4bd1f5d649f89e09638a66b61a8470` |
+| Bengal spots, main body | `body_main_bengal.png` | `art/exported/characters/patterns/bengal/body_main_bengal.png` | `8662fa198220cfdbe0aa83bdeeef7b855e20124d74f8481467f750d32b67ee8b` |
+| Bengal spots, round head | `head_round_bengal.png` | `art/exported/characters/patterns/bengal/head_round_bengal.png` | `f397ed8d152e3fda8181757a2bbd01925b7b8c2c4362f515d91c7f0fbf3ddfb6` |
+| Fox, body and arms | `body_arms_fox.png` | `art/exported/characters/patterns/fox/body_arms_fox.png` | `9930808718f31d84b415902f1ba55ac2a508bb2ac127300e793d73a8a013022d` |
+| Fox, main body | `body_main_fox.png` | `art/exported/characters/patterns/fox/body_main_fox.png` | `c65e4390173b8c31c9396edd053f940f0f809e47e01d18042cd7babc712dde9d` |
+| Fox, pointy head | `head_pointy_fox.png` | `art/exported/characters/patterns/fox/head_pointy_fox.png` | `71a9d2383e62884dbd3981460fcd985b18805fa907f61ffb16dce08ff9418ddf` |
+| Fox, round head | `head_round_fox.png` | `art/exported/characters/patterns/fox/head_round_fox.png` | `86dd7af8a2346faf67359ad668a117a74e2408676137d6b0626403cfcf2aba73` |
+| Fox tail | `tails_fox_fox.png` | `art/exported/characters/patterns/fox/tails_fox_fox.png` | `72da9673f038e2c3bb8aca19ed99932085fa3b162cab95366901c4e97153dd3e` |
+
+### Tekgator shop icon contribution record
+
+- Requested credit: `Tekgator`.
+- Original contributions: cooler-capacity, reel-speed, and barrier-power shop
+ icons.
+- Repository files and SHA-256:
+ - `items/icons/equipment/64_cooler_plus.png`:
+ `b63705be5b78915753c068170323781a90e22b555b57a5b2ca9466e2726539f7`
+ - `items/icons/shop/64_speed_plus.png`:
+ `938452798f2be505e06ce3fbef178f52459331fd3bced8763fbc2a80157125ca`
+ - `items/icons/shop/64_power_plus.png`:
+ `164d34ce152aa6d75de79b69f0be2d9074f7891057de9636678889028ff98ae7`
+- Permission record: retain the original permission record or a later written
+ confirmation covering Project use, modification, distribution, commercial
+ release, and applicable sublicensing.
+
+### Fishing fight loop source record
+
+- Source page: https://freesound.org/s/509902/
+- Creator: tosha73
+- Source title: `Spinning reel.wav`
+- License: Creative Commons Zero (CC0)
+- Downloaded source filename: `509902__tosha73__spinning-reel.wav`
+- Downloaded source SHA-256:
+ `9741afdb1ec9c73f5e039f0e5ac174998cb0a1f737b626531e63919d4d232fad`
+- Audacity working project: `fighting.aup3`
+- Audacity project SHA-256:
+ `9928f077ecf48d01416f8d05700707e1b07d0f731846db80e27116f5b82dbbf5`
+- Runtime edit source/destination SHA-256:
+ `b6f3f2f94bfaf9254ac04dd96b1fd28c15e1011a1db44bb3e70eeaa95de3c212`
+- Runtime format: 48 kHz, 16-bit, stereo PCM WAV; 2.593479 seconds;
+ configured as a forward loop by the fishing presentation.
+- Manual-reeling Audacity project: `reeling.aup3`
+- Manual-reeling Audacity project SHA-256:
+ `20ad52f6bdd16ae6561f06f8355fe309e95023e815053fd5dfbd5a5ce3c1f9f9`
+- Manual-reeling runtime source/destination SHA-256:
+ `e403d5b7c8af1da4b28599cc0f51de3eda70d9e9296db27852fe7dc95617a29d`
+- Manual-reeling runtime format: 48 kHz, 16-bit, stereo PCM WAV;
+ 2.388083 seconds; configured as a forward loop.
+- The downloaded source and Audacity projects remain in the project owner's
+ source-work archive; only the finished runtime edits ship in the game.
+
+### Saltwater wave ambience source record
+
+- Source page: https://freesound.org/s/852826/
+- Creator: kkenny101
+- Source title: `Gentle Ocean Waves Loop`
+- License: Creative Commons Zero (CC0)
+- Downloaded source filename:
+ `852826__kkenny101__gentle-ocean-waves-loop.wav`
+- Downloaded source and runtime source/destination SHA-256:
+ `f93e9890583f072ac52cf197b8b5942397d3d5e889fbdb9112a0776142f50229`
+- Runtime format: 48 kHz, 24-bit, mono PCM WAV; 21.769917 seconds;
+ configured as a forward loop.
+- The downloaded source remains in the project owner's source-work archive;
+ only the finished runtime loop ships in the game.
+
+### Bobber water-impact source record
+
+- Source page: https://freesound.org/s/792931/
+- Creator: qubodup
+- Source title: `Quick Water Droplet`
+- License: Creative Commons Zero (CC0)
+- Downloaded source filename: `792931__qubodup__quick-water-droplet.wav`
+- Downloaded source and runtime source/destination SHA-256:
+ `aef0d16384efed4a7b071c4d80c21597617f882f4e0c1d5295ac194d315eafb7`
+- Runtime format: 48 kHz, 16-bit, mono PCM WAV; 0.197146 seconds; one-shot.
+- The downloaded source remains in the project owner's source-work archive;
+ only the finished runtime sound ships in the game.
+
+### Character-call source records
+
+#### Bark
+
+- Source page: https://freesound.org/s/328729/
+- Creator: ivolipa
+- Source title: `Dog_Bark.wav`
+- License: Creative Commons Zero (CC0)
+- Downloaded source filename: `328729__ivolipa__dog_bark.wav`
+- Downloaded source SHA-256:
+ `c3d542dee7bfcc1901428e0c1408c0bd522d778d8e5e1dbca156cab008f3d712`
+- Runtime edit source/destination SHA-256:
+ `5ac2f32f33724a2fc232d725c5c37d4cfe3e93b3c1f19aa4177d2c8e3009ec78`
+- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.446780 seconds;
+ one-shot.
+
+#### Meow
+
+- Source page: https://freesound.org/s/495694/
+- Creator: Christyboy100
+- Source title: `Cat meow.m4a`
+- License: Attribution 3.0
+- Downloaded source filename: `495694__christyboy100__cat-meow.m4a`
+- Downloaded source SHA-256:
+ `afa3f6ef7afa2f7fee1e634d5505d2101cbba4421f8d8ff9adf562939c7a18f8`
+- Converted working WAV SHA-256:
+ `a505e6e230e7d9d76b65c46270d97a35a1acc510b43aa5e7343d7b04f424cade`
+- Runtime edit source/destination SHA-256:
+ `cce22ce1fbbc9325126a153aedc4526fde1aacf78780574fb432197dd44eb6b3`
+- Runtime format: 44.1 kHz, 16-bit, stereo PCM WAV; 0.605420 seconds;
+ one-shot.
+- The downloaded sources and working edits remain in the project owner's
+ source-work archive; only the finished runtime sounds ship in the game.
+
+### Rain ambience source record
+
+- Source page: https://freesound.org/s/212799/
+- Creator: Ayton
+- Source title: `Rain Loop Ontario`
+- License: Creative Commons Attribution 3.0
+- Downloaded source filename: `212799__ayton__rain-loop-ontario.aiff`
+- Downloaded source SHA-256:
+ `b491fc036b78a274d9ac7f6acbd014af1b5d24f5cba9bd7e3fdc05c5432ee66f`
+- Runtime edit SHA-256:
+ `b1979609b20fe34ed6f8902f3de65ae787a09abd71429e8aab850e87b74a4fa2`
+- Changes: converted from AIFF to Ogg Vorbis and configured as looping
+ weather ambience.
+
+## Generated resources
+
+Godot `.import` sidecars and deterministic shoreline `.tres` meshes are derived
+repository resources, not original artwork. `.godot/imported/`, editor caches,
+captures, exports, and temporary test data are not tracked.
+
+## Release gate
+
+Before a public binary or source release:
+
+1. Search exported resources for external filesystem paths.
+2. Include or make readily accessible the complete GPL text and identify the
+ exact corresponding source tag or commit.
+3. Include `ASSET-LICENSE.md`, `TRADEMARKS.md`, this attribution/provenance
+ record, both font notices, and every applicable third-party license.
+4. Retain the complete Godot Engine MIT notice above.
+5. Preserve third-party terms without adding incompatible restrictions.
+6. Avoid referring to a dirty or unavailable source revision.
+7. Publish or offer equivalent access to exact corresponding GPL source for
+ every distributed binary release.
+
+Desktop and PortMaster build scripts stage these authoritative files as
+sidecars. Godot export presets include them in exported resource packs for
+platforms where sidecar documents are not normally visible. Store and release
+pages should link to the exact source revision and public notices.
diff --git a/docs/BALANCE.md b/docs/BALANCE.md
deleted file mode 100644
index 948b882..0000000
--- a/docs/BALANCE.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Balance and content notes
-
-Balance is authored data and should change deliberately. This document records
-the policy; exact current values remain authoritative in `.tres` resources and
-typed scripts.
-
-## Fish
-
-- Stable fish IDs and catalog numbers must not be changed for display cleanup.
-- Species availability may constrain water type, time, weather, bait, and other
- authored context.
-- Location pools control selection weight; the global catalog remains
- comprehensive.
-- Freshwater/saltwater habitat is validated by the host in addition to pool
- membership.
-- Value, rarity, quality, and weight ranges should be reviewed together because
- they affect economy and catch difficulty.
-
-## Economy and progression
-
-- Sales and purchases are host-authoritative and must mutate inventory and
- wallet exactly once.
-- Reserved assets are rejected atomically; mixed valid/reserved batches must
- not partially succeed.
-- Item effects, shop prices, cooler capacity, fishing upgrades, jobs, and
- experience are separate balance axes. Avoid changing several in an unrelated
- presentation pass.
-
-## Recording a balance change
-
-Include in the change description:
-
-1. affected stable IDs and resource paths;
-2. old and new values;
-3. intended player-facing outcome;
-4. interactions with quality, availability, and economy;
-5. deterministic validation performed;
-6. whether existing saves remain semantically valid.
-
-Do not bump the save schema or network protocol simply because an authored
-number changed. Bump a format only when its serialized contract changes.
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
new file mode 100644
index 0000000..63d3b08
--- /dev/null
+++ b/docs/DEVELOPMENT.md
@@ -0,0 +1,352 @@
+# Development reference
+
+This is the authoritative reference for NETfishing architecture, engineering
+decisions, content policy, authoring, and validation.
+
+## Architecture
+
+### Composition
+
+`main/main.tscn` is the application composition root. It owns long-lived
+services, the active world, player container, save/settings managers, and the
+pixelated UI viewport. Services are scene-owned rather than global autoloads,
+which makes their dependencies visible in the main scene and allows focused
+tests to instantiate the same composition.
+
+The main script coordinates title, session, world, and UI lifecycle. Domain
+logic remains in typed resources and services rather than being stored solely
+in controls.
+
+### Domain boundaries
+
+- `fish/` defines species, availability, catches, pools, quality, and selection.
+- `fishing/` owns cast/chase state and resolves authoritative fishing surfaces.
+- `inventory/`, `items/`, `economy/`, `progression/`, and `jobs/` own persistent
+ player-facing game state.
+- `world/` owns authored map composition and presentation. Water type is a
+ shared typed definition used by water bodies, fish habitat, fishing
+ validation, Logbook classification, and saltwater shoreline presentation.
+- `ui/` observes and invokes domain services. It does not define stable item or
+ fish identity.
+
+Resource files (`.tres`) are authored data. Stable IDs, not display names or
+node names, connect persistent and networked state to that data.
+
+### Networking and authority
+
+`NetworkSession` owns ENet session lifecycle and peer registration. Dedicated
+network services validate and replicate bounded domains such as fishing,
+sales, shops, item use, profiles, jobs, mail, chat, drawings, time, and weather.
+
+`DiscoveryClient` is an optional directory layer beside `NetworkSession`. An
+open host may publish a short-lived room lease, and the shared Join Game page
+may browse compatible leases before handing the selected address back to the
+existing direct ENet connection flow. The directory does not carry gameplay
+traffic or become a gameplay authority. Its base URL comes from
+`network/discovery/base_url`, with `NETFISHING_DISCOVERY_URL` available as a
+development/deployment override.
+
+The host is authoritative. Clients submit requests or evidence; the host
+derives trusted context from registered peers, authoritative regions, and
+server-owned state before mutating inventory, wallet, progression, or shared
+world state. Private single-player uses the same host path. Client evidence is
+bounded and reconstructed where possible; UI activation is never proof that a
+server-side mutation succeeded.
+
+Moderation follows the same boundary. Player hosts may grant session-scoped
+operator status to an authenticated identity. Dedicated servers derive
+operators from their configured fingerprint allowlist. Operator status is
+replicated for presentation, but kick, ban, unban, and artwork-reset requests
+are always reauthorized against the authenticated sender by the host. Only a
+player host can grant or revoke operators; operators cannot moderate the host
+or another operator.
+
+Protocol compatibility is defined in `network/network_protocol.gd`. A visible
+release version is not a reason to change the protocol number.
+
+### Persistence and stable identifiers
+
+`PlayerDataRoot` selects and validates a portable data root. Stores receive
+paths from that owner rather than inventing unrelated locations. Progression is
+written by `PlayerSaveManager`; device settings and social/identity stores have
+separate formats and lifecycles.
+
+Save migrations are sequential and explicit. Existing catches and ownership
+are keyed by stable IDs so authored metadata can evolve without rewriting
+historical records. Current source constants—not documentation—are
+authoritative for format versions.
+
+Repository-owned resources are authoritative authored data. Persistent and
+networked records refer to stable IDs; display names, filenames, node names,
+coordinates, and pool names are not compatibility identifiers. Cross-domain
+concepts such as water type use one typed definition. Removing or changing a
+stable ID requires an explicit compatibility plan.
+
+### Presentation
+
+Gameplay is rendered in 3D with the GL Compatibility renderer. The main UI is
+presented through a uniformly scaled SubViewport. Shared UI components and
+palette resources prevent page-specific geometry and style drift.
+
+World presentation systems (time/weather visuals, procedural sky and water,
+shoreline ribbons, player blob shadows) do not own gameplay collision or
+network authority. Generated shoreline meshes are deterministic presentation
+resources baked from explicitly configured static terrain.
+
+### Engineering consequences
+
+- Shared mutations must behave consistently for private hosts, open hosts,
+ dedicated servers, and joined clients.
+- Networking changes require local-host and paired host/client validation.
+- Protocol payloads and rejection cleanup are explicit and bounded.
+- Renaming visible UI does not require a save migration.
+- Content validation covers stable-ID uniqueness, catalog completeness, pool
+ membership, and typed habitat compatibility.
+- New authored assets require provenance records as well as resource
+ references.
+
+## Content and balance
+
+Balance is authored data and should change deliberately. Exact current values
+remain authoritative in `.tres` resources and typed scripts.
+
+### Fish
+
+- Stable fish IDs and catalog numbers must not be changed for display cleanup.
+- Species availability may constrain water type, time, weather, bait, and
+ other authored context.
+- Location pools control selection weight; the global catalog remains
+ comprehensive.
+- Freshwater and saltwater habitat is validated by the host in addition to
+ pool membership.
+- Value, rarity, quality, weight ranges, and authored barrier-health bands
+ should be reviewed together because they affect economy and catch
+ difficulty.
+
+### Economy and progression
+
+- Sales and purchases are host-authoritative and must mutate inventory and
+ wallet exactly once.
+- Reserved assets are rejected atomically; mixed valid and reserved batches
+ must not partially succeed.
+- Item effects, shop prices, cooler capacity, fishing upgrades, jobs, and
+ experience are separate balance axes. Avoid changing several in an
+ unrelated presentation pass.
+
+Record affected stable IDs and resource paths, old and new values, intended
+player-facing outcome, interactions with quality/availability/economy,
+deterministic validation, and save-compatibility impact with each balance
+change. Do not bump a save schema or network protocol merely because an
+authored number changed.
+
+## Authoring
+
+### World composition
+
+The active test world uses the canonical starter island through
+`world/regions/starter_island_region.tscn`.
+
+`world/test_world.tscn` owns the gameplay-wide environment, sun, world bounds,
+and below-world failsafe. `StarterIslandRegion` owns the placed island content:
+
+```text
+StarterIslandRegion
+├── Terrain
+│ ├── Visual
+│ └── Collision
+├── WaterBodies
+│ ├── Pond
+│ │ ├── VisualWater
+│ │ ├── FishingRegion
+│ │ └── RecoveryRegion
+│ └── Ocean
+│ ├── VisualWater
+│ ├── FishingRegions
+│ └── RecoveryRegions
+├── PlayerSpawn
+├── SafeRespawns
+└── Interactables
+ ├── FishingShopWorld
+ └── PelicanCoolerPerch
+```
+
+Move a meaningful feature root rather than one of its implementation children.
+Child transforms are local offsets owned by that feature.
+
+Every fishable region authors its `water_type` explicitly. The starter pond is
+`FRESH_WATER`; the starter coast is `SALT_WATER`. Fish species use the same
+central type through an allowed-water-type bitmask. Do not infer habitat from
+node names, pool filenames, coordinates, or water height.
+
+Select `WaterBodies/Pond` to move or resize the pond. Its transform is the
+authoritative surface position; surface size and fishing/recovery coverage are
+owned together. Select `WaterBodies/Ocean` to move the surrounding water as one
+feature. Its explicit visual, fishing, and recovery lobes remain local to that
+root.
+
+Placed-feature ownership:
+
+- `PlayerSpawn` defines the initial player transform and facing.
+- `SafeRespawns` contains authoritative recovery destinations. Recovery
+ preserves current facing.
+- `Interactables/FishingShopWorld` owns the shop visual, collision, interaction
+ area, prompt, and entrance marker.
+- `Interactables/PelicanCoolerPerch` owns the Pelican landmark visual; selling
+ remains a Cooler action.
+- `Terrain` owns imported visuals and generated collision.
+- `BelowWorldFailsafe/Coverage` owns below-world recovery coverage.
+
+The starter-island GLB hierarchy is the terrain-collision authority. The
+region rebuilds one concave collision shape from every imported
+`MeshInstance3D` when it loads, so newly exported terrain and props participate
+without a separate stale collision bake. Keep purely decorative meshes out of
+that hierarchy if they should not block players.
+
+The active `Environment`, `Sun`, and starter-island grass material remain
+Inspector-authored and are not recreated by runtime scripts.
+
+### Reusable world props
+
+Use one placed `WorldProp` root for a complete landmark:
+
+```text
+WorldProp
+├── Visual
+└── Collision
+ └── CollisionShape3D
+```
+
+Put optional interaction areas, labels, and markers beneath the same root.
+Instance imported GLB content under `Visual` and keep gameplay collision under
+`Collision`. Author reusable assets at scale `(1, 1, 1)`. Uniform provisional
+root scaling is acceptable when visual and collision scale together; avoid
+non-uniform root scaling. Make mutable per-instance shapes, meshes, and
+materials local to the scene.
+
+### Shoreline tide ribbons
+
+Maps using generated tide ribbons own a `ShorelineRibbonBaker` and one
+`ShorelineRibbonConfig` per water body. Each configuration selects only its
+static terrain source, water height, generation bounds, water-facing reference,
+smoothing overrides, and generated `.tres` path. Props, players, bobbers, and
+gameplay areas are not scanned unless selected explicitly. Only `SALT_WATER`
+bodies generate ribbons.
+
+The editor automatically rebuilds configured shoreline resources when an
+authored terrain GLB is reimported. Select the baker and press **Rebuild
+Shoreline Ribbons** only when intentionally forcing a rebuild without a terrain
+reimport. The equivalent headless fallback and validation command is:
+
+```sh
+godot --headless --path . --script scripts/bake_shoreline_ribbons.gd
+```
+
+Use `debug_path_stage` only while comparing extraction stages and leave it Off
+in committed scenes. A rebuild is required when saltwater terrain at the
+waterline, water height, or generation bounds change; terrain reimports handle
+the usual case automatically. Normal gameplay loads committed generated meshes
+and never runs extraction.
+
+### Facial-feature textures
+
+Put new PNGs under the matching directory in
+`art/exported/characters/faces/`:
+
+```text
+eyes/.png
+noses/.png
+mouth/.png
+```
+
+The category directory is authoritative. A category prefix is optional, so
+both `sleepy.png` and `eyes_sleepy.png` produce the stable option ID `sleepy`.
+Filenames normalize to lowercase snake_case and are stored in appearance
+snapshots, so do not casually rename them. Preserve the established RGBA
+transparent canvas. Restart a development build after adding an image; rebuild
+exports to package new `res://` files.
+
+### Texture sampling
+
+NETfishing artwork always uses nearest-neighbor sampling. Do not enable linear,
+bilinear, trilinear, or anisotropic texture filtering, and do not generate
+mipmaps. Shader samplers must declare `filter_nearest`. The
+`TextureSamplingPolicy` autoload applies nearest sampling to 2D canvas items,
+Sprite3D presentations, imported 3D materials, and dynamically constructed
+mesh materials at runtime.
+
+After importing new artwork, normalize its tracked import metadata where
+needed and run the focused policy check:
+
+```sh
+godot --headless --path . --script scripts/normalize_texture_imports.gd \
+ -- --apply --root res://path/to/new/artwork
+godot --headless --path . --script tests/texture_sampling_validation.gd
+```
+
+### Bubble menus
+
+Instance `ui/components/bubble_menu/bubble_button.tscn` for each action, or
+attach `bubble_button.gd` to an existing button. Author neutral size, desktop
+and compact anchors, font-size limits, and deterministic motion in the
+Inspector. A label child may be assigned with `label_control_path`.
+
+Place buttons under a Control using `bubble_cluster.gd`, pass ordered button
+references to `configure()`, and call `apply_layout()` when available size or
+responsive layout changes. Order defines keyboard/controller focus neighbors.
+The shared profile owns palette, styles, proportional-font ratio, hover
+response, and contact tuning. Parent menus own labels, actions, anchors,
+availability, and confirmation behavior.
+
+`motion_scale = 0.0` disables idle drift/deformation while preserving hover and
+focus feedback. Contact correction is deterministic and bounded; do not replace
+it with physics that destabilizes layout, focus order, or hit targets.
+
+## Validation
+
+Tests are executable Godot `SceneTree` scripts. Some are pure content/domain
+checks, some instantiate the main scene, and multiplayer checks run paired host
+and client processes on loopback. The repository runner provides isolation and
+consistent entry points.
+
+### Consolidated runner
+
+```sh
+scripts/run_validations.sh quick
+scripts/run_validations.sh full
+scripts/run_validations.sh host
+scripts/run_validations.sh network
+scripts/run_validations.sh all
+scripts/run_validations.sh --list
+```
+
+- `quick` runs deterministic content and domain checks.
+- `full` adds socket-free scene/runtime checks.
+- `host` runs single-process authority checks that bind local UDP.
+- `network` runs loopback host/client pairs.
+- `all` runs `full`, `host`, and `network`.
+
+Set `GODOT_BIN` to select an executable and `TEST_TIMEOUT_SECONDS` to change
+the per-process timeout. The runner isolates and removes XDG roots.
+
+For one focused test:
+
+```sh
+test_root="$(mktemp -d)"
+XDG_DATA_HOME="$test_root/data" \
+XDG_CONFIG_HOME="$test_root/config" \
+godot --headless --path . --script tests/fish_catalog_content_validation.gd
+rm -rf -- "$test_root"
+```
+
+Do not point `NETFISHING_DATA_DIR` at an arbitrary empty directory; it is an
+explicit portable-data override and must identify a valid data root.
+
+Headless tests cannot prove visual alignment, mouse routing, shader appearance,
+controller feel, or resize behavior. Presentation changes require graphical
+review at the canonical 1280×720 layout and relevant low/high and ultrawide
+resolutions.
+
+Network tests require free loopback UDP ports and local-socket permission. A
+release audit additionally requires clean Git/tag verification, editor import,
+platform exports, executable smoke tests, archive inspection, and SHA-256
+verification; those checks are intentionally outside the development runner.
diff --git a/docs/PORTMASTER.md b/docs/PORTMASTER.md
new file mode 100644
index 0000000..2cd6038
--- /dev/null
+++ b/docs/PORTMASTER.md
@@ -0,0 +1,169 @@
+# PortMaster reference
+
+NETfishing's PortMaster release is a canonical PortMaster package, not a
+version-named generic ZIP. The installer-facing archive must be named
+`netfishing.zip`, and its root must contain exactly:
+
+```text
+NETfishing.sh
+netfishing/
+port.json
+```
+
+Do not derive a release package from an older local `portmaster-stage`
+directory. The templates in `scripts/portmaster/` are authoritative.
+
+## Release contract
+
+- `port.json` uses schema version 4 and names `netfishing.zip`.
+- `NETfishing.sh` starts with `# PORTMASTER: netfishing.zip, NETfishing.sh`.
+- The executable is `netfishing/NETfishing.aarch64`.
+- The package declares AArch64, two analog sticks, GLIBC 2.28, and
+ `weston_pkg_0.2.squashfs`.
+- The launcher must not start GPTOKEYB. Godot and NETfishing's controller
+ mapping manager handle controller input directly.
+- Persistent device data remains under `netfishing/conf/data`,
+ `netfishing/conf/config`, and `netfishing/conf/cache`.
+- The archive must not contain `conf/`, saves, identities, logs, source files,
+ `.git`, or `.godot` content.
+- Release downloads must publish `netfishing.zip`. A renamed versioned ZIP is
+ not a substitute because HarbourMaster identifies the canonical port by
+ archive name.
+
+## Build
+
+Run this only after the release commit and annotated `v` tag
+are pinned to the same clean `main` commit:
+
+```bash
+bash scripts/build_portmaster.sh
+```
+
+The script deletes and regenerates the Linux ARM64 export, stages the package,
+validates its structure, and writes:
+
+```text
+builds/v/netfishing.zip
+```
+
+`--package-only` is reserved for repackaging an already validated ARM64 export.
+It does not rebuild game content.
+
+## Local muOS installation
+
+The muOS auto-install directory is:
+
+```text
+/mnt/mmc/MUOS/PortMaster/autoinstall/
+```
+
+For an explicit offline installation test, copy `netfishing.zip` to a temporary
+device directory and run:
+
+```bash
+/mnt/mmc/MUOS/PortMaster/harbourmaster \
+ --offline --no-check install ./netfishing.zip
+```
+
+Before upgrading an existing installation, preserve
+`/mnt/mmc/ports/netfishing/conf/` on the device. After installation:
+
+1. Confirm the installed executable and PCK hashes match the staged release.
+2. Confirm the installed launcher contains the canonical PortMaster header and
+ does not contain `GPTOKEYB`.
+3. Confirm `conf/` was not replaced or removed.
+4. Launch the installed port through the normal muOS menu.
+5. Verify the displayed game version and controller face-button mapping.
+
+Installing the public PortMaster catalog entry can still install an older
+catalog build until the upstream `netfishing.zip` is updated. A local release
+test must install the generated local archive explicitly.
+
+## Template provenance
+
+The current catalog screenshot is a 640x480 PNG copied
+byte-for-byte into the package template:
+
+```text
+f24daae48f543b3a270a5aa46b5e73a31904bf0c7216d4c8a9e15a8dc48a5eed screenshot.png
+```
+
+The remaining catalog metadata assets were copied from the installed official
+`netfishing.zip` package and are intentionally preserved byte-for-byte:
+
+```text
+e2a9d132744684c67865c01eca027a8c9946b4c5a19da57c82f1af0373dc83b7 gameinfo.xml
+```
+
+The package’s `licenses/` directory is assembled from the authoritative root
+licenses and trademarks, the consolidated `docs/ATTRIBUTION.md`, and the font
+notices at build time. It also records the exact release tag and corresponding
+GPL source commit. Do not restore stale duplicated notice templates beneath
+`scripts/portmaster/`.
+
+The original catalog porter credit, `Voyager`, remains in `port.json`.
+
+## muOS H700 controller mapping
+
+Godot 4.7.1 and the SDL2 utilities shipped by muOS identify the same virtual
+controller differently. The PortMaster SDL2 database uses GUID
+`19000000010000000100000000010000`, while Godot reports GUID
+`19004ca6010000000100000000010000`. Passing the SDL2 entry unchanged leaves
+most controls unmapped in Godot.
+
+The device-verified Godot mapping is:
+
+- A `b0`, B `b1`, Y `b2`, X `b3`
+- left bumper `b4`, right bumper `b5`
+- select `b6`, start `b7`, guide `b8`
+- left-stick click `b9`, left trigger `b10`, right trigger `b11`, right-stick click `b12`
+- D-pad `h0`; left and right sticks `a0..a3`
+
+`scripts/portmaster/NETfishing.sh` must replace the incompatible SDL2 entry
+with the Godot entry when that SDL2 GUID is selected. Do not append the two
+entries with a newline: WestonPack evaluates launcher arguments through a
+shell and treats the second line as a command. Pass the single selected mapping
+as `SDL_GAMECONTROLLERCONFIG` in the game command after Weston initializes;
+Weston sources PortMaster's control file internally and otherwise restores the
+SDL2 value.
+
+Do not call `Input.add_joy_mapping(..., true)` for a recognized connected muOS
+controller. Updating this virtual controller after connection can stop Godot
+from delivering its standardized controller events until restart.
+
+Before shipping a PortMaster build on H700 hardware, verify all of the
+following in the installed game:
+
+- A, B, X, and Y each register independently.
+- The D-pad navigates every menu direction.
+- Both sticks, both bumpers, both triggers, Select, Start, L3, and R3 register.
+- A single button never cancels auto-map.
+- Holding both bumpers together for 1.25 seconds cancels auto-map.
+
+## Low-end performance profile
+
+The launcher keeps the normal game profile on unknown and stronger hardware.
+It enables the low-end profile only when the Linux device tree reports one of
+the identifiers used by Allwinner H616/H700 XX handhelds:
+
+- `allwinner,h616`
+- `sun50iw9p1`
+- `allwinner,sun50i-h700`
+
+The low-end profile passes these Godot options:
+
+- `--single-window`
+- `--disable-vsync`
+- `--max-fps 30`
+- `--audio-output-latency 40`
+
+It also passes `NETFISHING_LOW_END=1`. The game renders the 3D world at 75%
+linear resolution with nearest-neighbor scaling, reducing 3D pixel work by
+about 44% while the separately rendered UI retains its canonical resolution.
+
+Do not use Godot's low processor mode for this profile. It reduces idle CPU
+usage by sleeping between updates and is not a game-performance optimization.
+
+Before adding a device family, record its exact NUL-separated device-tree
+`compatible` value from hardware. Do not infer detection from a retail product
+name alone.
diff --git a/playtest/README-PLAYTEST.txt b/docs/README-PLAYTEST.txt
similarity index 80%
rename from playtest/README-PLAYTEST.txt
rename to docs/README-PLAYTEST.txt
index 8116fc2..9d895f1 100644
--- a/playtest/README-PLAYTEST.txt
+++ b/docs/README-PLAYTEST.txt
@@ -1,12 +1,13 @@
NETfishing
-v0.5.1-prealpha
-Pre-Alpha 0.5.1
+v0.7.1-alpha
+Alpha 0.7.1
Thank you for trying this early private playtest.
-NETfishing is currently a local gameplay prototype for a future
-multiplayer-first game. Networking and multiplayer are NOT implemented in
-this build.
+NETfishing is an early multiplayer fishing game. This alpha includes local
+progression, player-hosted and dedicated multiplayer sessions, public room
+discovery, and direct UDP connections. Expect rough edges and please keep a
+backup of any save or identity data you care about.
INSTALLATION
@@ -54,12 +55,15 @@ FISHING
- Coffee improves movement; other supplies temporarily improve fishing.
- The Cooler starts at 12 fish; buy permanent capacity expansions at the shop.
- Reel Speed upgrades increase authoritative green reeling progress.
-- Barrier Power upgrades increase damage per valid barrier action.
+- Rod Power upgrades increase damage per valid barrier action.
- Shop upgrades persist in the local progression save.
- Escape closes shop confirmations before closing the shop itself.
FEATURES TO TRY
+- Hosting a private or public room and joining compatible online sessions
+- Direct-IP, saved-server, recent-server, and public-room connection flows
+- Text chat, player calls, player lists, relationships, and moderation tools
- Movement, jumping, camera rotation, and zoom
- Short, medium, and maximum-distance casts
- Valid water and invalid land casts
@@ -101,11 +105,11 @@ Please include:
- How movement, casting, chase pressure, barrier clicking, menus, and camera
controls felt
-KNOWN PRE-ALPHA LIMITATIONS
+KNOWN ALPHA LIMITATIONS
-- Multiplayer/networking is not implemented.
-- Fish and character art are temporary.
-- UI and balance values are placeholders.
-- There is no audio.
+- Public sessions remain direct connections; restrictive NAT or carrier-grade
+ networks may prevent some players from joining.
+- Multiplayer, dedicated-server deployment, UI, and balance are still alpha.
+- Some fish and character artwork remains temporary.
- There is no installer or automatic updater.
- Windows builds are unsigned.
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..49645b3
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,60 @@
+# NETfishing documentation
+
+This directory is the single home for maintained project documentation.
+Start here instead of searching feature, asset, world, or script directories
+for local README files.
+
+## Authoritative references
+
+- [`DEVELOPMENT.md`](DEVELOPMENT.md): architecture, engineering decisions,
+ content and balance policy, authoring guidance, and validation.
+- [`ATTRIBUTION.md`](ATTRIBUTION.md): ownership, credits, licensing map,
+ third-party notices, asset provenance, and redistribution requirements.
+- [`PORTMASTER.md`](PORTMASTER.md): PortMaster packaging, installation,
+ controller mapping, performance behavior, and hardware release checks.
+- [`README-PLAYTEST.txt`](README-PLAYTEST.txt): the player-facing README staged
+ into desktop playtest packages.
+
+## Related repositories
+
+- [Discovery service API](https://forge.makearmy.io/woofmeow/netfishing-discovery-server/src/branch/main/docs/API.md)
+ stays with the service implementation and defines its versioned HTTP
+ contract.
+- [Dedicated-server packaging](https://forge.makearmy.io/woofmeow/netfishing-dedicated-server/src/branch/main/README.md)
+ stays with its installer and update scripts. It consumes this repository's
+ attribution and legal notices from the exact pinned game commit instead of
+ maintaining copies.
+
+Those code-coupled references remain in their own repositories. Game-wide
+architecture, authoring, licensing, credits, and provenance are not duplicated
+there.
+
+Exact runtime values and behavior remain authoritative in source code, scenes,
+and resources. These documents describe boundaries, policy, and maintenance
+procedures; they should not duplicate changing constants or inventories that
+can be derived reliably from the project.
+
+## Files intentionally kept at the repository root
+
+The following are entry points or governing legal documents rather than
+general project documentation, so they remain at conventional root paths:
+
+- `README.md`
+- `CONTRIBUTING.md`
+- `LICENSE`
+- `ASSET-LICENSE.md`
+- `TRADEMARKS.md`
+- `CONTRIBUTOR-TERMS.md`
+
+Third-party font license texts stay beside their font files under `ui/fonts/`
+so the licensed files and their original notices cannot drift apart. Build
+scripts collect those legal files and the authoritative attribution record
+when assembling releases.
+
+## Maintenance rule
+
+Do not add feature-specific README files elsewhere in the repository. Add or
+update the appropriate reference above and link to its heading when source
+comments need more context. Player-facing package instructions belong only in
+`README-PLAYTEST.txt`; source and scripts remain authoritative for command-line
+usage.
diff --git a/docs/TESTING.md b/docs/TESTING.md
deleted file mode 100644
index e70455b..0000000
--- a/docs/TESTING.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Testing
-
-NETfishing validations are Godot `SceneTree` scripts. They use assertions and
-exit nonzero on failure. Run them with isolated user data so development checks
-cannot touch real saves, identity, trust, relationships, or settings.
-
-## Consolidated runner
-
-```sh
-scripts/run_validations.sh quick
-scripts/run_validations.sh full
-scripts/run_validations.sh host
-scripts/run_validations.sh network
-scripts/run_validations.sh all
-scripts/run_validations.sh --list
-```
-
-- `quick` runs deterministic content and domain validations.
-- `full` adds socket-free scene/runtime checks suitable for headless execution.
-- `host` runs single-process authoritative-host checks that bind a local UDP
- port.
-- `network` runs the loopback host/client validations in pairs.
-- `all` runs `full`, `host`, and then `network`.
-
-Set `GODOT_BIN` to select another executable. Set `TEST_TIMEOUT_SECONDS` to
-change the per-process timeout. The runner creates one temporary XDG root per
-process and removes it on exit.
-
-## One focused test
-
-```sh
-test_root="$(mktemp -d)"
-XDG_DATA_HOME="$test_root/data" \
-XDG_CONFIG_HOME="$test_root/config" \
-godot --headless --path . --script tests/fish_catalog_content_validation.gd
-rm -rf -- "$test_root"
-```
-
-Do not set `NETFISHING_DATA_DIR` to an arbitrary empty folder: that variable is
-an explicit portable-data override and must point at a valid NETfishing data
-root. Isolating XDG paths is sufficient for the validation scripts.
-
-## Graphical checks
-
-Headless tests cannot prove visual alignment, actual mouse routing, shader
-appearance, controller feel, or window-resize behavior. Presentation changes
-need a real graphical startup with isolated XDG roots and inspection at the
-canonical 1280×720 layout plus relevant low/high and ultrawide resolutions.
-
-## Network checks
-
-Host and paired tests bind loopback UDP ports defined in their scripts. Ensure
-no old Godot validation process is holding those ports and that the execution
-environment permits local sockets. The runner starts paired hosts before their
-clients and requires both processes to exit successfully. Network tests do not
-contact external servers.
-
-## Release checks
-
-A release audit additionally includes clean Git/tag verification, editor import,
-export-template checks, platform exports, executable smoke tests, archive
-inspection, and SHA-256 verification. Those checks are intentionally not hidden
-inside the development runner.
diff --git a/docs/decisions/0001-host-authority.md b/docs/decisions/0001-host-authority.md
deleted file mode 100644
index f134d93..0000000
--- a/docs/decisions/0001-host-authority.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# ADR 0001: Host-authoritative shared state
-
-Status: accepted
-
-## Context
-
-NETfishing supports private hosts, open hosts, and joined clients. Catches,
-currency, owned items, jobs, mail, drawings, profiles, and moderation affect
-state that cannot safely trust a client's local presentation.
-
-## Decision
-
-The host validates requests against registered peers and host-owned context,
-then performs the authoritative mutation. Clients receive results and replicated
-presentation state. Client evidence is bounded and reconstructed where
-possible; it is not treated as authority.
-
-Private single-player uses the same host path. Presentation-only state does not
-add RPCs or persistence.
-
-## Consequences
-
-- Shared behavior is consistent across private, open-host, and joined-client
- modes.
-- Tests must cover local-host and paired host/client paths.
-- Stable protocol payloads and rejection cleanup require explicit handling.
-- UI activation cannot be used as proof that a server-side mutation succeeded.
diff --git a/docs/decisions/0002-authored-data-and-stable-ids.md b/docs/decisions/0002-authored-data-and-stable-ids.md
deleted file mode 100644
index 23163cb..0000000
--- a/docs/decisions/0002-authored-data-and-stable-ids.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# ADR 0002: Authored resources and stable identifiers
-
-Status: accepted
-
-## Context
-
-Fish, items, pools, availability, shop stock, and other game content evolve
-independently from saved catches and network messages. Display labels and scene
-node names are expected to change during development.
-
-## Decision
-
-Repository-owned resources are the authoritative authored data. Persistent and
-networked records refer to stable IDs. Display names, filenames, node names,
-coordinates, and pool names are not compatibility identifiers.
-
-Cross-domain concepts such as water type use one typed definition rather than
-duplicated strings. Comprehensive catalogs remain separate from location-
-specific selection pools.
-
-## Consequences
-
-- Renaming visible UI does not require save migration.
-- Removing or changing a stable ID requires an explicit compatibility plan.
-- Content validation checks uniqueness, catalog completeness, pool membership,
- and typed habitat compatibility.
-- New authored assets need provenance records as well as resource references.
diff --git a/drawing/surface_drawing_canvas.gd b/drawing/surface_drawing_canvas.gd
index 2d4f506..f6ceb94 100644
--- a/drawing/surface_drawing_canvas.gd
+++ b/drawing/surface_drawing_canvas.gd
@@ -340,13 +340,13 @@ func _sample_cell_transform(
tangent = Vector3.RIGHT
var bitangent: Vector3 = normal.cross(tangent).normalized()
var pixel_size: float = cell_size * clampf(fill, 0.05, 1.0)
- var basis := Basis(
+ var cell_basis := Basis(
tangent * pixel_size,
bitangent * pixel_size,
normal,
)
return Transform3D(
- basis,
+ cell_basis,
to_local(point + normal * _surface_offset()),
)
diff --git a/economy/buyers/pelicans.tres b/economy/buyers/pelicans.tres
index 7dce4ec..f1a4807 100644
--- a/economy/buyers/pelicans.tres
+++ b/economy/buyers/pelicans.tres
@@ -9,4 +9,4 @@ display_name = "pelicans"
animal_name_singular = "pelican"
animal_name_plural = "pelicans"
payout_multiplier = 0.25
-sale_message_template = "You sold your {fish} to the pelicans for ${payout}."
+sale_message_template = "You sold your {fish} to the pelicans."
diff --git a/economy/fish_buyer_profile.gd b/economy/fish_buyer_profile.gd
index 485df20..9bb59de 100644
--- a/economy/fish_buyer_profile.gd
+++ b/economy/fish_buyer_profile.gd
@@ -53,8 +53,7 @@ func get_sale_message(
var buyer_name: String = animal_name_plural
if buyer_name.is_empty():
buyer_name = display_name
- return "you sold your %s to the %s for $%d." % [
+ return "you sold your %s to the %s." % [
fish_name,
buyer_name,
- payout,
]
diff --git a/economy/fish_sale_service.gd b/economy/fish_sale_service.gd
index 722f766..6aca45d 100644
--- a/economy/fish_sale_service.gd
+++ b/economy/fish_sale_service.gd
@@ -165,9 +165,10 @@ func _validate_batch(
result.payout
)
else:
- result.sale_message = "you sold %d fish to the %s for $%d." % [
+ result.sale_message = (
+ "you sold %d fish to the %s." % [
result.fish_count,
result.buyer_animal_name,
- result.payout,
- ]
+ ]
+ )
return result
diff --git a/economy/fishing_shop_stock.gd b/economy/fishing_shop_stock.gd
index 4cbf863..87795ad 100644
--- a/economy/fishing_shop_stock.gd
+++ b/economy/fishing_shop_stock.gd
@@ -6,20 +6,46 @@ const ItemDataType = preload("res://items/item_data.gd")
const PlayerBagType = preload("res://inventory/player_bag.gd")
const PlayerWalletType = preload("res://economy/player_wallet.gd")
const WORM_MAX_STACK: int = 10
+const FISH_FINDER_ID: StringName = &"fish_finder"
+const BATTERIES_ID: StringName = &"batteries"
const ITEM_PRICES: Dictionary[StringName, int] = {
&"worms": 1,
+ &"snails": 3,
+ &"shrimp": 7,
+ &"squid_chunks": 15,
+ &"whole_anchovy": 60,
+ &"whole_sardine": 30,
+ &"luminous_roe": 125,
+ &"the_standby": 750,
&"coffee": 20,
&"energy_drink": 35,
&"snack": 30,
- &"fish_finder": 60,
+ FISH_FINDER_ID: 500,
+ BATTERIES_ID: 15,
+}
+const BAIT_UNLOCK_PRICES: Dictionary[StringName, int] = {
+ &"snails": 400,
+ &"shrimp": 1200,
+ &"squid_chunks": 3500,
+ &"whole_anchovy": 22000,
+ &"whole_sardine": 9000,
+ &"luminous_roe": 50000,
}
const ITEM_ORDER: Array[StringName] = [
&"worms",
+ &"snails",
+ &"shrimp",
+ &"squid_chunks",
+ &"whole_sardine",
+ &"whole_anchovy",
+ &"luminous_roe",
+ &"the_standby",
+ FISH_FINDER_ID,
&"coffee",
&"energy_drink",
&"snack",
- &"fish_finder",
+ BATTERIES_ID,
]
@@ -31,14 +57,49 @@ static func get_stock_item_ids() -> Array[StringName]:
return ITEM_ORDER.duplicate()
-static func get_purchase_quantity(item_id: StringName, owned: int) -> int:
- if item_id == &"worms":
- return maxi(WORM_MAX_STACK - owned, 0)
+static func get_unlock_price(item_id: StringName) -> int:
+ return BAIT_UNLOCK_PRICES.get(item_id, -1)
+
+
+static func get_purchase_quantity(
+ item_id: StringName,
+ owned: int,
+ maximum_stack: int = WORM_MAX_STACK,
+) -> int:
+ if is_bait_topoff(item_id):
+ return maxi(maximum_stack - owned, 0)
return 1
static func is_bait_topoff(item_id: StringName) -> bool:
- return item_id == &"worms"
+ return item_id == &"worms" or BAIT_UNLOCK_PRICES.has(item_id)
+
+
+static func is_permanent_unlock(
+ item_id: StringName,
+ item: ItemDataType,
+) -> bool:
+ return (
+ item != null
+ and (item.is_lure() or item_id == FISH_FINDER_ID)
+ )
+
+
+static func is_passive_supply(item_id: StringName) -> bool:
+ return item_id == BATTERIES_ID
+
+
+static func get_purchase_cost(
+ item_id: StringName,
+ quantity: int,
+ bait_unlocked: bool,
+) -> int:
+ if quantity <= 0:
+ return -1
+ if is_bait_topoff(item_id) and item_id != &"worms" and not bait_unlocked:
+ return get_unlock_price(item_id)
+ var unit_price: int = get_price(item_id)
+ return unit_price * quantity if unit_price >= 0 else -1
static func purchase_one(
@@ -49,22 +110,42 @@ static func purchase_one(
) -> bool:
if wallet == null or bag == null or catalog == null:
return false
- var price: int = get_price(item_id)
var item: ItemDataType = catalog.get_item_by_id(item_id)
+ var bait_topoff: bool = is_bait_topoff(item_id)
+ var permanent_unlock: bool = is_permanent_unlock(item_id, item)
+ var quantity: int = get_purchase_quantity(
+ item_id,
+ bag.get_quantity(item_id),
+ item.max_stack if item != null else WORM_MAX_STACK,
+ )
+ var price: int = get_purchase_cost(
+ item_id,
+ quantity,
+ bag.is_bait_unlocked(item_id),
+ )
if (
price < 0
or item == null
or not item.is_valid()
- or (item.category != ItemDataType.Category.CONSUMABLE and not is_bait_topoff(item_id))
- or not item.stackable
- or (not item.usable and not is_bait_topoff(item_id))
- or not bag.can_add_item(item_id, 1)
+ or (
+ item.category != ItemDataType.Category.CONSUMABLE
+ and not bait_topoff
+ and not permanent_unlock
+ )
+ or (not item.stackable and not permanent_unlock)
+ or (
+ not item.usable
+ and not bait_topoff
+ and not permanent_unlock
+ and not is_passive_supply(item_id)
+ )
+ or not bag.can_add_item(item_id, quantity)
or not wallet.can_afford(price)
):
return false
if not wallet.debit(price):
return false
- if bag.add_item(item_id, 1):
+ if bag.add_item(item_id, quantity):
return true
if not wallet.credit(price):
push_error("Fishing Shop failed to roll back an item purchase.")
diff --git a/export_presets.cfg b/export_presets.cfg
index 0618c92..bbcdec2 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -7,9 +7,9 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
-include_filter=""
-exclude_filter="builds/*,playtest/*,scripts/*"
-export_path="builds/v0.5.1-prealpha/windows-x86_64/NETfishing.exe"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*"
+export_path="builds/v0.7.1-alpha/windows-x86_64/NETfishing.exe"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
@@ -32,16 +32,16 @@ codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
-application/icon=""
+application/icon="res://art/exported/system_icons/netfishing.ico"
application/console_wrapper_icon=""
application/icon_interpolation=4
-application/file_version="0.5.1.0"
-application/product_version="0.5.1.0"
-application/company_name=""
+application/file_version="0.7.1.0"
+application/product_version="0.7.1.0"
+application/company_name="Woofmeow"
application/product_name="NETfishing"
-application/file_description="NETfishing v0.5.1-prealpha"
-application/copyright=""
-application/trademarks=""
+application/file_description="NETfishing v0.7.1-alpha"
+application/copyright="Copyright © 2026 Woofmeow"
+application/trademarks="NETfishing and Woofmeow branding is reserved; see TRADEMARKS.md"
application/export_angle=0
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
@@ -60,9 +60,9 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
-include_filter=""
-exclude_filter="builds/*,playtest/*,scripts/*"
-export_path="builds/v0.5.1-prealpha/linux-arm64/NETfishing.arm64"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*"
+export_path="builds/v0.7.1-alpha/linux-arm64/NETfishing.arm64"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
@@ -90,9 +90,9 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
-include_filter=""
-exclude_filter="builds/*,playtest/*,scripts/*"
-export_path="builds/v0.5.1-prealpha/macos/NETfishing.zip"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*"
+export_path="builds/v0.7.1-alpha/macos/NETfishing.zip"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
@@ -105,13 +105,45 @@ script_export_mode=2
custom_template/debug=""
custom_template/release=""
-application/bundle_identifier="io.makearmy.netfishing"
-application/short_version="0.5.1"
-application/version="0.5.1"
+application/bundle_identifier="io.woofmeow.netfishing"
+application/icon="res://art/exported/system_icons/netfishing_1024.png"
+application/icon_interpolation=0
+application/short_version="0.7.1"
+application/version="0.7.1"
application/architecture="universal"
codesign/enable=false
notarization/enable=false
+[preset.5]
+
+name="Linux Dedicated Server"
+platform="Linux"
+runnable=false
+advanced_options=false
+dedicated_server=true
+custom_features=""
+export_filter="all_resources"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*,tests/*"
+export_path="builds/v0.7.1-alpha/server-linux-x86_64/NETfishingServer.x86_64"
+patches=PackedStringArray()
+encryption_include_filters=""
+encryption_exclude_filters=""
+seed=0
+encrypt_pck=false
+encrypt_directory=false
+script_export_mode=2
+
+[preset.5.options]
+
+custom_template/debug=""
+custom_template/release=""
+debug/export_console_wrapper=0
+binary_format/embed_pck=false
+binary_format/architecture="x86_64"
+texture_format/s3tc_bptc=true
+texture_format/etc2_astc=false
+
[preset.2]
name="Android"
@@ -121,9 +153,9 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
-include_filter=""
-exclude_filter="builds/*,playtest/*,scripts/*"
-export_path="builds/v0.5.1-prealpha/android/NETfishing.apk"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*"
+export_path="builds/v0.7.1-alpha/android/NETfishing.apk"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
@@ -144,9 +176,9 @@ architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
-version/code=50100
-version/name="0.5.1-prealpha"
-package/unique_name="io.makearmy.netfishing"
+version/code=70100
+version/name="v0.7.1-alpha"
+package/unique_name="io.woofmeow.netfishing"
package/name="NETfishing"
package/signed=true
package/app_category=0
@@ -155,7 +187,7 @@ package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=true
-launcher_icons/main_192x192="res://icon.svg"
+launcher_icons/main_192x192="res://art/exported/system_icons/netfishing_256.png"
graphics/opengl_debug=false
screen/immersive_mode=true
screen/edge_to_edge=false
@@ -180,9 +212,9 @@ advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
-include_filter=""
-exclude_filter="builds/*,playtest/*,scripts/*"
-export_path="builds/v0.5.1-prealpha/linux-x86_64/NETfishing.x86_64"
+include_filter="LICENSE,ASSET-LICENSE.md,TRADEMARKS.md,docs/ATTRIBUTION.md,ui/fonts/*LICENSE.txt"
+exclude_filter="builds/*,scripts/*"
+export_path="builds/v0.7.1-alpha/linux-x86_64/NETfishing.x86_64"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
diff --git a/fish/fish_quality.gd b/fish/fish_quality.gd
index 0559679..61534e0 100644
--- a/fish/fish_quality.gd
+++ b/fish/fish_quality.gd
@@ -16,17 +16,18 @@ const ALL_TIERS_MASK: int = (1 << TIER_COUNT) - 1
# multipliers later without changing catch serialization or tier identity.
const BASE_ROLL_WEIGHTS: Array[float] = [40.0, 32.0, 18.0, 8.0, 2.0]
const WORM_ROLL_WEIGHTS: Array[float] = [80.0, 10.0, 5.0, 4.0, 1.0]
+const SNAIL_ROLL_WEIGHTS: Array[float] = [68.0, 16.0, 8.0, 6.0, 2.0]
+const SHRIMP_ROLL_WEIGHTS: Array[float] = [56.0, 21.0, 12.0, 8.0, 3.0]
+const SQUID_ROLL_WEIGHTS: Array[float] = [44.0, 25.0, 16.0, 11.0, 4.0]
+const MINNOW_ROLL_WEIGHTS: Array[float] = [34.0, 27.0, 20.0, 13.0, 6.0]
+const SARDINE_ROLL_WEIGHTS: Array[float] = [25.0, 28.0, 23.0, 16.0, 8.0]
+const LUMINOUS_ROE_ROLL_WEIGHTS: Array[float] = [16.0, 26.0, 26.0, 20.0, 12.0]
const SALE_MULTIPLIERS: Array[float] = [1.0, 1.1, 1.25, 1.5, 2.0]
-# Legacy profile multiplier retained for serialized/profile compatibility.
-# New encounters use the weighted quality/rarity/weight bands below.
+# Legacy multiplier helpers remain available for compatibility. New encounters
+# roll directly within the authored quality bands below.
const BARRIER_HEALTH_MULTIPLIERS: Array[float] = [1.0, 1.25, 1.6, 2.2, 3.25]
-# Barrier health is weighted 70% by quality, 20% by rarity, and 10% by the
-# catch's position in its authored weight range. The upper bounds define the
-# intended per-barrier challenge bands; a small seeded variance keeps barriers
-# from feeling identical without crossing those bands.
-const BARRIER_QUALITY_WEIGHT: float = 0.70
-const BARRIER_RARITY_WEIGHT: float = 0.20
-const BARRIER_WEIGHT_WEIGHT: float = 0.10
+# Inclusive per-barrier health bands authored for each quality tier. Encounter
+# generation rolls uniformly across the selected tier's complete band.
const BARRIER_HEALTH_MINIMUMS: Array[int] = [1, 10, 50, 100, 200]
const BARRIER_HEALTH_MAXIMUMS: Array[int] = [9, 50, 100, 200, 400]
const DISPLAY_NAMES: PackedStringArray = [
@@ -83,32 +84,26 @@ static func apply_barrier_health(base_health: int, quality: int) -> int:
)
-static func barrier_health_for_catch(
- quality: int,
- rarity: int,
- weight_percentile: float,
- variance: float = 1.0,
-) -> int:
+static func barrier_health_range(quality: int) -> Vector2i:
var safe_quality: int = (
quality if is_valid(quality) else Tier.BORING
)
- var safe_rarity: float = clampf(float(rarity) / 4.0, 0.0, 1.0)
- var safe_weight: float = clampf(weight_percentile, 0.0, 1.0)
- var weighted_health: float = float(BARRIER_HEALTH_MAXIMUMS[safe_quality]) * (
- BARRIER_QUALITY_WEIGHT
- + BARRIER_RARITY_WEIGHT * safe_rarity
- + BARRIER_WEIGHT_WEIGHT * safe_weight
- )
- var varied_health: int = roundi(
- weighted_health * clampf(variance, 0.8, 1.2)
- )
- return clampi(
- varied_health,
+ return Vector2i(
BARRIER_HEALTH_MINIMUMS[safe_quality],
BARRIER_HEALTH_MAXIMUMS[safe_quality],
)
+static func roll_barrier_health(
+ rng: RandomNumberGenerator,
+ quality: int,
+) -> int:
+ var health_range: Vector2i = barrier_health_range(quality)
+ if rng == null:
+ return health_range.x
+ return rng.randi_range(health_range.x, health_range.y)
+
+
static func roll(
rng: RandomNumberGenerator,
weight_multipliers: Array[float] = [],
@@ -136,17 +131,34 @@ static func roll(
static func roll_weights_for_bait(active_bait_tags: Array[StringName]) -> Array[float]:
+ var bait_weights: Array[float] = rarity_weights_for_bait(active_bait_tags)
+ var weights: Array[float] = []
+ for quality: int in TIER_COUNT:
+ weights.append(bait_weights[quality] / BASE_ROLL_WEIGHTS[quality])
+ return weights
+
+
+static func rarity_weights_for_bait(
+ active_bait_tags: Array[StringName],
+) -> Array[float]:
var weights: Array[float] = []
if active_bait_tags.is_empty():
- weights.assign([2.5, 0.0, 0.0, 0.0, 0.0])
+ weights.assign([100.0, 0.0, 0.0, 0.0, 0.0])
+ elif active_bait_tags.has(&"bait_rarity_6"):
+ weights.assign(LUMINOUS_ROE_ROLL_WEIGHTS)
+ elif active_bait_tags.has(&"bait_rarity_5"):
+ weights.assign(SARDINE_ROLL_WEIGHTS)
+ elif active_bait_tags.has(&"bait_rarity_4"):
+ weights.assign(MINNOW_ROLL_WEIGHTS)
+ elif active_bait_tags.has(&"bait_rarity_3"):
+ weights.assign(SQUID_ROLL_WEIGHTS)
+ elif active_bait_tags.has(&"bait_rarity_2"):
+ weights.assign(SHRIMP_ROLL_WEIGHTS)
+ elif active_bait_tags.has(&"bait_rarity_1"):
+ weights.assign(SNAIL_ROLL_WEIGHTS)
else:
- weights.assign([
- WORM_ROLL_WEIGHTS[0] / BASE_ROLL_WEIGHTS[0],
- WORM_ROLL_WEIGHTS[1] / BASE_ROLL_WEIGHTS[1],
- WORM_ROLL_WEIGHTS[2] / BASE_ROLL_WEIGHTS[2],
- WORM_ROLL_WEIGHTS[3] / BASE_ROLL_WEIGHTS[3],
- WORM_ROLL_WEIGHTS[4] / BASE_ROLL_WEIGHTS[4],
- ])
+ # Unknown and legacy bait tags retain the original worms behavior.
+ weights.assign(WORM_ROLL_WEIGHTS)
return weights
diff --git a/fish/fish_selector.gd b/fish/fish_selector.gd
index 17c3ff7..506a906 100644
--- a/fish/fish_selector.gd
+++ b/fish/fish_selector.gd
@@ -81,9 +81,9 @@ func select_fish(
func _roll_rarity(context: FishingContextType) -> int:
- var weights: Array[float] = [100.0, 0.0, 0.0, 0.0, 0.0]
- if not context.active_bait_tags.is_empty():
- weights = [80.0, 10.0, 5.0, 4.0, 1.0]
+ var weights: Array[float] = FishQualityType.rarity_weights_for_bait(
+ context.active_bait_tags
+ )
for index: int in range(weights.size()):
if index < rarity_weight_multipliers.size():
weights[index] *= maxf(rarity_weight_multipliers[index], 0.0)
diff --git a/fish/species/anchovy_european/anchovy_european.tres b/fish/species/anchovy_european/anchovy_european.tres
index 7df7b18..fea09ed 100644
--- a/fish/species/anchovy_european/anchovy_european.tres
+++ b/fish/species/anchovy_european/anchovy_european.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://6a063go0dcqk"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/anchovy_european/fish_anchovy_european.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://debgohfsg4ec7" path="res://fish/species/anchovy_european/fish_anchovy_european.png" id="4_texture"]
[sub_resource type="Resource" id="AnchovyEuropeanAvailability"]
script = ExtResource("3_availability_script")
@@ -14,7 +14,6 @@ script = ExtResource("1_fish_data")
id = &"anchovy_european"
display_name = "european anchovy"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.5
catch_profile = ExtResource("2_profile")
availability = SubResource("AnchovyEuropeanAvailability")
diff --git a/fish/species/anchovy_northern/anchovy_northern.tres b/fish/species/anchovy_northern/anchovy_northern.tres
index edd6d28..ad53d6e 100644
--- a/fish/species/anchovy_northern/anchovy_northern.tres
+++ b/fish/species/anchovy_northern/anchovy_northern.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://c30colwbajqf8"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/anchovy_northern/fish_anchovy_northern.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://6sikqc8eivta" path="res://fish/species/anchovy_northern/fish_anchovy_northern.png" id="4_texture"]
[sub_resource type="Resource" id="AnchovyNorthernAvailability"]
script = ExtResource("3_availability_script")
@@ -14,7 +14,6 @@ script = ExtResource("1_fish_data")
id = &"anchovy_northern"
display_name = "northern anchovy"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.5
catch_profile = ExtResource("2_profile")
availability = SubResource("AnchovyNorthernAvailability")
diff --git a/fish/species/chub_european/chub_european.tres b/fish/species/chub_european/chub_european.tres
index 73b1a5d..e282b90 100644
--- a/fish/species/chub_european/chub_european.tres
+++ b/fish/species/chub_european/chub_european.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cmyhlwqrx36wg"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/chub_european/fish_chub_european.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://c04wtbyslmpll" path="res://fish/species/chub_european/fish_chub_european.png" id="4_texture"]
[sub_resource type="Resource" id="ChubEuropeanAvailability"]
script = ExtResource("3_availability_script")
@@ -14,14 +14,12 @@ script = ExtResource("1_fish_data")
id = &"chub_european"
display_name = "european chub"
allowed_water_types = 1
-rarity = 0
base_catch_weight = 0.55
catch_profile = ExtResource("2_profile")
availability = SubResource("ChubEuropeanAvailability")
weight_min_lb = 0.2
weight_max_lb = 6.0
display_scale_min = 0.85
-display_scale_max = 1.2
display_scale_curve = 0.9
sell_value_min = 2
sell_value_max = 4
diff --git a/fish/species/chub_flame/chub_flame.tres b/fish/species/chub_flame/chub_flame.tres
index 976a007..d631ab0 100644
--- a/fish/species/chub_flame/chub_flame.tres
+++ b/fish/species/chub_flame/chub_flame.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://d25q23kfdhm3o"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/chub_flame/fish_chub_flame.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://bla6pc21imxsi" path="res://fish/species/chub_flame/fish_chub_flame.png" id="4_texture"]
[sub_resource type="Resource" id="ChubFlameAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/chub_lake/chub_lake.tres b/fish/species/chub_lake/chub_lake.tres
index b610f95..c04c5b3 100644
--- a/fish/species/chub_lake/chub_lake.tres
+++ b/fish/species/chub_lake/chub_lake.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://n7u2krjf4ril"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/chub_lake/fish_chub_lake.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://w8cjrpnv350h" path="res://fish/species/chub_lake/fish_chub_lake.png" id="4_texture"]
[sub_resource type="Resource" id="ChubLakeAvailability"]
script = ExtResource("3_availability_script")
@@ -14,7 +14,6 @@ script = ExtResource("1_fish_data")
id = &"chub_lake"
display_name = "lake chub"
allowed_water_types = 1
-rarity = 0
base_catch_weight = 0.55
catch_profile = ExtResource("2_profile")
availability = SubResource("ChubLakeAvailability")
diff --git a/fish/species/goldfish/goldfish.tres b/fish/species/goldfish/goldfish.tres
index c2d5d09..153365d 100644
--- a/fish/species/goldfish/goldfish.tres
+++ b/fish/species/goldfish/goldfish.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cw7vdjhhfgtax"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/goldfish/fish_goldfish.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://c6uth7aob03kg" path="res://fish/species/goldfish/fish_goldfish.png" id="4_texture"]
[sub_resource type="Resource" id="GoldfishAvailability"]
script = ExtResource("3_availability_script")
@@ -14,7 +14,6 @@ script = ExtResource("1_fish_data")
id = &"goldfish"
display_name = "goldfish"
allowed_water_types = 1
-rarity = 0
base_catch_weight = 0.5
catch_profile = ExtResource("2_profile")
availability = SubResource("GoldfishAvailability")
diff --git a/fish/species/goldfish_bubbleeye/goldfish_bubbleeye.tres b/fish/species/goldfish_bubbleeye/goldfish_bubbleeye.tres
index d5425a0..d6a288a 100644
--- a/fish/species/goldfish_bubbleeye/goldfish_bubbleeye.tres
+++ b/fish/species/goldfish_bubbleeye/goldfish_bubbleeye.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://beiutt7wq87rp"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/goldfish_bubbleeye/fish_goldfish_bubbleeye.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://brjjnxr6n7olr" path="res://fish/species/goldfish_bubbleeye/fish_goldfish_bubbleeye.png" id="4_texture"]
[sub_resource type="Resource" id="GoldfishBubbleeyeAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/grouper_gulf/grouper_gulf.tres b/fish/species/grouper_gulf/grouper_gulf.tres
index 17caf23..1e0446e 100644
--- a/fish/species/grouper_gulf/grouper_gulf.tres
+++ b/fish/species/grouper_gulf/grouper_gulf.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://c5w5e2rkqiaep"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/grouper_gulf/fish_grouper_gulf.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://ctu8xd5or7v3h" path="res://fish/species/grouper_gulf/fish_grouper_gulf.png" id="4_texture"]
[sub_resource type="Resource" id="GrouperGulfAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/grouper_red/grouper_red.tres b/fish/species/grouper_red/grouper_red.tres
index d7d8f02..5594641 100644
--- a/fish/species/grouper_red/grouper_red.tres
+++ b/fish/species/grouper_red/grouper_red.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://ckr1c747mvjl0"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/grouper_red/fish_grouper_red.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://jjcc78tffxhb" path="res://fish/species/grouper_red/fish_grouper_red.png" id="4_texture"]
[sub_resource type="Resource" id="GrouperRedAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/mackerel_atlantic/mackerel_atlantic.tres b/fish/species/mackerel_atlantic/mackerel_atlantic.tres
index 8b6ecaf..514ef07 100644
--- a/fish/species/mackerel_atlantic/mackerel_atlantic.tres
+++ b/fish/species/mackerel_atlantic/mackerel_atlantic.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cm8hgt2qubpi8"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/mackerel_atlantic/fish_mackerel_atlantic.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://breyc8fqq8lq3" path="res://fish/species/mackerel_atlantic/fish_mackerel_atlantic.png" id="4_texture"]
[sub_resource type="Resource" id="MackerelAtlanticAvailability"]
script = ExtResource("3_availability_script")
@@ -14,11 +14,9 @@ script = ExtResource("1_fish_data")
id = &"mackerel_atlantic"
display_name = "atlantic mackerel"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.5
catch_profile = ExtResource("2_profile")
availability = SubResource("MackerelAtlanticAvailability")
-weight_min_lb = 0.5
weight_max_lb = 5
display_scale_min = 0.85
display_scale_max = 1.4
diff --git a/fish/species/mackerel_cero/mackerel_cero.tres b/fish/species/mackerel_cero/mackerel_cero.tres
index 304af5a..fbbb612 100644
--- a/fish/species/mackerel_cero/mackerel_cero.tres
+++ b/fish/species/mackerel_cero/mackerel_cero.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://du4ixk4sssvac"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/mackerel_cero/fish_mackerel_cero.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://g8qanq47g1b8" path="res://fish/species/mackerel_cero/fish_mackerel_cero.png" id="4_texture"]
[sub_resource type="Resource" id="MackerelCeroAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/mackerel_chub/mackerel_chub.tres b/fish/species/mackerel_chub/mackerel_chub.tres
index 90c2746..f4ceca1 100644
--- a/fish/species/mackerel_chub/mackerel_chub.tres
+++ b/fish/species/mackerel_chub/mackerel_chub.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://b6lga2c60qkc4"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/mackerel_chub/fish_mackerel_chub.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://b7q2t02oo2bcp" path="res://fish/species/mackerel_chub/fish_mackerel_chub.png" id="4_texture"]
[sub_resource type="Resource" id="MackerelChubAvailability"]
script = ExtResource("3_availability_script")
@@ -14,11 +14,9 @@ script = ExtResource("1_fish_data")
id = &"mackerel_chub"
display_name = "chub mackerel"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.5
catch_profile = ExtResource("2_profile")
availability = SubResource("MackerelChubAvailability")
-weight_min_lb = 0.5
weight_max_lb = 4
display_scale_min = 0.85
display_scale_max = 1.4
diff --git a/fish/species/mackerel_king/mackerel_king.tres b/fish/species/mackerel_king/mackerel_king.tres
index df9f8f3..2c28071 100644
--- a/fish/species/mackerel_king/mackerel_king.tres
+++ b/fish/species/mackerel_king/mackerel_king.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://bacndgfbn8oj7"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/mackerel_king/fish_mackerel_king.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://b2fag3xemyx5s" path="res://fish/species/mackerel_king/fish_mackerel_king.png" id="4_texture"]
[sub_resource type="Resource" id="MackerelKingAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/mackerel_spanish/mackerel_spanish.tres b/fish/species/mackerel_spanish/mackerel_spanish.tres
index e93d082..0319917 100644
--- a/fish/species/mackerel_spanish/mackerel_spanish.tres
+++ b/fish/species/mackerel_spanish/mackerel_spanish.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cg7y0numxuy3e"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/mackerel_spanish/fish_mackerel_spanish.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://cy2hmpenpkee2" path="res://fish/species/mackerel_spanish/fish_mackerel_spanish.png" id="4_texture"]
[sub_resource type="Resource" id="MackerelSpanishAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/marlin_black/marlin_black.tres b/fish/species/marlin_black/marlin_black.tres
index f76b8e3..39110c5 100644
--- a/fish/species/marlin_black/marlin_black.tres
+++ b/fish/species/marlin_black/marlin_black.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://dlm608g365aa3"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/marlin_black/fish_marlin_black.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://dkdctr2o52vrb" path="res://fish/species/marlin_black/fish_marlin_black.png" id="4_texture"]
[sub_resource type="Resource" id="MarlinBlackAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/marlin_blue/marlin_blue.tres b/fish/species/marlin_blue/marlin_blue.tres
index 214587b..b3328ba 100644
--- a/fish/species/marlin_blue/marlin_blue.tres
+++ b/fish/species/marlin_blue/marlin_blue.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://b15syao6ighl4"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/marlin_blue/fish_marlin_blue.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://de35fjoytbomu" path="res://fish/species/marlin_blue/fish_marlin_blue.png" id="4_texture"]
[sub_resource type="Resource" id="MarlinBlueAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/marlin_white/marlin_white.tres b/fish/species/marlin_white/marlin_white.tres
index a4aada5..e90651c 100644
--- a/fish/species/marlin_white/marlin_white.tres
+++ b/fish/species/marlin_white/marlin_white.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://jjxr31djus2h"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/marlin_white/fish_marlin_white.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://bdvy4ujx2htcy" path="res://fish/species/marlin_white/fish_marlin_white.png" id="4_texture"]
[sub_resource type="Resource" id="MarlinWhiteAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/pomfret_black/pomfret_black.tres b/fish/species/pomfret_black/pomfret_black.tres
index c483306..8020100 100644
--- a/fish/species/pomfret_black/pomfret_black.tres
+++ b/fish/species/pomfret_black/pomfret_black.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://bsm1itwx50p1q"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/pomfret_black/fish_pomfret_black.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://ch3y6xdo22j1o" path="res://fish/species/pomfret_black/fish_pomfret_black.png" id="4_texture"]
[sub_resource type="Resource" id="PomfretBlackAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/pomfret_chinese/pomfret_chinese.tres b/fish/species/pomfret_chinese/pomfret_chinese.tres
index 1517438..2eaf34b 100644
--- a/fish/species/pomfret_chinese/pomfret_chinese.tres
+++ b/fish/species/pomfret_chinese/pomfret_chinese.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://di8qq1hek8cpo"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/pomfret_chinese/fish_pomfret_chinese.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://cijr0gseldncc" path="res://fish/species/pomfret_chinese/fish_pomfret_chinese.png" id="4_texture"]
[sub_resource type="Resource" id="PomfretChineseAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/pomfret_golden/pomfret_golden.tres b/fish/species/pomfret_golden/pomfret_golden.tres
index 203210e..da1f561 100644
--- a/fish/species/pomfret_golden/pomfret_golden.tres
+++ b/fish/species/pomfret_golden/pomfret_golden.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://b5ivfnfidlu81"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/pomfret_golden/fish_pomfret_golden.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://7rjv7k60bv7q" path="res://fish/species/pomfret_golden/fish_pomfret_golden.png" id="4_texture"]
[sub_resource type="Resource" id="PomfretGoldenAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/pomfret_white/pomfret_white.tres b/fish/species/pomfret_white/pomfret_white.tres
index 1687c15..fa317c7 100644
--- a/fish/species/pomfret_white/pomfret_white.tres
+++ b/fish/species/pomfret_white/pomfret_white.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://6rfka15wc2iy"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/pomfret_white/fish_pomfret_white.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://c3fr0x4e1nfe0" path="res://fish/species/pomfret_white/fish_pomfret_white.png" id="4_texture"]
[sub_resource type="Resource" id="PomfretWhiteAvailability"]
script = ExtResource("3_availability_script")
@@ -14,11 +14,9 @@ script = ExtResource("1_fish_data")
id = &"pomfret_white"
display_name = "white pomfret"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.45
catch_profile = ExtResource("2_profile")
availability = SubResource("PomfretWhiteAvailability")
-weight_min_lb = 0.5
weight_max_lb = 10
display_scale_min = 0.85
display_scale_max = 1.6
diff --git a/fish/species/sailfish/sailfish.tres b/fish/species/sailfish/sailfish.tres
index f90415d..7f6bea9 100644
--- a/fish/species/sailfish/sailfish.tres
+++ b/fish/species/sailfish/sailfish.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://b3auce81mglkx"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/sailfish/fish_sailfish.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://8rlcnfqx8or0" path="res://fish/species/sailfish/fish_sailfish.png" id="4_texture"]
[sub_resource type="Resource" id="SailfishAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/sauger/sauger.tres b/fish/species/sauger/sauger.tres
index 07c7fec..49cf5ad 100644
--- a/fish/species/sauger/sauger.tres
+++ b/fish/species/sauger/sauger.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://suhm4yemc0vf"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/sauger/fish_sauger.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://8k7qkk4juciy" path="res://fish/species/sauger/fish_sauger.png" id="4_texture"]
[sub_resource type="Resource" id="SaugerAvailability"]
script = ExtResource("3_availability_script")
@@ -18,7 +18,6 @@ rarity = 1
base_catch_weight = 0.35
catch_profile = ExtResource("2_profile")
availability = SubResource("SaugerAvailability")
-weight_min_lb = 0.5
weight_max_lb = 8
display_scale_min = 0.85
display_scale_max = 1.4
diff --git a/fish/species/saugeye/saugeye.tres b/fish/species/saugeye/saugeye.tres
index fc5e0f9..e834005 100644
--- a/fish/species/saugeye/saugeye.tres
+++ b/fish/species/saugeye/saugeye.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://oecfrxf7vgh0"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/saugeye/fish_saugeye.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://lom25y0eqcw3" path="res://fish/species/saugeye/fish_saugeye.png" id="4_texture"]
[sub_resource type="Resource" id="SaugeyeAvailability"]
script = ExtResource("3_availability_script")
@@ -18,7 +18,6 @@ rarity = 2
base_catch_weight = 0.2
catch_profile = ExtResource("2_profile")
availability = SubResource("SaugeyeAvailability")
-weight_min_lb = 0.5
weight_max_lb = 12
display_scale_min = 0.85
display_scale_max = 1.6
diff --git a/fish/species/snapper_lane/snapper_lane.tres b/fish/species/snapper_lane/snapper_lane.tres
index 448d973..e9e7422 100644
--- a/fish/species/snapper_lane/snapper_lane.tres
+++ b/fish/species/snapper_lane/snapper_lane.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://b7t3fuykfa6ri"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/snapper_lane/fish_snapper_lane.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://d3d8s30bxq4tp" path="res://fish/species/snapper_lane/fish_snapper_lane.png" id="4_texture"]
[sub_resource type="Resource" id="SnapperLaneAvailability"]
script = ExtResource("3_availability_script")
@@ -14,11 +14,9 @@ script = ExtResource("1_fish_data")
id = &"snapper_lane"
display_name = "lane snapper"
allowed_water_types = 2
-rarity = 0
base_catch_weight = 0.45
catch_profile = ExtResource("2_profile")
availability = SubResource("SnapperLaneAvailability")
-weight_min_lb = 0.5
weight_max_lb = 5
display_scale_min = 0.85
display_scale_max = 1.5
diff --git a/fish/species/snapper_mangrove/snapper_mangrove.tres b/fish/species/snapper_mangrove/snapper_mangrove.tres
index 976f3ac..58226ad 100644
--- a/fish/species/snapper_mangrove/snapper_mangrove.tres
+++ b/fish/species/snapper_mangrove/snapper_mangrove.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://d4eh51kwhsac0"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/snapper_mangrove/fish_snapper_mangrove.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://v34sdv1v7c2x" path="res://fish/species/snapper_mangrove/fish_snapper_mangrove.png" id="4_texture"]
[sub_resource type="Resource" id="SnapperMangroveAvailability"]
script = ExtResource("3_availability_script")
@@ -18,7 +18,6 @@ rarity = 1
base_catch_weight = 0.35
catch_profile = ExtResource("2_profile")
availability = SubResource("SnapperMangroveAvailability")
-weight_min_lb = 0.5
weight_max_lb = 12
display_scale_min = 0.85
display_scale_max = 1.7
diff --git a/fish/species/snapper_mutton/snapper_mutton.tres b/fish/species/snapper_mutton/snapper_mutton.tres
index 0791c4a..6d4441a 100644
--- a/fish/species/snapper_mutton/snapper_mutton.tres
+++ b/fish/species/snapper_mutton/snapper_mutton.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cfvwloicmu53b"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/snapper_mutton/fish_snapper_mutton.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://cawvpo8aysw5i" path="res://fish/species/snapper_mutton/fish_snapper_mutton.png" id="4_texture"]
[sub_resource type="Resource" id="SnapperMuttonAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/snapper_red/snapper_red.tres b/fish/species/snapper_red/snapper_red.tres
index 259a278..8778c98 100644
--- a/fish/species/snapper_red/snapper_red.tres
+++ b/fish/species/snapper_red/snapper_red.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://cpvi3raa6epib"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/snapper_red/fish_snapper_red.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://ei5scljuqklk" path="res://fish/species/snapper_red/fish_snapper_red.png" id="4_texture"]
[sub_resource type="Resource" id="SnapperRedAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/swordfish/swordfish.tres b/fish/species/swordfish/swordfish.tres
index d4ace6b..2184395 100644
--- a/fish/species/swordfish/swordfish.tres
+++ b/fish/species/swordfish/swordfish.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://chqva2v2mtm8q"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/swordfish/fish_swordfish.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://cs1qmm4galac4" path="res://fish/species/swordfish/fish_swordfish.png" id="4_texture"]
[sub_resource type="Resource" id="SwordfishAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/trout_cutthroat/trout_cutthroat.tres b/fish/species/trout_cutthroat/trout_cutthroat.tres
index 605ba3e..fa29c47 100644
--- a/fish/species/trout_cutthroat/trout_cutthroat.tres
+++ b/fish/species/trout_cutthroat/trout_cutthroat.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://bd2t2ktvkkovd"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/trout_cutthroat/fish_trout_cutthroat.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://nowggrl8wmr" path="res://fish/species/trout_cutthroat/fish_trout_cutthroat.png" id="4_texture"]
[sub_resource type="Resource" id="TroutCutthroatAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/trout_golden/trout_golden.tres b/fish/species/trout_golden/trout_golden.tres
index d5347b8..8aa3201 100644
--- a/fish/species/trout_golden/trout_golden.tres
+++ b/fish/species/trout_golden/trout_golden.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://n3ixatlsfp8y"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/trout_golden/fish_trout_golden.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://b64w3kwf3wins" path="res://fish/species/trout_golden/fish_trout_golden.png" id="4_texture"]
[sub_resource type="Resource" id="TroutGoldenAvailability"]
script = ExtResource("3_availability_script")
@@ -21,7 +21,6 @@ availability = SubResource("TroutGoldenAvailability")
weight_min_lb = 0.2
weight_max_lb = 3
display_scale_min = 0.85
-display_scale_max = 1.2
display_scale_curve = 0.9
sell_value_min = 8
sell_value_max = 16
diff --git a/fish/species/trout_rainbow/trout_rainbow.tres b/fish/species/trout_rainbow/trout_rainbow.tres
index f5d1bb4..f9c74f6 100644
--- a/fish/species/trout_rainbow/trout_rainbow.tres
+++ b/fish/species/trout_rainbow/trout_rainbow.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://c3r8v522etgaq"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/trout_rainbow/fish_trout_rainbow.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://mfxehkoxea21" path="res://fish/species/trout_rainbow/fish_trout_rainbow.png" id="4_texture"]
[sub_resource type="Resource" id="TroutRainbowAvailability"]
script = ExtResource("3_availability_script")
@@ -18,7 +18,6 @@ rarity = 1
base_catch_weight = 0.45
catch_profile = ExtResource("2_profile")
availability = SubResource("TroutRainbowAvailability")
-weight_min_lb = 0.5
weight_max_lb = 20
display_scale_min = 0.85
display_scale_max = 1.4
diff --git a/fish/species/trout_steelhead/trout_steelhead.tres b/fish/species/trout_steelhead/trout_steelhead.tres
index 51cb758..57887f7 100644
--- a/fish/species/trout_steelhead/trout_steelhead.tres
+++ b/fish/species/trout_steelhead/trout_steelhead.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://dv2hjtqd5xhfu"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/trout_steelhead/fish_trout_steelhead.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://cabbpc55sf2gw" path="res://fish/species/trout_steelhead/fish_trout_steelhead.png" id="4_texture"]
[sub_resource type="Resource" id="TroutSteelheadAvailability"]
script = ExtResource("3_availability_script")
diff --git a/fish/species/walleye/walleye.tres b/fish/species/walleye/walleye.tres
index 5a64198..ce833c9 100644
--- a/fish/species/walleye/walleye.tres
+++ b/fish/species/walleye/walleye.tres
@@ -1,9 +1,9 @@
-[gd_resource type="Resource" script_class="FishData" format=3]
+[gd_resource type="Resource" script_class="FishData" format=3 uid="uid://8j0f5dchtajt"]
-[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
+[ext_resource type="Script" uid="uid://h7hg45b7wmst" path="res://fish/fish_data.gd" id="1_fish_data"]
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
-[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
-[ext_resource type="Texture2D" path="res://fish/species/walleye/fish_walleye.png" id="4_texture"]
+[ext_resource type="Script" uid="uid://bs7cqi88csolc" path="res://fish/fish_availability.gd" id="3_availability_script"]
+[ext_resource type="Texture2D" uid="uid://c10j6jv6fv32r" path="res://fish/species/walleye/fish_walleye.png" id="4_texture"]
[sub_resource type="Resource" id="WalleyeAvailability"]
script = ExtResource("3_availability_script")
@@ -18,7 +18,6 @@ rarity = 1
base_catch_weight = 0.4
catch_profile = ExtResource("2_profile")
availability = SubResource("WalleyeAvailability")
-weight_min_lb = 0.5
weight_max_lb = 15
display_scale_min = 0.85
display_scale_max = 1.7
diff --git a/fishing/bass_catch_profile.tres b/fishing/bass_catch_profile.tres
index 6385eec..24024a7 100644
--- a/fishing/bass_catch_profile.tres
+++ b/fishing/bass_catch_profile.tres
@@ -6,8 +6,6 @@
script = ExtResource("1_profile")
barrier_count_min = 3
barrier_count_max = 4
-barrier_health_min = 4
-barrier_health_max = 7
first_barrier_margin = 0.14
final_barrier_margin = 0.1
minimum_barrier_spacing = 0.14
diff --git a/fishing/carp_catch_profile.tres b/fishing/carp_catch_profile.tres
index 94a8470..e1e0efe 100644
--- a/fishing/carp_catch_profile.tres
+++ b/fishing/carp_catch_profile.tres
@@ -6,8 +6,6 @@
script = ExtResource("1_profile")
barrier_count_min = 3
barrier_count_max = 4
-barrier_health_min = 5
-barrier_health_max = 8
first_barrier_margin = 0.13
final_barrier_margin = 0.09
minimum_barrier_spacing = 0.14
diff --git a/fishing/catch_controller.gd b/fishing/catch_controller.gd
index e051561..7e75370 100644
--- a/fishing/catch_controller.gd
+++ b/fishing/catch_controller.gd
@@ -69,8 +69,6 @@ var _reel_input_held: bool = false
var _reel_speed: float = 0.0
var _click_power: int = 1
var _fish_quality: int = FishQualityType.Tier.BORING
-var _fish_rarity: int = 0
-var _fish_weight_percentile: float = 0.0
var _chase_delay_remaining: float = 0.0
var _failure_epsilon: float = 0.0001
var _auto_click_accumulator: float = 0.0
@@ -113,8 +111,6 @@ func start_encounter(
reel_speed: float,
click_power: int,
fish_quality: int = FishQualityType.Tier.BORING,
- fish_rarity: int = 0,
- fish_weight_percentile: float = 0.0,
) -> void:
reset()
if profile == null:
@@ -128,8 +124,6 @@ func start_encounter(
if FishQualityType.is_valid(fish_quality)
else FishQualityType.Tier.BORING
)
- _fish_rarity = clampi(fish_rarity, 0, 4)
- _fish_weight_percentile = clampf(fish_weight_percentile, 0.0, 1.0)
_chase_delay_remaining = CHASE_START_DELAY
chase_progress = -CHASE_START_OFFSET
_seed_encounter_rng()
@@ -143,22 +137,18 @@ func start_authoritative_encounter(
profile: CatchDifficultyProfileType,
reel_speed: float,
click_power: int,
- seed: int,
+ encounter_seed_value: int,
fish_quality: int = FishQualityType.Tier.BORING,
- fish_rarity: int = 0,
- fish_weight_percentile: float = 0.0,
) -> void:
var previous_test_mode: bool = use_deterministic_test_seed
var previous_seed: int = deterministic_test_seed
use_deterministic_test_seed = true
- deterministic_test_seed = seed
+ deterministic_test_seed = encounter_seed_value
start_encounter(
profile,
reel_speed,
click_power,
fish_quality,
- fish_rarity,
- fish_weight_percentile,
)
use_deterministic_test_seed = previous_test_mode
deterministic_test_seed = previous_seed
@@ -327,11 +317,8 @@ func _generate_barriers(profile: CatchDifficultyProfileType) -> void:
+ spacing * float(barrier_index)
+ random_offsets[barrier_index] * random_slack
)
- var health: int = FishQualityType.barrier_health_for_catch(
- _fish_quality,
- _fish_rarity,
- _fish_weight_percentile,
- _rng.randf_range(0.9, 1.1),
+ var health: int = FishQualityType.roll_barrier_health(
+ _rng, _fish_quality
)
_barriers.append(Barrier.new(position, health))
diff --git a/fishing/catch_difficulty_profile.gd b/fishing/catch_difficulty_profile.gd
index bd2508c..60aa190 100644
--- a/fishing/catch_difficulty_profile.gd
+++ b/fishing/catch_difficulty_profile.gd
@@ -3,8 +3,6 @@ extends Resource
@export_range(0, 12, 1) var barrier_count_min: int = 2
@export_range(0, 12, 1) var barrier_count_max: int = 4
-@export_range(1, 100, 1) var barrier_health_min: int = 3
-@export_range(1, 100, 1) var barrier_health_max: int = 7
@export_range(0.0, 0.45, 0.01) var first_barrier_margin: float = 0.15
@export_range(0.0, 0.45, 0.01) var final_barrier_margin: float = 0.10
@export_range(0.01, 1.0, 0.01) var minimum_barrier_spacing: float = 0.15
@@ -15,11 +13,6 @@ func get_barrier_count_range() -> Vector2i:
return Vector2i(minimum, maxi(minimum, barrier_count_max))
-func get_barrier_health_range() -> Vector2i:
- var minimum: int = maxi(1, barrier_health_min)
- return Vector2i(minimum, maxi(minimum, barrier_health_max))
-
-
func get_generation_interval() -> Vector2:
var start: float = clampf(first_barrier_margin, 0.0, 0.95)
var finish: float = clampf(1.0 - final_barrier_margin, start, 1.0)
diff --git a/fishing/common_catch_profile.tres b/fishing/common_catch_profile.tres
index 4af3284..86c2b74 100644
--- a/fishing/common_catch_profile.tres
+++ b/fishing/common_catch_profile.tres
@@ -6,8 +6,6 @@
script = ExtResource("1_profile")
barrier_count_min = 2
barrier_count_max = 4
-barrier_health_min = 3
-barrier_health_max = 7
first_barrier_margin = 0.15
final_barrier_margin = 0.1
minimum_barrier_spacing = 0.15
diff --git a/fishing/fishing_presentation.gd b/fishing/fishing_presentation.gd
index 09ed554..71fedac 100644
--- a/fishing/fishing_presentation.gd
+++ b/fishing/fishing_presentation.gd
@@ -1,6 +1,10 @@
class_name FishingPresentation
extends Node3D
+const WaterSurfaceMotionType = preload(
+ "res://world/water_surface_motion.gd"
+)
+
signal cast_completed
signal outcome_completed(outcome: StringName)
signal presentation_interrupted
@@ -25,6 +29,7 @@ enum LineMode {
@export_range(0.0, 3.0, 0.01) var maximum_slack: float = 0.65
@export_range(2, 20, 1) var sag_interpolation_count: int = 8
@export_range(0.1, 30.0, 0.1) var line_transition_speed: float = 7.0
+@export_range(0.002, 0.05, 0.001) var line_thickness: float = 0.016
@export_category("Cast")
@export_range(0.1, 3.0, 0.05) var cast_travel_duration: float = 0.65
@@ -52,8 +57,11 @@ var _rod: Node3D
var _rod_tip: Marker3D
var _rod_neutral_rotation: Vector3
var _cast_arrival_position: Vector3
+var _active_cast_arc_height: float = 0.0
+var _cast_tracks_water_surface: bool = false
var _bobber_surface_position: Vector3
var _bobber_idle_elapsed: float = 0.0
+var _bobber_base_scale: Vector3 = Vector3.ONE
var _active_tween: Tween
var _rod_tween: Tween
var _bite_tween: Tween
@@ -68,6 +76,9 @@ func _process(delta: float) -> void:
if _mode == VisualMode.FISHING and _bobber.visible:
_bobber_idle_elapsed += delta
_apply_bobber_idle_motion()
+ var bobber_position := _bobber.global_position
+ bobber_position.y += WaterSurfaceMotionType.get_default_height_offset()
+ _bobber.global_position = bobber_position
if _line_mode != LineMode.HIDDEN:
_update_line(delta)
@@ -86,11 +97,13 @@ func begin_aim(
minimum_target: Vector3,
target_normal: Vector3,
target_is_fishable: bool,
+ character_scale: float = 1.0,
) -> void:
cleanup()
if rod_tip == null or rod == null:
return
+ _bobber_base_scale = Vector3.ONE * maxf(character_scale, 0.01)
_mode = VisualMode.AIMING
_rod = rod
_rod_tip = rod_tip
@@ -142,6 +155,7 @@ func begin_cast(
target: Vector3,
blocked_landing_position: Vector3 = Vector3.ZERO,
cast_is_blocked: bool = false,
+ resolved_arc_height: float = -1.0,
) -> void:
if _mode != VisualMode.AIMING or _rod_tip == null:
return
@@ -150,10 +164,16 @@ func begin_cast(
_mode = VisualMode.CASTING
_target_marker.visible = false
_bobber.visible = true
- _bobber.scale = Vector3.ONE
+ _bobber.scale = _bobber_base_scale
_cast_arrival_position = (
blocked_landing_position if cast_is_blocked else target
)
+ _active_cast_arc_height = (
+ maxf(resolved_arc_height, 0.0)
+ if resolved_arc_height >= 0.0
+ else cast_arc_height
+ )
+ _cast_tracks_water_surface = not cast_is_blocked
var cast_start: Vector3 = _rod_tip.global_position
_bobber.global_position = cast_start
@@ -179,26 +199,26 @@ func show_bite() -> void:
return
_kill_bite_tween()
- _bobber.scale = Vector3.ONE
+ _bobber.scale = _bobber_base_scale
_bite_tween = create_tween()
_bite_tween.set_trans(Tween.TRANS_QUAD)
_bite_tween.set_ease(Tween.EASE_IN_OUT)
_bite_tween.tween_property(
_bobber,
"scale",
- Vector3.ONE * 0.68,
+ _bobber_base_scale * 0.68,
0.08
)
_bite_tween.tween_property(
_bobber,
"scale",
- Vector3.ONE * 1.2,
+ _bobber_base_scale * 1.2,
0.1
)
_bite_tween.tween_property(
_bobber,
"scale",
- Vector3.ONE,
+ _bobber_base_scale,
0.1
)
_bite_tween.finished.connect(_on_bite_tween_finished)
@@ -238,7 +258,7 @@ func play_outcome(outcome: StringName) -> void:
# Withdrawal is a visible return, not an instant cancellation. Keep the
# bobber present even if the preceding reel update hid or reset it.
_bobber.visible = true
- _bobber.scale = Vector3.ONE
+ _bobber.scale = _bobber_base_scale
_active_tween = create_tween()
_active_tween.set_trans(Tween.TRANS_QUAD)
_active_tween.set_ease(Tween.EASE_IN)
@@ -287,8 +307,11 @@ func cleanup() -> void:
_invalid_target_marker.visible = false
_bobber.visible = false
_bobber.scale = Vector3.ONE
+ _bobber_base_scale = Vector3.ONE
_bobber.rotation = Vector3.ZERO
_cast_arrival_position = Vector3.ZERO
+ _active_cast_arc_height = 0.0
+ _cast_tracks_water_surface = false
_bobber_surface_position = Vector3.ZERO
_bobber_idle_elapsed = 0.0
set_line_mode(LineMode.HIDDEN)
@@ -305,7 +328,12 @@ func _set_cast_sample(
target: Vector3,
) -> void:
var sample: Vector3 = start.lerp(target, progress)
- sample.y += sin(progress * PI) * cast_arc_height
+ sample.y += sin(progress * PI) * _active_cast_arc_height
+ if _cast_tracks_water_surface:
+ sample.y += (
+ WaterSurfaceMotionType.get_default_height_offset()
+ * smoothstep(0.72, 1.0, progress)
+ )
_bobber.global_position = sample
@@ -390,10 +418,51 @@ func _update_line(delta: float) -> void:
_line_mesh.clear_surfaces()
if rendered_points.size() < 2:
return
- _line_mesh.surface_begin(Mesh.PRIMITIVE_LINES)
- for point_index: int in range(1, rendered_points.size()):
- _line_mesh.surface_add_vertex(to_local(rendered_points[point_index - 1]))
- _line_mesh.surface_add_vertex(to_local(rendered_points[point_index]))
+ _draw_line_ribbon(rendered_points)
+
+
+func _draw_line_ribbon(points: PackedVector3Array) -> void:
+ var camera: Camera3D = get_viewport().get_camera_3d()
+ if camera == null:
+ _line_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP)
+ for point: Vector3 in points:
+ _line_mesh.surface_add_vertex(to_local(point))
+ _line_mesh.surface_end()
+ return
+
+ var half_thickness: float = line_thickness * 0.5
+ var ribbon_vertices := PackedVector3Array()
+ for point_index: int in range(1, points.size()):
+ var start: Vector3 = points[point_index - 1]
+ var end: Vector3 = points[point_index]
+ var segment: Vector3 = end - start
+ if segment.length_squared() <= 0.000001:
+ continue
+ var to_camera: Vector3 = (
+ camera.global_position - start.lerp(end, 0.5)
+ )
+ var side: Vector3 = segment.normalized().cross(to_camera.normalized())
+ if side.length_squared() <= 0.000001:
+ side = segment.normalized().cross(Vector3.UP)
+ if side.length_squared() <= 0.000001:
+ side = segment.normalized().cross(Vector3.RIGHT)
+ side = side.normalized() * half_thickness
+
+ var start_left: Vector3 = to_local(start - side)
+ var start_right: Vector3 = to_local(start + side)
+ var end_right: Vector3 = to_local(end + side)
+ var end_left: Vector3 = to_local(end - side)
+ ribbon_vertices.append(start_left)
+ ribbon_vertices.append(start_right)
+ ribbon_vertices.append(end_right)
+ ribbon_vertices.append(start_left)
+ ribbon_vertices.append(end_right)
+ ribbon_vertices.append(end_left)
+ if ribbon_vertices.is_empty():
+ return
+ _line_mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
+ for vertex: Vector3 in ribbon_vertices:
+ _line_mesh.surface_add_vertex(vertex)
_line_mesh.surface_end()
@@ -460,7 +529,7 @@ func _kill_bite_tween() -> void:
_bite_tween.kill()
_bite_tween = null
if is_instance_valid(_bobber):
- _bobber.scale = Vector3.ONE
+ _bobber.scale = _bobber_base_scale
func _on_bite_tween_finished() -> void:
diff --git a/fishing/fishing_spot.gd b/fishing/fishing_spot.gd
index 8062de5..167a08b 100644
--- a/fishing/fishing_spot.gd
+++ b/fishing/fishing_spot.gd
@@ -47,6 +47,7 @@ const WorldWeatherServiceType = preload(
)
signal status_changed(status: String)
+signal local_speech_requested(message: String)
signal catch_display_changed(
progress: float,
chase_progress: float,
@@ -64,9 +65,8 @@ signal showcase_changed(
visible: bool,
)
signal bite_activated
+signal bite_prompt_changed(is_visible: bool)
signal ready_for_equipment_refresh
-signal fish_showcase_toggle_requested
-signal art_ui_toggle_requested
enum FishingState {
READY,
@@ -100,14 +100,14 @@ enum FishingState {
@export_range(0.0, 1.0, 0.01) var withdrawal_surface_clearance: float = 0.4
@export_category("Timing")
-const BITE_QUICK_MIN_SECONDS: float = 8.0
-const BITE_QUICK_MAX_SECONDS: float = 24.0
-const BITE_TYPICAL_MAX_SECONDS: float = 72.0
-const BITE_LONG_MAX_SECONDS: float = 144.0
-const BITE_MAX_SECONDS: float = 192.0
-const BITE_QUICK_PROBABILITY: float = 0.25
+const BITE_QUICK_MIN_SECONDS: float = 6.0
+const BITE_QUICK_MAX_SECONDS: float = 18.0
+const BITE_TYPICAL_MAX_SECONDS: float = 48.0
+const BITE_LONG_MAX_SECONDS: float = 72.0
+const BITE_MAX_SECONDS: float = 90.0
+const BITE_QUICK_PROBABILITY: float = 0.30
const BITE_TYPICAL_PROBABILITY: float = 0.65
-const BITE_LONG_PROBABILITY: float = 0.08
+const BITE_LONG_PROBABILITY: float = 0.04
const NETWORK_INPUT_RESEND_INTERVAL_SECONDS: float = 0.1
@export_range(0.1, 10.0, 0.1) var cooldown_duration: float = 1.0
@@ -151,6 +151,7 @@ var _cast_charge: float = 0.0
var _cast_direction: Vector3 = Vector3.FORWARD
var _cast_origin_position: Vector3
var _cast_target: Vector3
+var _preferred_cast_arc_height: float = -1.0
var _withdrawal_endpoint: Vector3
var _withdrawal_progress: float = 0.0
var _withdrawal_input_held: bool = false
@@ -175,6 +176,8 @@ var _network_auto_click_accumulator: float = 0.0
var _network_active_barrier_index: int = -1
var _bite_rng: RandomNumberGenerator = RandomNumberGenerator.new()
var _pending_cleanup_message: String = ""
+var _bite_confirmation_pending: bool = false
+var _bite_confirmation_requested: bool = false
func _ready() -> void:
@@ -251,6 +254,9 @@ func setup(
_network_fishing.local_bite_started.connect(
_on_network_bite_started
)
+ _network_fishing.local_bite_pending.connect(
+ _on_network_bite_pending
+ )
_network_fishing.local_snapshot_received.connect(
_on_network_fishing_snapshot
)
@@ -355,15 +361,15 @@ func handle_escape_action() -> bool:
func set_local_menu_input_suppressed(
- owner: StringName,
+ input_owner: StringName,
suppressed: bool,
) -> void:
- if owner.is_empty():
+ if input_owner.is_empty():
return
if suppressed:
- _local_menu_input_owners[owner] = true
+ _local_menu_input_owners[input_owner] = true
else:
- _local_menu_input_owners.erase(owner)
+ _local_menu_input_owners.erase(input_owner)
if suppressed and state == FishingState.WAITING_FOR_BITE:
_withdrawal_input_held = false
_stop_reeling_audio()
@@ -395,6 +401,11 @@ func begin_water_recovery() -> void:
FishingState.FIGHTING,
]:
_cancel_attempt()
+ # Recovery replaces the normal rod-return presentation. Finish the local
+ # cleanup now so its temporary movement lock is not captured and restored
+ # after the player respawns.
+ if state != FishingState.READY:
+ _finalize_attempt_cleanup("")
elif state == FishingState.SHOWING_CATCH:
_secure_showcase_catch_for_recovery()
@@ -497,31 +508,28 @@ func _unhandled_input(event: InputEvent) -> void:
FishingState.READY:
if not _new_cast_press_armed:
return
- if (
- _local_hotbar != null
- and not _local_hotbar.get_selected_fish_catch_id().is_empty()
- ):
- fish_showcase_toggle_requested.emit()
- get_viewport().set_input_as_handled()
- return
var active_item: ItemDataType = _get_active_item()
if (
active_item != null
- and active_item.item_id == ArtShopStockType.ART_KIT_ITEM_ID
- ):
- art_ui_toggle_requested.emit()
- get_viewport().set_input_as_handled()
- return
- if (
- active_item != null
- and active_item.category == ItemDataType.Category.CONSUMABLE
+ and (
+ active_item.category == ItemDataType.Category.CONSUMABLE
+ or (
+ active_item.item_id == PlayerItemEffectsType.FISH_FINDER_ID
+ )
+ )
):
if _network_item_use != null:
_network_item_use.request_use(active_item.item_id)
- elif _item_effects.use_consumable(active_item, _local_bag):
+ elif _item_effects.use_item(active_item, _local_bag):
status_changed.emit(_item_effects.get_feedback(
active_item.item_id
))
+ elif (
+ active_item.item_id == PlayerItemEffectsType.FISH_FINDER_ID
+ ):
+ local_speech_requested.emit(
+ PlayerItemEffectsType.FISH_FINDER_DEAD_MESSAGE
+ )
get_viewport().set_input_as_handled()
return
if not has_active_fishing_rod():
@@ -552,6 +560,10 @@ func _unhandled_input(event: InputEvent) -> void:
else:
return
FishingState.WAITING_FOR_BITE:
+ if _bite_confirmation_pending:
+ confirm_pending_bite()
+ get_viewport().set_input_as_handled()
+ return
_withdrawal_input_held = true
_start_reeling_audio()
if _network_fishing != null:
@@ -568,6 +580,9 @@ func _unhandled_input(event: InputEvent) -> void:
_confirm_cast()
get_viewport().set_input_as_handled()
elif state == FishingState.WAITING_FOR_BITE:
+ if _bite_confirmation_pending:
+ get_viewport().set_input_as_handled()
+ return
_withdrawal_input_held = false
_stop_reeling_audio()
if _network_fishing != null:
@@ -596,8 +611,12 @@ func _begin_aiming(player: PlayerType) -> void:
_cast_charge = 0.0
_cast_target = _calculate_cast_target(minimum_cast_distance)
state = FishingState.AIMING_CAST
+ _active_player.set_casting_visual()
status_changed.emit("")
- _cast_path_is_clear = is_cast_path_clear(_cast_origin_position, _cast_target)
+ _cast_path_is_clear = is_cast_path_clear(
+ _get_cast_launch_position(),
+ _cast_target,
+ )
var target_is_fishable: bool = (
_aim_surface_sample.is_fishable() and _cast_path_is_clear
)
@@ -609,7 +628,8 @@ func _begin_aiming(player: PlayerType) -> void:
_active_player.get_fishing_rod(),
preview_position,
_aim_surface_sample.normal,
- target_is_fishable
+ target_is_fishable,
+ _active_player.get_character_visual_scale(),
)
@@ -681,6 +701,28 @@ func is_fighting() -> bool:
return state == FishingState.FIGHTING
+func confirm_pending_bite() -> void:
+ if state != FishingState.WAITING_FOR_BITE or not _bite_confirmation_pending:
+ return
+ _bite_confirmation_requested = true
+ if _network_fishing != null:
+ _network_primary_input_held = false
+ _network_input_resend_elapsed = 0.0
+ _network_fishing.submit_local_input(false, true)
+ else:
+ _activate_bite(true)
+
+
+func _set_bite_confirmation_pending(is_pending: bool) -> void:
+ if _bite_confirmation_pending == is_pending:
+ if not is_pending:
+ _bite_confirmation_requested = false
+ return
+ _bite_confirmation_pending = is_pending
+ _bite_confirmation_requested = false
+ bite_prompt_changed.emit(is_pending)
+
+
func is_returning() -> bool:
return state == FishingState.RETURNING
@@ -702,7 +744,10 @@ func _update_cast_charge(delta: float) -> void:
var maximum_distance: float = maxf(minimum_cast_distance, maximum_cast_distance)
var distance: float = lerpf(minimum_cast_distance, maximum_distance, _cast_charge)
_cast_target = _calculate_cast_target(distance)
- _cast_path_is_clear = is_cast_path_clear(_cast_origin_position, _cast_target)
+ _cast_path_is_clear = is_cast_path_clear(
+ _get_cast_launch_position(),
+ _cast_target,
+ )
var target_is_fishable: bool = (
_aim_surface_sample.is_fishable() and _cast_path_is_clear
)
@@ -722,29 +767,45 @@ func _confirm_cast() -> void:
if state != FishingState.AIMING_CAST:
return
- _cast_path_is_clear = is_cast_path_clear(
- _cast_origin_position,
+ var cast_launch_position := _get_cast_launch_position()
+ var resolved_cast_arc: Dictionary = _surface_resolver.resolve_cast_arc(
+ get_world_3d().direct_space_state,
+ cast_launch_position,
_cast_target,
+ _presentation.cast_arc_height,
)
+ var resolved_arc_height: float = float(
+ resolved_cast_arc.get("arc_height", _presentation.cast_arc_height)
+ )
+ var resolved_cast_collision: Dictionary = resolved_cast_arc.get(
+ "collision",
+ {},
+ )
+ _cast_path_is_clear = resolved_cast_collision.is_empty()
var cast_is_invalid: bool = (
not _aim_surface_sample.is_fishable() or not _cast_path_is_clear
)
var arrival_position: Vector3 = _cast_target
if not _cast_path_is_clear:
- arrival_position = _resolve_cast_impact_position(
- _cast_origin_position,
+ var collision_position: Variant = resolved_cast_collision.get(
+ "position",
_cast_target,
)
+ if typeof(collision_position) == TYPE_VECTOR3:
+ arrival_position = collision_position
if _active_player != null:
# Movement is available while aiming, then locks once the cast is
# released so the active bobber/fishing event remains anchored.
_active_player.set_movement_enabled(false)
state = FishingState.CASTING
+ if _active_player != null:
+ _active_player.set_release_visual()
status_changed.emit("")
_presentation.begin_cast(
_cast_target,
arrival_position,
cast_is_invalid,
+ resolved_arc_height,
)
_presentation.set_line_mode(FishingPresentationType.LineMode.TAUT)
@@ -790,6 +851,7 @@ func _on_cast_completed() -> void:
_consume_active_bait()
state = FishingState.WAITING_FOR_BITE
+ _active_player.set_fishing_visual(true)
_state_time_remaining = roll_bite_wait_time() * (
_item_effects.get_bite_time_multiplier()
if _item_effects != null
@@ -806,7 +868,7 @@ func _on_cast_completed() -> void:
_cast_origin_position.z + _cast_direction.z * withdrawal_cancel_distance
)
_presentation.set_line_mode(FishingPresentationType.LineMode.SLACK)
- status_changed.emit("waiting for a bite...")
+ status_changed.emit("")
func _consume_active_bait() -> void:
@@ -844,6 +906,8 @@ func roll_bite_wait_time() -> float:
func _update_waiting_for_bite(delta: float) -> void:
+ if _bite_confirmation_pending:
+ return
if (
_withdrawal_input_held
and not Input.is_action_pressed("fish_primary")
@@ -938,7 +1002,7 @@ func _get_withdrawable_distance() -> float:
return landing_offset.length() - withdrawal_cancel_distance
-func _activate_bite() -> void:
+func _activate_bite(confirmation_override: bool = false) -> void:
if state != FishingState.WAITING_FOR_BITE:
return
@@ -950,8 +1014,21 @@ func _activate_bite() -> void:
):
_cancel_attempt()
return
+ if (
+ not confirmation_override
+ and _active_lure_has_effect(&"deferred_fight")
+ ):
+ _state_time_remaining = 0.0
+ _withdrawal_input_held = false
+ _set_bite_confirmation_pending(true)
+ status_changed.emit("")
+ _presentation.set_line_mode(FishingPresentationType.LineMode.TAUT)
+ _presentation.show_bite()
+ return
+ _set_bite_confirmation_pending(false)
state = FishingState.FIGHTING
+ _active_player.set_fighting_visual(true)
_state_time_remaining = 0.0
_withdrawal_input_held = false
_pending_catch = _fish_selector.create_catch(_selected_fish)
@@ -968,8 +1045,6 @@ func _activate_bite() -> void:
_get_effective_reel_speed(),
_get_effective_barrier_damage(),
_pending_catch.quality,
- int(_pending_catch.fish.rarity),
- _pending_catch.fish.get_weight_percentile(_pending_catch.weight_lb),
)
_catch_controller.set_reel_input(
Input.is_action_pressed("fish_primary")
@@ -1012,7 +1087,7 @@ func _on_catch_encounter_updated(
barrier_health: PackedInt32Array,
barrier_max_health: PackedInt32Array,
active_barrier_index: int,
- visible: bool,
+ encounter_visible: bool,
) -> void:
catch_display_changed.emit(
progress,
@@ -1021,9 +1096,9 @@ func _on_catch_encounter_updated(
barrier_health,
barrier_max_health,
active_barrier_index,
- visible
+ encounter_visible
)
- if state != FishingState.FIGHTING or not visible:
+ if state != FishingState.FIGHTING or not encounter_visible:
return
@@ -1040,6 +1115,8 @@ func _on_catch_completed() -> void:
_cancel_attempt()
return
_stop_fight_audio()
+ _active_player.set_fighting_visual(false)
+ _active_player.set_retract_visual()
state = FishingState.SHOWING_CATCH
_showcase_ready = false
_showcase_outcome_completed = false
@@ -1054,13 +1131,16 @@ func _on_catch_escaped() -> void:
return
_stop_fight_audio()
- var fish_name: String = "the fish"
- if _selected_fish != null and not _selected_fish.display_name.is_empty():
- fish_name = "the %s" % _selected_fish.display_name
- _cleanup_attempt("%s got away!" % fish_name, &"escape")
+ _cleanup_attempt("", &"escape")
func _on_outcome_completed(outcome: StringName) -> void:
+ var retracting_player := _active_player
+ if (
+ retracting_player != null
+ and not retracting_player.is_retract_visual_complete()
+ ):
+ await retracting_player.retract_visual_finished
if state == FishingState.RETURNING:
var cleanup_message: String = _pending_cleanup_message
_pending_cleanup_message = ""
@@ -1160,8 +1240,20 @@ func _cleanup_attempt(
cooldown_message: String = "",
visual_outcome: StringName = &"",
) -> void:
+ _set_bite_confirmation_pending(false)
_stop_fight_audio()
_stop_reeling_audio()
+ if _active_player != null:
+ _active_player.set_fighting_visual(false)
+ if visual_outcome.is_empty():
+ _active_player.set_fishing_visual(false)
+ elif visual_outcome == &"catch":
+ # A successful catch already retracted the line before the fish
+ # showcase. Returning from the pocket transition should settle back
+ # to idle instead of replaying the retract animation.
+ _active_player.set_fishing_visual(false)
+ else:
+ _active_player.set_retract_visual()
if not visual_outcome.is_empty():
if state == FishingState.RETURNING:
return
@@ -1190,6 +1282,8 @@ func _cleanup_attempt(
func _finalize_attempt_cleanup(cooldown_message: String) -> void:
_showcase_restore_generation += 1
if _active_player != null:
+ _active_player.set_fighting_visual(false)
+ _active_player.set_fishing_visual(false)
_active_player.end_catch_showcase()
_active_player.set_movement_enabled(true)
_active_player = null
@@ -1272,6 +1366,14 @@ func _capture_cast_direction(player: PlayerType) -> Vector3:
return direction.normalized()
+func _get_cast_launch_position() -> Vector3:
+ if _active_player != null:
+ var rod_tip: Marker3D = _active_player.get_fishing_rod_tip()
+ if rod_tip != null and is_instance_valid(rod_tip):
+ return rod_tip.global_position
+ return _cast_origin_position
+
+
func _calculate_cast_target(distance: float) -> Vector3:
var query_position := Vector3(
_cast_origin_position.x + _cast_direction.x * distance,
@@ -1317,6 +1419,7 @@ func resolve_fishing_surface(
get_world_3d().direct_space_state,
target,
resolved_reference_y,
+ water_occlusion_tolerance,
)
@@ -1327,17 +1430,25 @@ func is_target_fishable(target: Vector3) -> bool:
func _is_cast_target_valid(target: Vector3) -> bool:
return (
is_target_fishable(target)
- and is_cast_path_clear(_cast_origin_position, target)
+ and is_cast_path_clear(_get_cast_launch_position(), target)
)
func is_cast_path_clear(origin: Vector3, target: Vector3) -> bool:
- return _surface_resolver.find_first_cast_collision(
+ if _preferred_cast_arc_height < 0.0:
+ _preferred_cast_arc_height = maxf(
+ _presentation.cast_arc_height,
+ 0.0,
+ )
+ var resolved_arc: Dictionary = _surface_resolver.resolve_cast_arc(
get_world_3d().direct_space_state,
origin,
target,
- _presentation.cast_arc_height,
- ).is_empty()
+ _preferred_cast_arc_height,
+ )
+ _presentation.cast_arc_height = float(resolved_arc["arc_height"])
+ var collision: Dictionary = resolved_arc["collision"]
+ return collision.is_empty()
func _resolve_cast_impact_position(origin: Vector3, target: Vector3) -> Vector3:
@@ -1404,6 +1515,21 @@ func _get_active_bait_tags() -> Array[StringName]:
return item.bait_tags.duplicate() if item != null and item.is_bait() else []
+func _active_lure_has_effect(effect_id: StringName) -> bool:
+ if (
+ _local_player == null
+ or _item_catalog == null
+ or _local_bag == null
+ or _local_player.active_lure_id.is_empty()
+ or not _local_bag.owns_item(_local_player.active_lure_id)
+ ):
+ return false
+ var lure: ItemDataType = _item_catalog.get_item_by_id(
+ _local_player.active_lure_id
+ )
+ return lure != null and lure.is_lure() and effect_id in lure.lure_effects
+
+
func _build_network_evidence() -> Dictionary:
var rarity_multipliers: Array[float] = []
for rarity: int in range(FishDataType.Rarity.size()):
@@ -1415,6 +1541,7 @@ func _build_network_evidence() -> Dictionary:
var item: ItemDataType = _get_active_item()
return {
"bait_id": str(_active_player.active_bait_id),
+ "lure_id": str(_active_player.active_lure_id),
"rod_id": str(item.item_id) if item != null else "",
"reel_speed": _active_player.reel_speed * (
_fishing_upgrades.get_reel_speed_multiplier()
@@ -1435,6 +1562,13 @@ func _on_network_item_use_finished(
accepted: bool,
message: String,
) -> void:
+ if (
+ not accepted
+ and message == PlayerItemEffectsType.FISH_FINDER_DEAD_MESSAGE
+ ):
+ status_changed.emit("")
+ local_speech_requested.emit(message)
+ return
status_changed.emit(message)
if accepted:
refresh_active_item_status()
@@ -1445,15 +1579,22 @@ func _on_network_cast_accepted(
target: Vector3,
) -> void:
if state != FishingState.CASTING:
+ # A cast response can arrive after water recovery has already cancelled
+ # its local presentation. Do not leave that late authoritative attempt
+ # alive with its movement lock still applied.
+ if _network_fishing != null and _network_fishing.has_local_attempt():
+ _network_fishing.cancel_local_attempt("")
return
_cast_target = target
_bobber_water_position = target
state = FishingState.WAITING_FOR_BITE
+ if _active_player != null:
+ _active_player.set_fishing_visual(true)
_network_primary_input_held = false
_network_input_resend_elapsed = 0.0
_presentation.show_withdrawal_position(_bobber_water_position)
_presentation.set_line_mode(FishingPresentationType.LineMode.SLACK)
- status_changed.emit("waiting for a bite...")
+ status_changed.emit("")
func _on_network_cast_rejected(message: String) -> void:
@@ -1472,11 +1613,27 @@ func _on_network_cast_rejected(message: String) -> void:
_cleanup_attempt(visible_message, &"invalid")
+func _on_network_bite_pending(_attempt_id: String) -> void:
+ if state != FishingState.WAITING_FOR_BITE:
+ return
+ _stop_reeling_audio()
+ _withdrawal_input_held = false
+ _network_primary_input_held = false
+ _network_input_resend_elapsed = 0.0
+ _set_bite_confirmation_pending(true)
+ status_changed.emit("")
+ _presentation.set_line_mode(FishingPresentationType.LineMode.TAUT)
+ _presentation.show_bite()
+
+
func _on_network_bite_started(_attempt_id: String) -> void:
if state != FishingState.WAITING_FOR_BITE:
return
_stop_reeling_audio()
+ _set_bite_confirmation_pending(false)
state = FishingState.FIGHTING
+ if _active_player != null:
+ _active_player.set_fighting_visual(true)
_withdrawal_input_held = false
_network_primary_input_held = Input.is_action_pressed("fish_primary")
_network_input_resend_elapsed = 0.0
@@ -1504,7 +1661,10 @@ func _resend_network_input_state(delta: float) -> void:
_network_input_resend_elapsed,
NETWORK_INPUT_RESEND_INTERVAL_SECONDS,
)
- _network_fishing.submit_local_input(_network_primary_input_held, false)
+ _network_fishing.submit_local_input(
+ false if _bite_confirmation_pending else _network_primary_input_held,
+ _bite_confirmation_pending and _bite_confirmation_requested,
+ )
func _on_network_fishing_snapshot(snapshot: Dictionary) -> void:
@@ -1567,6 +1727,9 @@ func _on_network_catch_received(fish_catch: FishCatchType) -> void:
return
_stop_fight_audio()
_pending_catch = fish_catch
+ if _active_player != null:
+ _active_player.set_fighting_visual(false)
+ _active_player.set_fishing_visual(false)
state = FishingState.SHOWING_CATCH
_showcase_ready = false
_showcase_outcome_completed = false
@@ -1576,6 +1739,8 @@ func _on_network_catch_received(fish_catch: FishCatchType) -> void:
PackedInt32Array(), -1, false
)
_presentation.set_line_mode(FishingPresentationType.LineMode.TAUT)
+ if _active_player != null:
+ _active_player.set_retract_visual()
_presentation.play_outcome(&"catch")
diff --git a/fishing/fishing_spot.tscn b/fishing/fishing_spot.tscn
index 09cf1ae..ef6d0bf 100644
--- a/fishing/fishing_spot.tscn
+++ b/fishing/fishing_spot.tscn
@@ -17,6 +17,7 @@ roughness = 0.45
[sub_resource type="StandardMaterial3D" id="LineMaterial"]
shading_mode = 0
+cull_mode = 2
albedo_color = Color(0.9, 0.9, 0.82, 1)
[sub_resource type="CylinderMesh" id="CastTargetMesh"]
diff --git a/fishing/fishing_surface_resolver.gd b/fishing/fishing_surface_resolver.gd
index 08818ce..821d8cc 100644
--- a/fishing/fishing_surface_resolver.gd
+++ b/fishing/fishing_surface_resolver.gd
@@ -23,6 +23,7 @@ func resolve_surface(
space_state: PhysicsDirectSpaceState3D,
query_position: Vector3,
reference_y: float,
+ maximum_solid_rise: float = INF,
) -> FishingSurfaceSampleType:
var sample := FishingSurfaceSampleType.new()
var ray_top: float = maxf(query_position.y, reference_y) + ray_start_height
@@ -33,12 +34,18 @@ func resolve_surface(
ray_top,
ray_bottom,
)
- var solid_hit: Dictionary = _find_top_solid_surface(
- space_state,
- query_position,
+ var solid_ray_top: float = minf(
ray_top,
- ray_bottom,
+ reference_y + maximum_solid_rise,
)
+ var solid_hit: Dictionary = {}
+ if solid_ray_top > ray_bottom:
+ solid_hit = _find_top_solid_surface(
+ space_state,
+ query_position,
+ solid_ray_top,
+ ray_bottom,
+ )
if water_region != null:
var water_height: float = water_region.get_surface_height()
@@ -101,6 +108,40 @@ func find_first_cast_collision(
return {}
+func resolve_cast_arc(
+ space_state: PhysicsDirectSpaceState3D,
+ origin: Vector3,
+ target: Vector3,
+ preferred_arc_height: float,
+) -> Dictionary:
+ var raised_arc_height: float = maxf(preferred_arc_height, 0.0)
+ var raised_collision := find_first_cast_collision(
+ space_state,
+ origin,
+ target,
+ raised_arc_height,
+ )
+ if raised_collision.is_empty() or is_zero_approx(raised_arc_height):
+ return {
+ "arc_height": raised_arc_height,
+ "collision": raised_collision,
+ }
+
+ # A canopy or pier roof can intersect the decorative raised arc even when
+ # the direct path out toward the water is unobstructed. Prefer that low cast
+ # instead of visibly sending the bobber and line upward into the ceiling.
+ var direct_collision := find_first_cast_collision(
+ space_state,
+ origin,
+ target,
+ 0.0,
+ )
+ return {
+ "arc_height": 0.0,
+ "collision": direct_collision,
+ }
+
+
func resolve_withdrawal_surface(
space_state: PhysicsDirectSpaceState3D,
current_position: Vector3,
diff --git a/fishing/fishing_surface_sample.gd b/fishing/fishing_surface_sample.gd
index 4d2dd2c..121658b 100644
--- a/fishing/fishing_surface_sample.gd
+++ b/fishing/fishing_surface_sample.gd
@@ -4,6 +4,9 @@ extends RefCounted
const FishableWaterRegionType = preload(
"res://world/fishable_water_region.gd"
)
+const WaterSurfaceMotionType = preload(
+ "res://world/water_surface_motion.gd"
+)
var has_surface: bool = false
var position: Vector3 = Vector3.ZERO
@@ -19,7 +22,12 @@ func is_fishable() -> bool:
func get_marker_position(vertical_offset: float) -> Vector3:
if not has_surface:
return position
- return position + normal.normalized() * vertical_offset
+ var presentation_offset := vertical_offset
+ if is_water_surface:
+ presentation_offset += (
+ WaterSurfaceMotionType.get_default_height_offset()
+ )
+ return position + normal.normalized() * presentation_offset
func get_bobber_position(solid_clearance: float) -> Vector3:
diff --git a/fishing/remote_fishing_presentation.gd b/fishing/remote_fishing_presentation.gd
index 6399819..5a5b05b 100644
--- a/fishing/remote_fishing_presentation.gd
+++ b/fishing/remote_fishing_presentation.gd
@@ -1,6 +1,11 @@
class_name RemoteFishingPresentation
extends Node3D
+const WaterSurfaceMotionType = preload(
+ "res://world/water_surface_motion.gd"
+)
+const LINE_THICKNESS: float = 0.016
+
signal return_completed
var _owner: Player
@@ -15,6 +20,7 @@ var _return_tween: Tween
var _showcase_tween: Tween
var _return_showcase_catch: FishCatch
var _bobber_idle_elapsed: float = 0.0
+var _bobber_base_scale: Vector3 = Vector3.ONE
func setup(owning_player: Player) -> void:
@@ -33,6 +39,7 @@ func setup(owning_player: Player) -> void:
_line.mesh = _line_mesh
var line_material := StandardMaterial3D.new()
line_material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
+ line_material.cull_mode = BaseMaterial3D.CULL_DISABLED
line_material.albedo_color = Color(0.9, 0.9, 0.82, 1.0)
_line.material_override = line_material
add_child(_line)
@@ -48,14 +55,16 @@ func show_cast(origin: Vector3, target: Vector3) -> void:
return
_kill_cast_tween()
_active = true
+ _bobber_base_scale = Vector3.ONE * _owner.get_character_visual_scale()
_target = origin
_pending_target = target
_bobber_idle_elapsed = 0.0
_bobber.global_position = origin
- _bobber.scale = Vector3.ONE
+ _bobber.scale = _bobber_base_scale
_bobber.visible = true
_line.visible = true
_owner.set_active_item_is_rod(true)
+ _owner.set_release_visual()
_redraw_line()
_cast_tween = create_tween()
_cast_tween.set_trans(Tween.TRANS_SINE)
@@ -83,12 +92,17 @@ func update_bobber(world_position: Vector3) -> void:
func show_bite() -> void:
if not _active:
return
+ if _owner != null and is_instance_valid(_owner):
+ _owner.set_fighting_visual(true)
var tween: Tween = create_tween()
- tween.tween_property(_bobber, "scale", Vector3.ONE * 0.7, 0.08)
- tween.tween_property(_bobber, "scale", Vector3.ONE, 0.12)
+ tween.tween_property(_bobber, "scale", _bobber_base_scale * 0.7, 0.08)
+ tween.tween_property(_bobber, "scale", _bobber_base_scale, 0.12)
func play_return(showcase_catch: FishCatch = null) -> void:
+ if _owner != null and is_instance_valid(_owner):
+ _owner.set_fighting_visual(false)
+ _owner.set_retract_visual()
if not _active or _bobber == null:
cleanup()
return_completed.emit()
@@ -124,10 +138,13 @@ func cleanup() -> void:
_return_showcase_catch = null
_bobber_idle_elapsed = 0.0
if _owner != null and is_instance_valid(_owner):
+ _owner.set_fighting_visual(false)
+ _owner.set_fishing_visual(false)
_owner.end_catch_showcase(Callable(), true)
if _bobber != null:
_bobber.visible = false
_bobber.scale = Vector3.ONE
+ _bobber_base_scale = Vector3.ONE
if _line != null:
_line.visible = false
_line_mesh.clear_surfaces()
@@ -140,19 +157,28 @@ func _set_cast_sample(
) -> void:
_target = start.lerp(target, progress)
_target.y += sin(progress * PI) * 2.0
+ _target.y += (
+ WaterSurfaceMotionType.get_default_height_offset()
+ * smoothstep(0.72, 1.0, progress)
+ )
_bobber.global_position = _target
func _on_cast_finished() -> void:
_cast_tween = null
_bobber_idle_elapsed = 0.0
+ if _owner != null and is_instance_valid(_owner):
+ _owner.set_fishing_visual(true)
_apply_bobber_idle_motion()
_redraw_line()
func _apply_bobber_idle_motion() -> void:
var phase: float = _bobber_idle_elapsed * 0.7 * TAU
- _target = _pending_target + Vector3.UP * sin(phase) * 0.035
+ _target = _pending_target + Vector3.UP * (
+ WaterSurfaceMotionType.get_default_height_offset()
+ + sin(phase) * 0.035
+ )
_bobber.global_position = _target
_bobber.rotation.z = deg_to_rad(4.0) * sin(phase * 0.73)
@@ -175,6 +201,12 @@ func _on_return_finished() -> void:
_bobber.visible = false
_line.visible = false
_line_mesh.clear_surfaces()
+ if (
+ _owner != null
+ and is_instance_valid(_owner)
+ and not _owner.is_retract_visual_complete()
+ ):
+ await _owner.retract_visual_finished
if (
_return_showcase_catch != null
and _owner != null
@@ -192,7 +224,12 @@ func _on_return_finished() -> void:
func _on_showcase_finished() -> void:
_showcase_tween = null
if _owner != null and is_instance_valid(_owner):
- _owner.end_catch_showcase()
+ _owner.end_catch_showcase(_on_showcase_put_away_finished)
+ return
+ _on_showcase_put_away_finished()
+
+
+func _on_showcase_put_away_finished() -> void:
return_completed.emit()
@@ -234,10 +271,50 @@ func _redraw_line() -> void:
if tip == null:
return
_line_mesh.clear_surfaces()
- _line_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP)
- _line_mesh.surface_add_vertex(to_local(tip.global_position))
var midpoint: Vector3 = tip.global_position.lerp(_target, 0.5)
midpoint.y -= 0.12
- _line_mesh.surface_add_vertex(to_local(midpoint))
- _line_mesh.surface_add_vertex(to_local(_target))
+ _draw_line_ribbon(PackedVector3Array([
+ tip.global_position,
+ midpoint,
+ _target,
+ ]))
+
+
+func _draw_line_ribbon(points: PackedVector3Array) -> void:
+ var camera: Camera3D = get_viewport().get_camera_3d()
+ if camera == null:
+ _line_mesh.surface_begin(Mesh.PRIMITIVE_LINE_STRIP)
+ for point: Vector3 in points:
+ _line_mesh.surface_add_vertex(to_local(point))
+ _line_mesh.surface_end()
+ return
+
+ var half_thickness: float = LINE_THICKNESS * 0.5
+ _line_mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
+ for point_index: int in range(1, points.size()):
+ var start: Vector3 = points[point_index - 1]
+ var end: Vector3 = points[point_index]
+ var segment: Vector3 = end - start
+ if segment.length_squared() <= 0.000001:
+ continue
+ var to_camera: Vector3 = (
+ camera.global_position - start.lerp(end, 0.5)
+ )
+ var side: Vector3 = segment.normalized().cross(to_camera.normalized())
+ if side.length_squared() <= 0.000001:
+ side = segment.normalized().cross(Vector3.UP)
+ if side.length_squared() <= 0.000001:
+ side = segment.normalized().cross(Vector3.RIGHT)
+ side = side.normalized() * half_thickness
+
+ var start_left: Vector3 = to_local(start - side)
+ var start_right: Vector3 = to_local(start + side)
+ var end_right: Vector3 = to_local(end + side)
+ var end_left: Vector3 = to_local(end - side)
+ _line_mesh.surface_add_vertex(start_left)
+ _line_mesh.surface_add_vertex(start_right)
+ _line_mesh.surface_add_vertex(end_right)
+ _line_mesh.surface_add_vertex(start_left)
+ _line_mesh.surface_add_vertex(end_right)
+ _line_mesh.surface_add_vertex(end_left)
_line_mesh.surface_end()
diff --git a/icon.svg b/icon.svg
deleted file mode 100644
index c6bbb7d..0000000
--- a/icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/icon.svg.import b/icon.svg.import
deleted file mode 100644
index 1b9da13..0000000
--- a/icon.svg.import
+++ /dev/null
@@ -1,43 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://cxpiqjwgff0xr"
-path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://icon.svg"
-dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/inventory/player_bag.gd b/inventory/player_bag.gd
index 1e885ee..4fc12b6 100644
--- a/inventory/player_bag.gd
+++ b/inventory/player_bag.gd
@@ -5,10 +5,15 @@ const ItemCatalogType = preload("res://items/item_catalog.gd")
const ItemDataType = preload("res://items/item_data.gd")
const OwnedItemType = preload("res://items/owned_item.gd")
+const DEFAULT_UNLOCKED_BAIT_IDS: Array[StringName] = [&"worms"]
+
signal contents_changed
var _catalog: ItemCatalogType
var _items: Array[OwnedItemType] = []
+var _unlocked_bait_ids: Array[StringName] = (
+ DEFAULT_UNLOCKED_BAIT_IDS.duplicate()
+)
func setup(catalog: ItemCatalogType) -> void:
@@ -27,6 +32,8 @@ func add_item(item_id: StringName, quantity: int = 1) -> bool:
owned.item_id = item_id
owned.quantity = quantity
_items.append(owned)
+ if item.is_bait() and not _unlocked_bait_ids.has(item_id):
+ _unlocked_bait_ids.append(item_id)
contents_changed.emit()
return true
@@ -85,6 +92,46 @@ func get_all_items() -> Array[OwnedItemType]:
return result
+func get_unlocked_bait_ids() -> Array[StringName]:
+ return _unlocked_bait_ids.duplicate()
+
+
+func is_bait_unlocked(item_id: StringName) -> bool:
+ return _unlocked_bait_ids.has(item_id)
+
+
+func get_unlocked_bait_items() -> Array[OwnedItemType]:
+ var result: Array[OwnedItemType] = []
+ for item_id: StringName in _unlocked_bait_ids:
+ var owned: OwnedItemType = get_owned_item(item_id)
+ if owned != null:
+ result.append(owned.duplicate_record())
+ continue
+ var empty_record := OwnedItemType.new()
+ empty_record.item_id = item_id
+ empty_record.quantity = 0
+ result.append(empty_record)
+ return result
+
+
+func replace_unlocked_bait_ids(item_ids: Array[StringName]) -> bool:
+ var validated: Array[StringName] = DEFAULT_UNLOCKED_BAIT_IDS.duplicate()
+ var seen: Dictionary[StringName, bool] = {}
+ for item_id: StringName in item_ids:
+ if item_id.is_empty() or seen.has(item_id):
+ return false
+ seen[item_id] = true
+ if validated.has(item_id):
+ continue
+ var item: ItemDataType = _resolve_valid_item(item_id)
+ if item == null or not item.is_bait():
+ return false
+ validated.append(item_id)
+ _unlocked_bait_ids = validated
+ contents_changed.emit()
+ return true
+
+
func replace_all_items(items: Array[OwnedItemType]) -> bool:
var validated: Array[OwnedItemType] = []
var seen: Dictionary[StringName, bool] = {}
diff --git a/items/catalog/art_kit.tres b/items/catalog/art_kit.tres
index 3bbc0f6..ee5b28e 100644
--- a/items/catalog/art_kit.tres
+++ b/items/catalog/art_kit.tres
@@ -1,7 +1,7 @@
[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
[ext_resource type="Script" path="res://items/item_data.gd" id="1_item"]
-[ext_resource type="Texture2D" path="res://items/icons/placeholder/art_kit.svg" id="2_icon"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit.png" id="2_icon"]
[resource]
script = ExtResource("1_item")
diff --git a/items/catalog/batteries.tres b/items/catalog/batteries.tres
new file mode 100644
index 0000000..9f26650
--- /dev/null
+++ b/items/catalog/batteries.tres
@@ -0,0 +1,15 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1_item"]
+
+[resource]
+script = ExtResource("1_item")
+item_id = &"batteries"
+display_name = "batteries"
+description = "replacement batteries for the fish finder."
+category = 3
+stackable = true
+max_stack = 99
+usable = false
+equippable = false
+hotbar_allowed = false
diff --git a/items/catalog/fish_finder.tres b/items/catalog/fish_finder.tres
index 4c6d4a2..a3fb6c4 100644
--- a/items/catalog/fish_finder.tres
+++ b/items/catalog/fish_finder.tres
@@ -7,10 +7,11 @@
script = ExtResource("1")
item_id = &"fish_finder"
display_name = "fish finder"
-description = "temporarily shortens bite waits and improves rarity weights."
-category = 3
+description = "uses one battery to temporarily shorten bite waits and improve rarity weights."
+category = 1
icon = ExtResource("2")
-stackable = true
-max_stack = 99
+stackable = false
+max_stack = 1
usable = true
+equippable = true
hotbar_allowed = true
diff --git a/items/catalog/item_catalog.tres b/items/catalog/item_catalog.tres
index 95f130e..43377ba 100644
--- a/items/catalog/item_catalog.tres
+++ b/items/catalog/item_catalog.tres
@@ -1,4 +1,4 @@
-[gd_resource type="Resource" script_class="ItemCatalog" load_steps=10 format=3]
+[gd_resource type="Resource" script_class="ItemCatalog" load_steps=18 format=3]
[ext_resource type="Script" path="res://items/item_catalog.gd" id="1_script"]
[ext_resource type="Resource" path="res://items/catalog/basic_fishing_rod.tres" id="2_rod"]
@@ -9,7 +9,15 @@
[ext_resource type="Resource" path="res://items/catalog/cooler_expansion.tres" id="7_cooler"]
[ext_resource type="Resource" path="res://items/catalog/art_kit.tres" id="8_art_kit"]
[ext_resource type="Resource" path="res://items/catalog/worms.tres" id="9_worms"]
+[ext_resource type="Resource" path="res://items/catalog/snails.tres" id="10_snails"]
+[ext_resource type="Resource" path="res://items/catalog/shrimp.tres" id="11_shrimp"]
+[ext_resource type="Resource" path="res://items/catalog/squid_chunks.tres" id="12_squid"]
+[ext_resource type="Resource" path="res://items/catalog/whole_anchovy.tres" id="13_anchovy"]
+[ext_resource type="Resource" path="res://items/catalog/whole_sardine.tres" id="14_sardine"]
+[ext_resource type="Resource" path="res://items/catalog/luminous_roe.tres" id="15_roe"]
+[ext_resource type="Resource" path="res://items/catalog/the_standby.tres" id="16_standby"]
+[ext_resource type="Resource" path="res://items/catalog/batteries.tres" id="17_batteries"]
[resource]
script = ExtResource("1_script")
-items = [ExtResource("2_rod"), ExtResource("3_coffee"), ExtResource("4_energy"), ExtResource("5_snack"), ExtResource("6_finder"), ExtResource("7_cooler"), ExtResource("8_art_kit"), ExtResource("9_worms")]
+items = [ExtResource("2_rod"), ExtResource("3_coffee"), ExtResource("4_energy"), ExtResource("5_snack"), ExtResource("6_finder"), ExtResource("7_cooler"), ExtResource("8_art_kit"), ExtResource("9_worms"), ExtResource("10_snails"), ExtResource("11_shrimp"), ExtResource("12_squid"), ExtResource("14_sardine"), ExtResource("13_anchovy"), ExtResource("15_roe"), ExtResource("16_standby"), ExtResource("17_batteries")]
diff --git a/items/catalog/luminous_roe.tres b/items/catalog/luminous_roe.tres
new file mode 100644
index 0000000..7814f42
--- /dev/null
+++ b/items/catalog/luminous_roe.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_roe_luminous.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"luminous_roe"
+display_name = "luminous roe"
+description = "rare glowing roe with the strongest rare catch odds."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_6"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/shrimp.tres b/items/catalog/shrimp.tres
new file mode 100644
index 0000000..e308163
--- /dev/null
+++ b/items/catalog/shrimp.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_shrimp.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"shrimp"
+display_name = "shrimp"
+description = "lively bait that noticeably improves rare catch chances."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_2"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/snails.tres b/items/catalog/snails.tres
new file mode 100644
index 0000000..12d4497
--- /dev/null
+++ b/items/catalog/snails.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_snail.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"snails"
+display_name = "snails"
+description = "slow-moving bait with a better chance for rarer catches."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_1"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/squid_chunks.tres b/items/catalog/squid_chunks.tres
new file mode 100644
index 0000000..dfe245f
--- /dev/null
+++ b/items/catalog/squid_chunks.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_squid.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"squid_chunks"
+display_name = "squid chunks"
+description = "rich cut bait that strongly favors rarer catches."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_3"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/the_standby.tres b/items/catalog/the_standby.tres
new file mode 100644
index 0000000..1fcc92e
--- /dev/null
+++ b/items/catalog/the_standby.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1_item"]
+
+[resource]
+script = ExtResource("1_item")
+item_id = &"the_standby"
+display_name = "The Standby"
+description = "holds a bite until you're ready to start the fight."
+category = 7
+lure_effects = Array[StringName]([&"deferred_fight"])
+stackable = false
+max_stack = 1
+usable = false
+equippable = true
+hotbar_allowed = false
diff --git a/items/catalog/whole_anchovy.tres b/items/catalog/whole_anchovy.tres
new file mode 100644
index 0000000..cbc60b6
--- /dev/null
+++ b/items/catalog/whole_anchovy.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_sardine.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"whole_anchovy"
+display_name = "sardine"
+description = "valuable oily schooling bait tuned for exceptional catches."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_5"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/whole_sardine.tres b/items/catalog/whole_sardine.tres
new file mode 100644
index 0000000..c5d0163
--- /dev/null
+++ b/items/catalog/whole_sardine.tres
@@ -0,0 +1,16 @@
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_minnow.png" id="2_icon"]
+
+[resource]
+script = ExtResource("1")
+item_id = &"whole_sardine"
+display_name = "minnow"
+description = "small live bait with high rare catch potential."
+icon = ExtResource("2_icon")
+category = 2
+bait_tags = Array[StringName]([&"bait_rarity_4"])
+stackable = true
+max_stack = 10
+hotbar_allowed = false
diff --git a/items/catalog/worms.tres b/items/catalog/worms.tres
index 32827f6..f01258e 100644
--- a/items/catalog/worms.tres
+++ b/items/catalog/worms.tres
@@ -1,14 +1,16 @@
-[gd_resource type="Resource" script_class="ItemData" load_steps=2 format=3]
+[gd_resource type="Resource" script_class="ItemData" load_steps=3 format=3]
[ext_resource type="Script" path="res://items/item_data.gd" id="1"]
+[ext_resource type="Texture2D" path="res://items/icons/bait/64_bait_worms.png" id="2_icon"]
[resource]
script = ExtResource("1")
item_id = &"worms"
display_name = "worms"
-description = "common bait. fills your tacklebox at the fishing shop."
+description = "basic bait that opens a small chance for rarer catches."
+icon = ExtResource("2_icon")
category = 2
-bait_tags = Array[StringName]([&"worm"])
+bait_tags = Array[StringName]([&"worm", &"bait_rarity_0"])
stackable = true
max_stack = 10
hotbar_allowed = false
diff --git a/items/icons/art/art_kit.png b/items/icons/art/art_kit.png
new file mode 100644
index 0000000..39bc32b
Binary files /dev/null and b/items/icons/art/art_kit.png differ
diff --git a/art/exported/environment/textures/grass.png.import b/items/icons/art/art_kit.png.import
similarity index 73%
rename from art/exported/environment/textures/grass.png.import
rename to items/icons/art/art_kit.png.import
index 9d7961f..053fd1f 100644
--- a/art/exported/environment/textures/grass.png.import
+++ b/items/icons/art/art_kit.png.import
@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
-uid="uid://b4n8bf4cgua4s"
-path="res://.godot/imported/grass.png-4d1108b11a421d9c16bd72fb0bc993d3.ctex"
+uid="uid://datu7j7tq2k3e"
+path="res://.godot/imported/art_kit.png-b54a66a446203c844f97c37241065423.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://art/exported/environment/textures/grass.png"
-dest_files=["res://.godot/imported/grass.png-4d1108b11a421d9c16bd72fb0bc993d3.ctex"]
+source_file="res://items/icons/art/art_kit.png"
+dest_files=["res://.godot/imported/art_kit.png-b54a66a446203c844f97c37241065423.ctex"]
[params]
diff --git a/items/icons/art/art_kit_eraser.png b/items/icons/art/art_kit_eraser.png
new file mode 100644
index 0000000..6eb3003
Binary files /dev/null and b/items/icons/art/art_kit_eraser.png differ
diff --git a/art/exported/environment/textures/dirt_wall.png.import b/items/icons/art/art_kit_eraser.png.import
similarity index 72%
rename from art/exported/environment/textures/dirt_wall.png.import
rename to items/icons/art/art_kit_eraser.png.import
index 1b09653..a25a8d1 100644
--- a/art/exported/environment/textures/dirt_wall.png.import
+++ b/items/icons/art/art_kit_eraser.png.import
@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
-uid="uid://c3j0gailr6yfy"
-path="res://.godot/imported/dirt_wall.png-8ba7bb24831d83f929bfa44b53af9288.ctex"
+uid="uid://cdbba3bvhuear"
+path="res://.godot/imported/art_kit_eraser.png-4df8445ba3139b8236508fc61a024158.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://art/exported/environment/textures/dirt_wall.png"
-dest_files=["res://.godot/imported/dirt_wall.png-8ba7bb24831d83f929bfa44b53af9288.ctex"]
+source_file="res://items/icons/art/art_kit_eraser.png"
+dest_files=["res://.godot/imported/art_kit_eraser.png-4df8445ba3139b8236508fc61a024158.ctex"]
[params]
diff --git a/items/icons/art/art_kit_grid_finish_light.png b/items/icons/art/art_kit_grid_finish_light.png
new file mode 100644
index 0000000..684efed
Binary files /dev/null and b/items/icons/art/art_kit_grid_finish_light.png differ
diff --git a/items/icons/art/art_kit_grid_finish_light.png.import b/items/icons/art/art_kit_grid_finish_light.png.import
new file mode 100644
index 0000000..63d8261
--- /dev/null
+++ b/items/icons/art/art_kit_grid_finish_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dm24dy3ebvqmv"
+path="res://.godot/imported/art_kit_grid_finish_light.png-fe16d574640fb174cb8b6ff3cfb95e5e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/art/art_kit_grid_finish_light.png"
+dest_files=["res://.godot/imported/art_kit_grid_finish_light.png-fe16d574640fb174cb8b6ff3cfb95e5e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/art/art_kit_grid_hidden_light.png b/items/icons/art/art_kit_grid_hidden_light.png
new file mode 100644
index 0000000..af01077
Binary files /dev/null and b/items/icons/art/art_kit_grid_hidden_light.png differ
diff --git a/items/icons/art/art_kit_grid_hidden_light.png.import b/items/icons/art/art_kit_grid_hidden_light.png.import
new file mode 100644
index 0000000..95d7ac3
--- /dev/null
+++ b/items/icons/art/art_kit_grid_hidden_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cv6yicrysb0vs"
+path="res://.godot/imported/art_kit_grid_hidden_light.png-e92350d8a3e2c3e3bf286658f1ae0c41.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/art/art_kit_grid_hidden_light.png"
+dest_files=["res://.godot/imported/art_kit_grid_hidden_light.png-e92350d8a3e2c3e3bf286658f1ae0c41.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/art/art_kit_grid_light.png b/items/icons/art/art_kit_grid_light.png
new file mode 100644
index 0000000..58089a3
Binary files /dev/null and b/items/icons/art/art_kit_grid_light.png differ
diff --git a/items/icons/art/art_kit_grid_light.png.import b/items/icons/art/art_kit_grid_light.png.import
new file mode 100644
index 0000000..6435819
--- /dev/null
+++ b/items/icons/art/art_kit_grid_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dh2tu3ptqe6f7"
+path="res://.godot/imported/art_kit_grid_light.png-d445eba68746a34d73bbf1744fe56777.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/art/art_kit_grid_light.png"
+dest_files=["res://.godot/imported/art_kit_grid_light.png-d445eba68746a34d73bbf1744fe56777.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/art/art_kit_grid_restore_light.png b/items/icons/art/art_kit_grid_restore_light.png
new file mode 100644
index 0000000..9517e6d
Binary files /dev/null and b/items/icons/art/art_kit_grid_restore_light.png differ
diff --git a/items/icons/art/art_kit_grid_restore_light.png.import b/items/icons/art/art_kit_grid_restore_light.png.import
new file mode 100644
index 0000000..9672eab
--- /dev/null
+++ b/items/icons/art/art_kit_grid_restore_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ckxdpi5sqerao"
+path="res://.godot/imported/art_kit_grid_restore_light.png-d2f2458a90dabc79430d7ff0e0e3385d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/art/art_kit_grid_restore_light.png"
+dest_files=["res://.godot/imported/art_kit_grid_restore_light.png-d2f2458a90dabc79430d7ff0e0e3385d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/art/art_kit_marker.png b/items/icons/art/art_kit_marker.png
new file mode 100644
index 0000000..403f69c
Binary files /dev/null and b/items/icons/art/art_kit_marker.png differ
diff --git a/art/exported/environment/textures/cliff_wall.png.import b/items/icons/art/art_kit_marker.png.import
similarity index 72%
rename from art/exported/environment/textures/cliff_wall.png.import
rename to items/icons/art/art_kit_marker.png.import
index 026f231..cffece6 100644
--- a/art/exported/environment/textures/cliff_wall.png.import
+++ b/items/icons/art/art_kit_marker.png.import
@@ -2,16 +2,16 @@
importer="texture"
type="CompressedTexture2D"
-uid="uid://cd7qwsbeg1jxx"
-path="res://.godot/imported/cliff_wall.png-7ce756d49c24c7b8fdda307d68086d87.ctex"
+uid="uid://b20kab6kxh7ap"
+path="res://.godot/imported/art_kit_marker.png-77e7b82481305350436ed5cca046df56.ctex"
metadata={
"vram_texture": false
}
[deps]
-source_file="res://art/exported/environment/textures/cliff_wall.png"
-dest_files=["res://.godot/imported/cliff_wall.png-7ce756d49c24c7b8fdda307d68086d87.ctex"]
+source_file="res://items/icons/art/art_kit_marker.png"
+dest_files=["res://.godot/imported/art_kit_marker.png-77e7b82481305350436ed5cca046df56.ctex"]
[params]
diff --git a/items/icons/bait/64_bait_minnow.png b/items/icons/bait/64_bait_minnow.png
new file mode 100644
index 0000000..f083d65
Binary files /dev/null and b/items/icons/bait/64_bait_minnow.png differ
diff --git a/items/icons/bait/64_bait_minnow.png.import b/items/icons/bait/64_bait_minnow.png.import
new file mode 100644
index 0000000..67f57f5
--- /dev/null
+++ b/items/icons/bait/64_bait_minnow.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://oc1nckfxeir0"
+path="res://.godot/imported/64_bait_minnow.png-25bb645caffd0cad87b30d6b38b80ca4.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_minnow.png"
+dest_files=["res://.godot/imported/64_bait_minnow.png-25bb645caffd0cad87b30d6b38b80ca4.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_roe_luminous.png b/items/icons/bait/64_bait_roe_luminous.png
new file mode 100644
index 0000000..dc89fbd
Binary files /dev/null and b/items/icons/bait/64_bait_roe_luminous.png differ
diff --git a/items/icons/bait/64_bait_roe_luminous.png.import b/items/icons/bait/64_bait_roe_luminous.png.import
new file mode 100644
index 0000000..b0a78d0
--- /dev/null
+++ b/items/icons/bait/64_bait_roe_luminous.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bnqji6j6nigjq"
+path="res://.godot/imported/64_bait_roe_luminous.png-cfa7eaf935630a20e2e8111f803c7741.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_roe_luminous.png"
+dest_files=["res://.godot/imported/64_bait_roe_luminous.png-cfa7eaf935630a20e2e8111f803c7741.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_sardine.png b/items/icons/bait/64_bait_sardine.png
new file mode 100644
index 0000000..9161ba5
Binary files /dev/null and b/items/icons/bait/64_bait_sardine.png differ
diff --git a/items/icons/bait/64_bait_sardine.png.import b/items/icons/bait/64_bait_sardine.png.import
new file mode 100644
index 0000000..03f94bf
--- /dev/null
+++ b/items/icons/bait/64_bait_sardine.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ddbyrbcbm40i4"
+path="res://.godot/imported/64_bait_sardine.png-28b5d49b506c3007ebf15dcc8f198a94.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_sardine.png"
+dest_files=["res://.godot/imported/64_bait_sardine.png-28b5d49b506c3007ebf15dcc8f198a94.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_shrimp.png b/items/icons/bait/64_bait_shrimp.png
new file mode 100644
index 0000000..8a20783
Binary files /dev/null and b/items/icons/bait/64_bait_shrimp.png differ
diff --git a/items/icons/bait/64_bait_shrimp.png.import b/items/icons/bait/64_bait_shrimp.png.import
new file mode 100644
index 0000000..8c65f4a
--- /dev/null
+++ b/items/icons/bait/64_bait_shrimp.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bpq47xg8tv6th"
+path="res://.godot/imported/64_bait_shrimp.png-f68293fc8a81e803d5eeb1f268e4f3d3.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_shrimp.png"
+dest_files=["res://.godot/imported/64_bait_shrimp.png-f68293fc8a81e803d5eeb1f268e4f3d3.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_snail.png b/items/icons/bait/64_bait_snail.png
new file mode 100644
index 0000000..39e6c16
Binary files /dev/null and b/items/icons/bait/64_bait_snail.png differ
diff --git a/items/icons/bait/64_bait_snail.png.import b/items/icons/bait/64_bait_snail.png.import
new file mode 100644
index 0000000..de8d419
--- /dev/null
+++ b/items/icons/bait/64_bait_snail.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dihevd23dh5x3"
+path="res://.godot/imported/64_bait_snail.png-9a7a0c9f93be442a8a1d685a5324e3f6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_snail.png"
+dest_files=["res://.godot/imported/64_bait_snail.png-9a7a0c9f93be442a8a1d685a5324e3f6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_squid.png b/items/icons/bait/64_bait_squid.png
new file mode 100644
index 0000000..57e2b64
Binary files /dev/null and b/items/icons/bait/64_bait_squid.png differ
diff --git a/items/icons/bait/64_bait_squid.png.import b/items/icons/bait/64_bait_squid.png.import
new file mode 100644
index 0000000..41bf2b4
--- /dev/null
+++ b/items/icons/bait/64_bait_squid.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://kf3aglrd1en3"
+path="res://.godot/imported/64_bait_squid.png-6ec6c9776ffcae93fd2fa312c8a9013d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_squid.png"
+dest_files=["res://.godot/imported/64_bait_squid.png-6ec6c9776ffcae93fd2fa312c8a9013d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/bait/64_bait_worms.png b/items/icons/bait/64_bait_worms.png
new file mode 100644
index 0000000..51cb396
Binary files /dev/null and b/items/icons/bait/64_bait_worms.png differ
diff --git a/items/icons/bait/64_bait_worms.png.import b/items/icons/bait/64_bait_worms.png.import
new file mode 100644
index 0000000..5fbd6cd
--- /dev/null
+++ b/items/icons/bait/64_bait_worms.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bn6815x0rrspw"
+path="res://.godot/imported/64_bait_worms.png-c9f31d77527e73888fc56963d4e78e30.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/bait/64_bait_worms.png"
+dest_files=["res://.godot/imported/64_bait_worms.png-c9f31d77527e73888fc56963d4e78e30.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/consumables/64_consumable_coffee.png b/items/icons/consumables/64_consumable_coffee.png
index 270f191..3282a17 100644
Binary files a/items/icons/consumables/64_consumable_coffee.png and b/items/icons/consumables/64_consumable_coffee.png differ
diff --git a/items/icons/consumables/64_consumable_energybar.png b/items/icons/consumables/64_consumable_energybar.png
index 370cf40..1657a6f 100644
Binary files a/items/icons/consumables/64_consumable_energybar.png and b/items/icons/consumables/64_consumable_energybar.png differ
diff --git a/items/icons/consumables/64_consumable_energydrink_redfish.png b/items/icons/consumables/64_consumable_energydrink_redfish.png
index e0f1457..92a55dc 100644
Binary files a/items/icons/consumables/64_consumable_energydrink_redfish.png and b/items/icons/consumables/64_consumable_energydrink_redfish.png differ
diff --git a/items/icons/consumables/64_consumable_fishfinder.png b/items/icons/consumables/64_consumable_fishfinder.png
index 2cace25..5c92ce1 100644
Binary files a/items/icons/consumables/64_consumable_fishfinder.png and b/items/icons/consumables/64_consumable_fishfinder.png differ
diff --git a/items/icons/equipment/64_cooler_plus.png b/items/icons/equipment/64_cooler_plus.png
new file mode 100644
index 0000000..acbd889
Binary files /dev/null and b/items/icons/equipment/64_cooler_plus.png differ
diff --git a/items/icons/equipment/64_cooler_plus.png.import b/items/icons/equipment/64_cooler_plus.png.import
new file mode 100644
index 0000000..44e493a
--- /dev/null
+++ b/items/icons/equipment/64_cooler_plus.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://baht2hredfky8"
+path="res://.godot/imported/64_cooler_plus.png-d0daa39246f92fd9774ec1721970efad.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/equipment/64_cooler_plus.png"
+dest_files=["res://.godot/imported/64_cooler_plus.png-d0daa39246f92fd9774ec1721970efad.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/placeholder/art_kit.svg b/items/icons/placeholder/art_kit.svg
deleted file mode 100644
index bd89210..0000000
--- a/items/icons/placeholder/art_kit.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/items/icons/placeholder/art_kit.svg.import b/items/icons/placeholder/art_kit.svg.import
deleted file mode 100644
index d28daa6..0000000
--- a/items/icons/placeholder/art_kit.svg.import
+++ /dev/null
@@ -1,43 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://bm0kkevv62mu0"
-path="res://.godot/imported/art_kit.svg-d4bd09e1da2e2339f7d505ee23d771f8.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://items/icons/placeholder/art_kit.svg"
-dest_files=["res://.godot/imported/art_kit.svg-d4bd09e1da2e2339f7d505ee23d771f8.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/items/icons/placeholder/fish_coin.svg b/items/icons/placeholder/fish_coin.svg
deleted file mode 100644
index ac4da92..0000000
--- a/items/icons/placeholder/fish_coin.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/items/icons/placeholder/fish_coin.svg.import b/items/icons/placeholder/fish_coin.svg.import
deleted file mode 100644
index 1dca3c6..0000000
--- a/items/icons/placeholder/fish_coin.svg.import
+++ /dev/null
@@ -1,43 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://trqvs4dgd4rt"
-path="res://.godot/imported/fish_coin.svg-9d00b5918d94a555938a84ee65e06386.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://items/icons/placeholder/fish_coin.svg"
-dest_files=["res://.godot/imported/fish_coin.svg-9d00b5918d94a555938a84ee65e06386.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/items/icons/placeholder/reel_speed_upgrade.svg b/items/icons/placeholder/reel_speed_upgrade.svg
deleted file mode 100644
index a92d9fb..0000000
--- a/items/icons/placeholder/reel_speed_upgrade.svg
+++ /dev/null
@@ -1,12 +0,0 @@
-
diff --git a/items/icons/placeholder/reel_speed_upgrade.svg.import b/items/icons/placeholder/reel_speed_upgrade.svg.import
deleted file mode 100644
index 211c08f..0000000
--- a/items/icons/placeholder/reel_speed_upgrade.svg.import
+++ /dev/null
@@ -1,43 +0,0 @@
-[remap]
-
-importer="texture"
-type="CompressedTexture2D"
-uid="uid://c2hal1gkmnuqa"
-path="res://.godot/imported/reel_speed_upgrade.svg-6bce0cfdbf18895938d0bcb4850467c8.ctex"
-metadata={
-"vram_texture": false
-}
-
-[deps]
-
-source_file="res://items/icons/placeholder/reel_speed_upgrade.svg"
-dest_files=["res://.godot/imported/reel_speed_upgrade.svg-6bce0cfdbf18895938d0bcb4850467c8.ctex"]
-
-[params]
-
-compress/mode=0
-compress/high_quality=false
-compress/lossy_quality=0.7
-compress/uastc_level=0
-compress/rdo_quality_loss=0.0
-compress/hdr_compression=1
-compress/normal_map=0
-compress/channel_pack=0
-mipmaps/generate=false
-mipmaps/limit=-1
-roughness/mode=0
-roughness/src_normal=""
-process/channel_remap/red=0
-process/channel_remap/green=1
-process/channel_remap/blue=2
-process/channel_remap/alpha=3
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/normal_map_invert_y=false
-process/hdr_as_srgb=false
-process/hdr_clamp_exposure=false
-process/size_limit=0
-detect_3d/compress_to=1
-svg/scale=1.0
-editor/scale_with_editor_scale=false
-editor/convert_colors_with_editor_theme=false
diff --git a/items/icons/shop/32_currency.png b/items/icons/shop/32_currency.png
new file mode 100644
index 0000000..de2a80c
Binary files /dev/null and b/items/icons/shop/32_currency.png differ
diff --git a/items/icons/shop/32_currency.png.import b/items/icons/shop/32_currency.png.import
new file mode 100644
index 0000000..1614c30
--- /dev/null
+++ b/items/icons/shop/32_currency.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bf3jlmqhmmuge"
+path="res://.godot/imported/32_currency.png-c07c9577bae5b0fbbae9513440339b6f.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/shop/32_currency.png"
+dest_files=["res://.godot/imported/32_currency.png-c07c9577bae5b0fbbae9513440339b6f.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/shop/64_power_plus.png b/items/icons/shop/64_power_plus.png
new file mode 100644
index 0000000..8aacdbc
Binary files /dev/null and b/items/icons/shop/64_power_plus.png differ
diff --git a/items/icons/shop/64_power_plus.png.import b/items/icons/shop/64_power_plus.png.import
new file mode 100644
index 0000000..c82907d
--- /dev/null
+++ b/items/icons/shop/64_power_plus.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://xh2g4eytrjep"
+path="res://.godot/imported/64_power_plus.png-98b7e06d3090a4411d56e2046b8c9d4b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/shop/64_power_plus.png"
+dest_files=["res://.godot/imported/64_power_plus.png-98b7e06d3090a4411d56e2046b8c9d4b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/icons/shop/64_speed_plus.png b/items/icons/shop/64_speed_plus.png
new file mode 100644
index 0000000..bd605fe
Binary files /dev/null and b/items/icons/shop/64_speed_plus.png differ
diff --git a/items/icons/shop/64_speed_plus.png.import b/items/icons/shop/64_speed_plus.png.import
new file mode 100644
index 0000000..6d330de
--- /dev/null
+++ b/items/icons/shop/64_speed_plus.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dk6yx5cbpblo6"
+path="res://.godot/imported/64_speed_plus.png-c695fb4021c17dfa94ed7aa48ce262c1.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://items/icons/shop/64_speed_plus.png"
+dest_files=["res://.godot/imported/64_speed_plus.png-c695fb4021c17dfa94ed7aa48ce262c1.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/items/item_data.gd b/items/item_data.gd
index 9ba078e..a34cec0 100644
--- a/items/item_data.gd
+++ b/items/item_data.gd
@@ -17,6 +17,7 @@ enum Category {
@export_multiline var description: String
@export var category: Category = Category.UTILITY
@export var bait_tags: Array[StringName] = []
+@export var lure_effects: Array[StringName] = []
@export var icon: Texture2D
@export var stackable: bool = false
@export_range(1, 999, 1) var max_stack: int = 1
@@ -40,3 +41,7 @@ func get_category_name() -> String:
func is_bait() -> bool:
return category == Category.BAIT and not bait_tags.is_empty()
+
+
+func is_lure() -> bool:
+ return category == Category.LURE and equippable
diff --git a/jobs/job_catalog.gd b/jobs/job_catalog.gd
index 4429e89..009a152 100644
--- a/jobs/job_catalog.gd
+++ b/jobs/job_catalog.gd
@@ -383,7 +383,7 @@ static func _lifetime_title(chain_id: String, target: int) -> String:
"catch":
return "seasoned angler"
"sell":
- return "fish coin regular"
+ return "market regular"
"level":
return "reach level %d" % target
"discover":
diff --git a/jobs/player_job_service.gd b/jobs/player_job_service.gd
index 5f764f8..18d6f89 100644
--- a/jobs/player_job_service.gd
+++ b/jobs/player_job_service.gd
@@ -36,7 +36,7 @@ var _pending_rewards: Array[Dictionary] = []
var _lifetime_claimed: Array[String] = []
var _total_catches: int = 0
var _total_sold: int = 0
-var _previous_hour: float = WorldTimeService.DEFAULT_START_HOUR
+var _daily_clock_hour: float = WorldTimeService.DEFAULT_START_HOUR
func setup(
@@ -55,8 +55,8 @@ func setup(
_world_time = world_time
_world_weather = world_weather
_session = session
- _previous_hour = _world_time.get_time_hours()
- _world_time.time_changed.connect(_on_time_changed)
+ _daily_clock_hour = _world_time.get_time_hours()
+ _world_time.natural_time_advanced.connect(_on_natural_time_advanced)
_session.state_changed.connect(_on_session_state_changed)
_collection.collection_changed.connect(_on_current_state_changed)
_experience.experience_changed.connect(_on_experience_changed)
@@ -86,7 +86,6 @@ func set_save_manager(save_manager: PlayerSaveManager) -> void:
func begin_progression_session() -> void:
_progression_ready = true
- _previous_hour = _world_time.get_time_hours()
if _session.is_host():
_activate_host_board()
changed.emit()
@@ -151,11 +150,15 @@ func get_plan_id() -> String:
return _active_plan_id
+func has_active_board() -> bool:
+ return validate_board(_active_board)
+
+
func get_time_until_refresh_text() -> String:
if _active_plan_id.is_empty() or _world_time == null:
return "daily jobs unavailable"
var elapsed: float = fposmod(
- _world_time.get_time_hours() - DAILY_REFRESH_HOUR,
+ _daily_clock_hour - DAILY_REFRESH_HOUR,
WorldTimeService.HOURS_PER_DAY,
)
var hours_remaining: float = WorldTimeService.HOURS_PER_DAY - elapsed
@@ -185,7 +188,10 @@ func claim(claim_id: String) -> bool:
func get_host_board_network_data() -> Dictionary:
- return _host_board.duplicate(true)
+ var board := _host_board.duplicate(true)
+ if not board.is_empty():
+ board["daily_clock_hour"] = _daily_clock_hour
+ return board
func apply_remote_board(board: Dictionary) -> bool:
@@ -198,6 +204,8 @@ func apply_remote_board(board: Dictionary) -> bool:
_daily_progress.clear()
_daily_completions.clear()
_active_board = board.duplicate(true)
+ if board.has("daily_clock_hour"):
+ _daily_clock_hour = float(board["daily_clock_hour"])
changed.emit()
return true
@@ -223,6 +231,7 @@ func to_save_data() -> Dictionary:
"active_plan_id": _active_plan_id,
"daily_progress": progress,
"daily_completions": completions,
+ "daily_clock_hour": _daily_clock_hour,
"pending_rewards": _pending_rewards.duplicate(true),
"lifetime_claimed": _lifetime_claimed.duplicate(),
"statistics": {
@@ -246,6 +255,12 @@ func restore_from_save_data(data: Dictionary) -> bool:
var completions: Dictionary = data.get("daily_completions", {})
for key: Variant in completions:
_daily_completions[str(key)] = mini(int(completions[key]), 1)
+ _daily_clock_hour = float(data.get(
+ "daily_clock_hour",
+ _world_time.get_time_hours()
+ if _world_time != null
+ else WorldTimeService.DEFAULT_START_HOUR,
+ ))
_pending_rewards.clear()
var rewards: Array = data.get("pending_rewards", [])
var restored_daily_rewards: Dictionary[String, bool] = {}
@@ -290,6 +305,7 @@ func reset_to_defaults() -> void:
_lifetime_claimed.clear()
_total_catches = 0
_total_sold = 0
+ _daily_clock_hour = WorldTimeService.DEFAULT_START_HOUR
changed.emit()
@@ -300,6 +316,7 @@ static func default_save_data() -> Dictionary:
"active_plan_id": "",
"daily_progress": {},
"daily_completions": {},
+ "daily_clock_hour": WorldTimeService.DEFAULT_START_HOUR,
"pending_rewards": [],
"lifetime_claimed": [],
"statistics": {"fish_caught": 0, "fish_sold": 0},
@@ -363,6 +380,16 @@ static func validate_save_data(value: Variant) -> bool:
var host_board: Dictionary = data.get("host_board", {})
if not host_board.is_empty() and not validate_board(host_board):
return false
+ if (
+ data.has("daily_clock_hour")
+ and (
+ typeof(data["daily_clock_hour"]) not in [TYPE_FLOAT, TYPE_INT]
+ or not is_finite(float(data["daily_clock_hour"]))
+ or float(data["daily_clock_hour"]) < 0.0
+ or float(data["daily_clock_hour"]) >= WorldTimeService.HOURS_PER_DAY
+ )
+ ):
+ return false
var progress: Dictionary = data.get("daily_progress", {})
if progress.size() > 8:
return false
@@ -475,19 +502,22 @@ func _apply_host_weather_plan() -> void:
)
-func _on_time_changed(
- time_hours: float,
- _phase: WorldTimeService.Phase,
-) -> void:
+func _on_natural_time_advanced(hours: float) -> void:
+ if not is_finite(hours) or hours <= 0.0:
+ return
+ var previous_hour := _daily_clock_hour
+ _daily_clock_hour = fposmod(
+ _daily_clock_hour + hours,
+ WorldTimeService.HOURS_PER_DAY,
+ )
if (
_progression_ready
and _session != null
and _session.is_host()
- and _crossed_daily_refresh(_previous_hour, time_hours)
+ and _crossed_daily_refresh(previous_hour, _daily_clock_hour)
):
var cycle: int = int(_host_board.get("cycle", -1)) + 1
_generate_host_board(maxi(cycle, 0))
- _previous_hour = time_hours
func _on_session_state_changed(state: NetworkSession.State) -> void:
@@ -630,9 +660,7 @@ func _reward_claimed(reward: Dictionary) -> void:
var fish_coin: int = int(reward.get("fish_coin", 0))
var experience: int = int(reward.get("experience", 0))
reward_claimed.emit(title, fish_coin, experience)
- status_changed.emit("payment received — $%d and %d xp" % [
- fish_coin, experience,
- ])
+ status_changed.emit("payment received — %d xp" % experience)
changed.emit()
diff --git a/main/main.gd b/main/main.gd
index bfdc498..e028509 100644
--- a/main/main.gd
+++ b/main/main.gd
@@ -38,6 +38,10 @@ const WorldPixelationPostprocessType = preload(
"res://main/world_pixelation_postprocess.gd"
)
const NetworkSessionType = preload("res://network/network_session.gd")
+const DiscoveryClientType = preload("res://network/discovery_client.gd")
+const DedicatedServerConfigType = preload(
+ "res://server/dedicated_server_config.gd"
+)
const NetworkProfilePreferencesType = preload(
"res://network/network_profile_preferences.gd"
)
@@ -50,6 +54,7 @@ const PlayerSpawnServiceType = preload(
const NetworkFishingServiceType = preload(
"res://network/network_fishing_service.gd"
)
+const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
const NetworkSaleServiceType = preload(
"res://network/network_sale_service.gd"
)
@@ -91,10 +96,12 @@ const WorldWeatherServiceType = preload("res://world/world_weather_service.gd")
const NetworkWorldWeatherServiceType = preload(
"res://network/network_world_weather_service.gd"
)
+const RainAmbienceType = preload("res://world/rain_ambience.gd")
const PlayerJobServiceType = preload("res://jobs/player_job_service.gd")
const NetworkJobServiceType = preload("res://network/network_job_service.gd")
const TITLE_MUSIC_SILENCE_DB: float = -80.0
+const TIME_CROSSING_EPSILON_HOURS: float = 0.000001
const PLAYER_MENU_PATTERN_SCALE: float = 0.85
const PLAYER_MENU_PATTERN_SCROLL_VELOCITY := Vector2(-7.0, -5.0)
const SHOP_PATTERN_SCALE: float = 1.75
@@ -119,6 +126,7 @@ const SHOP_PATTERN_SCALE: float = 1.75
)
@onready var _interface_fonts: InterfaceFontController = %InterfaceFontController
@onready var _title_music: AudioStreamPlayer = %TitleMusic
+@onready var _dusk_music: AudioStreamPlayer = %DuskMusic
@onready var _ui_pixelation: UIPixelationPresenterType = %UIPresentation
@onready var _pixelation_reset: PixelationResetOverlayType = (
%PixelationResetOverlay
@@ -127,6 +135,7 @@ const SHOP_PATTERN_SCALE: float = 1.75
%WorldPixelationPostprocess
)
@onready var _network_session: NetworkSessionType = %NetworkSession
+@onready var _discovery: DiscoveryClientType = %DiscoveryClient
@onready var _world_time: WorldTimeServiceType = %WorldTimeService
@onready var _world_time_visuals: WorldTimeVisualControllerType = (
%WorldTimeVisualController
@@ -190,6 +199,7 @@ var _shop_interaction: FishingShopInteractionType
var _title_music_tween: Tween
var _title_music_transition_generation: int = 0
var _title_music_requested: bool = false
+var _dusk_music_played_for_natural_day: bool = false
var _quit_in_progress: bool = false
var _join_requested_from_title: bool = false
var _join_requested_from_pause: bool = false
@@ -208,12 +218,22 @@ var _restore_data_setup_after_picker: bool = false
var _application_initialized := false
var _pending_existing_root_path := ""
var _local_recovery_attempt_id: String = ""
+var _dedicated_runtime: bool = false
@onready var _shoreline_ambience: ShorelineAmbience = %ShorelineAmbience
+var _rain_ambience: RainAmbienceType
func _ready() -> void:
+ _dedicated_runtime = _is_dedicated_server_runtime()
+ if _dedicated_runtime:
+ call_deferred("_start_dedicated_server")
+ return
DisplayServer.window_set_title("NETfishing")
+ _rain_ambience = RainAmbienceType.new()
+ _rain_ambience.name = "RainAmbience"
+ add_child(_rain_ambience)
+ _rain_ambience.configure(_world_weather)
_shoreline_ambience.configure(
_player,
_test_world.get_saltwater_shoreline_mesh(),
@@ -255,6 +275,91 @@ func _ready() -> void:
_show_data_root_setup()
+func _is_dedicated_server_runtime() -> bool:
+ if OS.has_feature("dedicated_server"):
+ return true
+ return "--dedicated-server" in OS.get_cmdline_user_args()
+
+
+func _start_dedicated_server() -> void:
+ var config: DedicatedServerConfigType = DedicatedServerConfigType.from_runtime()
+ if not config.is_valid():
+ _fail_dedicated_server(config.error_message)
+ return
+ var data_path: String = config.data_directory
+ var manifest_path: String = data_path.path_join(
+ PlayerDataRoot.MANIFEST_FILENAME
+ )
+ if not FileAccess.file_exists(manifest_path):
+ var created: Dictionary = _data_root.create_unbound_root(data_path)
+ if not bool(created.get("ok", false)):
+ _fail_dedicated_server(str(created.get(
+ "message", "Could not create the server data directory."
+ )))
+ return
+ if not _data_root.activate_process_root(data_path):
+ _fail_dedicated_server(_data_root.error_message)
+ return
+ var identity_directory: String = data_path.path_join("server")
+ if DirAccess.make_dir_recursive_absolute(identity_directory) != OK:
+ _fail_dedicated_server("Could not create the server identity directory.")
+ return
+ _host_identity.configure("host_identity", true, identity_directory)
+ if not _discovery.set_base_url_override(config.discovery_url):
+ _fail_dedicated_server("The discovery URL is invalid.")
+ return
+ if not _network_session.configure_dedicated_operators(
+ config.operator_fingerprints
+ ):
+ _fail_dedicated_server("The server operator list is invalid.")
+ return
+ _configure_portable_stores()
+ if not _discovery.configure_dedicated_runtime(config.server_name):
+ _fail_dedicated_server("The server room name is invalid.")
+ return
+ _initialize_application(true)
+ _player.set_local_control(false)
+ _player.visible = false
+ _player.collision_layer = 0
+ _player.collision_mask = 0
+ _player.set_physics_process(false)
+ if not _network_session.start_dedicated_host(
+ config.port,
+ config.max_players,
+ config.bind_address,
+ ):
+ _fail_dedicated_server("Could not start the dedicated server.")
+ return
+ _network_session.set_session_display_name(config.server_name)
+ if not _network_session.set_host_open(true):
+ _fail_dedicated_server("Could not open the dedicated server.")
+ return
+ _player_jobs.begin_progression_session()
+ if config.public_listing and not _discovery.set_discoverable(true):
+ _network_session.disconnect_session("Discovery setup failed.")
+ _fail_dedicated_server(_discovery.get_host_status_message())
+ return
+ print(
+ "NETfishing dedicated server ready: %s on %s:%d (%d players, %s)"
+ % [
+ config.server_name,
+ config.bind_address,
+ config.port,
+ config.max_players,
+ "public" if config.public_listing else "unlisted",
+ ]
+ )
+ print(
+ "Server identity: %s"
+ % _network_session.get_host_identity_fingerprint()
+ )
+
+
+func _fail_dedicated_server(message: String) -> void:
+ push_error("Dedicated server startup failed: %s" % message)
+ get_tree().quit(1)
+
+
func _configure_portable_stores() -> void:
_save_manager.configure_storage(
_data_root.path_for(&"player_save"), _data_root
@@ -283,6 +388,10 @@ func _configure_portable_stores() -> void:
func _initialize_after_data_root() -> void:
+ _initialize_application(false)
+
+
+func _initialize_application(dedicated: bool) -> void:
if _application_initialized:
return
_application_initialized = true
@@ -302,14 +411,24 @@ func _initialize_after_data_root() -> void:
_known_players,
_server_trust,
_host_bans,
+ dedicated,
)
- _world_time_visuals.setup(
- _world_time,
- _test_world.get_world_environment(),
- _test_world.get_sun(),
- _world_weather,
- _player,
- )
+ _discovery.setup(_network_session)
+ if not dedicated:
+ _world_time_visuals.setup(
+ _world_time,
+ _test_world.get_world_environment(),
+ _test_world.get_sun(),
+ _world_weather,
+ _player,
+ Callable(_player, "get_active_gameplay_camera"),
+ )
+ if not _world_time.natural_time_advanced.is_connected(
+ _on_natural_time_advanced
+ ):
+ _world_time.natural_time_advanced.connect(
+ _on_natural_time_advanced
+ )
_network_world_time.setup(_network_session, _world_time)
_network_world_weather.setup(_network_session, _world_weather)
_player_jobs.setup(
@@ -338,22 +457,23 @@ func _initialize_after_data_root() -> void:
_network_chat,
_network_mail,
)
- _network_session.set_local_appearance_snapshot(
- _appearance_store.get_snapshot()
- )
- _network_session.join_authenticated.connect(
- _on_network_join_authenticated
- )
- _network_session.connection_error.connect(
- _on_network_connection_error
- )
- _network_session.server_trust_required.connect(
- _on_server_trust_required
- )
+ if not dedicated:
+ _network_session.set_local_appearance_snapshot(
+ _appearance_store.get_snapshot()
+ )
+ _network_session.join_authenticated.connect(
+ _on_network_join_authenticated
+ )
+ _network_session.connection_error.connect(
+ _on_network_connection_error
+ )
+ _network_session.server_trust_required.connect(
+ _on_server_trust_required
+ )
+ _network_session.server_lost.connect(_on_network_server_lost)
_network_session.peer_identity_observed.connect(
_on_peer_identity_observed
)
- _network_session.server_lost.connect(_on_network_server_lost)
_network_session.remote_recovery_requested.connect(
_on_remote_recovery_requested
)
@@ -370,10 +490,14 @@ func _initialize_after_data_root() -> void:
_player.bag.setup(item_catalog)
_player.hotbar.setup(_player.bag, item_catalog, _player.inventory)
_shop_interaction = _test_world.get_fishing_shop()
- _shop_interaction.setup_local_player(_player)
- _shop_interaction.local_player_range_changed.connect(
- _on_shop_range_changed
- )
+ if not dedicated:
+ _shop_interaction.setup_local_player(_player)
+ _shop_interaction.local_player_range_changed.connect(
+ _on_shop_range_changed
+ )
+ _game_ui.set_shop_npc_player_in_range(
+ _shop_interaction.is_local_player_in_range()
+ )
_save_manager.setup(
_player.inventory,
_player.collection_log,
@@ -431,17 +555,19 @@ func _initialize_after_data_root() -> void:
_player,
_surface_drawings_root,
_player.bag,
+ _player.hotbar,
_player.art_unlocks,
)
_network_player_list.set_surface_drawing_service(
_network_surface_drawing
)
- _network_chat.setup(_network_session)
+ _network_chat.setup(_network_session, _world_time, _world_weather)
_network_fishing.setup(
_network_session,
_player_spawn_service,
_fishing_spot,
_player.inventory,
+ _player.bag,
_player.collection_log,
_player.cooler_capacity,
_player.experience,
@@ -499,6 +625,8 @@ func _initialize_after_data_root() -> void:
_world_time,
_world_weather,
)
+ if dedicated:
+ return
_game_ui.setup(
_player,
_player.inventory,
@@ -527,6 +655,7 @@ func _initialize_after_data_root() -> void:
_asset_reservations,
_network_profile_service,
_network_player_list,
+ _discovery,
_settings_manager,
_network_surface_drawing,
_player.art_unlocks,
@@ -604,6 +733,7 @@ func _initialize_after_data_root() -> void:
_network_session,
_saved_servers,
_server_trust,
+ _discovery,
)
var pause_menu: PauseMenuType = _game_ui.get_pause_menu()
pause_menu.setup(
@@ -614,6 +744,7 @@ func _initialize_after_data_root() -> void:
_network_session,
_saved_servers,
_server_trust,
+ _discovery,
)
title_screen.join_game_requested.connect(_on_title_join_game_requested)
pause_menu.join_game_requested.connect(_on_pause_join_game_requested)
@@ -627,16 +758,13 @@ func _initialize_after_data_root() -> void:
pause_menu.menu_visibility_changed.connect(
_game_ui.set_system_menu_open
)
- _player.hotbar.selected_slot_changed.connect(
+ _player.hotbar.selected_assignment_changed.connect(
_on_active_hotbar_item_changed
)
_player.bag.contents_changed.connect(_refresh_active_hotbar_item)
_fishing_spot.ready_for_equipment_refresh.connect(
_refresh_active_hotbar_item
)
- _fishing_spot.fish_showcase_toggle_requested.connect(
- _network_fish_showcase.toggle_selected_fish
- )
_water_recovery.recovery_starting.connect(
_on_water_recovery_starting
)
@@ -646,10 +774,7 @@ func _initialize_after_data_root() -> void:
_water_recovery.local_respawn_completed.connect(
_on_local_respawn_completed
)
- _on_active_hotbar_item_changed(
- _player.hotbar.get_selected_slot(),
- _player.hotbar.get_selected_item_id()
- )
+ _refresh_active_hotbar_item()
_show_title_music(true)
@@ -954,6 +1079,8 @@ func _confirm_server_trust() -> void:
_server_trust_dialog.ok_button_text = "Replace Pin"
_server_trust_dialog.popup_centered(Vector2i(520, 260))
return
+ if _server_trust_dialog != null:
+ _server_trust_dialog.hide()
_network_session.resolve_server_trust(true)
@@ -1093,17 +1220,41 @@ func _unhandled_input(event: InputEvent) -> void:
):
_game_ui.set_shop_prompt_visible(false)
get_viewport().set_input_as_handled()
+ elif event is InputEventJoypadButton and _player != null:
+ _player.hotbar.clear_slot(_player.hotbar.get_selected_slot())
+ get_viewport().set_input_as_handled()
func _process(_delta: float) -> void:
- _game_ui.set_shop_prompt_visible(_can_show_shop_prompt())
+ if _dedicated_runtime:
+ return
+ var show_shop_prompt := _can_show_shop_prompt()
+ var shop_prompt_anchor := (
+ _shop_interaction.get_prompt_anchor_position()
+ if _shop_interaction != null
+ else Vector3.ZERO
+ )
+ _game_ui.set_shop_prompt_visible(
+ show_shop_prompt,
+ shop_prompt_anchor,
+ )
func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
if settings == null:
return
+ var requested_window_mode: DisplayServer.WindowMode = (
+ DisplayServer.WINDOW_MODE_FULLSCREEN
+ if settings.fullscreen_enabled
+ else DisplayServer.WINDOW_MODE_WINDOWED
+ )
+ if DisplayServer.window_get_mode() != requested_window_mode:
+ DisplayServer.window_set_mode(requested_window_mode)
_apply_world_pixelation(settings.world_pixel_size)
_ui_pixelation.set_pixel_size(settings.ui_pixel_size)
+ _ui_pixelation.set_on_screen_keyboard_enabled(
+ settings.on_screen_keyboard_enabled
+ )
_game_ui.get_title_screen().set_world_pixelation(
settings.world_pixel_size
)
@@ -1126,7 +1277,11 @@ func _apply_runtime_settings(settings: PlayerSettingsType) -> void:
func _apply_world_pixelation(pixel_size: int) -> void:
var root_viewport: Viewport = get_viewport()
root_viewport.scaling_3d_mode = Viewport.SCALING_3D_MODE_NEAREST
- root_viewport.scaling_3d_scale = 1.0
+ root_viewport.scaling_3d_scale = (
+ 0.75
+ if OS.get_environment("NETFISHING_LOW_END") == "1"
+ else 1.0
+ )
root_viewport.msaa_3d = Viewport.MSAA_DISABLED
root_viewport.screen_space_aa = Viewport.SCREEN_SPACE_AA_DISABLED
root_viewport.use_taa = false
@@ -1149,8 +1304,18 @@ func _reset_pixelation() -> void:
func _set_gameplay_active(active: bool) -> void:
+ var was_gameplay_started: bool = _gameplay_started
_gameplay_started = active
_shoreline_ambience.set_active(active)
+ _rain_ambience.set_active(active)
+ if active and not was_gameplay_started:
+ var current_hour: float = _world_time.get_time_hours()
+ _dusk_music_played_for_natural_day = (
+ current_hour >= WorldTimeServiceType.DUSK_START_HOUR
+ or current_hour < WorldTimeServiceType.DAWN_START_HOUR
+ )
+ elif not active:
+ _dusk_music.stop()
_title_background.visible = not active
_world_pixelation.set_gameplay_active(active)
_ui_pixelation.set_gameplay_active(active)
@@ -1172,11 +1337,55 @@ func _set_gameplay_active(active: bool) -> void:
_set_shop_backdrop_visible(false)
-func _set_player_menu_backdrop_visible(is_visible: bool) -> void:
+func _on_natural_time_advanced(advanced_hours: float) -> void:
+ if not _gameplay_started or advanced_hours <= 0.0:
+ return
+ var current_hour: float = _world_time.get_time_hours()
+ var previous_hour: float = fposmod(
+ current_hour - advanced_hours,
+ WorldTimeServiceType.HOURS_PER_DAY,
+ )
+ if _natural_interval_crosses_hour(
+ previous_hour,
+ advanced_hours,
+ WorldTimeServiceType.DAWN_START_HOUR,
+ ):
+ _dusk_music_played_for_natural_day = false
+ if (
+ not _dusk_music_played_for_natural_day
+ and _natural_interval_crosses_hour(
+ previous_hour,
+ advanced_hours,
+ WorldTimeServiceType.DUSK_START_HOUR,
+ )
+ ):
+ _dusk_music_played_for_natural_day = true
+ _dusk_music.play(0.0)
+
+
+static func _natural_interval_crosses_hour(
+ previous_hour: float,
+ advanced_hours: float,
+ target_hour: float,
+) -> bool:
+ if advanced_hours >= WorldTimeServiceType.HOURS_PER_DAY:
+ return true
+ var distance_to_target: float = fposmod(
+ target_hour - previous_hour,
+ WorldTimeServiceType.HOURS_PER_DAY,
+ )
+ return (
+ distance_to_target > 0.0
+ and distance_to_target
+ <= advanced_hours + TIME_CROSSING_EPSILON_HOURS
+ )
+
+
+func _set_player_menu_backdrop_visible(requested_visible: bool) -> void:
if _player_menu_backdrop_tween != null:
_player_menu_backdrop_tween.kill()
_player_menu_backdrop_tween = null
- var should_show: bool = is_visible and _gameplay_started
+ var should_show: bool = requested_visible and _gameplay_started
if should_show:
var was_visible: bool = _player_menu_backdrop.visible
_player_menu_backdrop.visible = true
@@ -1207,11 +1416,11 @@ func _set_player_menu_backdrop_visible(is_visible: bool) -> void:
)
-func _set_shop_backdrop_visible(is_visible: bool) -> void:
+func _set_shop_backdrop_visible(requested_visible: bool) -> void:
if _shop_backdrop_tween != null:
_shop_backdrop_tween.kill()
_shop_backdrop_tween = null
- var should_show: bool = is_visible and _gameplay_started
+ var should_show: bool = requested_visible and _gameplay_started
if should_show:
var was_visible: bool = _shop_backdrop.visible
_shop_backdrop.visible = true
@@ -1347,8 +1556,13 @@ func _on_pause_join_game_requested(endpoint: String) -> void:
_join_requested_from_title = false
_pending_join_endpoint = endpoint
_game_ui.get_pause_menu().close_for_title_transition()
+ var preserved_public_join: bool = (
+ _discovery.preserve_public_join_for_session_switch()
+ )
_network_session.disconnect_session("Connecting to another game.")
if not _network_session.join_direct(endpoint):
+ if preserved_public_join:
+ _discovery.cancel_pending_public_join()
_handle_failed_session_switch(
"Could not begin the direct connection."
)
@@ -1433,14 +1647,16 @@ func _handle_failed_session_switch(message: String) -> void:
_show_title_music(true)
-func _on_network_server_lost() -> void:
+func _on_network_server_lost(message: String) -> void:
if not _gameplay_started:
return
+ _join_requested_from_title = false
+ _join_requested_from_pause = false
+ _pending_join_endpoint = ""
_set_gameplay_active(false)
var title_screen: TitleScreenType = _game_ui.get_title_screen()
- title_screen.reopen()
- title_screen.open_join_game_page(_pending_join_endpoint)
- title_screen.report_network_error("The server connection was lost.")
+ title_screen.reopen_to_menu()
+ title_screen.report_network_error(message)
_show_title_music(true)
@@ -1535,23 +1751,33 @@ func _on_remote_recovery_presentation_changed(
func _on_active_hotbar_item_changed(
_slot_index: int,
- item_id: StringName,
+ kind: int,
+ identity: StringName,
) -> void:
if _fishing_spot.state != FishingSpotType.FishingState.READY:
return
+ var item_id: StringName = (
+ identity
+ if kind == PlayerHotbarType.AssignmentKind.ITEM
+ else StringName()
+ )
var item = item_catalog.get_item_by_id(item_id)
var active_is_rod: bool = (
item != null
and item.category == ItemDataType.Category.ROD
and _player.bag.owns_item(item_id)
)
- _player.set_active_item_is_rod(active_is_rod)
- _player.set_active_art_kit(
- item.icon if item != null else null,
+ var active_is_art_kit: bool = (
item_id == ArtShopStockType.ART_KIT_ITEM_ID
and item != null
- and _player.bag.owns_item(item_id),
+ and _player.bag.owns_item(item_id)
)
+ _player.set_active_item_is_rod(active_is_rod, true)
+ _player.set_active_art_kit(
+ item.icon if item != null else null,
+ active_is_art_kit,
+ )
+ _game_ui.set_surface_drawing_hotbar_selected(active_is_art_kit)
_network_item_use.submit_local_equipped(item_id, active_is_rod or (
item != null and _player.bag.owns_item(item_id)
))
@@ -1559,9 +1785,18 @@ func _on_active_hotbar_item_changed(
func _refresh_active_hotbar_item() -> void:
+ var kind: int = (
+ _player.hotbar.get_selected_assignment_kind()
+ )
+ var identity: StringName = StringName()
+ if kind == PlayerHotbarType.AssignmentKind.ITEM:
+ identity = _player.hotbar.get_selected_item_id()
+ elif kind == PlayerHotbarType.AssignmentKind.FISH:
+ identity = _player.hotbar.get_selected_fish_catch_id()
_on_active_hotbar_item_changed(
_player.hotbar.get_selected_slot(),
- _player.hotbar.get_selected_item_id()
+ kind,
+ identity,
)
@@ -1645,15 +1880,21 @@ func _finish_quit() -> void:
func _exit_tree() -> void:
+ if _dedicated_runtime and _network_session != null:
+ _network_session.disconnect_session("Dedicated server stopping.")
if _title_music_tween != null:
_title_music_tween.kill()
_title_music_tween = null
if is_instance_valid(_title_music):
_title_music.stop()
_title_music.stream = null
+ if is_instance_valid(_dusk_music):
+ _dusk_music.stop()
+ _dusk_music.stream = null
func _on_shop_range_changed(in_range: bool) -> void:
+ _game_ui.set_shop_npc_player_in_range(in_range)
if not in_range:
_game_ui.get_fishing_shop().close_for_range_exit()
_game_ui.set_shop_prompt_visible(_can_show_shop_prompt())
diff --git a/main/main.tscn b/main/main.tscn
index 83d11b7..6b9f496 100644
--- a/main/main.tscn
+++ b/main/main.tscn
@@ -43,7 +43,6 @@
[ext_resource type="Texture2D" uid="uid://f8a0cs0s7ler" path="res://art/patterns/pattern_tealdot.png" id="41_menu_pattern"]
[ext_resource type="Shader" uid="uid://byw3iub66qvog" path="res://ui/player_menu_pattern.gdshader" id="42_menu_pattern"]
[ext_resource type="Texture2D" uid="uid://b6xws1d2dnbnn" path="res://art/patterns/pattern_moneyfish.png" id="43_shop_pattern"]
-[ext_resource type="PackedScene" uid="uid://w7n4gjqq1juc" path="res://art/exported/characters/base/netfishing_base_character.glb" id="44_4pcu1"]
[ext_resource type="Script" uid="uid://m4n0bn38f34i" path="res://network/network_fish_showcase_service.gd" id="45_fish_showcase"]
[ext_resource type="Script" uid="uid://bkiepgu8j5r6t" path="res://network/network_surface_drawing_service.gd" id="46_surface_drawing"]
[ext_resource type="Script" uid="uid://5lceyulaglpf" path="res://world/world_time_service.gd" id="47_world_time"]
@@ -56,6 +55,8 @@
[ext_resource type="Script" uid="uid://b0c3o2vy76fg3" path="res://world/shoreline_ambience.gd" id="54_shoreline_ambience"]
[ext_resource type="AudioStream" uid="uid://dck3tf8qkadea" path="res://audio/ambience/waves.wav" id="55_waves"]
[ext_resource type="Script" uid="uid://c80x8jkdnx0xy" path="res://settings/controller_mapping_manager.gd" id="56_controller_mapping"]
+[ext_resource type="Script" uid="uid://d0jv8n2nfqia0" path="res://network/discovery_client.gd" id="57_discovery"]
+[ext_resource type="AudioStream" uid="uid://c4y8puv0n6xk8" path="res://audio/music/world/craft.mp3" id="dusk_music"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water_native"]
shader = ExtResource("40_title_water")
@@ -84,6 +85,57 @@ shader_parameter/source_tile_size = Vector2(64, 64)
shader_parameter/display_scale = 1.75
shader_parameter/scroll_velocity_pixels = Vector2(-7, -5)
+[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_hifdc"]
+data = PackedVector3Array(-13.598646, -21.527378, 3.4402227, -13.598646, -21.04931, 3.716229, -13.64679, -21.345833, 3.1714065, -13.64679, -21.345833, 3.1714065, -13.598646, -21.04931, 3.716229, -13.598646, -21.04931, 3.1642165, -13.598646, -21.601322, 3.716229, -13.598646, -21.04931, 3.716229, -13.598646, -21.527378, 3.4402227, -13.598646, -21.04931, 3.1642165, -13.598646, -21.04931, 3.716229, -13.598646, -20.773304, 3.238161, -13.604641, -21.54901, 3.9200878, -13.598646, -21.04931, 3.716229, -13.598646, -21.601322, 3.716229, -13.598646, -20.773304, 3.238161, -13.598646, -21.04931, 3.716229, -13.598646, -20.571243, 3.4402227, -13.598646, -21.325317, 4.194297, -13.598646, -21.04931, 3.716229, -13.604641, -21.54901, 3.9200878, -13.598646, -20.571243, 3.4402227, -13.598646, -21.04931, 3.716229, -13.598646, -20.4973, 3.716229, -13.602205, -21.078318, 4.268241, -13.598646, -21.04931, 3.716229, -13.598646, -21.325317, 4.194297, -13.598646, -20.4973, 3.716229, -13.598646, -21.04931, 3.716229, -13.598646, -20.571243, 3.992235, -13.598646, -20.773304, 4.194297, -13.598646, -21.04931, 3.716229, -13.602205, -21.078318, 4.268241, -13.598646, -20.571243, 3.992235, -13.598646, -21.04931, 3.716229, -13.598646, -20.773304, 4.194297, -19.042458, -21.325317, 3.2381601, -19.042458, -21.04931, 3.716228, -19.042458, -21.527378, 3.4402218, -19.042458, -21.527378, 3.4402218, -19.042458, -21.04931, 3.716228, -19.042458, -21.601322, 3.716228, -19.042458, -21.04931, 3.1642156, -19.042458, -21.04931, 3.716228, -19.042458, -21.325317, 3.2381601, -19.042458, -21.601322, 3.716228, -19.042458, -21.04931, 3.716228, -19.042458, -21.527378, 3.992234, -19.042458, -20.773304, 3.2381601, -19.042458, -21.04931, 3.716228, -19.042458, -21.04931, 3.1642156, -19.042458, -21.527378, 3.992234, -19.042458, -21.04931, 3.716228, -19.042458, -21.325317, 4.194296, -18.784327, -20.60149, 3.4511306, -19.042458, -21.04931, 3.716228, -19.042458, -20.773304, 3.2381601, -19.042458, -21.325317, 4.194296, -19.042458, -21.04931, 3.716228, -19.042458, -21.04931, 4.26824, -19.042458, -20.4973, 3.716228, -19.042458, -21.04931, 3.716228, -18.784327, -20.60149, 3.4511306, -19.042458, -21.04931, 4.26824, -19.042458, -21.04931, 3.716228, -19.042458, -20.773304, 4.194296, -19.042458, -20.571243, 3.992234, -19.042458, -21.04931, 3.716228, -19.042458, -20.4973, 3.716228, -19.042458, -20.773304, 4.194296, -19.042458, -21.04931, 3.716228, -19.042458, -20.571243, 3.992234, -14.534702, -21.32513, 3.238533, -17.467253, -21.04931, 3.1645257, -17.467253, -21.32513, 3.2384703, -17.467253, -21.32513, 3.2384703, -19.084044, -21.586075, 3.4063175, -17.467253, -21.52707, 3.440408, -17.467253, -21.32513, 3.2384703, -19.084044, -21.35922, 3.1794631, -19.084044, -21.586075, 3.4063175, -17.467253, -21.04931, 3.1645257, -19.084044, -21.35922, 3.1794631, -17.467253, -21.32513, 3.2384703, -17.467253, -21.32513, 3.2384703, -17.467253, -21.52707, 3.440408, -14.516907, -21.527006, 3.4404085, -17.467253, -21.32513, 3.2384703, -14.516907, -21.527006, 3.4404085, -14.534702, -21.32513, 3.238533, -17.467253, -21.04931, 3.1645257, -19.084044, -21.04931, 3.0964072, -19.084044, -21.35922, 3.1794631, -13.605204, -21.379738, 3.1126475, -14.534702, -21.32513, 3.238533, -14.516907, -21.527006, 3.4404085, -13.605204, -21.379738, 3.1126475, -14.516907, -21.527006, 3.4404085, -13.55706, -21.586075, 3.4063187, -13.55706, -21.04931, 3.0964081, -14.534702, -21.32513, 3.238533, -13.605204, -21.379738, 3.1126475, -13.55706, -21.04931, 3.0964081, -14.519905, -21.04931, 3.1645882, -14.534702, -21.32513, 3.238533, -14.534702, -21.32513, 3.238533, -14.519905, -21.04931, 3.1645882, -17.467253, -21.04931, 3.1645257, -13.55706, -20.7394, 3.179464, -14.519905, -21.04931, 3.1645882, -13.55706, -21.04931, 3.0964081, -17.467253, -20.77349, 3.2384703, -19.084044, -21.04931, 3.0964072, -17.467253, -21.04931, 3.1645257, -17.467253, -20.77349, 3.2384703, -17.467253, -21.04931, 3.1645257, -14.519905, -21.04931, 3.1645882, -17.467253, -20.77349, 3.2384703, -19.084044, -20.7394, 3.1794631, -19.084044, -21.04931, 3.0964072, -17.467253, -20.571552, 3.440408, -19.084044, -20.7394, 3.1794631, -17.467253, -20.77349, 3.2384703, -17.467253, -20.571552, 3.440408, -18.82591, -20.542793, 3.4172263, -19.084044, -20.7394, 3.1794631, -17.467253, -20.77349, 3.2384703, -14.519905, -21.04931, 3.1645882, -14.509039, -20.77349, 3.238533, -17.467253, -20.571552, 3.440408, -17.467253, -20.77349, 3.2384703, -14.509039, -20.77349, 3.238533, -13.55706, -20.7394, 3.179464, -14.509039, -20.77349, 3.238533, -14.519905, -21.04931, 3.1645882, -17.467253, -20.571552, 3.440408, -14.509039, -20.77349, 3.238533, -14.509039, -20.571615, 3.4404085, -13.55706, -20.512547, 3.4063187, -14.509039, -20.77349, 3.238533, -13.55706, -20.7394, 3.179464, -13.55706, -20.512547, 3.4063187, -14.509039, -20.571615, 3.4404085, -14.509039, -20.77349, 3.238533, -17.467253, -21.52707, 3.440408, -14.509039, -21.60095, 3.7162287, -14.516907, -21.527006, 3.4404085, -13.55706, -21.586075, 3.4063187, -14.516907, -21.527006, 3.4404085, -14.509039, -21.60095, 3.7162287, -13.55706, -21.586075, 3.4063187, -14.509039, -21.60095, 3.7162287, -13.55706, -21.669132, 3.716229, -13.55706, -21.669132, 3.716229, -14.509039, -21.60095, 3.7162287, -14.511475, -21.527006, 3.992049, -13.55706, -21.669132, 3.716229, -14.511475, -21.527006, 3.992049, -13.563242, -21.607708, 3.9539921, -17.467253, -21.601013, 3.7162282, -14.511475, -21.527006, 3.992049, -14.509039, -21.60095, 3.7162287, -17.467253, -21.52707, 3.440408, -17.467253, -21.601013, 3.7162282, -14.509039, -21.60095, 3.7162287, -17.467253, -21.601013, 3.7162282, -17.467253, -21.52707, 3.9920485, -14.511475, -21.527006, 3.992049, -17.467253, -21.601013, 3.7162282, -19.084044, -21.586075, 4.0261383, -17.467253, -21.52707, 3.9920485, -17.467253, -21.601013, 3.7162282, -19.084044, -21.669132, 3.716228, -19.084044, -21.586075, 4.0261383, -17.467253, -21.52707, 3.440408, -19.084044, -21.669132, 3.716228, -17.467253, -21.601013, 3.7162282, -17.467253, -21.52707, 3.440408, -19.084044, -21.586075, 3.4063175, -19.084044, -21.669132, 3.716228, -17.467253, -21.52707, 3.9920485, -14.509039, -21.32513, 4.1939244, -14.511475, -21.527006, 3.992049, -13.563242, -21.607708, 3.9539921, -14.511475, -21.527006, 3.992049, -14.509039, -21.32513, 4.1939244, -13.563242, -21.607708, 3.9539921, -14.509039, -21.32513, 4.1939244, -13.557062, -21.35922, 4.2529936, -13.557062, -21.35922, 4.2529936, -14.509039, -21.32513, 4.1939244, -14.510912, -21.04931, 4.267869, -13.557062, -21.35922, 4.2529936, -14.510912, -21.04931, 4.267869, -13.560621, -21.078318, 4.3360496, -17.467253, -21.52707, 3.9920485, -17.467253, -21.32513, 4.193986, -14.509039, -21.32513, 4.1939244, -17.467253, -21.32513, 4.193986, -14.510912, -21.04931, 4.267869, -14.509039, -21.32513, 4.1939244, -17.467253, -21.52707, 3.9920485, -19.084044, -21.35922, 4.2529926, -17.467253, -21.32513, 4.193986, -17.467253, -21.52707, 3.9920485, -19.084044, -21.586075, 4.0261383, -19.084044, -21.35922, 4.2529926, -17.467253, -21.32513, 4.193986, -19.084044, -21.35922, 4.2529926, -19.084044, -21.04931, 4.3360486, -17.467253, -21.32513, 4.193986, -19.084044, -21.04931, 4.3360486, -17.467253, -21.04931, 4.2679305, -17.467253, -21.32513, 4.193986, -17.467253, -21.04931, 4.2679305, -14.510912, -21.04931, 4.267869, -17.467253, -21.04931, 4.2679305, -19.084044, -21.04931, 4.3360486, -19.084044, -20.7394, 4.2529926, -13.560621, -21.078318, 4.3360496, -14.510912, -21.04931, 4.267869, -14.510912, -20.795122, 4.1217775, -17.467253, -21.04931, 4.2679305, -14.510912, -20.795122, 4.1217775, -14.510912, -21.04931, 4.267869, -13.560621, -21.078318, 4.3360496, -14.510912, -20.795122, 4.1217775, -13.557062, -20.7394, 4.2529936, -17.467253, -21.04931, 4.2679305, -19.084044, -20.7394, 4.2529926, -17.467253, -20.77349, 4.193986, -17.467253, -21.04931, 4.2679305, -17.467253, -20.77349, 4.193986, -14.510912, -20.795122, 4.1217775, -17.467253, -20.77349, 4.193986, -19.084044, -20.7394, 4.2529926, -19.084044, -20.512547, 4.0261383, -17.467253, -20.77349, 4.193986, -19.084044, -20.512547, 4.0261383, -17.467253, -20.571552, 3.9920485, -17.467253, -20.77349, 4.193986, -17.467253, -20.571552, 3.9920485, -14.509039, -20.571615, 3.992049, -17.467253, -20.77349, 4.193986, -14.509039, -20.571615, 3.992049, -14.510912, -20.795122, 4.1217775, -13.557062, -20.7394, 4.2529936, -14.510912, -20.795122, 4.1217775, -14.509039, -20.571615, 3.992049, -13.557062, -20.7394, 4.2529936, -14.509039, -20.571615, 3.992049, -13.55706, -20.512547, 4.0261393, -17.467253, -20.571552, 3.9920485, -14.509039, -20.497732, 3.7162287, -14.509039, -20.571615, 3.992049, -13.55706, -20.512547, 4.0261393, -14.509039, -20.571615, 3.992049, -14.509039, -20.497732, 3.7162287, -13.55706, -20.512547, 4.0261393, -14.509039, -20.497732, 3.7162287, -13.55706, -20.42949, 3.716229, -13.55706, -20.42949, 3.716229, -14.509039, -20.497732, 3.7162287, -14.509039, -20.571615, 3.4404085, -13.55706, -20.42949, 3.716229, -14.509039, -20.571615, 3.4404085, -13.55706, -20.512547, 3.4063187, -17.467253, -20.497608, 3.7162282, -14.509039, -20.571615, 3.4404085, -14.509039, -20.497732, 3.7162287, -17.467253, -20.571552, 3.9920485, -17.467253, -20.497608, 3.7162282, -14.509039, -20.497732, 3.7162287, -17.467253, -20.497608, 3.7162282, -17.467253, -20.571552, 3.440408, -14.509039, -20.571615, 3.4404085, -17.467253, -20.497608, 3.7162282, -18.82591, -20.542793, 3.4172263, -17.467253, -20.571552, 3.440408, -17.467253, -20.497608, 3.7162282, -19.084044, -20.42949, 3.716228, -18.82591, -20.542793, 3.4172263, -17.467253, -20.571552, 3.9920485, -19.084044, -20.42949, 3.716228, -17.467253, -20.497608, 3.7162282, -17.467253, -20.571552, 3.9920485, -19.084044, -20.512547, 4.0261383, -19.084044, -20.42949, 3.716228, -19.084044, -21.35922, 3.1794631, -19.084044, -21.586075, 3.4063175, -19.084044, -21.586075, 3.4063175, -19.084044, -21.586075, 3.4063175, -19.084044, -21.586075, 3.4063175, -19.084044, -21.669132, 3.716228, -19.084044, -21.35922, 3.1794631, -19.084044, -21.35922, 3.1794631, -19.084044, -21.586075, 3.4063175, -19.084044, -21.04931, 3.0964072, -19.084044, -21.35922, 3.1794631, -19.084044, -21.35922, 3.1794631, -19.084044, -21.04931, 3.0964072, -19.084044, -21.04931, 3.0964072, -19.084044, -21.35922, 3.1794631, -19.084044, -21.586075, 3.4063175, -19.084044, -21.669132, 3.716228, -19.084044, -21.669132, 3.716228, -19.084044, -21.669132, 3.716228, -19.084044, -21.669132, 3.716228, -19.084044, -21.586075, 4.0261383, -19.084044, -21.669132, 3.716228, -19.084044, -21.586075, 4.0261383, -19.084044, -21.586075, 4.0261383, -19.084044, -21.586075, 4.0261383, -19.084044, -21.586075, 4.0261383, -19.084044, -21.35922, 4.2529926, -19.084044, -21.586075, 4.0261383, -19.084044, -21.35922, 4.2529926, -19.084044, -21.35922, 4.2529926, -19.084044, -21.35922, 4.2529926, -19.084044, -21.35922, 4.2529926, -19.084044, -21.04931, 4.3360486, -19.084044, -21.35922, 4.2529926, -19.084044, -21.04931, 4.3360486, -19.084044, -21.04931, 4.3360486, -19.084044, -21.04931, 4.3360486, -19.084044, -21.04931, 4.3360486, -19.084044, -20.7394, 4.2529926, -19.084044, -21.04931, 4.3360486, -19.084044, -20.7394, 4.2529926, -19.084044, -20.7394, 4.2529926, -19.084044, -20.7394, 4.2529926, -19.084044, -20.7394, 4.2529926, -19.084044, -20.512547, 4.0261383, -19.084044, -20.7394, 4.2529926, -19.084044, -20.512547, 4.0261383, -19.084044, -20.512547, 4.0261383, -19.084044, -20.512547, 4.0261383, -19.084044, -20.512547, 4.0261383, -19.084044, -20.42949, 3.716228, -19.084044, -20.512547, 4.0261383, -19.084044, -20.42949, 3.716228, -19.084044, -20.42949, 3.716228, -19.084044, -20.42949, 3.716228, -19.084044, -20.42949, 3.716228, -18.82591, -20.542793, 3.4172263, -19.084044, -20.42949, 3.716228, -18.82591, -20.542793, 3.4172263, -18.82591, -20.542793, 3.4172263, -18.82591, -20.542793, 3.4172263, -19.084044, -20.7394, 3.1794631, -19.084044, -20.7394, 3.1794631, -18.82591, -20.542793, 3.4172263, -18.82591, -20.542793, 3.4172263, -19.084044, -20.7394, 3.1794631, -19.084044, -20.7394, 3.1794631, -19.084044, -21.04931, 3.0964072, -19.084044, -21.04931, 3.0964072, -19.084044, -20.7394, 3.1794631, -19.084044, -20.7394, 3.1794631, -19.084044, -21.04931, 3.0964072, -13.55706, -21.586075, 3.4063187, -13.605204, -21.345833, 3.1714065, -13.605204, -21.379738, 3.1126475, -13.605204, -21.379738, 3.1126475, -13.605204, -21.345833, 3.1714065, -13.55706, -21.04931, 3.1642165, -13.55706, -21.586075, 3.4063187, -13.55706, -21.527378, 3.4402227, -13.605204, -21.345833, 3.1714065, -13.605204, -21.379738, 3.1126475, -13.55706, -21.04931, 3.1642165, -13.55706, -21.04931, 3.0964081, -13.55706, -21.669132, 3.716229, -13.55706, -21.527378, 3.4402227, -13.55706, -21.586075, 3.4063187, -13.55706, -21.04931, 3.0964081, -13.55706, -21.04931, 3.1642165, -13.55706, -20.773304, 3.238161, -13.55706, -21.669132, 3.716229, -13.55706, -21.601322, 3.716229, -13.55706, -21.527378, 3.4402227, -13.55706, -21.04931, 3.0964081, -13.55706, -20.773304, 3.238161, -13.55706, -20.7394, 3.179464, -13.563242, -21.607708, 3.9539921, -13.55706, -21.601322, 3.716229, -13.55706, -21.669132, 3.716229, -13.55706, -20.7394, 3.179464, -13.55706, -20.773304, 3.238161, -13.55706, -20.571243, 3.4402227, -13.563242, -21.607708, 3.9539921, -13.563242, -21.54901, 3.9200878, -13.55706, -21.601322, 3.716229, -13.55706, -20.7394, 3.179464, -13.55706, -20.571243, 3.4402227, -13.55706, -20.512547, 3.4063187, -13.557062, -21.35922, 4.2529936, -13.563242, -21.54901, 3.9200878, -13.563242, -21.607708, 3.9539921, -13.55706, -20.512547, 3.4063187, -13.55706, -20.571243, 3.4402227, -13.55706, -20.4973, 3.716229, -13.557062, -21.35922, 4.2529936, -13.55706, -21.325317, 4.194297, -13.563242, -21.54901, 3.9200878, -13.55706, -20.512547, 3.4063187, -13.55706, -20.4973, 3.716229, -13.55706, -20.42949, 3.716229, -13.560621, -21.078318, 4.3360496, -13.55706, -21.325317, 4.194297, -13.557062, -21.35922, 4.2529936, -13.55706, -20.42949, 3.716229, -13.55706, -20.4973, 3.716229, -13.55706, -20.571243, 3.9922352, -13.560621, -21.078318, 4.3360496, -13.560621, -21.078318, 4.268241, -13.55706, -21.325317, 4.194297, -13.55706, -20.42949, 3.716229, -13.55706, -20.571243, 3.9922352, -13.55706, -20.512547, 4.0261393, -13.557062, -20.7394, 4.2529936, -13.560621, -21.078318, 4.268241, -13.560621, -21.078318, 4.3360496, -13.55706, -20.512547, 4.0261393, -13.55706, -20.571243, 3.9922352, -13.55706, -20.773304, 4.194297, -13.557062, -20.7394, 4.2529936, -13.55706, -20.773304, 4.194297, -13.560621, -21.078318, 4.268241, -13.55706, -20.512547, 4.0261393, -13.55706, -20.773304, 4.194297, -13.557062, -20.7394, 4.2529936, -19.084044, -21.35922, 3.1794631, -19.084044, -21.527378, 3.4402218, -19.084044, -21.586075, 3.4063175, -19.084044, -21.586075, 3.4063175, -19.084044, -21.527378, 3.4402218, -19.084044, -21.601322, 3.716228, -19.084044, -21.35922, 3.1794631, -19.084044, -21.325317, 3.2381601, -19.084044, -21.527378, 3.4402218, -19.084044, -21.586075, 3.4063175, -19.084044, -21.601322, 3.716228, -19.084044, -21.669132, 3.716228, -19.084044, -21.04931, 3.0964072, -19.084044, -21.325317, 3.2381601, -19.084044, -21.35922, 3.1794631, -19.084044, -21.669132, 3.716228, -19.084044, -21.601322, 3.716228, -19.084044, -21.527378, 3.992234, -19.084044, -21.04931, 3.0964072, -19.084044, -21.04931, 3.1642156, -19.084044, -21.325317, 3.2381601, -19.084044, -21.669132, 3.716228, -19.084044, -21.527378, 3.992234, -19.084044, -21.586075, 4.0261383, -19.084044, -20.7394, 3.1794631, -19.084044, -21.04931, 3.1642156, -19.084044, -21.04931, 3.0964072, -19.084044, -21.586075, 4.0261383, -19.084044, -21.527378, 3.992234, -19.084044, -21.325317, 4.194296, -19.084044, -20.7394, 3.1794631, -19.084044, -20.773304, 3.2381601, -19.084044, -21.04931, 3.1642156, -19.084044, -21.586075, 4.0261383, -19.084044, -21.325317, 4.194296, -19.084044, -21.35922, 4.2529926, -18.82591, -20.542793, 3.4172263, -19.084044, -20.773304, 3.2381601, -19.084044, -20.7394, 3.1794631, -19.084044, -21.35922, 4.2529926, -19.084044, -21.325317, 4.194296, -19.084044, -21.04931, 4.26824, -18.82591, -20.542793, 3.4172263, -18.82591, -20.60149, 3.4511306, -19.084044, -20.773304, 3.2381601, -19.084044, -21.35922, 4.2529926, -19.084044, -21.04931, 4.26824, -19.084044, -21.04931, 4.3360486, -19.084044, -20.42949, 3.716228, -18.82591, -20.60149, 3.4511306, -18.82591, -20.542793, 3.4172263, -19.084044, -21.04931, 4.3360486, -19.084044, -21.04931, 4.26824, -19.084044, -20.773304, 4.194296, -19.084044, -20.42949, 3.716228, -19.084044, -20.4973, 3.716228, -18.82591, -20.60149, 3.4511306, -19.084044, -21.04931, 4.3360486, -19.084044, -20.773304, 4.194296, -19.084044, -20.7394, 4.2529926, -19.084044, -20.512547, 4.0261383, -19.084044, -20.4973, 3.716228, -19.084044, -20.42949, 3.716228, -19.084044, -20.7394, 4.2529926, -19.084044, -20.773304, 4.194296, -19.084044, -20.571243, 3.992234, -19.084044, -20.512547, 4.0261383, -19.084044, -20.571243, 3.992234, -19.084044, -20.4973, 3.716228, -19.084044, -20.7394, 4.2529926, -19.084044, -20.571243, 3.992234, -19.084044, -20.512547, 4.0261383, -13.55706, -21.527378, 3.4402227, -13.64679, -21.345833, 3.1714065, -13.605204, -21.345833, 3.1714065, -13.55706, -21.527378, 3.4402227, -13.598646, -21.527378, 3.4402227, -13.64679, -21.345833, 3.1714065, -13.55706, -21.601322, 3.716229, -13.598646, -21.527378, 3.4402227, -13.55706, -21.527378, 3.4402227, -13.55706, -21.601322, 3.716229, -13.598646, -21.601322, 3.716229, -13.598646, -21.527378, 3.4402227, -13.563242, -21.54901, 3.9200878, -13.598646, -21.601322, 3.716229, -13.55706, -21.601322, 3.716229, -13.563242, -21.54901, 3.9200878, -13.604641, -21.54901, 3.9200878, -13.598646, -21.601322, 3.716229, -13.55706, -21.325317, 4.194297, -13.604641, -21.54901, 3.9200878, -13.563242, -21.54901, 3.9200878, -13.55706, -21.325317, 4.194297, -13.598646, -21.325317, 4.194297, -13.604641, -21.54901, 3.9200878, -13.560621, -21.078318, 4.268241, -13.598646, -21.325317, 4.194297, -13.55706, -21.325317, 4.194297, -13.560621, -21.078318, 4.268241, -13.602205, -21.078318, 4.268241, -13.598646, -21.325317, 4.194297, -13.55706, -20.773304, 4.194297, -13.602205, -21.078318, 4.268241, -13.560621, -21.078318, 4.268241, -13.55706, -20.773304, 4.194297, -13.598646, -20.773304, 4.194297, -13.602205, -21.078318, 4.268241, -13.55706, -20.571243, 3.9922352, -13.598646, -20.773304, 4.194297, -13.55706, -20.773304, 4.194297, -13.55706, -20.571243, 3.9922352, -13.598646, -20.571243, 3.992235, -13.598646, -20.773304, 4.194297, -13.55706, -20.4973, 3.716229, -13.598646, -20.571243, 3.992235, -13.55706, -20.571243, 3.9922352, -13.55706, -20.4973, 3.716229, -13.598646, -20.4973, 3.716229, -13.598646, -20.571243, 3.992235, -13.55706, -20.571243, 3.4402227, -13.598646, -20.4973, 3.716229, -13.55706, -20.4973, 3.716229, -13.55706, -20.571243, 3.4402227, -13.598646, -20.571243, 3.4402227, -13.598646, -20.4973, 3.716229, -13.55706, -20.773304, 3.238161, -13.598646, -20.571243, 3.4402227, -13.55706, -20.571243, 3.4402227, -13.55706, -20.773304, 3.238161, -13.598646, -20.773304, 3.238161, -13.598646, -20.571243, 3.4402227, -13.55706, -21.04931, 3.1642165, -13.598646, -20.773304, 3.238161, -13.55706, -20.773304, 3.238161, -13.55706, -21.04931, 3.1642165, -13.598646, -21.04931, 3.1642165, -13.598646, -20.773304, 3.238161, -13.605204, -21.345833, 3.1714065, -13.598646, -21.04931, 3.1642165, -13.55706, -21.04931, 3.1642165, -13.605204, -21.345833, 3.1714065, -13.64679, -21.345833, 3.1714065, -13.598646, -21.04931, 3.1642165, -19.084044, -21.325317, 3.2381601, -19.042458, -21.527378, 3.4402218, -19.084044, -21.527378, 3.4402218, -19.084044, -21.325317, 3.2381601, -19.042458, -21.325317, 3.2381601, -19.042458, -21.527378, 3.4402218, -19.084044, -21.527378, 3.4402218, -19.042458, -21.601322, 3.716228, -19.084044, -21.601322, 3.716228, -19.084044, -21.527378, 3.4402218, -19.042458, -21.527378, 3.4402218, -19.042458, -21.601322, 3.716228, -19.084044, -21.601322, 3.716228, -19.042458, -21.527378, 3.992234, -19.084044, -21.527378, 3.992234, -19.084044, -21.601322, 3.716228, -19.042458, -21.601322, 3.716228, -19.042458, -21.527378, 3.992234, -19.084044, -21.527378, 3.992234, -19.042458, -21.325317, 4.194296, -19.084044, -21.325317, 4.194296, -19.084044, -21.527378, 3.992234, -19.042458, -21.527378, 3.992234, -19.042458, -21.325317, 4.194296, -19.084044, -21.325317, 4.194296, -19.042458, -21.04931, 4.26824, -19.084044, -21.04931, 4.26824, -19.084044, -21.325317, 4.194296, -19.042458, -21.325317, 4.194296, -19.042458, -21.04931, 4.26824, -19.084044, -21.04931, 4.26824, -19.042458, -21.04931, 4.26824, -19.042458, -20.773304, 4.194296, -19.084044, -21.04931, 4.26824, -19.042458, -20.773304, 4.194296, -19.084044, -20.773304, 4.194296, -19.084044, -20.773304, 4.194296, -19.042458, -20.571243, 3.992234, -19.084044, -20.571243, 3.992234, -19.084044, -20.773304, 4.194296, -19.042458, -20.773304, 4.194296, -19.042458, -20.571243, 3.992234, -19.084044, -20.571243, 3.992234, -19.042458, -20.4973, 3.716228, -19.084044, -20.4973, 3.716228, -19.084044, -20.571243, 3.992234, -19.042458, -20.571243, 3.992234, -19.042458, -20.4973, 3.716228, -19.084044, -20.4973, 3.716228, -18.784327, -20.60149, 3.4511306, -18.82591, -20.60149, 3.4511306, -19.084044, -20.4973, 3.716228, -19.042458, -20.4973, 3.716228, -18.784327, -20.60149, 3.4511306, -18.82591, -20.60149, 3.4511306, -19.042458, -20.773304, 3.2381601, -19.084044, -20.773304, 3.2381601, -18.82591, -20.60149, 3.4511306, -18.784327, -20.60149, 3.4511306, -19.042458, -20.773304, 3.2381601, -19.084044, -20.773304, 3.2381601, -19.042458, -21.04931, 3.1642156, -19.084044, -21.04931, 3.1642156, -19.084044, -20.773304, 3.2381601, -19.042458, -20.773304, 3.2381601, -19.042458, -21.04931, 3.1642156, -19.084044, -21.04931, 3.1642156, -19.042458, -21.04931, 3.1642156, -19.042458, -21.325317, 3.2381601, -19.084044, -21.04931, 3.1642156, -19.042458, -21.325317, 3.2381601, -19.084044, -21.325317, 3.2381601, -0.49230337, 3.2260702, -2.5408025, -0.2174604, 3.7041378, -2.5661154, -0.75557137, 3.4076157, -2.4682097, -0.75557137, 3.4076157, -2.4682097, -0.2174604, 3.7041378, -2.5661154, -0.7671461, 3.7041378, -2.5154896, -0.2174604, 3.1521254, -2.5661154, -0.2174604, 3.7041378, -2.5661154, -0.49230337, 3.2260702, -2.5408025, -0.7671461, 3.7041378, -2.5154896, -0.2174604, 3.7041378, -2.5661154, -0.6935134, 3.980144, -2.5222712, -0.01391077, 3.2044384, -2.5788422, -0.2174604, 3.7041378, -2.5661154, -0.2174604, 3.1521254, -2.5661154, -0.6935134, 3.980144, -2.5222712, -0.2174604, 3.7041378, -2.5661154, -0.49230337, 4.1822057, -2.5408025, 0.2585926, 3.4281316, -2.6099591, -0.2174604, 3.7041378, -2.5661154, -0.01391077, 3.2044384, -2.5788422, -0.49230337, 4.1822057, -2.5408025, -0.2174604, 3.7041378, -2.5661154, -0.2174604, 4.2561502, -2.5661154, 0.33255196, 3.6751301, -2.6131968, -0.2174604, 3.7041378, -2.5661154, 0.2585926, 3.4281316, -2.6099591, -0.2174604, 4.2561502, -2.5661154, -0.2174604, 3.7041378, -2.5661154, 0.057382584, 4.1822057, -2.5914283, 0.2585926, 3.980144, -2.6099591, -0.2174604, 3.7041378, -2.5661154, 0.33255196, 3.6751301, -2.6131968, 0.057382584, 4.1822057, -2.5914283, -0.2174604, 3.7041378, -2.5661154, 0.2585926, 3.980144, -2.6099591, -0.19425559, 3.4281316, 2.8985977, 0.2817974, 3.7041378, 2.8547535, 0.0069544315, 3.2260702, 2.8800664, 0.0069544315, 3.2260702, 2.8800664, 0.2817974, 3.7041378, 2.8547535, 0.2817974, 3.1521254, 2.8547535, -0.26788855, 3.7041378, 2.9053793, 0.2817974, 3.7041378, 2.8547535, -0.19425559, 3.4281316, 2.8985977, 0.2817974, 3.1521254, 2.8547535, 0.2817974, 3.7041378, 2.8547535, 0.55664027, 3.2260702, 2.8294406, -0.19425559, 3.980144, 2.8985977, 0.2817974, 3.7041378, 2.8547535, -0.26788855, 3.7041378, 2.9053793, 0.55664027, 3.2260702, 2.8294406, 0.2817974, 3.7041378, 2.8547535, 0.75785017, 3.4281316, 2.8109093, -0.0058562756, 4.1519585, 2.6220222, 0.2817974, 3.7041378, 2.8547535, -0.19425559, 3.980144, 2.8985977, 0.75785017, 3.4281316, 2.8109093, 0.2817974, 3.7041378, 2.8547535, 0.8314831, 3.7041378, 2.8041277, 0.2817974, 4.2561502, 2.8547535, 0.2817974, 3.7041378, 2.8547535, -0.0058562756, 4.1519585, 2.6220222, 0.8314831, 3.7041378, 2.8041277, 0.2817974, 3.7041378, 2.8547535, 0.75785017, 3.980144, 2.8109093, 0.55664027, 4.1822057, 2.8294406, 0.2817974, 3.7041378, 2.8547535, 0.2817974, 4.2561502, 2.8547535, 0.75785017, 3.980144, 2.8109093, 0.2817974, 3.7041378, 2.8547535, 0.55664027, 4.1822057, 2.8294406, -0.6072962, 3.4283175, -1.5901942, -0.41204357, 3.7041378, 1.3367851, -0.33841062, 3.4283175, 1.3300035, -0.33841062, 3.4283175, 1.3300035, -0.022993088, 3.1673732, 2.9245868, -0.1373241, 3.2263799, 1.3114836, -0.33841062, 3.4283175, 1.3300035, -0.24889135, 3.3942275, 2.9453917, -0.022993088, 3.1673732, 2.9245868, -0.41204357, 3.7041378, 1.3367851, -0.24889135, 3.3942275, 2.9453917, -0.33841062, 3.4283175, 1.3300035, -0.33841062, 3.4283175, 1.3300035, -0.1373241, 3.2263799, 1.3114836, -0.40790343, 3.2264419, -1.6264291, -0.33841062, 3.4283175, 1.3300035, -0.40790343, 3.2264419, -1.6264291, -0.6072962, 3.4283175, -1.5901942, -0.41204357, 3.7041378, 1.3367851, -0.33159733, 3.7041378, 2.9530087, -0.24889135, 3.3942275, 2.9453917, -0.81789684, 3.3737113, -2.5042315, -0.6072962, 3.4283175, -1.5901942, -0.40790343, 3.2264419, -1.6264291, -0.81789684, 3.3737113, -2.5042315, -0.40790343, 3.2264419, -1.6264291, -0.5298786, 3.1673732, -2.5791035, -0.83848286, 3.7041378, -2.5506816, -0.6072962, 3.4283175, -1.5901942, -0.81789684, 3.3737113, -2.5042315, -0.83848286, 3.7041378, -2.5506816, -0.6822865, 3.7041378, -1.5981488, -0.6072962, 3.4283175, -1.5901942, -0.6072962, 3.4283175, -1.5901942, -0.6822865, 3.7041378, -1.5981488, -0.41204357, 3.7041378, 1.3367851, -0.7557769, 4.014048, -2.5582986, -0.6822865, 3.7041378, -1.5981488, -0.83848286, 3.7041378, -2.5506816, -0.33841062, 3.979958, 1.3300035, -0.33159733, 3.7041378, 2.9530087, -0.41204357, 3.7041378, 1.3367851, -0.33841062, 3.979958, 1.3300035, -0.41204357, 3.7041378, 1.3367851, -0.6822865, 3.7041378, -1.5981488, -0.33841062, 3.979958, 1.3300035, -0.24889135, 4.014048, 2.9453917, -0.33159733, 3.7041378, 2.9530087, -0.1373241, 4.1818957, 1.3114836, -0.24889135, 4.014048, 2.9453917, -0.33841062, 3.979958, 1.3300035, -0.1373241, 4.1818957, 1.3114836, -0.035803795, 4.210655, 2.666542, -0.24889135, 4.014048, 2.9453917, -0.33841062, 3.979958, 1.3300035, -0.6822865, 3.7041378, -1.5981488, -0.6096499, 3.979958, -1.6157494, -0.1373241, 4.1818957, 1.3114836, -0.33841062, 3.979958, 1.3300035, -0.6096499, 3.979958, -1.6157494, -0.7557769, 4.014048, -2.5582986, -0.6096499, 3.979958, -1.6157494, -0.6822865, 3.7041378, -1.5981488, -0.1373241, 4.1818957, 1.3114836, -0.6096499, 3.979958, -1.6157494, -0.40862513, 4.1818337, -1.6342635, -0.5298786, 4.2409024, -2.5791035, -0.6096499, 3.979958, -1.6157494, -0.7557769, 4.014048, -2.5582986, -0.5298786, 4.2409024, -2.5791035, -0.40862513, 4.1818337, -1.6342635, -0.6096499, 3.979958, -1.6157494, -0.1373241, 3.2263799, 1.3114836, -0.13396716, 3.1524973, -1.6595592, -0.40790343, 3.2264419, -1.6264291, -0.5298786, 3.1673732, -2.5791035, -0.40790343, 3.2264419, -1.6264291, -0.13396716, 3.1524973, -1.6595592, -0.5298786, 3.1673732, -2.5791035, -0.13396716, 3.1524973, -1.6595592, -0.22127414, 3.0843172, -2.6075258, -0.22127414, 3.0843172, -2.6075258, -0.13396716, 3.1524973, -1.6595592, 0.14091396, 3.2264419, -1.68243, -0.22127414, 3.0843172, -2.6075258, 0.14091396, 3.2264419, -1.68243, 0.016053915, 3.1457415, -2.6231756, 0.13733363, 3.1524353, 1.2861879, 0.14091396, 3.2264419, -1.68243, -0.13396716, 3.1524973, -1.6595592, -0.1373241, 3.2263799, 1.3114836, 0.13733363, 3.1524353, 1.2861879, -0.13396716, 3.1524973, -1.6595592, 0.13733363, 3.1524353, 1.2861879, 0.4119916, 3.2263799, 1.2608922, 0.14091396, 3.2264419, -1.68243, 0.13733363, 3.1524353, 1.2861879, 0.5942155, 3.1673732, 2.867742, 0.4119916, 3.2263799, 1.2608922, 0.13733363, 3.1524353, 1.2861879, 0.28561115, 3.0843172, 2.8961644, 0.5942155, 3.1673732, 2.867742, -0.1373241, 3.2263799, 1.3114836, 0.28561115, 3.0843172, 2.8961644, 0.13733363, 3.1524353, 1.2861879, -0.1373241, 3.2263799, 1.3114836, -0.022993088, 3.1673732, 2.9245868, 0.28561115, 3.0843172, 2.8961644, 0.4119916, 3.2263799, 1.2608922, 0.34171534, 3.4283175, -1.7033694, 0.14091396, 3.2264419, -1.68243, 0.016053915, 3.1457415, -2.6231756, 0.14091396, 3.2264419, -1.68243, 0.34171534, 3.4283175, -1.7033694, 0.016053915, 3.1457415, -2.6231756, 0.34171534, 3.4283175, -1.7033694, 0.31322837, 3.3942275, -2.656753, 0.31322837, 3.3942275, -2.656753, 0.34171534, 3.4283175, -1.7033694, 0.4155202, 3.7041378, -1.7082856, 0.31322837, 3.3942275, -2.656753, 0.4155202, 3.7041378, -1.7082856, 0.39626074, 3.6751301, -2.6608262, 0.4119916, 3.2263799, 1.2608922, 0.613078, 3.4283175, 1.2423723, 0.34171534, 3.4283175, -1.7033694, 0.613078, 3.4283175, 1.2423723, 0.4155202, 3.7041378, -1.7082856, 0.34171534, 3.4283175, -1.7033694, 0.4119916, 3.2263799, 1.2608922, 0.8201138, 3.3942275, 2.8469372, 0.613078, 3.4283175, 1.2423723, 0.4119916, 3.2263799, 1.2608922, 0.5942155, 3.1673732, 2.867742, 0.8201138, 3.3942275, 2.8469372, 0.613078, 3.4283175, 1.2423723, 0.8201138, 3.3942275, 2.8469372, 0.90281975, 3.7041378, 2.8393202, 0.613078, 3.4283175, 1.2423723, 0.90281975, 3.7041378, 2.8393202, 0.68671095, 3.7041378, 1.2355907, 0.613078, 3.4283175, 1.2423723, 0.68671095, 3.7041378, 1.2355907, 0.4155202, 3.7041378, -1.7082856, 0.68671095, 3.7041378, 1.2355907, 0.90281975, 3.7041378, 2.8393202, 0.8201138, 4.014048, 2.8469372, 0.39626074, 3.6751301, -2.6608262, 0.4155202, 3.7041378, -1.7082856, 0.2700441, 3.9583263, -1.6948872, 0.68671095, 3.7041378, 1.2355907, 0.2700441, 3.9583263, -1.6948872, 0.4155202, 3.7041378, -1.7082856, 0.39626074, 3.6751301, -2.6608262, 0.2700441, 3.9583263, -1.6948872, 0.31322837, 4.014048, -2.656753, 0.68671095, 3.7041378, 1.2355907, 0.8201138, 4.014048, 2.8469372, 0.613078, 3.979958, 1.2423723, 0.68671095, 3.7041378, 1.2355907, 0.613078, 3.979958, 1.2423723, 0.2700441, 3.9583263, -1.6948872, 0.613078, 3.979958, 1.2423723, 0.8201138, 4.014048, 2.8469372, 0.5942155, 4.2409024, 2.867742, 0.613078, 3.979958, 1.2423723, 0.5942155, 4.2409024, 2.867742, 0.4119916, 4.1818957, 1.2608922, 0.613078, 3.979958, 1.2423723, 0.4119916, 4.1818957, 1.2608922, 0.14069057, 4.1818337, -1.684855, 0.613078, 3.979958, 1.2423723, 0.14069057, 4.1818337, -1.684855, 0.2700441, 3.9583263, -1.6948872, 0.31322837, 4.014048, -2.656753, 0.2700441, 3.9583263, -1.6948872, 0.14069057, 4.1818337, -1.684855, 0.31322837, 4.014048, -2.656753, 0.14069057, 4.1818337, -1.684855, 0.0873301, 4.2409024, -2.6359482, 0.4119916, 4.1818957, 1.2608922, -0.13396716, 4.2557163, -1.6595592, 0.14069057, 4.1818337, -1.684855, 0.0873301, 4.2409024, -2.6359482, 0.14069057, 4.1818337, -1.684855, -0.13396716, 4.2557163, -1.6595592, 0.0873301, 4.2409024, -2.6359482, -0.13396716, 4.2557163, -1.6595592, -0.22127414, 4.3239584, -2.6075258, -0.22127414, 4.3239584, -2.6075258, -0.13396716, 4.2557163, -1.6595592, -0.40862513, 4.1818337, -1.6342635, -0.22127414, 4.3239584, -2.6075258, -0.40862513, 4.1818337, -1.6342635, -0.5298786, 4.2409024, -2.5791035, 0.13733363, 4.2558403, 1.2861879, -0.40862513, 4.1818337, -1.6342635, -0.13396716, 4.2557163, -1.6595592, 0.4119916, 4.1818957, 1.2608922, 0.13733363, 4.2558403, 1.2861879, -0.13396716, 4.2557163, -1.6595592, 0.13733363, 4.2558403, 1.2861879, -0.1373241, 4.1818957, 1.3114836, -0.40862513, 4.1818337, -1.6342635, 0.13733363, 4.2558403, 1.2861879, -0.035803795, 4.210655, 2.666542, -0.1373241, 4.1818957, 1.3114836, 0.13733363, 4.2558403, 1.2861879, 0.28561115, 4.3239584, 2.8961644, -0.035803795, 4.210655, 2.666542, 0.4119916, 4.1818957, 1.2608922, 0.28561115, 4.3239584, 2.8961644, 0.13733363, 4.2558403, 1.2861879, 0.4119916, 4.1818957, 1.2608922, 0.5942155, 4.2409024, 2.867742, 0.28561115, 4.3239584, 2.8961644, -0.24889135, 3.3942275, 2.9453917, -0.022993088, 3.1673732, 2.9245868, -0.022993088, 3.1673732, 2.9245868, -0.022993088, 3.1673732, 2.9245868, -0.022993088, 3.1673732, 2.9245868, 0.28561115, 3.0843172, 2.8961644, -0.24889135, 3.3942275, 2.9453917, -0.24889135, 3.3942275, 2.9453917, -0.022993088, 3.1673732, 2.9245868, -0.33159733, 3.7041378, 2.9530087, -0.24889135, 3.3942275, 2.9453917, -0.24889135, 3.3942275, 2.9453917, -0.33159733, 3.7041378, 2.9530087, -0.33159733, 3.7041378, 2.9530087, -0.24889135, 3.3942275, 2.9453917, -0.022993088, 3.1673732, 2.9245868, 0.28561115, 3.0843172, 2.8961644, 0.28561115, 3.0843172, 2.8961644, 0.28561115, 3.0843172, 2.8961644, 0.28561115, 3.0843172, 2.8961644, 0.5942155, 3.1673732, 2.867742, 0.28561115, 3.0843172, 2.8961644, 0.5942155, 3.1673732, 2.867742, 0.5942155, 3.1673732, 2.867742, 0.5942155, 3.1673732, 2.867742, 0.5942155, 3.1673732, 2.867742, 0.8201138, 3.3942275, 2.8469372, 0.5942155, 3.1673732, 2.867742, 0.8201138, 3.3942275, 2.8469372, 0.8201138, 3.3942275, 2.8469372, 0.8201138, 3.3942275, 2.8469372, 0.8201138, 3.3942275, 2.8469372, 0.90281975, 3.7041378, 2.8393202, 0.8201138, 3.3942275, 2.8469372, 0.90281975, 3.7041378, 2.8393202, 0.90281975, 3.7041378, 2.8393202, 0.90281975, 3.7041378, 2.8393202, 0.90281975, 3.7041378, 2.8393202, 0.8201138, 4.014048, 2.8469372, 0.90281975, 3.7041378, 2.8393202, 0.8201138, 4.014048, 2.8469372, 0.8201138, 4.014048, 2.8469372, 0.8201138, 4.014048, 2.8469372, 0.8201138, 4.014048, 2.8469372, 0.5942155, 4.2409024, 2.867742, 0.8201138, 4.014048, 2.8469372, 0.5942155, 4.2409024, 2.867742, 0.5942155, 4.2409024, 2.867742, 0.5942155, 4.2409024, 2.867742, 0.5942155, 4.2409024, 2.867742, 0.28561115, 4.3239584, 2.8961644, 0.5942155, 4.2409024, 2.867742, 0.28561115, 4.3239584, 2.8961644, 0.28561115, 4.3239584, 2.8961644, 0.28561115, 4.3239584, 2.8961644, 0.28561115, 4.3239584, 2.8961644, -0.035803795, 4.210655, 2.666542, 0.28561115, 4.3239584, 2.8961644, -0.035803795, 4.210655, 2.666542, -0.035803795, 4.210655, 2.666542, -0.035803795, 4.210655, 2.666542, -0.24889135, 4.014048, 2.9453917, -0.24889135, 4.014048, 2.9453917, -0.035803795, 4.210655, 2.666542, -0.035803795, 4.210655, 2.666542, -0.24889135, 4.014048, 2.9453917, -0.24889135, 4.014048, 2.9453917, -0.33159733, 3.7041378, 2.9530087, -0.33159733, 3.7041378, 2.9530087, -0.24889135, 4.014048, 2.9453917, -0.24889135, 4.014048, 2.9453917, -0.33159733, 3.7041378, 2.9530087, -0.5298786, 3.1673732, -2.5791035, -0.75938535, 3.4076157, -2.5096202, -0.81789684, 3.3737113, -2.5042315, -0.81789684, 3.3737113, -2.5042315, -0.75938535, 3.4076157, -2.5096202, -0.7709601, 3.7041378, -2.5569, -0.5298786, 3.1673732, -2.5791035, -0.49611712, 3.2260702, -2.582213, -0.75938535, 3.4076157, -2.5096202, -0.81789684, 3.3737113, -2.5042315, -0.7709601, 3.7041378, -2.5569, -0.83848286, 3.7041378, -2.5506816, -0.22127414, 3.0843172, -2.6075258, -0.49611712, 3.2260702, -2.582213, -0.5298786, 3.1673732, -2.5791035, -0.83848286, 3.7041378, -2.5506816, -0.7709601, 3.7041378, -2.5569, -0.69732714, 3.980144, -2.5636816, -0.22127414, 3.0843172, -2.6075258, -0.22127414, 3.1521254, -2.6075258, -0.49611712, 3.2260702, -2.582213, -0.83848286, 3.7041378, -2.5506816, -0.69732714, 3.980144, -2.5636816, -0.7557769, 4.014048, -2.5582986, 0.016053915, 3.1457415, -2.6231756, -0.22127414, 3.1521254, -2.6075258, -0.22127414, 3.0843172, -2.6075258, -0.7557769, 4.014048, -2.5582986, -0.69732714, 3.980144, -2.5636816, -0.49611712, 4.1822057, -2.582213, 0.016053915, 3.1457415, -2.6231756, -0.017707348, 3.2044384, -2.6200662, -0.22127414, 3.1521254, -2.6075258, -0.7557769, 4.014048, -2.5582986, -0.49611712, 4.1822057, -2.582213, -0.5298786, 4.2409024, -2.5791035, 0.31322837, 3.3942275, -2.656753, -0.017707348, 3.2044384, -2.6200662, 0.016053915, 3.1457415, -2.6231756, -0.5298786, 4.2409024, -2.5791035, -0.49611712, 4.1822057, -2.582213, -0.22127414, 4.2561502, -2.6075258, 0.31322837, 3.3942275, -2.656753, 0.25477862, 3.4281316, -2.65137, -0.017707348, 3.2044384, -2.6200662, -0.5298786, 4.2409024, -2.5791035, -0.22127414, 4.2561502, -2.6075258, -0.22127414, 4.3239584, -2.6075258, 0.39626074, 3.6751301, -2.6608262, 0.25477862, 3.4281316, -2.65137, 0.31322837, 3.3942275, -2.656753, -0.22127414, 4.3239584, -2.6075258, -0.22127414, 4.2561502, -2.6075258, 0.05356884, 4.1822057, -2.6328387, 0.39626074, 3.6751301, -2.6608262, 0.32873797, 3.6751301, -2.6546073, 0.25477862, 3.4281316, -2.65137, -0.22127414, 4.3239584, -2.6075258, 0.05356884, 4.1822057, -2.6328387, 0.0873301, 4.2409024, -2.6359482, 0.31322837, 4.014048, -2.656753, 0.32873797, 3.6751301, -2.6546073, 0.39626074, 3.6751301, -2.6608262, 0.0873301, 4.2409024, -2.6359482, 0.05356884, 4.1822057, -2.6328387, 0.25477862, 3.980144, -2.65137, 0.31322837, 4.014048, -2.656753, 0.25477862, 3.980144, -2.65137, 0.32873797, 3.6751301, -2.6546073, 0.0873301, 4.2409024, -2.6359482, 0.25477862, 3.980144, -2.65137, 0.31322837, 4.014048, -2.656753, -0.24889135, 3.3942275, 2.9453917, 0.010768175, 3.2260702, 2.9214773, -0.022993088, 3.1673732, 2.9245868, -0.022993088, 3.1673732, 2.9245868, 0.010768175, 3.2260702, 2.9214773, 0.28561115, 3.1521254, 2.8961644, -0.24889135, 3.3942275, 2.9453917, -0.19044161, 3.4281316, 2.9400086, 0.010768175, 3.2260702, 2.9214773, -0.022993088, 3.1673732, 2.9245868, 0.28561115, 3.1521254, 2.8961644, 0.28561115, 3.0843172, 2.8961644, -0.33159733, 3.7041378, 2.9530087, -0.19044161, 3.4281316, 2.9400086, -0.24889135, 3.3942275, 2.9453917, 0.28561115, 3.0843172, 2.8961644, 0.28561115, 3.1521254, 2.8961644, 0.56045413, 3.2260702, 2.8708515, -0.33159733, 3.7041378, 2.9530087, -0.2640748, 3.7041378, 2.9467902, -0.19044161, 3.4281316, 2.9400086, 0.28561115, 3.0843172, 2.8961644, 0.56045413, 3.2260702, 2.8708515, 0.5942155, 3.1673732, 2.867742, -0.24889135, 4.014048, 2.9453917, -0.2640748, 3.7041378, 2.9467902, -0.33159733, 3.7041378, 2.9530087, 0.5942155, 3.1673732, 2.867742, 0.56045413, 3.2260702, 2.8708515, 0.76166415, 3.4281316, 2.8523202, -0.24889135, 4.014048, 2.9453917, -0.19044161, 3.980144, 2.9400086, -0.2640748, 3.7041378, 2.9467902, 0.5942155, 3.1673732, 2.867742, 0.76166415, 3.4281316, 2.8523202, 0.8201138, 3.3942275, 2.8469372, -0.035803795, 4.210655, 2.666542, -0.19044161, 3.980144, 2.9400086, -0.24889135, 4.014048, 2.9453917, 0.8201138, 3.3942275, 2.8469372, 0.76166415, 3.4281316, 2.8523202, 0.8352971, 3.7041378, 2.8455386, -0.035803795, 4.210655, 2.666542, -0.002042532, 4.1519585, 2.6634326, -0.19044161, 3.980144, 2.9400086, 0.8201138, 3.3942275, 2.8469372, 0.8352971, 3.7041378, 2.8455386, 0.90281975, 3.7041378, 2.8393202, 0.28561115, 4.3239584, 2.8961644, -0.002042532, 4.1519585, 2.6634326, -0.035803795, 4.210655, 2.666542, 0.90281975, 3.7041378, 2.8393202, 0.8352971, 3.7041378, 2.8455386, 0.76166415, 3.980144, 2.8523202, 0.28561115, 4.3239584, 2.8961644, 0.28561115, 4.2561502, 2.8961644, -0.002042532, 4.1519585, 2.6634326, 0.90281975, 3.7041378, 2.8393202, 0.76166415, 3.980144, 2.8523202, 0.8201138, 4.014048, 2.8469372, 0.5942155, 4.2409024, 2.867742, 0.28561115, 4.2561502, 2.8961644, 0.28561115, 4.3239584, 2.8961644, 0.8201138, 4.014048, 2.8469372, 0.76166415, 3.980144, 2.8523202, 0.56045413, 4.1822057, 2.8708515, 0.5942155, 4.2409024, 2.867742, 0.56045413, 4.1822057, 2.8708515, 0.28561115, 4.2561502, 2.8961644, 0.8201138, 4.014048, 2.8469372, 0.56045413, 4.1822057, 2.8708515, 0.5942155, 4.2409024, 2.867742, -0.49611712, 3.2260702, -2.582213, -0.75557137, 3.4076157, -2.4682097, -0.75938535, 3.4076157, -2.5096202, -0.49611712, 3.2260702, -2.582213, -0.49230337, 3.2260702, -2.5408025, -0.75557137, 3.4076157, -2.4682097, -0.22127414, 3.1521254, -2.6075258, -0.49230337, 3.2260702, -2.5408025, -0.49611712, 3.2260702, -2.582213, -0.22127414, 3.1521254, -2.6075258, -0.2174604, 3.1521254, -2.5661154, -0.49230337, 3.2260702, -2.5408025, -0.017707348, 3.2044384, -2.6200662, -0.2174604, 3.1521254, -2.5661154, -0.22127414, 3.1521254, -2.6075258, -0.017707348, 3.2044384, -2.6200662, -0.01391077, 3.2044384, -2.5788422, -0.2174604, 3.1521254, -2.5661154, 0.25477862, 3.4281316, -2.65137, -0.01391077, 3.2044384, -2.5788422, -0.017707348, 3.2044384, -2.6200662, 0.25477862, 3.4281316, -2.65137, 0.2585926, 3.4281316, -2.6099591, -0.01391077, 3.2044384, -2.5788422, 0.32873797, 3.6751301, -2.6546073, 0.2585926, 3.4281316, -2.6099591, 0.25477862, 3.4281316, -2.65137, 0.32873797, 3.6751301, -2.6546073, 0.33255196, 3.6751301, -2.6131968, 0.2585926, 3.4281316, -2.6099591, 0.25477862, 3.980144, -2.65137, 0.33255196, 3.6751301, -2.6131968, 0.32873797, 3.6751301, -2.6546073, 0.25477862, 3.980144, -2.65137, 0.2585926, 3.980144, -2.6099591, 0.33255196, 3.6751301, -2.6131968, 0.05356884, 4.1822057, -2.6328387, 0.2585926, 3.980144, -2.6099591, 0.25477862, 3.980144, -2.65137, 0.05356884, 4.1822057, -2.6328387, 0.057382584, 4.1822057, -2.5914283, 0.2585926, 3.980144, -2.6099591, -0.22127414, 4.2561502, -2.6075258, 0.057382584, 4.1822057, -2.5914283, 0.05356884, 4.1822057, -2.6328387, -0.22127414, 4.2561502, -2.6075258, -0.2174604, 4.2561502, -2.5661154, 0.057382584, 4.1822057, -2.5914283, -0.49611712, 4.1822057, -2.582213, -0.2174604, 4.2561502, -2.5661154, -0.22127414, 4.2561502, -2.6075258, -0.49611712, 4.1822057, -2.582213, -0.49230337, 4.1822057, -2.5408025, -0.2174604, 4.2561502, -2.5661154, -0.69732714, 3.980144, -2.5636816, -0.49230337, 4.1822057, -2.5408025, -0.49611712, 4.1822057, -2.582213, -0.69732714, 3.980144, -2.5636816, -0.6935134, 3.980144, -2.5222712, -0.49230337, 4.1822057, -2.5408025, -0.7709601, 3.7041378, -2.5569, -0.6935134, 3.980144, -2.5222712, -0.69732714, 3.980144, -2.5636816, -0.7709601, 3.7041378, -2.5569, -0.7671461, 3.7041378, -2.5154896, -0.6935134, 3.980144, -2.5222712, -0.75938535, 3.4076157, -2.5096202, -0.7671461, 3.7041378, -2.5154896, -0.7709601, 3.7041378, -2.5569, -0.75938535, 3.4076157, -2.5096202, -0.75557137, 3.4076157, -2.4682097, -0.7671461, 3.7041378, -2.5154896, -0.19044161, 3.4281316, 2.9400086, 0.0069544315, 3.2260702, 2.8800664, 0.010768175, 3.2260702, 2.9214773, -0.19044161, 3.4281316, 2.9400086, -0.19425559, 3.4281316, 2.8985977, 0.0069544315, 3.2260702, 2.8800664, 0.010768175, 3.2260702, 2.9214773, 0.2817974, 3.1521254, 2.8547535, 0.28561115, 3.1521254, 2.8961644, 0.010768175, 3.2260702, 2.9214773, 0.0069544315, 3.2260702, 2.8800664, 0.2817974, 3.1521254, 2.8547535, 0.28561115, 3.1521254, 2.8961644, 0.55664027, 3.2260702, 2.8294406, 0.56045413, 3.2260702, 2.8708515, 0.28561115, 3.1521254, 2.8961644, 0.2817974, 3.1521254, 2.8547535, 0.55664027, 3.2260702, 2.8294406, 0.56045413, 3.2260702, 2.8708515, 0.75785017, 3.4281316, 2.8109093, 0.76166415, 3.4281316, 2.8523202, 0.56045413, 3.2260702, 2.8708515, 0.55664027, 3.2260702, 2.8294406, 0.75785017, 3.4281316, 2.8109093, 0.76166415, 3.4281316, 2.8523202, 0.8314831, 3.7041378, 2.8041277, 0.8352971, 3.7041378, 2.8455386, 0.76166415, 3.4281316, 2.8523202, 0.75785017, 3.4281316, 2.8109093, 0.8314831, 3.7041378, 2.8041277, 0.8352971, 3.7041378, 2.8455386, 0.8314831, 3.7041378, 2.8041277, 0.75785017, 3.980144, 2.8109093, 0.8352971, 3.7041378, 2.8455386, 0.75785017, 3.980144, 2.8109093, 0.76166415, 3.980144, 2.8523202, 0.76166415, 3.980144, 2.8523202, 0.55664027, 4.1822057, 2.8294406, 0.56045413, 4.1822057, 2.8708515, 0.76166415, 3.980144, 2.8523202, 0.75785017, 3.980144, 2.8109093, 0.55664027, 4.1822057, 2.8294406, 0.56045413, 4.1822057, 2.8708515, 0.2817974, 4.2561502, 2.8547535, 0.28561115, 4.2561502, 2.8961644, 0.56045413, 4.1822057, 2.8708515, 0.55664027, 4.1822057, 2.8294406, 0.2817974, 4.2561502, 2.8547535, 0.28561115, 4.2561502, 2.8961644, -0.0058562756, 4.1519585, 2.6220222, -0.002042532, 4.1519585, 2.6634326, 0.28561115, 4.2561502, 2.8961644, 0.2817974, 4.2561502, 2.8547535, -0.0058562756, 4.1519585, 2.6220222, -0.002042532, 4.1519585, 2.6634326, -0.19425559, 3.980144, 2.8985977, -0.19044161, 3.980144, 2.9400086, -0.002042532, 4.1519585, 2.6634326, -0.0058562756, 4.1519585, 2.6220222, -0.19425559, 3.980144, 2.8985977, -0.19044161, 3.980144, 2.9400086, -0.26788855, 3.7041378, 2.9053793, -0.2640748, 3.7041378, 2.9467902, -0.19044161, 3.980144, 2.9400086, -0.19425559, 3.980144, 2.8985977, -0.26788855, 3.7041378, 2.9053793, -0.2640748, 3.7041378, 2.9467902, -0.26788855, 3.7041378, 2.9053793, -0.19425559, 3.4281316, 2.8985977, -0.2640748, 3.7041378, 2.9467902, -0.19425559, 3.4281316, 2.8985977, -0.19044161, 3.4281316, 2.9400086, -5.555945, -21.30843, 0.44781768, -3.54707, -21.129436, 0.3570392, -5.555945, -21.129436, 0.44781768, -5.555945, -21.30843, 0.44781768, -3.54707, -21.30843, 0.3570392, -3.54707, -21.129436, 0.3570392, -7.629112, -21.129436, 0.3570392, -5.555945, -21.30843, 0.44781768, -5.555945, -21.129436, 0.44781768, -7.629112, -21.129436, 0.3570392, -7.629112, -21.30843, 0.3570392, -5.555945, -21.30843, 0.44781768, -5.555945, -21.30843, 0.9271282, -3.54707, -21.30843, 0.3570392, -5.555945, -21.30843, 0.44781768, -5.555945, -21.30843, 0.9271282, -3.54707, -21.30843, 0.7632997, -3.54707, -21.30843, 0.3570392, -5.555945, -21.30843, 0.44781768, -7.629112, -21.30843, 0.91196275, -5.555945, -21.30843, 0.9271282, -5.555945, -21.30843, 0.44781768, -7.629112, -21.30843, 0.62980187, -7.629112, -21.30843, 0.91196275, -7.629112, -21.30843, 0.62980187, -5.555945, -21.30843, 0.44781768, -7.629112, -21.30843, 0.3570392, -3.54707, -21.30843, 0.7632997, -3.54707, -21.129436, 0.3570392, -3.54707, -21.30843, 0.3570392, -3.54707, -21.30843, 0.7632997, -3.54707, -21.129435, 0.7632997, -3.54707, -21.129436, 0.3570392, -7.629112, -21.129436, 0.5971217, -7.5507226, -21.183048, 0.6447537, -7.629112, -21.30843, 0.62980187, -5.555945, -21.129435, 0.80730057, -5.555945, -21.174292, 0.9271282, -6.0741305, -21.129435, 0.92328346, -5.555945, -21.129435, 0.80730057, -5.0537796, -21.129435, 0.8861177, -5.555945, -21.174292, 0.9271282, -5.555945, -21.129435, 0.80730057, -3.54707, -21.129435, 0.7632997, -5.0537796, -21.129435, 0.8861177, -5.555945, -21.129435, 0.80730057, -3.54707, -21.129436, 0.3570392, -3.54707, -21.129435, 0.7632997, -3.54707, -21.129436, 0.3570392, -5.555945, -21.129435, 0.80730057, -5.555945, -21.129436, 0.44781768, -6.0741305, -21.129435, 0.92328346, -5.555945, -21.129436, 0.44781768, -5.555945, -21.129435, 0.80730057, -5.555945, -21.129436, 0.44781768, -7.629112, -21.129436, 0.5971217, -7.629112, -21.129436, 0.3570392, -5.555945, -21.129436, 0.44781768, -7.2726197, -21.129435, 0.6462488, -7.629112, -21.129436, 0.5971217, -6.0741305, -21.129435, 0.92328346, -7.2726197, -21.129435, 0.6462488, -5.555945, -21.129436, 0.44781768, -7.5507226, -21.183048, 0.6447537, -7.629112, -21.129436, 0.5971217, -7.2726197, -21.129435, 0.6462488, -7.629112, -21.129435, 0.7325418, -7.5507226, -21.183048, 0.6447537, -7.2726197, -21.129435, 0.6462488, -7.2726197, -21.129435, 0.6462488, -6.0741305, -21.129435, 0.92328346, -7.629112, -21.129435, 0.7325418, -7.629112, -21.129435, 0.7325418, -6.0741305, -21.129435, 0.92328346, -7.629112, -21.129435, 0.91196275, -7.629112, -21.30843, 0.3570392, -7.629112, -21.129436, 0.5971217, -7.629112, -21.30843, 0.62980187, -7.629112, -21.30843, 0.3570392, -7.629112, -21.129436, 0.3570392, -7.629112, -21.129436, 0.5971217, -7.629112, -21.129435, 0.7325418, -7.629112, -21.30843, 0.91196275, -7.629112, -21.30843, 0.62980187, -7.629112, -21.129435, 0.7325418, -7.629112, -21.129435, 0.91196275, -7.629112, -21.30843, 0.91196275, -7.5507226, -21.183048, 0.6447537, -7.629112, -21.129435, 0.7325418, -7.629112, -21.30843, 0.62980187, -7.629112, -21.129435, 0.91196275, -5.555945, -21.30843, 0.9271282, -7.629112, -21.30843, 0.91196275, -5.555945, -21.30843, 0.9271282, -7.629112, -21.129435, 0.91196275, -6.0741305, -21.129435, 0.92328346, -5.555945, -21.30843, 0.9271282, -6.0741305, -21.129435, 0.92328346, -5.555945, -21.174292, 0.9271282, -5.555945, -21.174292, 0.9271282, -3.54707, -21.30843, 0.7632997, -5.555945, -21.30843, 0.9271282, -5.555945, -21.174292, 0.9271282, -3.54707, -21.129435, 0.7632997, -3.54707, -21.30843, 0.7632997, -3.54707, -21.129435, 0.7632997, -5.555945, -21.174292, 0.9271282, -5.0537796, -21.129435, 0.8861177, -3.988361, -21.129435, 2.1034038, -3.54707, -21.30843, 2.1130157, -3.988361, -21.30843, 2.1034038, -3.988361, -21.129435, 2.1034038, -3.54707, -21.129435, 2.1130157, -3.54707, -21.30843, 2.1130157, -3.988361, -21.30843, 2.1034038, -6.7189775, -21.129435, 2.110666, -3.988361, -21.129435, 2.1034038, -3.988361, -21.30843, 2.1034038, -7.629112, -21.17429, 2.1130157, -6.7189775, -21.129435, 2.110666, -7.629112, -21.17429, 2.1130157, -3.988361, -21.30843, 2.1034038, -7.629112, -21.30843, 2.1130157, -3.54707, -21.129435, 1.6317828, -3.988361, -21.129435, 2.1034038, -3.988361, -21.129435, 1.6206758, -6.7189775, -21.129435, 2.110666, -3.988361, -21.129435, 1.6206758, -3.988361, -21.129435, 2.1034038, -6.7189775, -21.129435, 2.110666, -7.629112, -21.129435, 1.7067552, -3.988361, -21.129435, 1.6206758, -7.629112, -21.129435, 1.7067552, -6.7189775, -21.129435, 2.110666, -7.629112, -21.129435, 2.0113437, -7.629112, -21.129435, 2.0113437, -6.7189775, -21.129435, 2.110666, -7.629112, -21.17429, 2.1130157, -3.988361, -21.129435, 2.1034038, -3.54707, -21.129435, 1.6317828, -3.78224, -21.129435, 1.8853219, -3.78224, -21.129435, 1.8853219, -3.54707, -21.129435, 1.6317828, -3.54707, -21.129435, 1.8257284, -3.54707, -21.129435, 1.8257284, -3.5872264, -21.197786, 1.8791275, -3.78224, -21.129435, 1.8853219, -3.5872264, -21.197786, 1.8791275, -3.54707, -21.129435, 1.959867, -3.78224, -21.129435, 1.8853219, -3.988361, -21.129435, 2.1034038, -3.78224, -21.129435, 1.8853219, -3.54707, -21.129435, 1.959867, -3.988361, -21.129435, 2.1034038, -3.54707, -21.129435, 1.959867, -3.54707, -21.129435, 2.1130157, -3.988361, -21.30843, 1.6206758, -3.54707, -21.129435, 1.6317828, -3.988361, -21.129435, 1.6206758, -3.988361, -21.30843, 1.6206758, -3.54707, -21.30843, 1.6317829, -3.54707, -21.129435, 1.6317828, -7.629112, -21.129435, 1.7067552, -3.988361, -21.30843, 1.6206758, -3.988361, -21.129435, 1.6206758, -7.629112, -21.129435, 1.7067552, -7.629112, -21.30843, 1.7067553, -3.988361, -21.30843, 1.6206758, -3.54707, -21.30843, 2.1130157, -3.988361, -21.30843, 1.6206758, -3.988361, -21.30843, 2.1034038, -3.988361, -21.30843, 1.6206758, -3.54707, -21.30843, 2.1130157, -3.54707, -21.30843, 1.8528552, -3.988361, -21.30843, 1.6206758, -3.54707, -21.30843, 1.8528552, -3.54707, -21.30843, 1.6317829, -7.629112, -21.30843, 1.7067553, -3.988361, -21.30843, 2.1034038, -3.988361, -21.30843, 1.6206758, -7.629112, -21.30843, 1.7067553, -7.629112, -21.30843, 2.1130157, -3.988361, -21.30843, 2.1034038, -3.54707, -21.129435, 1.959867, -3.5872264, -21.197786, 1.8791275, -3.54707, -21.30843, 1.8528552, -3.5872264, -21.197786, 1.8791275, -3.54707, -21.129435, 1.8257284, -3.54707, -21.30843, 1.8528552, -3.54707, -21.30843, 2.1130157, -3.54707, -21.129435, 1.959867, -3.54707, -21.30843, 1.8528552, -3.54707, -21.30843, 2.1130157, -3.54707, -21.129435, 2.1130157, -3.54707, -21.129435, 1.959867, -3.54707, -21.129435, 1.8257284, -3.54707, -21.30843, 1.6317829, -3.54707, -21.30843, 1.8528552, -3.54707, -21.129435, 1.8257284, -3.54707, -21.129435, 1.6317828, -3.54707, -21.30843, 1.6317829, -7.629112, -21.129435, 1.7067552, -7.629112, -21.30843, 2.1130157, -7.629112, -21.30843, 1.7067553, -7.629112, -21.30843, 2.1130157, -7.629112, -21.129435, 1.7067552, -7.629112, -21.129435, 2.0113437, -7.629112, -21.30843, 2.1130157, -7.629112, -21.129435, 2.0113437, -7.629112, -21.17429, 2.1130157, -3.9170194, -21.320818, -0.44629717, -3.8958735, -21.335342, -0.95978284, -3.8958735, -21.34047, -0.43775296, -3.9170194, -21.320818, -0.44629717, -3.9170194, -21.31612, -0.95081186, -3.8958735, -21.335342, -0.95978284, -3.9170194, -21.31612, -0.95081186, -3.8958735, -21.210388, -0.979434, -3.8958735, -21.335342, -0.95978284, -3.9170194, -21.31612, -0.95081186, -3.9170194, -21.215515, -0.9587152, -3.8958735, -21.210388, -0.979434, -3.8958735, -21.34047, -0.43775296, -3.9170194, -21.35478, -0.9687538, -3.9170194, -21.36012, -0.4289956, -3.8958735, -21.34047, -0.43775296, -3.8958735, -21.335342, -0.95978284, -3.9170194, -21.35478, -0.9687538, -3.8958735, -21.335342, -0.95978284, -3.9170194, -21.205263, -1.0001528, -3.9170194, -21.35478, -0.9687538, -3.8958735, -21.335342, -0.95978284, -3.8958735, -21.210388, -0.979434, -3.9170194, -21.205263, -1.0001528, -3.9170194, -21.36012, -0.4289956, -3.9385924, -21.335342, -0.95978284, -3.9385924, -21.34047, -0.43775296, -3.9170194, -21.36012, -0.4289956, -3.9170194, -21.35478, -0.9687538, -3.9385924, -21.335342, -0.95978284, -3.9170194, -21.35478, -0.9687538, -3.9385924, -21.210388, -0.979434, -3.9385924, -21.335342, -0.95978284, -3.9170194, -21.35478, -0.9687538, -3.9170194, -21.205263, -1.0001528, -3.9385924, -21.210388, -0.979434, -3.9385924, -21.34047, -0.43775296, -3.9170194, -21.31612, -0.95081186, -3.9170194, -21.320818, -0.44629717, -3.9385924, -21.34047, -0.43775296, -3.9385924, -21.335342, -0.95978284, -3.9170194, -21.31612, -0.95081186, -3.9385924, -21.335342, -0.95978284, -3.9170194, -21.215515, -0.9587152, -3.9170194, -21.31612, -0.95081186, -3.9385924, -21.335342, -0.95978284, -3.9385924, -21.210388, -0.979434, -3.9170194, -21.215515, -0.9587152, -3.9170194, -21.215515, -0.9587152, -3.8958735, -21.105513, -0.94718075, -3.8958735, -21.210388, -0.979434, -3.9170194, -21.215515, -0.9587152, -3.9170194, -21.126446, -0.9426954, -3.8958735, -21.105513, -0.94718075, -3.9170194, -21.126446, -0.9426954, -3.8958735, -21.10359, -0.44181156, -3.8958735, -21.105513, -0.94718075, -3.9170194, -21.126446, -0.9426954, -3.9170194, -21.12431, -0.44693804, -3.8958735, -21.10359, -0.44181156, -3.9170194, -21.12431, -0.44693804, -3.8958735, -21.219788, -0.39460683, -3.8958735, -21.10359, -0.44181156, -3.9170194, -21.12431, -0.44693804, -3.9170194, -21.22406, -0.4155395, -3.8958735, -21.219788, -0.39460683, -3.8958735, -21.210388, -0.979434, -3.9170194, -21.084795, -0.95188, -3.9170194, -21.205263, -1.0001528, -3.8958735, -21.210388, -0.979434, -3.8958735, -21.105513, -0.94718075, -3.9170194, -21.084795, -0.95188, -3.8958735, -21.105513, -0.94718075, -3.9170194, -21.082659, -0.43668532, -3.9170194, -21.084795, -0.95188, -3.8958735, -21.105513, -0.94718075, -3.8958735, -21.10359, -0.44181156, -3.9170194, -21.082659, -0.43668532, -3.8958735, -21.10359, -0.44181156, -3.9170194, -21.215515, -0.3736744, -3.9170194, -21.082659, -0.43668532, -3.8958735, -21.10359, -0.44181156, -3.8958735, -21.219788, -0.39460683, -3.9170194, -21.215515, -0.3736744, -3.9170194, -21.205263, -1.0001528, -3.9385924, -21.105513, -0.94718075, -3.9385924, -21.210388, -0.979434, -3.9170194, -21.205263, -1.0001528, -3.9170194, -21.084795, -0.95188, -3.9385924, -21.105513, -0.94718075, -3.9385924, -21.210388, -0.979434, -3.9170194, -21.126446, -0.9426954, -3.9170194, -21.215515, -0.9587152, -3.9385924, -21.210388, -0.979434, -3.9385924, -21.105513, -0.94718075, -3.9170194, -21.126446, -0.9426954, -3.9385924, -21.105513, -0.94718075, -3.9170194, -21.12431, -0.44693804, -3.9170194, -21.126446, -0.9426954, -3.9385924, -21.105513, -0.94718075, -3.9385924, -21.10359, -0.44181156, -3.9170194, -21.12431, -0.44693804, -3.9385924, -21.10359, -0.44181156, -3.9170194, -21.22406, -0.4155395, -3.9170194, -21.12431, -0.44693804, -3.9385924, -21.10359, -0.44181156, -3.9385924, -21.219788, -0.39460683, -3.9170194, -21.22406, -0.4155395, -3.9170194, -21.084795, -0.95188, -3.9385924, -21.10359, -0.44181156, -3.9385924, -21.105513, -0.94718075, -3.9170194, -21.084795, -0.95188, -3.9170194, -21.082659, -0.43668532, -3.9385924, -21.10359, -0.44181156, -3.9170194, -21.082659, -0.43668532, -3.9385924, -21.219788, -0.39460683, -3.9385924, -21.10359, -0.44181156, -3.9170194, -21.082659, -0.43668532, -3.9170194, -21.215515, -0.3736744, -3.9385924, -21.219788, -0.39460683, -3.9170194, -21.22406, -0.4155395, -3.8958735, -21.34047, -0.43775296, -3.8958735, -21.219788, -0.39460683, -3.9170194, -21.22406, -0.4155395, -3.9170194, -21.320818, -0.44629717, -3.8958735, -21.34047, -0.43775296, -3.8958735, -21.219788, -0.39460683, -3.9170194, -21.36012, -0.4289956, -3.9170194, -21.215515, -0.3736744, -3.8958735, -21.219788, -0.39460683, -3.8958735, -21.34047, -0.43775296, -3.9170194, -21.36012, -0.4289956, -3.9170194, -21.215515, -0.3736744, -3.9385924, -21.34047, -0.43775296, -3.9385924, -21.219788, -0.39460683, -3.9170194, -21.215515, -0.3736744, -3.9170194, -21.36012, -0.4289956, -3.9385924, -21.34047, -0.43775296, -3.9385924, -21.219788, -0.39460683, -3.9170194, -21.320818, -0.44629717, -3.9170194, -21.22406, -0.4155395, -3.9385924, -21.219788, -0.39460683, -3.9385924, -21.34047, -0.43775296, -3.9170194, -21.320818, -0.44629717, -7.464643, -21.40476, 5.450674, -7.3512235, -21.359264, 5.450674, -7.3512235, -21.40476, 5.450674, -7.464643, -21.40476, 5.450674, -7.464643, -21.359264, 5.450674, -7.3512235, -21.359264, 5.450674, -7.464643, -21.359264, 5.450674, -7.3512235, -21.359266, -1.0281336, -7.3512235, -21.359264, 5.450674, -7.464643, -21.359264, 5.450674, -7.464643, -21.359266, -1.0281336, -7.3512235, -21.359266, -1.0281336, -7.464643, -21.359266, -1.0281336, -7.3512235, -21.404762, -1.0281336, -7.3512235, -21.359266, -1.0281336, -7.464643, -21.359266, -1.0281336, -7.464643, -21.404762, -1.0281336, -7.3512235, -21.404762, -1.0281336, -7.464643, -21.404762, -1.0281336, -7.3512235, -21.40476, 5.450674, -7.3512235, -21.404762, -1.0281336, -7.464643, -21.404762, -1.0281336, -7.464643, -21.40476, 5.450674, -7.3512235, -21.40476, 5.450674, -7.3512235, -21.40476, 5.450674, -7.3512235, -21.359266, -1.0281336, -7.3512235, -21.404762, -1.0281336, -7.3512235, -21.40476, 5.450674, -7.3512235, -21.359264, 5.450674, -7.3512235, -21.359266, -1.0281336, -7.464643, -21.404762, -1.0281336, -7.464643, -21.359264, 5.450674, -7.464643, -21.40476, 5.450674, -7.464643, -21.404762, -1.0281336, -7.464643, -21.359266, -1.0281336, -7.464643, -21.359264, 5.450674, -6.9564967, -21.30843, -0.21347666, -3.4046016, -21.129436, -0.29165316, -6.9564967, -21.129436, -0.2134769, -6.9564967, -21.30843, -0.21347666, -3.4046016, -21.30843, -0.29165292, -3.4046016, -21.129436, -0.29165316, -7.7713675, -21.129436, -0.21689463, -6.9564967, -21.30843, -0.21347666, -6.9564967, -21.129436, -0.2134769, -7.7713675, -21.129436, -0.21689463, -7.7713675, -21.30843, -0.21689439, -6.9564967, -21.30843, -0.21347666, -6.9564967, -21.30843, 0.28014445, -3.4046016, -21.30843, -0.29165292, -6.9564967, -21.30843, -0.21347666, -6.9564967, -21.30843, 0.28014445, -3.4046016, -21.30843, 0.1893661, -3.4046016, -21.30843, -0.29165292, -7.7713675, -21.30843, -0.21689439, -6.9564967, -21.30843, 0.28014445, -6.9564967, -21.30843, -0.21347666, -7.7713675, -21.30843, -0.21689439, -7.7713675, -21.30843, 0.1893661, -6.9564967, -21.30843, 0.28014445, -7.7713675, -21.30843, -0.21689439, -7.7713675, -21.129436, 0.18936586, -7.7713675, -21.30843, 0.1893661, -7.7713675, -21.30843, -0.21689439, -7.7713675, -21.129436, -0.21689463, -7.7713675, -21.129436, 0.18936586, -6.9564967, -21.129436, 0.15668559, -6.9564967, -21.174292, 0.28014445, -7.1602683, -21.129436, 0.25750327, -6.9564967, -21.129436, 0.15668559, -6.0685763, -21.129436, 0.25750327, -6.9564967, -21.174292, 0.28014445, -6.9564967, -21.129436, 0.15668559, -4.0705953, -21.129436, 0.20624006, -6.0685763, -21.129436, 0.25750327, -7.1602683, -21.129436, 0.25750327, -6.9564967, -21.129436, -0.2134769, -6.9564967, -21.129436, 0.15668559, -7.1602683, -21.129436, 0.25750327, -7.7713675, -21.129436, -0.21689463, -6.9564967, -21.129436, -0.2134769, -7.7713675, -21.129436, -0.21689463, -7.1602683, -21.129436, 0.25750327, -7.7713675, -21.129436, 0.18936586, -3.4046016, -21.129436, -0.29165316, -6.9564967, -21.129436, 0.15668559, -6.9564967, -21.129436, -0.2134769, -6.9564967, -21.129436, 0.15668559, -3.4046016, -21.129436, -0.29165316, -4.0705953, -21.129436, 0.20624006, -4.0705953, -21.129436, 0.20624006, -3.4046016, -21.129436, -0.29165316, -3.4046016, -21.129436, 0.06911111, -4.0705953, -21.129436, 0.20624006, -3.4046016, -21.129436, 0.06911111, -3.4046016, -21.174292, 0.18936586, -7.7713675, -21.129436, 0.18936586, -6.9564967, -21.30843, 0.28014445, -7.7713675, -21.30843, 0.1893661, -6.9564967, -21.30843, 0.28014445, -7.7713675, -21.129436, 0.18936586, -7.1602683, -21.129436, 0.25750327, -6.9564967, -21.30843, 0.28014445, -7.1602683, -21.129436, 0.25750327, -6.9564967, -21.174292, 0.28014445, -6.9564967, -21.174292, 0.28014445, -3.4046016, -21.30843, 0.1893661, -6.9564967, -21.30843, 0.28014445, -6.9564967, -21.174292, 0.28014445, -4.0705953, -21.129436, 0.20624006, -3.4046016, -21.30843, 0.1893661, -3.4046016, -21.30843, 0.1893661, -4.0705953, -21.129436, 0.20624006, -3.4046016, -21.174292, 0.18936586, -4.0705953, -21.129436, 0.20624006, -6.9564967, -21.174292, 0.28014445, -6.0685763, -21.129436, 0.25750327, -3.4046016, -21.174292, 0.18936586, -3.4046016, -21.30843, -0.29165292, -3.4046016, -21.30843, 0.1893661, -3.4046016, -21.30843, -0.29165292, -3.4046016, -21.174292, 0.18936586, -3.4046016, -21.129436, 0.06911111, -3.4046016, -21.30843, -0.29165292, -3.4046016, -21.129436, 0.06911111, -3.4046016, -21.129436, -0.29165316, -7.7320657, -21.3975, -1.0330465, -7.351437, -19.082968, -0.9484632, -7.4360213, -21.3975, -1.0330465, -7.7320657, -21.3975, -1.0330465, -7.81665, -19.082968, -0.9484632, -7.351437, -19.082968, -0.9484632, -7.81665, -19.082968, -0.9484632, -7.351437, -19.082968, -1.4134626, -7.351437, -19.082968, -0.9484632, -7.81665, -19.082968, -0.9484632, -7.81665, -19.082968, -1.4134626, -7.351437, -19.082968, -1.4134626, -7.81665, -19.082968, -1.4134626, -7.4360213, -21.3975, -1.3288774, -7.351437, -19.082968, -1.4134626, -7.81665, -19.082968, -1.4134626, -7.7320657, -21.3975, -1.3288774, -7.4360213, -21.3975, -1.3288774, -7.7320657, -21.3975, -1.3288774, -7.4360213, -21.3975, -1.0330465, -7.4360213, -21.3975, -1.3288774, -7.7320657, -21.3975, -1.3288774, -7.7320657, -21.3975, -1.0330465, -7.4360213, -21.3975, -1.0330465, -7.4360213, -21.3975, -1.0330465, -7.351437, -19.082968, -1.4134626, -7.4360213, -21.3975, -1.3288774, -7.4360213, -21.3975, -1.0330465, -7.351437, -19.082968, -0.9484632, -7.351437, -19.082968, -1.4134626, -7.7320657, -21.3975, -1.3288774, -7.81665, -19.082968, -0.9484632, -7.7320657, -21.3975, -1.0330465, -7.7320657, -21.3975, -1.3288774, -7.81665, -19.082968, -1.4134626, -7.81665, -19.082968, -0.9484632, -3.988361, -21.129436, -0.4571905, -3.54707, -21.30843, -0.4477923, -3.988361, -21.30843, -0.45719028, -3.988361, -21.129436, -0.4571905, -3.54707, -21.129436, -0.44779253, -3.54707, -21.30843, -0.4477923, -3.988361, -21.30843, -0.45719028, -6.7189775, -21.129436, -0.4501419, -3.988361, -21.129436, -0.4571905, -3.988361, -21.30843, -0.45719028, -7.629112, -21.174292, -0.44779253, -6.7189775, -21.129436, -0.4501419, -7.629112, -21.174292, -0.44779253, -3.988361, -21.30843, -0.45719028, -7.629112, -21.30843, -0.4477923, -3.54707, -21.129436, -0.92881155, -3.988361, -21.129436, -0.4571905, -3.988361, -21.129436, -0.9401324, -6.7189775, -21.129436, -0.4501419, -3.988361, -21.129436, -0.9401324, -3.988361, -21.129436, -0.4571905, -6.7189775, -21.129436, -0.4501419, -7.629112, -21.129436, -0.8540528, -3.988361, -21.129436, -0.9401324, -7.629112, -21.129436, -0.8540528, -6.7189775, -21.129436, -0.4501419, -7.629112, -21.129436, -0.5492506, -7.629112, -21.129436, -0.5492506, -6.7189775, -21.129436, -0.4501419, -7.629112, -21.174292, -0.44779253, -3.988361, -21.129436, -0.4571905, -3.54707, -21.129436, -0.92881155, -3.78224, -21.129436, -0.6754861, -3.78224, -21.129436, -0.6754861, -3.54707, -21.129436, -0.92881155, -3.54707, -21.129436, -0.7350795, -3.54707, -21.129436, -0.7350795, -3.5872264, -21.197786, -0.68168044, -3.78224, -21.129436, -0.6754861, -3.5872264, -21.197786, -0.68168044, -3.54707, -21.129436, -0.6009412, -3.78224, -21.129436, -0.6754861, -3.988361, -21.129436, -0.4571905, -3.78224, -21.129436, -0.6754861, -3.54707, -21.129436, -0.6009412, -3.988361, -21.129436, -0.4571905, -3.54707, -21.129436, -0.6009412, -3.54707, -21.129436, -0.44779253, -3.988361, -21.30843, -0.94013214, -3.54707, -21.129436, -0.92881155, -3.988361, -21.129436, -0.9401324, -3.988361, -21.30843, -0.94013214, -3.54707, -21.30843, -0.9288113, -3.54707, -21.129436, -0.92881155, -7.629112, -21.129436, -0.8540528, -3.988361, -21.30843, -0.94013214, -3.988361, -21.129436, -0.9401324, -7.629112, -21.129436, -0.8540528, -7.629112, -21.30843, -0.85405254, -3.988361, -21.30843, -0.94013214, -3.54707, -21.30843, -0.4477923, -3.988361, -21.30843, -0.94013214, -3.988361, -21.30843, -0.45719028, -3.988361, -21.30843, -0.94013214, -3.54707, -21.30843, -0.4477923, -3.54707, -21.30843, -0.7079525, -3.988361, -21.30843, -0.94013214, -3.54707, -21.30843, -0.7079525, -3.54707, -21.30843, -0.9288113, -7.629112, -21.30843, -0.85405254, -3.988361, -21.30843, -0.45719028, -3.988361, -21.30843, -0.94013214, -7.629112, -21.30843, -0.85405254, -7.629112, -21.30843, -0.4477923, -3.988361, -21.30843, -0.45719028, -3.54707, -21.129436, -0.6009412, -3.5872264, -21.197786, -0.68168044, -3.54707, -21.30843, -0.7079525, -3.5872264, -21.197786, -0.68168044, -3.54707, -21.129436, -0.7350795, -3.54707, -21.30843, -0.7079525, -3.54707, -21.30843, -0.4477923, -3.54707, -21.129436, -0.6009412, -3.54707, -21.30843, -0.7079525, -3.54707, -21.30843, -0.4477923, -3.54707, -21.129436, -0.44779253, -3.54707, -21.129436, -0.6009412, -3.54707, -21.129436, -0.7350795, -3.54707, -21.30843, -0.9288113, -3.54707, -21.30843, -0.7079525, -3.54707, -21.129436, -0.7350795, -3.54707, -21.129436, -0.92881155, -3.54707, -21.30843, -0.9288113, -7.629112, -21.129436, -0.8540528, -7.629112, -21.30843, -0.4477923, -7.629112, -21.30843, -0.85405254, -7.629112, -21.30843, -0.4477923, -7.629112, -21.129436, -0.8540528, -7.629112, -21.129436, -0.5492506, -7.629112, -21.30843, -0.4477923, -7.629112, -21.129436, -0.5492506, -7.629112, -21.174292, -0.44779253, -3.8766494, -21.129435, 2.6811824, -3.4046016, -21.308428, 2.6905806, -3.8766494, -21.308428, 2.6811824, -3.8766494, -21.129435, 2.6811824, -3.4046016, -21.129435, 2.6905804, -3.4046016, -21.308428, 2.6905806, -3.8766494, -21.308428, 2.6811824, -6.797795, -21.129435, 2.688231, -3.8766494, -21.129435, 2.6811824, -3.8766494, -21.308428, 2.6811824, -7.7713675, -21.17429, 2.6905804, -6.797795, -21.129435, 2.688231, -7.7713675, -21.17429, 2.6905804, -3.8766494, -21.308428, 2.6811824, -7.7713675, -21.308428, 2.6905806, -3.4046016, -21.129435, 2.2095613, -3.8766494, -21.129435, 2.6811824, -3.8766494, -21.129435, 2.1984541, -6.797795, -21.129435, 2.688231, -3.8766494, -21.129435, 2.1984541, -3.8766494, -21.129435, 2.6811824, -6.797795, -21.129435, 2.688231, -7.7713675, -21.129435, 2.28432, -3.8766494, -21.129435, 2.1984541, -7.7713675, -21.129435, 2.28432, -6.797795, -21.129435, 2.688231, -7.7713675, -21.129435, 2.5891223, -7.7713675, -21.129435, 2.5891223, -6.797795, -21.129435, 2.688231, -7.7713675, -21.17429, 2.6905804, -3.8766494, -21.129435, 2.6811824, -3.4046016, -21.129435, 2.2095613, -3.656218, -21.129435, 2.4631002, -3.656218, -21.129435, 2.4631002, -3.4046016, -21.129435, 2.2095613, -3.4046016, -21.129435, 2.4032931, -3.4046016, -21.129435, 2.4032931, -3.4477482, -21.197786, 2.4566922, -3.656218, -21.129435, 2.4631002, -3.4477482, -21.197786, 2.4566922, -3.4046016, -21.129435, 2.5376453, -3.656218, -21.129435, 2.4631002, -3.8766494, -21.129435, 2.6811824, -3.656218, -21.129435, 2.4631002, -3.4046016, -21.129435, 2.5376453, -3.8766494, -21.129435, 2.6811824, -3.4046016, -21.129435, 2.5376453, -3.4046016, -21.129435, 2.6905804, -3.8766494, -21.30843, 2.1984544, -3.4046016, -21.129435, 2.2095613, -3.8766494, -21.129435, 2.1984541, -3.8766494, -21.30843, 2.1984544, -3.4046016, -21.30843, 2.2095613, -3.4046016, -21.129435, 2.2095613, -7.7713675, -21.129435, 2.28432, -3.8766494, -21.30843, 2.1984544, -3.8766494, -21.129435, 2.1984541, -7.7713675, -21.129435, 2.28432, -7.7713675, -21.30843, 2.28432, -3.8766494, -21.30843, 2.1984544, -3.4046016, -21.308428, 2.6905806, -3.8766494, -21.30843, 2.1984544, -3.8766494, -21.308428, 2.6811824, -3.8766494, -21.30843, 2.1984544, -3.4046016, -21.308428, 2.6905806, -3.4046016, -21.308428, 2.4306335, -3.8766494, -21.30843, 2.1984544, -3.4046016, -21.308428, 2.4306335, -3.4046016, -21.30843, 2.2095613, -7.7713675, -21.30843, 2.28432, -3.8766494, -21.308428, 2.6811824, -3.8766494, -21.30843, 2.1984544, -7.7713675, -21.30843, 2.28432, -7.7713675, -21.308428, 2.6905806, -3.8766494, -21.308428, 2.6811824, -3.4046016, -21.129435, 2.5376453, -3.4477482, -21.197786, 2.4566922, -3.4046016, -21.308428, 2.4306335, -3.4477482, -21.197786, 2.4566922, -3.4046016, -21.129435, 2.4032931, -3.4046016, -21.308428, 2.4306335, -3.4046016, -21.308428, 2.6905806, -3.4046016, -21.129435, 2.5376453, -3.4046016, -21.308428, 2.4306335, -3.4046016, -21.308428, 2.6905806, -3.4046016, -21.129435, 2.6905804, -3.4046016, -21.129435, 2.5376453, -3.4046016, -21.129435, 2.4032931, -3.4046016, -21.30843, 2.2095613, -3.4046016, -21.308428, 2.4306335, -3.4046016, -21.129435, 2.4032931, -3.4046016, -21.129435, 2.2095613, -3.4046016, -21.30843, 2.2095613, -7.7713675, -21.129435, 2.28432, -7.7713675, -21.308428, 2.6905806, -7.7713675, -21.30843, 2.28432, -7.7713675, -21.308428, 2.6905806, -7.7713675, -21.129435, 2.28432, -7.7713675, -21.129435, 2.5891223, -7.7713675, -21.308428, 2.6905806, -7.7713675, -21.129435, 2.5891223, -7.7713675, -21.17429, 2.6905804, -5.5538087, -21.308428, 2.944333, -3.4046016, -21.129435, 2.853768, -5.5538087, -21.129435, 2.944333, -5.5538087, -21.308428, 2.944333, -3.4046016, -21.308428, 2.8537683, -3.4046016, -21.129435, 2.853768, -7.7713675, -21.129435, 2.853768, -5.5538087, -21.308428, 2.944333, -5.5538087, -21.129435, 2.944333, -7.7713675, -21.129435, 2.853768, -7.7713675, -21.308428, 2.8537683, -5.5538087, -21.308428, 2.944333, -5.5538087, -21.308428, 3.4236436, -3.4046016, -21.308428, 2.8537683, -5.5538087, -21.308428, 2.944333, -5.5538087, -21.308428, 3.4236436, -3.4046016, -21.308428, 3.2600288, -3.4046016, -21.308428, 2.8537683, -5.5538087, -21.308428, 2.944333, -7.7713675, -21.308428, 3.4084783, -5.5538087, -21.308428, 3.4236436, -5.5538087, -21.308428, 2.944333, -7.7713675, -21.308428, 3.126531, -7.7713675, -21.308428, 3.4084783, -7.7713675, -21.308428, 3.126531, -5.5538087, -21.308428, 2.944333, -7.7713675, -21.308428, 2.8537683, -3.4046016, -21.308428, 3.2600288, -3.4046016, -21.129435, 2.853768, -3.4046016, -21.308428, 2.8537683, -3.4046016, -21.308428, 3.2600288, -3.4046016, -21.129435, 3.2600288, -3.4046016, -21.129435, 2.853768, -7.7713675, -21.129435, 3.0938506, -7.687638, -21.183048, 3.1414826, -7.7713675, -21.308428, 3.126531, -5.5538087, -21.129435, 3.3038158, -5.5538087, -21.17429, 3.4236436, -6.108092, -21.129435, 3.4197989, -5.5538087, -21.129435, 3.3038158, -5.0164003, -21.129435, 3.3828466, -5.5538087, -21.17429, 3.4236436, -5.5538087, -21.129435, 3.3038158, -3.4046016, -21.129435, 3.2600288, -5.0164003, -21.129435, 3.3828466, -5.5538087, -21.129435, 3.3038158, -3.4046016, -21.129435, 2.853768, -3.4046016, -21.129435, 3.2600288, -3.4046016, -21.129435, 2.853768, -5.5538087, -21.129435, 3.3038158, -5.5538087, -21.129435, 2.944333, -6.108092, -21.129435, 3.4197989, -5.5538087, -21.129435, 2.944333, -5.5538087, -21.129435, 3.3038158, -5.5538087, -21.129435, 2.944333, -7.7713675, -21.129435, 3.0938506, -7.7713675, -21.129435, 2.853768, -5.5538087, -21.129435, 2.944333, -7.3903117, -21.129435, 3.142764, -7.7713675, -21.129435, 3.0938506, -6.108092, -21.129435, 3.4197989, -7.3903117, -21.129435, 3.142764, -5.5538087, -21.129435, 2.944333, -7.687638, -21.183048, 3.1414826, -7.7713675, -21.129435, 3.0938506, -7.3903117, -21.129435, 3.142764, -7.7713675, -21.129435, 3.2290573, -7.687638, -21.183048, 3.1414826, -7.3903117, -21.129435, 3.142764, -7.3903117, -21.129435, 3.142764, -6.108092, -21.129435, 3.4197989, -7.7713675, -21.129435, 3.2290573, -7.7713675, -21.129435, 3.2290573, -6.108092, -21.129435, 3.4197989, -7.7713675, -21.129435, 3.4084783, -7.7713675, -21.308428, 2.8537683, -7.7713675, -21.129435, 3.0938506, -7.7713675, -21.308428, 3.126531, -7.7713675, -21.308428, 2.8537683, -7.7713675, -21.129435, 2.853768, -7.7713675, -21.129435, 3.0938506, -7.7713675, -21.129435, 3.2290573, -7.7713675, -21.308428, 3.4084783, -7.7713675, -21.308428, 3.126531, -7.7713675, -21.129435, 3.2290573, -7.7713675, -21.129435, 3.4084783, -7.7713675, -21.308428, 3.4084783, -7.687638, -21.183048, 3.1414826, -7.7713675, -21.129435, 3.2290573, -7.7713675, -21.308428, 3.126531, -7.7713675, -21.129435, 3.4084783, -5.5538087, -21.308428, 3.4236436, -7.7713675, -21.308428, 3.4084783, -5.5538087, -21.308428, 3.4236436, -7.7713675, -21.129435, 3.4084783, -6.108092, -21.129435, 3.4197989, -5.5538087, -21.308428, 3.4236436, -6.108092, -21.129435, 3.4197989, -5.5538087, -21.17429, 3.4236436, -5.5538087, -21.17429, 3.4236436, -3.4046016, -21.308428, 3.2600288, -5.5538087, -21.308428, 3.4236436, -5.5538087, -21.17429, 3.4236436, -3.4046016, -21.129435, 3.2600288, -3.4046016, -21.308428, 3.2600288, -3.4046016, -21.129435, 3.2600288, -5.5538087, -21.17429, 3.4236436, -5.0164003, -21.129435, 3.3828466, -3.988361, -21.129435, 4.050549, -3.54707, -21.308428, 4.0599475, -3.988361, -21.308428, 4.050549, -3.988361, -21.129435, 4.050549, -3.54707, -21.129435, 4.0599475, -3.54707, -21.308428, 4.0599475, -3.988361, -21.308428, 4.050549, -6.7189775, -21.129435, 4.057598, -3.988361, -21.129435, 4.050549, -3.988361, -21.308428, 4.050549, -7.629112, -21.17429, 4.0599475, -6.7189775, -21.129435, 4.057598, -7.629112, -21.17429, 4.0599475, -3.988361, -21.308428, 4.050549, -7.629112, -21.308428, 4.0599475, -3.54707, -21.129435, 3.5789282, -3.988361, -21.129435, 4.050549, -3.988361, -21.129435, 3.567821, -6.7189775, -21.129435, 4.057598, -3.988361, -21.129435, 3.567821, -3.988361, -21.129435, 4.050549, -6.7189775, -21.129435, 4.057598, -7.629112, -21.129435, 3.653687, -3.988361, -21.129435, 3.567821, -7.629112, -21.129435, 3.653687, -6.7189775, -21.129435, 4.057598, -7.629112, -21.129435, 3.958489, -7.629112, -21.129435, 3.958489, -6.7189775, -21.129435, 4.057598, -7.629112, -21.17429, 4.0599475, -3.988361, -21.129435, 4.050549, -3.54707, -21.129435, 3.5789282, -3.78224, -21.129435, 3.8322535, -3.78224, -21.129435, 3.8322535, -3.54707, -21.129435, 3.5789282, -3.54707, -21.129435, 3.7726603, -3.54707, -21.129435, 3.7726603, -3.5872264, -21.197784, 3.8260593, -3.78224, -21.129435, 3.8322535, -3.5872264, -21.197784, 3.8260593, -3.54707, -21.129435, 3.9070125, -3.78224, -21.129435, 3.8322535, -3.988361, -21.129435, 4.050549, -3.78224, -21.129435, 3.8322535, -3.54707, -21.129435, 3.9070125, -3.988361, -21.129435, 4.050549, -3.54707, -21.129435, 3.9070125, -3.54707, -21.129435, 4.0599475, -3.988361, -21.308428, 3.567821, -3.54707, -21.129435, 3.5789282, -3.988361, -21.129435, 3.567821, -3.988361, -21.308428, 3.567821, -3.54707, -21.308428, 3.5789282, -3.54707, -21.129435, 3.5789282, -7.629112, -21.129435, 3.653687, -3.988361, -21.308428, 3.567821, -3.988361, -21.129435, 3.567821, -7.629112, -21.129435, 3.653687, -7.629112, -21.308428, 3.653687, -3.988361, -21.308428, 3.567821, -3.54707, -21.308428, 4.0599475, -3.988361, -21.308428, 3.567821, -3.988361, -21.308428, 4.050549, -3.988361, -21.308428, 3.567821, -3.54707, -21.308428, 4.0599475, -3.54707, -21.308428, 3.799787, -3.988361, -21.308428, 3.567821, -3.54707, -21.308428, 3.799787, -3.54707, -21.308428, 3.5789282, -7.629112, -21.308428, 3.653687, -3.988361, -21.308428, 4.050549, -3.988361, -21.308428, 3.567821, -7.629112, -21.308428, 3.653687, -7.629112, -21.308428, 4.0599475, -3.988361, -21.308428, 4.050549, -3.54707, -21.129435, 3.9070125, -3.5872264, -21.197784, 3.8260593, -3.54707, -21.308428, 3.799787, -3.5872264, -21.197784, 3.8260593, -3.54707, -21.129435, 3.7726603, -3.54707, -21.308428, 3.799787, -3.54707, -21.308428, 4.0599475, -3.54707, -21.129435, 3.9070125, -3.54707, -21.308428, 3.799787, -3.54707, -21.308428, 4.0599475, -3.54707, -21.129435, 4.0599475, -3.54707, -21.129435, 3.9070125, -3.54707, -21.129435, 3.7726603, -3.54707, -21.308428, 3.5789282, -3.54707, -21.308428, 3.799787, -3.54707, -21.129435, 3.7726603, -3.54707, -21.129435, 3.5789282, -3.54707, -21.308428, 3.5789282, -7.629112, -21.129435, 3.653687, -7.629112, -21.308428, 4.0599475, -7.629112, -21.308428, 3.653687, -7.629112, -21.308428, 4.0599475, -7.629112, -21.129435, 3.653687, -7.629112, -21.129435, 3.958489, -7.629112, -21.308428, 4.0599475, -7.629112, -21.129435, 3.958489, -7.629112, -21.17429, 4.0599475, -3.950554, -21.3975, -1.0022886, -3.6320815, -19.082968, -1.0409505, -3.5934205, -21.3975, -1.0022886, -3.950554, -21.3975, -1.0022886, -3.911893, -19.082968, -1.0409505, -3.6320815, -19.082968, -1.0409505, -3.911893, -19.082968, -1.0409505, -3.6320815, -19.082968, -1.3209753, -3.6320815, -19.082968, -1.0409505, -3.911893, -19.082968, -1.0409505, -3.911893, -19.082968, -1.3209753, -3.6320815, -19.082968, -1.3209753, -3.911893, -19.082968, -1.3209753, -3.5934205, -21.3975, -1.3596354, -3.6320815, -19.082968, -1.3209753, -3.911893, -19.082968, -1.3209753, -3.950554, -21.3975, -1.3596354, -3.5934205, -21.3975, -1.3596354, -3.950554, -21.3975, -1.3596354, -3.5934205, -21.3975, -1.0022886, -3.5934205, -21.3975, -1.3596354, -3.950554, -21.3975, -1.3596354, -3.950554, -21.3975, -1.0022886, -3.5934205, -21.3975, -1.0022886, -3.5934205, -21.3975, -1.0022886, -3.6320815, -19.082968, -1.3209753, -3.5934205, -21.3975, -1.3596354, -3.5934205, -21.3975, -1.0022886, -3.6320815, -19.082968, -1.0409505, -3.6320815, -19.082968, -1.3209753, -3.950554, -21.3975, -1.3596354, -3.911893, -19.082968, -1.0409505, -3.950554, -21.3975, -1.0022886, -3.950554, -21.3975, -1.3596354, -3.911893, -19.082968, -1.3209753, -3.911893, -19.082968, -1.0409505, -7.8010573, -21.397497, 5.803108, -7.4439244, -19.082966, 5.8031073, -7.4439244, -21.397497, 5.803108, -7.8010573, -21.397497, 5.803108, -7.8010573, -19.082966, 5.8031073, -7.4439244, -19.082966, 5.8031073, -7.8010573, -21.397497, 5.4459753, -7.4439244, -21.397497, 5.803108, -7.4439244, -21.397497, 5.4459753, -7.8010573, -21.397497, 5.4459753, -7.8010573, -21.397497, 5.803108, -7.4439244, -21.397497, 5.803108, -7.4439244, -21.397497, 5.803108, -7.4439244, -19.082966, 5.4459743, -7.4439244, -21.397497, 5.4459753, -7.4439244, -21.397497, 5.803108, -7.4439244, -19.082966, 5.8031073, -7.4439244, -19.082966, 5.4459743, -7.8010573, -19.661598, 5.4459743, -7.7117743, -19.082966, 5.4459743, -7.8010573, -19.082966, 5.5352573, -7.8010573, -21.397497, 5.803108, -7.8010573, -19.661598, 5.4459743, -7.8010573, -19.082966, 5.5352573, -7.8010573, -19.661598, 5.4459743, -7.8010573, -21.397497, 5.803108, -7.8010573, -21.397497, 5.4459753, -7.8010573, -21.397497, 5.803108, -7.8010573, -19.082966, 5.5352573, -7.8010573, -19.082966, 5.8031073, -7.8010573, -19.082966, 5.5352573, -7.4439244, -19.082966, 5.8031073, -7.8010573, -19.082966, 5.8031073, -7.4439244, -19.082966, 5.8031073, -7.8010573, -19.082966, 5.5352573, -7.7117743, -19.082966, 5.4459743, -7.4439244, -19.082966, 5.8031073, -7.7117743, -19.082966, 5.4459743, -7.4439244, -19.082966, 5.4459743, -7.8010573, -21.397497, 5.4459753, -7.7117743, -19.082966, 5.4459743, -7.8010573, -19.661598, 5.4459743, -7.7117743, -19.082966, 5.4459743, -7.8010573, -21.397497, 5.4459753, -7.4439244, -21.397497, 5.4459753, -7.7117743, -19.082966, 5.4459743, -7.4439244, -21.397497, 5.4459753, -7.4439244, -19.082966, 5.4459743, -5.555945, -21.308428, 4.955558, -3.54707, -21.129435, 4.8647785, -5.555945, -21.129435, 4.9555573, -5.555945, -21.308428, 4.955558, -3.54707, -21.308428, 4.864779, -3.54707, -21.129435, 4.8647785, -7.629112, -21.129435, 4.8647785, -5.555945, -21.308428, 4.955558, -5.555945, -21.129435, 4.9555573, -7.629112, -21.129435, 4.8647785, -7.629112, -21.308428, 4.864779, -5.555945, -21.308428, 4.955558, -5.555945, -21.308428, 5.434868, -3.54707, -21.308428, 4.864779, -5.555945, -21.308428, 4.955558, -5.555945, -21.308428, 5.434868, -3.54707, -21.308428, 5.2710395, -3.54707, -21.308428, 4.864779, -5.555945, -21.308428, 4.955558, -7.629112, -21.308428, 5.4197025, -5.555945, -21.308428, 5.434868, -5.555945, -21.308428, 4.955558, -7.629112, -21.308428, 5.137542, -7.629112, -21.308428, 5.4197025, -7.629112, -21.308428, 5.137542, -5.555945, -21.308428, 4.955558, -7.629112, -21.308428, 4.864779, -3.54707, -21.308428, 5.2710395, -3.54707, -21.129435, 4.8647785, -3.54707, -21.308428, 4.864779, -3.54707, -21.308428, 5.2710395, -3.54707, -21.129435, 5.271039, -3.54707, -21.129435, 4.8647785, -7.629112, -21.129435, 5.1048613, -7.5507226, -21.183046, 5.1524935, -7.629112, -21.308428, 5.137542, -5.555945, -21.129435, 5.31504, -5.555945, -21.17429, 5.434868, -6.0741305, -21.129435, 5.431023, -5.555945, -21.129435, 5.31504, -5.0537796, -21.129435, 5.3940706, -5.555945, -21.17429, 5.434868, -5.555945, -21.129435, 5.31504, -3.54707, -21.129435, 5.271039, -5.0537796, -21.129435, 5.3940706, -5.555945, -21.129435, 5.31504, -3.54707, -21.129435, 4.8647785, -3.54707, -21.129435, 5.271039, -3.54707, -21.129435, 4.8647785, -5.555945, -21.129435, 5.31504, -5.555945, -21.129435, 4.9555573, -6.0741305, -21.129435, 5.431023, -5.555945, -21.129435, 4.9555573, -5.555945, -21.129435, 5.31504, -5.555945, -21.129435, 4.9555573, -7.629112, -21.129435, 5.1048613, -7.629112, -21.129435, 4.8647785, -5.555945, -21.129435, 4.9555573, -7.2726197, -21.129435, 5.1539884, -7.629112, -21.129435, 5.1048613, -6.0741305, -21.129435, 5.431023, -7.2726197, -21.129435, 5.1539884, -5.555945, -21.129435, 4.9555573, -7.5507226, -21.183046, 5.1524935, -7.629112, -21.129435, 5.1048613, -7.2726197, -21.129435, 5.1539884, -7.629112, -21.129435, 5.240281, -7.5507226, -21.183046, 5.1524935, -7.2726197, -21.129435, 5.1539884, -7.2726197, -21.129435, 5.1539884, -6.0741305, -21.129435, 5.431023, -7.629112, -21.129435, 5.240281, -7.629112, -21.129435, 5.240281, -6.0741305, -21.129435, 5.431023, -7.629112, -21.129435, 5.4197025, -7.629112, -21.308428, 4.864779, -7.629112, -21.129435, 5.1048613, -7.629112, -21.308428, 5.137542, -7.629112, -21.308428, 4.864779, -7.629112, -21.129435, 4.8647785, -7.629112, -21.129435, 5.1048613, -7.629112, -21.129435, 5.240281, -7.629112, -21.308428, 5.4197025, -7.629112, -21.308428, 5.137542, -7.629112, -21.129435, 5.240281, -7.629112, -21.129435, 5.4197025, -7.629112, -21.308428, 5.4197025, -7.5507226, -21.183046, 5.1524935, -7.629112, -21.129435, 5.240281, -7.629112, -21.308428, 5.137542, -7.629112, -21.129435, 5.4197025, -5.555945, -21.308428, 5.434868, -7.629112, -21.308428, 5.4197025, -5.555945, -21.308428, 5.434868, -7.629112, -21.129435, 5.4197025, -6.0741305, -21.129435, 5.431023, -5.555945, -21.308428, 5.434868, -6.0741305, -21.129435, 5.431023, -5.555945, -21.17429, 5.434868, -5.555945, -21.17429, 5.434868, -3.54707, -21.308428, 5.2710395, -5.555945, -21.308428, 5.434868, -5.555945, -21.17429, 5.434868, -3.54707, -21.129435, 5.271039, -3.54707, -21.308428, 5.2710395, -3.54707, -21.129435, 5.271039, -5.555945, -21.17429, 5.434868, -5.0537796, -21.129435, 5.3940706, -6.926807, -21.30843, 1.0420431, -3.4520202, -21.129435, 0.96386683, -6.926807, -21.129435, 1.0420431, -6.926807, -21.30843, 1.0420431, -3.4520202, -21.30843, 0.96386683, -3.4520202, -21.129435, 0.96386683, -7.723949, -21.129435, 1.0386255, -6.926807, -21.30843, 1.0420431, -6.926807, -21.129435, 1.0420431, -7.723949, -21.129435, 1.0386255, -7.723949, -21.30843, 1.0386255, -6.926807, -21.30843, 1.0420431, -6.926807, -21.30843, 1.5358781, -3.4520202, -21.30843, 0.96386683, -6.926807, -21.30843, 1.0420431, -6.926807, -21.30843, 1.5358781, -3.4520202, -21.30843, 1.444886, -3.4520202, -21.30843, 0.96386683, -7.723949, -21.30843, 1.0386255, -6.926807, -21.30843, 1.5358781, -6.926807, -21.30843, 1.0420431, -7.723949, -21.30843, 1.0386255, -7.723949, -21.30843, 1.444886, -6.926807, -21.30843, 1.5358781, -7.723949, -21.30843, 1.0386255, -7.723949, -21.129435, 1.444886, -7.723949, -21.30843, 1.444886, -7.723949, -21.30843, 1.0386255, -7.723949, -21.129435, 1.0386255, -7.723949, -21.129435, 1.444886, -6.926807, -21.129435, 1.4124193, -6.926807, -21.17429, 1.5358781, -7.1260924, -21.129435, 1.5130231, -6.926807, -21.129435, 1.4124193, -6.0581107, -21.129435, 1.5130231, -6.926807, -21.17429, 1.5358781, -6.926807, -21.129435, 1.4124193, -4.1037025, -21.129435, 1.4619737, -6.0581107, -21.129435, 1.5130231, -7.1260924, -21.129435, 1.5130231, -6.926807, -21.129435, 1.0420431, -6.926807, -21.129435, 1.4124193, -7.1260924, -21.129435, 1.5130231, -7.723949, -21.129435, 1.0386255, -6.926807, -21.129435, 1.0420431, -7.723949, -21.129435, 1.0386255, -7.1260924, -21.129435, 1.5130231, -7.723949, -21.129435, 1.444886, -3.4520202, -21.129435, 0.96386683, -6.926807, -21.129435, 1.4124193, -6.926807, -21.129435, 1.0420431, -6.926807, -21.129435, 1.4124193, -3.4520202, -21.129435, 0.96386683, -4.1037025, -21.129435, 1.4619737, -4.1037025, -21.129435, 1.4619737, -3.4520202, -21.129435, 0.96386683, -3.4520202, -21.129435, 1.3246312, -4.1037025, -21.129435, 1.4619737, -3.4520202, -21.129435, 1.3246312, -3.4520202, -21.17429, 1.444886, -7.723949, -21.129435, 1.444886, -6.926807, -21.30843, 1.5358781, -7.723949, -21.30843, 1.444886, -6.926807, -21.30843, 1.5358781, -7.723949, -21.129435, 1.444886, -7.1260924, -21.129435, 1.5130231, -6.926807, -21.30843, 1.5358781, -7.1260924, -21.129435, 1.5130231, -6.926807, -21.17429, 1.5358781, -6.926807, -21.17429, 1.5358781, -3.4520202, -21.30843, 1.444886, -6.926807, -21.30843, 1.5358781, -6.926807, -21.17429, 1.5358781, -4.1037025, -21.129435, 1.4619737, -3.4520202, -21.30843, 1.444886, -3.4520202, -21.30843, 1.444886, -4.1037025, -21.129435, 1.4619737, -3.4520202, -21.17429, 1.444886, -4.1037025, -21.129435, 1.4619737, -6.926807, -21.17429, 1.5358781, -6.0581107, -21.129435, 1.5130231, -3.4520202, -21.17429, 1.444886, -3.4520202, -21.30843, 0.96386683, -3.4520202, -21.30843, 1.444886, -3.4520202, -21.30843, 0.96386683, -3.4520202, -21.17429, 1.444886, -3.4520202, -21.129435, 1.3246312, -3.4520202, -21.30843, 0.96386683, -3.4520202, -21.129435, 1.3246312, -3.4520202, -21.129435, 0.96386683, -6.9564967, -21.308428, 4.294263, -3.4046016, -21.129435, 4.2160864, -6.9564967, -21.129435, 4.294263, -6.9564967, -21.308428, 4.294263, -3.4046016, -21.308428, 4.2160864, -3.4046016, -21.129435, 4.2160864, -7.7713675, -21.129435, 4.290845, -6.9564967, -21.308428, 4.294263, -6.9564967, -21.129435, 4.294263, -7.7713675, -21.129435, 4.290845, -7.7713675, -21.308428, 4.2908454, -6.9564967, -21.308428, 4.294263, -6.9564967, -21.308428, 4.787884, -3.4046016, -21.308428, 4.2160864, -6.9564967, -21.308428, 4.294263, -6.9564967, -21.308428, 4.787884, -3.4046016, -21.308428, 4.6971054, -3.4046016, -21.308428, 4.2160864, -7.7713675, -21.308428, 4.2908454, -6.9564967, -21.308428, 4.787884, -6.9564967, -21.308428, 4.294263, -7.7713675, -21.308428, 4.2908454, -7.7713675, -21.308428, 4.6971054, -6.9564967, -21.308428, 4.787884, -7.7713675, -21.308428, 4.2908454, -7.7713675, -21.129435, 4.6971054, -7.7713675, -21.308428, 4.6971054, -7.7713675, -21.308428, 4.2908454, -7.7713675, -21.129435, 4.290845, -7.7713675, -21.129435, 4.6971054, -6.9564967, -21.129435, 4.6646385, -6.9564967, -21.17429, 4.7878838, -7.1602683, -21.129435, 4.7652426, -6.9564967, -21.129435, 4.6646385, -6.0685763, -21.129435, 4.7652426, -6.9564967, -21.17429, 4.7878838, -6.9564967, -21.129435, 4.6646385, -4.0705953, -21.129435, 4.7141933, -6.0685763, -21.129435, 4.7652426, -7.1602683, -21.129435, 4.7652426, -6.9564967, -21.129435, 4.294263, -6.9564967, -21.129435, 4.6646385, -7.1602683, -21.129435, 4.7652426, -7.7713675, -21.129435, 4.290845, -6.9564967, -21.129435, 4.294263, -7.7713675, -21.129435, 4.290845, -7.1602683, -21.129435, 4.7652426, -7.7713675, -21.129435, 4.6971054, -3.4046016, -21.129435, 4.2160864, -6.9564967, -21.129435, 4.6646385, -6.9564967, -21.129435, 4.294263, -6.9564967, -21.129435, 4.6646385, -3.4046016, -21.129435, 4.2160864, -4.0705953, -21.129435, 4.7141933, -4.0705953, -21.129435, 4.7141933, -3.4046016, -21.129435, 4.2160864, -3.4046016, -21.129435, 4.576851, -4.0705953, -21.129435, 4.7141933, -3.4046016, -21.129435, 4.576851, -3.4046016, -21.17429, 4.6971054, -7.7713675, -21.129435, 4.6971054, -6.9564967, -21.308428, 4.787884, -7.7713675, -21.308428, 4.6971054, -6.9564967, -21.308428, 4.787884, -7.7713675, -21.129435, 4.6971054, -7.1602683, -21.129435, 4.7652426, -6.9564967, -21.308428, 4.787884, -7.1602683, -21.129435, 4.7652426, -6.9564967, -21.17429, 4.7878838, -6.9564967, -21.17429, 4.7878838, -3.4046016, -21.308428, 4.6971054, -6.9564967, -21.308428, 4.787884, -6.9564967, -21.17429, 4.7878838, -4.0705953, -21.129435, 4.7141933, -3.4046016, -21.308428, 4.6971054, -3.4046016, -21.308428, 4.6971054, -4.0705953, -21.129435, 4.7141933, -3.4046016, -21.17429, 4.6971054, -4.0705953, -21.129435, 4.7141933, -6.9564967, -21.17429, 4.7878838, -6.0685763, -21.129435, 4.7652426, -3.4046016, -21.17429, 4.6971054, -3.4046016, -21.308428, 4.2160864, -3.4046016, -21.308428, 4.6971054, -3.4046016, -21.308428, 4.2160864, -3.4046016, -21.17429, 4.6971054, -3.4046016, -21.129435, 4.576851, -3.4046016, -21.308428, 4.2160864, -3.4046016, -21.129435, 4.576851, -3.4046016, -21.129435, 4.2160864, -3.8851933, -21.397497, 5.744369, -3.5280604, -19.082966, 5.744368, -3.5280604, -21.397497, 5.744369, -3.8851933, -21.397497, 5.744369, -3.8851933, -19.351458, 5.7443686, -3.5280604, -19.082966, 5.744368, -3.8851933, -19.351458, 5.7443686, -3.5280604, -19.082966, 5.387021, -3.5280604, -19.082966, 5.744368, -3.8851933, -19.351458, 5.7443686, -3.8851933, -19.082966, 5.387021, -3.5280604, -19.082966, 5.387021, -3.8851933, -19.082966, 5.387021, -3.5280604, -21.397497, 5.387022, -3.5280604, -19.082966, 5.387021, -3.8851933, -19.082966, 5.387021, -3.8851933, -21.397497, 5.387022, -3.5280604, -21.397497, 5.387022, -3.8851933, -21.397497, 5.387022, -3.5280604, -21.397497, 5.744369, -3.5280604, -21.397497, 5.387022, -3.8851933, -21.397497, 5.387022, -3.8851933, -21.397497, 5.744369, -3.5280604, -21.397497, 5.744369, -3.5280604, -21.397497, 5.744369, -3.5280604, -19.082966, 5.387021, -3.5280604, -21.397497, 5.387022, -3.5280604, -21.397497, 5.744369, -3.5280604, -19.082966, 5.744368, -3.5280604, -19.082966, 5.387021, -3.8851933, -21.397497, 5.387022, -3.8851933, -19.351458, 5.7443686, -3.8851933, -21.397497, 5.744369, -3.8851933, -21.397497, 5.387022, -3.8851933, -19.082966, 5.387021, -3.8851933, -19.351458, 5.7443686, -3.8144932, -21.40476, 5.450674, -3.7010732, -21.359264, 5.450674, -3.7010732, -21.40476, 5.450674, -3.8144932, -21.40476, 5.450674, -3.8144932, -21.359264, 5.450674, -3.7010732, -21.359264, 5.450674, -3.8144932, -21.359264, 5.450674, -3.7010732, -21.359266, -1.0281336, -3.7010732, -21.359264, 5.450674, -3.8144932, -21.359264, 5.450674, -3.8144932, -21.359266, -1.0281336, -3.7010732, -21.359266, -1.0281336, -3.8144932, -21.359266, -1.0281336, -3.7010732, -21.404762, -1.0281336, -3.7010732, -21.359266, -1.0281336, -3.8144932, -21.359266, -1.0281336, -3.8144932, -21.404762, -1.0281336, -3.7010732, -21.404762, -1.0281336, -3.8144932, -21.404762, -1.0281336, -3.7010732, -21.40476, 5.450674, -3.7010732, -21.404762, -1.0281336, -3.8144932, -21.404762, -1.0281336, -3.8144932, -21.40476, 5.450674, -3.7010732, -21.40476, 5.450674, -3.7010732, -21.40476, 5.450674, -3.7010732, -21.359266, -1.0281336, -3.7010732, -21.404762, -1.0281336, -3.7010732, -21.40476, 5.450674, -3.7010732, -21.359264, 5.450674, -3.7010732, -21.359266, -1.0281336, -3.8144932, -21.404762, -1.0281336, -3.8144932, -21.359264, 5.450674, -3.8144932, -21.40476, 5.450674, -3.8144932, -21.404762, -1.0281336, -3.8144932, -21.359266, -1.0281336, -3.8144932, -21.359264, 5.450674, -7.4172244, -21.333633, 0.22268713, -7.393088, -21.35008, -0.25406027, -7.393088, -21.355635, 0.23059022, -7.4172244, -21.333633, 0.22268713, -7.4172244, -21.328295, -0.24551606, -7.393088, -21.35008, -0.25406027, -7.4172244, -21.328295, -0.24551606, -7.393088, -21.208893, -0.27221608, -7.393088, -21.35008, -0.25406027, -7.4172244, -21.328295, -0.24551606, -7.4172244, -21.21466, -0.25277877, -7.393088, -21.208893, -0.27221608, -7.393088, -21.355635, 0.23059022, -7.4172244, -21.371868, -0.26239038, -7.4172244, -21.377848, 0.2384932, -7.393088, -21.355635, 0.23059022, -7.393088, -21.35008, -0.25406027, -7.4172244, -21.371868, -0.26239038, -7.393088, -21.35008, -0.25406027, -7.4172244, -21.20334, -0.29122615, -7.4172244, -21.371868, -0.26239038, -7.393088, -21.35008, -0.25406027, -7.393088, -21.208893, -0.27221608, -7.4172244, -21.20334, -0.29122615, -7.4172244, -21.377848, 0.2384932, -7.441361, -21.35008, -0.25406027, -7.441361, -21.355635, 0.23059022, -7.4172244, -21.377848, 0.2384932, -7.4172244, -21.371868, -0.26239038, -7.441361, -21.35008, -0.25406027, -7.4172244, -21.371868, -0.26239038, -7.441361, -21.208893, -0.27221608, -7.441361, -21.35008, -0.25406027, -7.4172244, -21.371868, -0.26239038, -7.4172244, -21.20334, -0.29122615, -7.441361, -21.208893, -0.27221608, -7.441361, -21.355635, 0.23059022, -7.4172244, -21.328295, -0.24551606, -7.4172244, -21.333633, 0.22268713, -7.441361, -21.355635, 0.23059022, -7.441361, -21.35008, -0.25406027, -7.4172244, -21.328295, -0.24551606, -7.441361, -21.35008, -0.25406027, -7.4172244, -21.21466, -0.25277877, -7.4172244, -21.328295, -0.24551606, -7.441361, -21.35008, -0.25406027, -7.441361, -21.208893, -0.27221608, -7.4172244, -21.21466, -0.25277877, -7.4172244, -21.21466, -0.25277877, -7.393088, -21.090775, -0.24231243, -7.393088, -21.208893, -0.27221608, -7.4172244, -21.21466, -0.25277877, -7.4172244, -21.114271, -0.23804045, -7.393088, -21.090775, -0.24231243, -7.4172244, -21.114271, -0.23804045, -7.393088, -21.088425, 0.22674549, -7.393088, -21.090775, -0.24231243, -7.4172244, -21.114271, -0.23804045, -7.4172244, -21.111708, 0.22204626, -7.393088, -21.088425, 0.22674549, -7.4172244, -21.111708, 0.22204626, -7.393088, -21.219574, 0.2705326, -7.393088, -21.088425, 0.22674549, -7.4172244, -21.111708, 0.22204626, -7.4172244, -21.224485, 0.2510954, -7.393088, -21.219574, 0.2705326, -7.393088, -21.208893, -0.27221608, -7.4172244, -21.06728, -0.24658465, -7.4172244, -21.20334, -0.29122615, -7.393088, -21.208893, -0.27221608, -7.393088, -21.090775, -0.24231243, -7.4172244, -21.06728, -0.24658465, -7.393088, -21.090775, -0.24231243, -7.4172244, -21.06493, 0.23144436, -7.4172244, -21.06728, -0.24658465, -7.393088, -21.090775, -0.24231243, -7.393088, -21.088425, 0.22674549, -7.4172244, -21.06493, 0.23144436, -7.393088, -21.088425, 0.22674549, -7.4172244, -21.214874, 0.28996992, -7.4172244, -21.06493, 0.23144436, -7.393088, -21.088425, 0.22674549, -7.393088, -21.219574, 0.2705326, -7.4172244, -21.214874, 0.28996992, -7.4172244, -21.20334, -0.29122615, -7.441361, -21.090775, -0.24231243, -7.441361, -21.208893, -0.27221608, -7.4172244, -21.20334, -0.29122615, -7.4172244, -21.06728, -0.24658465, -7.441361, -21.090775, -0.24231243, -7.441361, -21.208893, -0.27221608, -7.4172244, -21.114271, -0.23804045, -7.4172244, -21.21466, -0.25277877, -7.441361, -21.208893, -0.27221608, -7.441361, -21.090775, -0.24231243, -7.4172244, -21.114271, -0.23804045, -7.441361, -21.090775, -0.24231243, -7.4172244, -21.111708, 0.22204626, -7.4172244, -21.114271, -0.23804045, -7.441361, -21.090775, -0.24231243, -7.441361, -21.088425, 0.22674549, -7.4172244, -21.111708, 0.22204626, -7.441361, -21.088425, 0.22674549, -7.4172244, -21.224485, 0.2510954, -7.4172244, -21.111708, 0.22204626, -7.441361, -21.088425, 0.22674549, -7.441361, -21.219574, 0.2705326, -7.4172244, -21.224485, 0.2510954, -7.4172244, -21.06728, -0.24658465, -7.441361, -21.088425, 0.22674549, -7.441361, -21.090775, -0.24231243, -7.4172244, -21.06728, -0.24658465, -7.4172244, -21.06493, 0.23144436, -7.441361, -21.088425, 0.22674549, -7.4172244, -21.06493, 0.23144436, -7.441361, -21.219574, 0.2705326, -7.441361, -21.088425, 0.22674549, -7.4172244, -21.06493, 0.23144436, -7.4172244, -21.214874, 0.28996992, -7.441361, -21.219574, 0.2705326, -7.4172244, -21.224485, 0.2510954, -7.393088, -21.355635, 0.23059022, -7.393088, -21.219574, 0.2705326, -7.4172244, -21.224485, 0.2510954, -7.4172244, -21.333633, 0.22268713, -7.393088, -21.355635, 0.23059022, -7.393088, -21.219574, 0.2705326, -7.4172244, -21.377848, 0.2384932, -7.4172244, -21.214874, 0.28996992, -7.393088, -21.219574, 0.2705326, -7.393088, -21.355635, 0.23059022, -7.4172244, -21.377848, 0.2384932, -7.4172244, -21.214874, 0.28996992, -7.441361, -21.355635, 0.23059022, -7.441361, -21.219574, 0.2705326, -7.4172244, -21.214874, 0.28996992, -7.4172244, -21.377848, 0.2384932, -7.441361, -21.355635, 0.23059022, -7.441361, -21.219574, 0.2705326, -7.4172244, -21.333633, 0.22268713, -7.4172244, -21.224485, 0.2510954, -7.441361, -21.219574, 0.2705326, -7.441361, -21.355635, 0.23059022, -7.4172244, -21.333633, 0.22268713, -3.8775039, -21.320818, 0.20923042, -3.8561444, -21.335342, -0.30446887, -3.8561444, -21.34047, 0.21777427, -3.8775039, -21.320818, 0.20923042, -3.8775039, -21.316118, -0.29528427, -3.8561444, -21.335342, -0.30446887, -3.8775039, -21.316118, -0.29528427, -3.8561444, -21.210388, -0.32390642, -3.8561444, -21.335342, -0.30446887, -3.8775039, -21.316118, -0.29528427, -3.8775039, -21.215515, -0.3031876, -3.8561444, -21.210388, -0.32390642, -3.8561444, -21.34047, 0.21777427, -3.8775039, -21.35478, -0.31322622, -3.8775039, -21.36012, 0.22631812, -3.8561444, -21.34047, 0.21777427, -3.8561444, -21.335342, -0.30446887, -3.8775039, -21.35478, -0.31322622, -3.8561444, -21.335342, -0.30446887, -3.8775039, -21.205263, -0.34462523, -3.8775039, -21.35478, -0.31322622, -3.8561444, -21.335342, -0.30446887, -3.8561444, -21.210388, -0.32390642, -3.8775039, -21.205263, -0.34462523, -3.8775039, -21.36012, 0.22631812, -3.8988638, -21.335342, -0.30446887, -3.8988638, -21.34047, 0.21777427, -3.8775039, -21.36012, 0.22631812, -3.8775039, -21.35478, -0.31322622, -3.8988638, -21.335342, -0.30446887, -3.8775039, -21.35478, -0.31322622, -3.8988638, -21.210388, -0.32390642, -3.8988638, -21.335342, -0.30446887, -3.8775039, -21.35478, -0.31322622, -3.8775039, -21.205263, -0.34462523, -3.8988638, -21.210388, -0.32390642, -3.8988638, -21.34047, 0.21777427, -3.8775039, -21.316118, -0.29528427, -3.8775039, -21.320818, 0.20923042, -3.8988638, -21.34047, 0.21777427, -3.8988638, -21.335342, -0.30446887, -3.8775039, -21.316118, -0.29528427, -3.8988638, -21.335342, -0.30446887, -3.8775039, -21.215515, -0.3031876, -3.8775039, -21.316118, -0.29528427, -3.8988638, -21.335342, -0.30446887, -3.8988638, -21.210388, -0.32390642, -3.8775039, -21.215515, -0.3031876, -3.8775039, -21.215515, -0.3031876, -3.8561444, -21.105513, -0.29165316, -3.8561444, -21.210388, -0.32390642, -3.8775039, -21.215515, -0.3031876, -3.8775039, -21.126446, -0.2871678, -3.8561444, -21.105513, -0.29165316, -3.8775039, -21.126446, -0.2871678, -3.8561444, -21.10359, 0.2135024, -3.8561444, -21.105513, -0.29165316, -3.8775039, -21.126446, -0.2871678, -3.8775039, -21.12431, 0.20858967, -3.8561444, -21.10359, 0.2135024, -3.8775039, -21.12431, 0.20858967, -3.8561444, -21.219788, 0.26070714, -3.8561444, -21.10359, 0.2135024, -3.8775039, -21.12431, 0.20858967, -3.8775039, -21.224058, 0.23977482, -3.8561444, -21.219788, 0.26070714, -3.8561444, -21.210388, -0.32390642, -3.8775039, -21.084795, -0.2963524, -3.8775039, -21.205263, -0.34462523, -3.8561444, -21.210388, -0.32390642, -3.8561444, -21.105513, -0.29165316, -3.8775039, -21.084795, -0.2963524, -3.8561444, -21.105513, -0.29165316, -3.8775039, -21.082659, 0.21862864, -3.8775039, -21.084795, -0.2963524, -3.8561444, -21.105513, -0.29165316, -3.8561444, -21.10359, 0.2135024, -3.8775039, -21.082659, 0.21862864, -3.8561444, -21.10359, 0.2135024, -3.8775039, -21.215515, 0.2816397, -3.8775039, -21.082659, 0.21862864, -3.8561444, -21.10359, 0.2135024, -3.8561444, -21.219788, 0.26070714, -3.8775039, -21.215515, 0.2816397, -3.8775039, -21.205263, -0.34462523, -3.8988638, -21.105513, -0.29165316, -3.8988638, -21.210388, -0.32390642, -3.8775039, -21.205263, -0.34462523, -3.8775039, -21.084795, -0.2963524, -3.8988638, -21.105513, -0.29165316, -3.8988638, -21.210388, -0.32390642, -3.8775039, -21.126446, -0.2871678, -3.8775039, -21.215515, -0.3031876, -3.8988638, -21.210388, -0.32390642, -3.8988638, -21.105513, -0.29165316, -3.8775039, -21.126446, -0.2871678, -3.8988638, -21.105513, -0.29165316, -3.8775039, -21.12431, 0.20858967, -3.8775039, -21.126446, -0.2871678, -3.8988638, -21.105513, -0.29165316, -3.8988638, -21.10359, 0.2135024, -3.8775039, -21.12431, 0.20858967, -3.8988638, -21.10359, 0.2135024, -3.8775039, -21.224058, 0.23977482, -3.8775039, -21.12431, 0.20858967, -3.8988638, -21.10359, 0.2135024, -3.8988638, -21.219788, 0.26070714, -3.8775039, -21.224058, 0.23977482, -3.8775039, -21.084795, -0.2963524, -3.8988638, -21.10359, 0.2135024, -3.8988638, -21.105513, -0.29165316, -3.8775039, -21.084795, -0.2963524, -3.8775039, -21.082659, 0.21862864, -3.8988638, -21.10359, 0.2135024, -3.8775039, -21.082659, 0.21862864, -3.8988638, -21.219788, 0.26070714, -3.8988638, -21.10359, 0.2135024, -3.8775039, -21.082659, 0.21862864, -3.8775039, -21.215515, 0.2816397, -3.8988638, -21.219788, 0.26070714, -3.8775039, -21.224058, 0.23977482, -3.8561444, -21.34047, 0.21777427, -3.8561444, -21.219788, 0.26070714, -3.8775039, -21.224058, 0.23977482, -3.8775039, -21.320818, 0.20923042, -3.8561444, -21.34047, 0.21777427, -3.8561444, -21.219788, 0.26070714, -3.8775039, -21.36012, 0.22631812, -3.8775039, -21.215515, 0.2816397, -3.8561444, -21.219788, 0.26070714, -3.8561444, -21.34047, 0.21777427, -3.8775039, -21.36012, 0.22631812, -3.8775039, -21.215515, 0.2816397, -3.8988638, -21.34047, 0.21777427, -3.8988638, -21.219788, 0.26070714, -3.8775039, -21.215515, 0.2816397, -3.8775039, -21.36012, 0.22631812, -3.8988638, -21.34047, 0.21777427, -3.8988638, -21.219788, 0.26070714, -3.8775039, -21.320818, 0.20923042, -3.8775039, -21.224058, 0.23977482, -3.8988638, -21.219788, 0.26070714, -3.8988638, -21.34047, 0.21777427, -3.8775039, -21.320818, 0.20923042, -7.34631, -21.333633, 0.9091861, -7.3221745, -21.35008, 0.3158151, -7.3221745, -21.355635, 0.9190115, -7.34631, -21.333633, 0.9091861, -7.34631, -21.328295, 0.3260677, -7.3221745, -21.35008, 0.3158151, -7.34631, -21.328295, 0.3260677, -7.3221745, -21.208893, 0.2931739, -7.3221745, -21.35008, 0.3158151, -7.34631, -21.328295, 0.3260677, -7.34631, -21.21466, 0.3170967, -7.3221745, -21.208893, 0.2931739, -7.3221745, -21.355635, 0.9190115, -7.34631, -21.371868, 0.30534887, -7.34631, -21.377848, 0.92883694, -7.3221745, -21.355635, 0.9190115, -7.3221745, -21.35008, 0.3158151, -7.34631, -21.371868, 0.30534887, -7.3221745, -21.35008, 0.3158151, -7.34631, -21.20334, 0.2692511, -7.34631, -21.371868, 0.30534887, -7.3221745, -21.35008, 0.3158151, -7.3221745, -21.208893, 0.2931739, -7.34631, -21.20334, 0.2692511, -7.34631, -21.377848, 0.92883694, -7.3704467, -21.35008, 0.3158151, -7.3704467, -21.355635, 0.9190115, -7.34631, -21.377848, 0.92883694, -7.34631, -21.371868, 0.30534887, -7.3704467, -21.35008, 0.3158151, -7.34631, -21.371868, 0.30534887, -7.3704467, -21.208893, 0.2931739, -7.3704467, -21.35008, 0.3158151, -7.34631, -21.371868, 0.30534887, -7.34631, -21.20334, 0.2692511, -7.3704467, -21.208893, 0.2931739, -7.3704467, -21.355635, 0.9190115, -7.34631, -21.328295, 0.3260677, -7.34631, -21.333633, 0.9091861, -7.3704467, -21.355635, 0.9190115, -7.3704467, -21.35008, 0.3158151, -7.34631, -21.328295, 0.3260677, -7.3704467, -21.35008, 0.3158151, -7.34631, -21.21466, 0.3170967, -7.34631, -21.328295, 0.3260677, -7.3704467, -21.35008, 0.3158151, -7.3704467, -21.208893, 0.2931739, -7.34631, -21.21466, 0.3170967, -7.34631, -21.21466, 0.3170967, -7.3221745, -21.090775, 0.33033967, -7.3221745, -21.208893, 0.2931739, -7.34631, -21.21466, 0.3170967, -7.34631, -21.114271, 0.33567965, -7.3221745, -21.090775, 0.33033967, -7.34631, -21.114271, 0.33567965, -7.3221745, -21.088425, 0.91409886, -7.3221745, -21.090775, 0.33033967, -7.34631, -21.114271, 0.33567965, -7.34631, -21.111708, 0.90833163, -7.3221745, -21.088425, 0.91409886, -7.34631, -21.111708, 0.90833163, -7.3221745, -21.219574, 0.96877944, -7.3221745, -21.088425, 0.91409886, -7.34631, -21.111708, 0.90833163, -7.34631, -21.224485, 0.9444295, -7.3221745, -21.219574, 0.96877944, -7.3221745, -21.208893, 0.2931739, -7.34631, -21.06728, 0.32499957, -7.34631, -21.20334, 0.2692511, -7.3221745, -21.208893, 0.2931739, -7.3221745, -21.090775, 0.33033967, -7.34631, -21.06728, 0.32499957, -7.3221745, -21.090775, 0.33033967, -7.34631, -21.06493, 0.92007935, -7.34631, -21.06728, 0.32499957, -7.3221745, -21.090775, 0.33033967, -7.3221745, -21.088425, 0.91409886, -7.34631, -21.06493, 0.92007935, -7.3221745, -21.088425, 0.91409886, -7.34631, -21.214874, 0.99291587, -7.34631, -21.06493, 0.92007935, -7.3221745, -21.088425, 0.91409886, -7.3221745, -21.219574, 0.96877944, -7.34631, -21.214874, 0.99291587, -7.34631, -21.20334, 0.2692511, -7.3704467, -21.090775, 0.33033967, -7.3704467, -21.208893, 0.2931739, -7.34631, -21.20334, 0.2692511, -7.34631, -21.06728, 0.32499957, -7.3704467, -21.090775, 0.33033967, -7.3704467, -21.208893, 0.2931739, -7.34631, -21.114271, 0.33567965, -7.34631, -21.21466, 0.3170967, -7.3704467, -21.208893, 0.2931739, -7.3704467, -21.090775, 0.33033967, -7.34631, -21.114271, 0.33567965, -7.3704467, -21.090775, 0.33033967, -7.34631, -21.111708, 0.90833163, -7.34631, -21.114271, 0.33567965, -7.3704467, -21.090775, 0.33033967, -7.3704467, -21.088425, 0.91409886, -7.34631, -21.111708, 0.90833163, -7.3704467, -21.088425, 0.91409886, -7.34631, -21.224485, 0.9444295, -7.34631, -21.111708, 0.90833163, -7.3704467, -21.088425, 0.91409886, -7.3704467, -21.219574, 0.96877944, -7.34631, -21.224485, 0.9444295, -7.34631, -21.06728, 0.32499957, -7.3704467, -21.088425, 0.91409886, -7.3704467, -21.090775, 0.33033967, -7.34631, -21.06728, 0.32499957, -7.34631, -21.06493, 0.92007935, -7.3704467, -21.088425, 0.91409886, -7.34631, -21.06493, 0.92007935, -7.3704467, -21.219574, 0.96877944, -7.3704467, -21.088425, 0.91409886, -7.34631, -21.06493, 0.92007935, -7.34631, -21.214874, 0.99291587, -7.3704467, -21.219574, 0.96877944, -7.34631, -21.224485, 0.9444295, -7.3221745, -21.355635, 0.9190115, -7.3221745, -21.219574, 0.96877944, -7.34631, -21.224485, 0.9444295, -7.34631, -21.333633, 0.9091861, -7.3221745, -21.355635, 0.9190115, -7.3221745, -21.219574, 0.96877944, -7.34631, -21.377848, 0.92883694, -7.34631, -21.214874, 0.99291587, -7.3221745, -21.219574, 0.96877944, -7.3221745, -21.355635, 0.9190115, -7.34631, -21.377848, 0.92883694, -7.34631, -21.214874, 0.99291587, -7.3704467, -21.355635, 0.9190115, -7.3704467, -21.219574, 0.96877944, -7.34631, -21.214874, 0.99291587, -7.34631, -21.377848, 0.92883694, -7.3704467, -21.355635, 0.9190115, -7.3704467, -21.219574, 0.96877944, -7.34631, -21.333633, 0.9091861, -7.34631, -21.224485, 0.9444295, -7.3704467, -21.219574, 0.96877944, -7.3704467, -21.355635, 0.9190115, -7.34631, -21.333633, 0.9091861, -7.433244, -21.333633, 2.1138701, -7.4093213, -21.35008, 1.6759974, -7.4093213, -21.355633, 2.1211324, -7.433244, -21.333633, 2.1138701, -7.433244, -21.328293, 1.6839005, -7.4093213, -21.35008, 1.6759974, -7.4093213, -21.355633, 2.1211324, -7.433244, -21.371868, 1.6683079, -7.433244, -21.377848, 2.1283946, -7.4093213, -21.355633, 2.1211324, -7.4093213, -21.35008, 1.6759974, -7.433244, -21.371868, 1.6683079, -7.433244, -21.377848, 2.1283946, -7.457381, -21.35008, 1.6759974, -7.457381, -21.355633, 2.1211324, -7.433244, -21.377848, 2.1283946, -7.433244, -21.371868, 1.6683079, -7.457381, -21.35008, 1.6759974, -7.457381, -21.355633, 2.1211324, -7.433244, -21.328293, 1.6839005, -7.433244, -21.333633, 2.1138701, -7.457381, -21.355633, 2.1211324, -7.457381, -21.35008, 1.6759974, -7.433244, -21.328293, 1.6839005, -7.433244, -21.328293, 1.6839005, -7.4093213, -21.208893, 1.6595504, -7.4093213, -21.35008, 1.6759974, -7.433244, -21.328293, 1.6839005, -7.433244, -21.21466, 1.6770654, -7.4093213, -21.208893, 1.6595504, -7.4093213, -21.35008, 1.6759974, -7.433244, -21.203339, 1.6418219, -7.433244, -21.371868, 1.6683079, -7.4093213, -21.35008, 1.6759974, -7.4093213, -21.208893, 1.6595504, -7.433244, -21.203339, 1.6418219, -7.433244, -21.371868, 1.6683079, -7.457381, -21.208893, 1.6595504, -7.457381, -21.35008, 1.6759974, -7.433244, -21.371868, 1.6683079, -7.433244, -21.203339, 1.6418219, -7.457381, -21.208893, 1.6595504, -7.457381, -21.35008, 1.6759974, -7.433244, -21.21466, 1.6770654, -7.433244, -21.328293, 1.6839005, -7.457381, -21.35008, 1.6759974, -7.457381, -21.208893, 1.6595504, -7.433244, -21.21466, 1.6770654, -7.433244, -21.21466, 1.6770654, -7.4093213, -21.090775, 1.6868907, -7.4093213, -21.208893, 1.6595504, -7.433244, -21.21466, 1.6770654, -7.433244, -21.11427, 1.6907355, -7.4093213, -21.090775, 1.6868907, -7.4093213, -21.208893, 1.6595504, -7.433244, -21.067278, 1.6828324, -7.433244, -21.203339, 1.6418219, -7.4093213, -21.208893, 1.6595504, -7.4093213, -21.090775, 1.6868907, -7.433244, -21.067278, 1.6828324, -7.433244, -21.203339, 1.6418219, -7.457381, -21.090775, 1.6868907, -7.457381, -21.208893, 1.6595504, -7.433244, -21.203339, 1.6418219, -7.433244, -21.067278, 1.6828324, -7.457381, -21.090775, 1.6868907, -7.457381, -21.208893, 1.6595504, -7.433244, -21.11427, 1.6907355, -7.433244, -21.21466, 1.6770654, -7.457381, -21.208893, 1.6595504, -7.457381, -21.090775, 1.6868907, -7.433244, -21.11427, 1.6907355, -7.433244, -21.11427, 1.6907355, -7.4093213, -21.088425, 2.1175013, -7.4093213, -21.090775, 1.6868907, -7.433244, -21.11427, 1.6907355, -7.433244, -21.111706, 2.1132293, -7.4093213, -21.088425, 2.1175013, -7.433244, -21.111706, 2.1132293, -7.4093213, -21.219572, 2.157871, -7.4093213, -21.088425, 2.1175013, -7.433244, -21.111706, 2.1132293, -7.433244, -21.224485, 2.1399288, -7.4093213, -21.219572, 2.157871, -7.4093213, -21.090775, 1.6868907, -7.433244, -21.064928, 2.121773, -7.433244, -21.067278, 1.6828324, -7.4093213, -21.090775, 1.6868907, -7.4093213, -21.088425, 2.1175013, -7.433244, -21.064928, 2.121773, -7.4093213, -21.088425, 2.1175013, -7.433244, -21.214874, 2.1755996, -7.433244, -21.064928, 2.121773, -7.4093213, -21.088425, 2.1175013, -7.4093213, -21.219572, 2.157871, -7.433244, -21.214874, 2.1755996, -7.433244, -21.067278, 1.6828324, -7.457381, -21.088425, 2.1175013, -7.457381, -21.090775, 1.6868907, -7.433244, -21.067278, 1.6828324, -7.433244, -21.064928, 2.121773, -7.457381, -21.088425, 2.1175013, -7.433244, -21.064928, 2.121773, -7.457381, -21.219572, 2.157871, -7.457381, -21.088425, 2.1175013, -7.433244, -21.064928, 2.121773, -7.433244, -21.214874, 2.1755996, -7.457381, -21.219572, 2.157871, -7.457381, -21.090775, 1.6868907, -7.433244, -21.111706, 2.1132293, -7.433244, -21.11427, 1.6907355, -7.457381, -21.090775, 1.6868907, -7.457381, -21.088425, 2.1175013, -7.433244, -21.111706, 2.1132293, -7.457381, -21.088425, 2.1175013, -7.433244, -21.224485, 2.1399288, -7.433244, -21.111706, 2.1132293, -7.457381, -21.088425, 2.1175013, -7.457381, -21.219572, 2.157871, -7.433244, -21.224485, 2.1399288, -7.433244, -21.224485, 2.1399288, -7.4093213, -21.355633, 2.1211324, -7.4093213, -21.219572, 2.157871, -7.433244, -21.224485, 2.1399288, -7.433244, -21.333633, 2.1138701, -7.4093213, -21.355633, 2.1211324, -7.4093213, -21.219572, 2.157871, -7.433244, -21.377848, 2.1283946, -7.433244, -21.214874, 2.1755996, -7.4093213, -21.219572, 2.157871, -7.4093213, -21.355633, 2.1211324, -7.433244, -21.377848, 2.1283946, -7.433244, -21.214874, 2.1755996, -7.457381, -21.355633, 2.1211324, -7.457381, -21.219572, 2.157871, -7.433244, -21.214874, 2.1755996, -7.433244, -21.377848, 2.1283946, -7.457381, -21.355633, 2.1211324, -7.457381, -21.219572, 2.157871, -7.433244, -21.333633, 2.1138701, -7.433244, -21.224485, 2.1399288, -7.457381, -21.219572, 2.157871, -7.457381, -21.355633, 2.1211324, -7.433244, -21.333633, 2.1138701, -7.433244, -21.333633, 3.4082646, -7.4093213, -21.35008, 2.8360398, -7.4093213, -21.355633, 3.4176629, -7.433244, -21.333633, 3.4082646, -7.433244, -21.328293, 2.8460789, -7.4093213, -21.35008, 2.8360398, -7.433244, -21.328293, 2.8460789, -7.4093213, -21.208893, 2.8142529, -7.4093213, -21.35008, 2.8360398, -7.433244, -21.328293, 2.8460789, -7.433244, -21.21466, 2.837535, -7.4093213, -21.208893, 2.8142529, -7.4093213, -21.355633, 3.4176629, -7.433244, -21.371866, 2.8260007, -7.433244, -21.377848, 3.4272747, -7.4093213, -21.355633, 3.4176629, -7.4093213, -21.35008, 2.8360398, -7.433244, -21.371866, 2.8260007, -7.4093213, -21.35008, 2.8360398, -7.433244, -21.203339, 2.7911844, -7.433244, -21.371866, 2.8260007, -7.4093213, -21.35008, 2.8360398, -7.4093213, -21.208893, 2.8142529, -7.433244, -21.203339, 2.7911844, -7.433244, -21.377848, 3.4272747, -7.457381, -21.35008, 2.8360398, -7.457381, -21.355633, 3.4176629, -7.433244, -21.377848, 3.4272747, -7.433244, -21.371866, 2.8260007, -7.457381, -21.35008, 2.8360398, -7.433244, -21.371866, 2.8260007, -7.457381, -21.208893, 2.8142529, -7.457381, -21.35008, 2.8360398, -7.433244, -21.371866, 2.8260007, -7.433244, -21.203339, 2.7911844, -7.457381, -21.208893, 2.8142529, -7.457381, -21.355633, 3.4176629, -7.433244, -21.328293, 2.8460789, -7.433244, -21.333633, 3.4082646, -7.457381, -21.355633, 3.4176629, -7.457381, -21.35008, 2.8360398, -7.433244, -21.328293, 2.8460789, -7.457381, -21.35008, 2.8360398, -7.433244, -21.21466, 2.837535, -7.433244, -21.328293, 2.8460789, -7.457381, -21.35008, 2.8360398, -7.457381, -21.208893, 2.8142529, -7.433244, -21.21466, 2.837535, -7.433244, -21.21466, 2.837535, -7.4093213, -21.090775, 2.850137, -7.4093213, -21.208893, 2.8142529, -7.433244, -21.21466, 2.837535, -7.433244, -21.11427, 2.8552632, -7.4093213, -21.090775, 2.850137, -7.433244, -21.11427, 2.8552632, -7.4093213, -21.088425, 3.4129639, -7.4093213, -21.090775, 2.850137, -7.433244, -21.11427, 2.8552632, -7.433244, -21.111706, 3.4071965, -7.4093213, -21.088425, 3.4129639, -7.433244, -21.111706, 3.4071965, -7.4093213, -21.219572, 3.4655085, -7.4093213, -21.088425, 3.4129639, -7.433244, -21.111706, 3.4071965, -7.433244, -21.224485, 3.4422264, -7.4093213, -21.219572, 3.4655085, -7.4093213, -21.208893, 2.8142529, -7.433244, -21.067278, 2.8450108, -7.433244, -21.203339, 2.7911844, -7.4093213, -21.208893, 2.8142529, -7.4093213, -21.090775, 2.850137, -7.433244, -21.067278, 2.8450108, -7.4093213, -21.090775, 2.850137, -7.433244, -21.064928, 3.4187307, -7.433244, -21.067278, 2.8450108, -7.4093213, -21.090775, 2.850137, -7.4093213, -21.088425, 3.4129639, -7.433244, -21.064928, 3.4187307, -7.4093213, -21.088425, 3.4129639, -7.433244, -21.214872, 3.4887905, -7.433244, -21.064928, 3.4187307, -7.4093213, -21.088425, 3.4129639, -7.4093213, -21.219572, 3.4655085, -7.433244, -21.214872, 3.4887905, -7.433244, -21.203339, 2.7911844, -7.457381, -21.090775, 2.850137, -7.457381, -21.208893, 2.8142529, -7.433244, -21.203339, 2.7911844, -7.433244, -21.067278, 2.8450108, -7.457381, -21.090775, 2.850137, -7.457381, -21.208893, 2.8142529, -7.433244, -21.11427, 2.8552632, -7.433244, -21.21466, 2.837535, -7.457381, -21.208893, 2.8142529, -7.457381, -21.090775, 2.850137, -7.433244, -21.11427, 2.8552632, -7.457381, -21.090775, 2.850137, -7.433244, -21.111706, 3.4071965, -7.433244, -21.11427, 2.8552632, -7.457381, -21.090775, 2.850137, -7.457381, -21.088425, 3.4129639, -7.433244, -21.111706, 3.4071965, -7.457381, -21.088425, 3.4129639, -7.433244, -21.224485, 3.4422264, -7.433244, -21.111706, 3.4071965, -7.457381, -21.088425, 3.4129639, -7.457381, -21.219572, 3.4655085, -7.433244, -21.224485, 3.4422264, -7.433244, -21.067278, 2.8450108, -7.457381, -21.088425, 3.4129639, -7.457381, -21.090775, 2.850137, -7.433244, -21.067278, 2.8450108, -7.433244, -21.064928, 3.4187307, -7.457381, -21.088425, 3.4129639, -7.433244, -21.064928, 3.4187307, -7.457381, -21.219572, 3.4655085, -7.457381, -21.088425, 3.4129639, -7.433244, -21.064928, 3.4187307, -7.433244, -21.214872, 3.4887905, -7.457381, -21.219572, 3.4655085, -7.433244, -21.224485, 3.4422264, -7.4093213, -21.355633, 3.4176629, -7.4093213, -21.219572, 3.4655085, -7.433244, -21.224485, 3.4422264, -7.433244, -21.333633, 3.4082646, -7.4093213, -21.355633, 3.4176629, -7.4093213, -21.219572, 3.4655085, -7.433244, -21.377848, 3.4272747, -7.433244, -21.214872, 3.4887905, -7.4093213, -21.219572, 3.4655085, -7.4093213, -21.355633, 3.4176629, -7.433244, -21.377848, 3.4272747, -7.433244, -21.214872, 3.4887905, -7.457381, -21.355633, 3.4176629, -7.457381, -21.219572, 3.4655085, -7.433244, -21.214872, 3.4887905, -7.433244, -21.377848, 3.4272747, -7.457381, -21.355633, 3.4176629, -7.457381, -21.219572, 3.4655085, -7.433244, -21.333633, 3.4082646, -7.433244, -21.224485, 3.4422264, -7.457381, -21.219572, 3.4655085, -7.457381, -21.355633, 3.4176629, -7.433244, -21.333633, 3.4082646, -3.7589583, -21.320816, 4.036238, -3.7375984, -21.335342, 3.5225387, -3.7375984, -21.340467, 4.044782, -3.7589583, -21.320816, 4.036238, -3.7589583, -21.316118, 3.5317235, -3.7375984, -21.335342, 3.5225387, -3.7589583, -21.316118, 3.5317235, -3.7375984, -21.210388, 3.5031013, -3.7375984, -21.335342, 3.5225387, -3.7589583, -21.316118, 3.5317235, -3.7589583, -21.215513, 3.5238204, -3.7375984, -21.210388, 3.5031013, -3.7375984, -21.340467, 4.044782, -3.7589583, -21.354778, 3.5137813, -3.7589583, -21.360119, 4.0533257, -3.7375984, -21.340467, 4.044782, -3.7375984, -21.335342, 3.5225387, -3.7589583, -21.354778, 3.5137813, -3.7375984, -21.335342, 3.5225387, -3.7589583, -21.205261, 3.4823828, -3.7589583, -21.354778, 3.5137813, -3.7375984, -21.335342, 3.5225387, -3.7375984, -21.210388, 3.5031013, -3.7589583, -21.205261, 3.4823828, -3.7589583, -21.360119, 4.0533257, -3.7803178, -21.335342, 3.5225387, -3.7803178, -21.340467, 4.044782, -3.7589583, -21.360119, 4.0533257, -3.7589583, -21.354778, 3.5137813, -3.7803178, -21.335342, 3.5225387, -3.7589583, -21.354778, 3.5137813, -3.7803178, -21.210388, 3.5031013, -3.7803178, -21.335342, 3.5225387, -3.7589583, -21.354778, 3.5137813, -3.7589583, -21.205261, 3.4823828, -3.7803178, -21.210388, 3.5031013, -3.7803178, -21.340467, 4.044782, -3.7589583, -21.316118, 3.5317235, -3.7589583, -21.320816, 4.036238, -3.7803178, -21.340467, 4.044782, -3.7803178, -21.335342, 3.5225387, -3.7589583, -21.316118, 3.5317235, -3.7803178, -21.335342, 3.5225387, -3.7589583, -21.215513, 3.5238204, -3.7589583, -21.316118, 3.5317235, -3.7803178, -21.335342, 3.5225387, -3.7803178, -21.210388, 3.5031013, -3.7589583, -21.215513, 3.5238204, -3.7589583, -21.215513, 3.5238204, -3.7375984, -21.105513, 3.5353546, -3.7375984, -21.210388, 3.5031013, -3.7589583, -21.215513, 3.5238204, -3.7589583, -21.126444, 3.5398402, -3.7375984, -21.105513, 3.5353546, -3.7589583, -21.126444, 3.5398402, -3.7375984, -21.10359, 4.04051, -3.7375984, -21.105513, 3.5353546, -3.7589583, -21.126444, 3.5398402, -3.7589583, -21.124308, 4.0355973, -3.7375984, -21.10359, 4.04051, -3.7589583, -21.124308, 4.0355973, -3.7375984, -21.219786, 4.087715, -3.7375984, -21.10359, 4.04051, -3.7589583, -21.124308, 4.0355973, -3.7589583, -21.224058, 4.0667825, -3.7375984, -21.219786, 4.087715, -3.7375984, -21.210388, 3.5031013, -3.7589583, -21.084793, 3.5306554, -3.7589583, -21.205261, 3.4823828, -3.7375984, -21.210388, 3.5031013, -3.7375984, -21.105513, 3.5353546, -3.7589583, -21.084793, 3.5306554, -3.7375984, -21.105513, 3.5353546, -3.7589583, -21.082657, 4.045636, -3.7589583, -21.084793, 3.5306554, -3.7375984, -21.105513, 3.5353546, -3.7375984, -21.10359, 4.04051, -3.7589583, -21.082657, 4.045636, -3.7375984, -21.10359, 4.04051, -3.7589583, -21.215513, 4.1086473, -3.7589583, -21.082657, 4.045636, -3.7375984, -21.10359, 4.04051, -3.7375984, -21.219786, 4.087715, -3.7589583, -21.215513, 4.1086473, -3.7589583, -21.205261, 3.4823828, -3.7803178, -21.105513, 3.5353546, -3.7803178, -21.210388, 3.5031013, -3.7589583, -21.205261, 3.4823828, -3.7589583, -21.084793, 3.5306554, -3.7803178, -21.105513, 3.5353546, -3.7803178, -21.210388, 3.5031013, -3.7589583, -21.126444, 3.5398402, -3.7589583, -21.215513, 3.5238204, -3.7803178, -21.210388, 3.5031013, -3.7803178, -21.105513, 3.5353546, -3.7589583, -21.126444, 3.5398402, -3.7803178, -21.105513, 3.5353546, -3.7589583, -21.124308, 4.0355973, -3.7589583, -21.126444, 3.5398402, -3.7803178, -21.105513, 3.5353546, -3.7803178, -21.10359, 4.04051, -3.7589583, -21.124308, 4.0355973, -3.7803178, -21.10359, 4.04051, -3.7589583, -21.224058, 4.0667825, -3.7589583, -21.124308, 4.0355973, -3.7803178, -21.10359, 4.04051, -3.7803178, -21.219786, 4.087715, -3.7589583, -21.224058, 4.0667825, -3.7589583, -21.084793, 3.5306554, -3.7803178, -21.10359, 4.04051, -3.7803178, -21.105513, 3.5353546, -3.7589583, -21.084793, 3.5306554, -3.7589583, -21.082657, 4.045636, -3.7803178, -21.10359, 4.04051, -3.7589583, -21.082657, 4.045636, -3.7803178, -21.219786, 4.087715, -3.7803178, -21.10359, 4.04051, -3.7589583, -21.082657, 4.045636, -3.7589583, -21.215513, 4.1086473, -3.7803178, -21.219786, 4.087715, -3.7589583, -21.224058, 4.0667825, -3.7375984, -21.340467, 4.044782, -3.7375984, -21.219786, 4.087715, -3.7589583, -21.224058, 4.0667825, -3.7589583, -21.320816, 4.036238, -3.7375984, -21.340467, 4.044782, -3.7375984, -21.219786, 4.087715, -3.7589583, -21.360119, 4.0533257, -3.7589583, -21.215513, 4.1086473, -3.7375984, -21.219786, 4.087715, -3.7375984, -21.340467, 4.044782, -3.7589583, -21.360119, 4.0533257, -3.7589583, -21.215513, 4.1086473, -3.7803178, -21.340467, 4.044782, -3.7803178, -21.219786, 4.087715, -3.7589583, -21.215513, 4.1086473, -3.7589583, -21.360119, 4.0533257, -3.7803178, -21.340467, 4.044782, -3.7803178, -21.219786, 4.087715, -3.7589583, -21.320816, 4.036238, -3.7589583, -21.224058, 4.0667825, -3.7803178, -21.219786, 4.087715, -3.7803178, -21.340467, 4.044782, -3.7589583, -21.320816, 4.036238, -7.491342, -21.333633, 1.4549251, -7.4672065, -21.35008, 1.0367032, -7.4672065, -21.355635, 1.4619738, -7.491342, -21.333633, 1.4549251, -7.491342, -21.328293, 1.0439655, -7.4672065, -21.35008, 1.0367032, -7.4672065, -21.355635, 1.4619738, -7.491342, -21.371868, 1.0292273, -7.491342, -21.377848, 1.4688089, -7.4672065, -21.355635, 1.4619738, -7.4672065, -21.35008, 1.0367032, -7.491342, -21.371868, 1.0292273, -7.491342, -21.377848, 1.4688089, -7.5154786, -21.35008, 1.0367032, -7.5154786, -21.355635, 1.4619738, -7.491342, -21.377848, 1.4688089, -7.491342, -21.371868, 1.0292273, -7.5154786, -21.35008, 1.0367032, -7.5154786, -21.355635, 1.4619738, -7.491342, -21.328293, 1.0439655, -7.491342, -21.333633, 1.4549251, -7.5154786, -21.355635, 1.4619738, -7.5154786, -21.35008, 1.0367032, -7.491342, -21.328293, 1.0439655, -7.491342, -21.328293, 1.0439655, -7.4672065, -21.208893, 1.0206835, -7.4672065, -21.35008, 1.0367032, -7.491342, -21.328293, 1.0439655, -7.491342, -21.21466, 1.0375576, -7.4672065, -21.208893, 1.0206835, -7.4672065, -21.35008, 1.0367032, -7.491342, -21.20334, 1.0038093, -7.491342, -21.371868, 1.0292273, -7.4672065, -21.35008, 1.0367032, -7.4672065, -21.208893, 1.0206835, -7.491342, -21.20334, 1.0038093, -7.491342, -21.371868, 1.0292273, -7.5154786, -21.208893, 1.0206835, -7.5154786, -21.35008, 1.0367032, -7.491342, -21.371868, 1.0292273, -7.491342, -21.20334, 1.0038093, -7.5154786, -21.208893, 1.0206835, -7.5154786, -21.35008, 1.0367032, -7.491342, -21.21466, 1.0375576, -7.491342, -21.328293, 1.0439655, -7.5154786, -21.35008, 1.0367032, -7.5154786, -21.208893, 1.0206835, -7.491342, -21.21466, 1.0375576, -7.491342, -21.21466, 1.0375576, -7.4672065, -21.090775, 1.0469557, -7.4672065, -21.208893, 1.0206835, -7.491342, -21.21466, 1.0375576, -7.491342, -21.11427, 1.0505869, -7.4672065, -21.090775, 1.0469557, -7.4672065, -21.208893, 1.0206835, -7.491342, -21.067278, 1.0431108, -7.491342, -21.20334, 1.0038093, -7.4672065, -21.208893, 1.0206835, -7.4672065, -21.090775, 1.0469557, -7.491342, -21.067278, 1.0431108, -7.491342, -21.20334, 1.0038093, -7.5154786, -21.090775, 1.0469557, -7.5154786, -21.208893, 1.0206835, -7.491342, -21.20334, 1.0038093, -7.491342, -21.067278, 1.0431108, -7.5154786, -21.090775, 1.0469557, -7.5154786, -21.208893, 1.0206835, -7.491342, -21.11427, 1.0505869, -7.491342, -21.21466, 1.0375576, -7.5154786, -21.208893, 1.0206835, -7.5154786, -21.090775, 1.0469557, -7.491342, -21.11427, 1.0505869, -7.491342, -21.11427, 1.0505869, -7.4672065, -21.088425, 1.4585562, -7.4672065, -21.090775, 1.0469557, -7.491342, -21.11427, 1.0505869, -7.491342, -21.111706, 1.4542842, -7.4672065, -21.088425, 1.4585562, -7.4672065, -21.090775, 1.0469557, -7.491342, -21.06493, 1.4626144, -7.491342, -21.067278, 1.0431108, -7.4672065, -21.090775, 1.0469557, -7.4672065, -21.088425, 1.4585562, -7.491342, -21.06493, 1.4626144, -7.491342, -21.067278, 1.0431108, -7.5154786, -21.088425, 1.4585562, -7.5154786, -21.090775, 1.0469557, -7.491342, -21.067278, 1.0431108, -7.491342, -21.06493, 1.4626144, -7.5154786, -21.088425, 1.4585562, -7.5154786, -21.090775, 1.0469557, -7.491342, -21.111706, 1.4542842, -7.491342, -21.11427, 1.0505869, -7.5154786, -21.090775, 1.0469557, -7.5154786, -21.088425, 1.4585562, -7.491342, -21.111706, 1.4542842, -7.491342, -21.111706, 1.4542842, -7.4672065, -21.219572, 1.4970036, -7.4672065, -21.088425, 1.4585562, -7.491342, -21.111706, 1.4542842, -7.491342, -21.224485, 1.4799159, -7.4672065, -21.219572, 1.4970036, -7.4672065, -21.088425, 1.4585562, -7.491342, -21.214874, 1.5138776, -7.491342, -21.06493, 1.4626144, -7.4672065, -21.088425, 1.4585562, -7.4672065, -21.219572, 1.4970036, -7.491342, -21.214874, 1.5138776, -7.491342, -21.06493, 1.4626144, -7.5154786, -21.219572, 1.4970036, -7.5154786, -21.088425, 1.4585562, -7.491342, -21.06493, 1.4626144, -7.491342, -21.214874, 1.5138776, -7.5154786, -21.219572, 1.4970036, -7.5154786, -21.088425, 1.4585562, -7.491342, -21.224485, 1.4799159, -7.491342, -21.111706, 1.4542842, -7.5154786, -21.088425, 1.4585562, -7.5154786, -21.219572, 1.4970036, -7.491342, -21.224485, 1.4799159, -7.491342, -21.224485, 1.4799159, -7.4672065, -21.355635, 1.4619738, -7.4672065, -21.219572, 1.4970036, -7.491342, -21.224485, 1.4799159, -7.491342, -21.333633, 1.4549251, -7.4672065, -21.355635, 1.4619738, -7.4672065, -21.219572, 1.4970036, -7.491342, -21.377848, 1.4688089, -7.491342, -21.214874, 1.5138776, -7.4672065, -21.219572, 1.4970036, -7.4672065, -21.355635, 1.4619738, -7.491342, -21.377848, 1.4688089, -7.491342, -21.214874, 1.5138776, -7.5154786, -21.355635, 1.4619738, -7.5154786, -21.219572, 1.4970036, -7.491342, -21.214874, 1.5138776, -7.491342, -21.377848, 1.4688089, -7.5154786, -21.355635, 1.4619738, -7.5154786, -21.219572, 1.4970036, -7.491342, -21.333633, 1.4549251, -7.491342, -21.224485, 1.4799159, -7.5154786, -21.219572, 1.4970036, -7.5154786, -21.355635, 1.4619738, -7.491342, -21.333633, 1.4549251, -7.4881387, -21.333633, 2.66858, -7.464002, -21.35008, 2.2503583, -7.464002, -21.355633, 2.6756287, -7.4881387, -21.333633, 2.66858, -7.4881387, -21.328293, 2.2576206, -7.464002, -21.35008, 2.2503583, -7.464002, -21.355633, 2.6756287, -7.4881387, -21.371866, 2.2428825, -7.4881387, -21.377848, 2.682464, -7.464002, -21.355633, 2.6756287, -7.464002, -21.35008, 2.2503583, -7.4881387, -21.371866, 2.2428825, -7.4881387, -21.377848, 2.682464, -7.512275, -21.35008, 2.2503583, -7.512275, -21.355633, 2.6756287, -7.4881387, -21.377848, 2.682464, -7.4881387, -21.371866, 2.2428825, -7.512275, -21.35008, 2.2503583, -7.512275, -21.355633, 2.6756287, -7.4881387, -21.328293, 2.2576206, -7.4881387, -21.333633, 2.66858, -7.512275, -21.355633, 2.6756287, -7.512275, -21.35008, 2.2503583, -7.4881387, -21.328293, 2.2576206, -7.4881387, -21.328293, 2.2576206, -7.464002, -21.208893, 2.2343385, -7.464002, -21.35008, 2.2503583, -7.4881387, -21.328293, 2.2576206, -7.4881387, -21.21466, 2.2512126, -7.464002, -21.208893, 2.2343385, -7.464002, -21.35008, 2.2503583, -7.4881387, -21.203339, 2.2174644, -7.4881387, -21.371866, 2.2428825, -7.464002, -21.35008, 2.2503583, -7.464002, -21.208893, 2.2343385, -7.4881387, -21.203339, 2.2174644, -7.4881387, -21.371866, 2.2428825, -7.512275, -21.208893, 2.2343385, -7.512275, -21.35008, 2.2503583, -7.4881387, -21.371866, 2.2428825, -7.4881387, -21.203339, 2.2174644, -7.512275, -21.208893, 2.2343385, -7.512275, -21.35008, 2.2503583, -7.4881387, -21.21466, 2.2512126, -7.4881387, -21.328293, 2.2576206, -7.512275, -21.35008, 2.2503583, -7.512275, -21.208893, 2.2343385, -7.4881387, -21.21466, 2.2512126, -7.4881387, -21.21466, 2.2512126, -7.464002, -21.090775, 2.2606108, -7.464002, -21.208893, 2.2343385, -7.4881387, -21.21466, 2.2512126, -7.4881387, -21.11427, 2.264242, -7.464002, -21.090775, 2.2606108, -7.464002, -21.208893, 2.2343385, -7.4881387, -21.067278, 2.256766, -7.4881387, -21.203339, 2.2174644, -7.464002, -21.208893, 2.2343385, -7.464002, -21.090775, 2.2606108, -7.4881387, -21.067278, 2.256766, -7.4881387, -21.203339, 2.2174644, -7.512275, -21.090775, 2.2606108, -7.512275, -21.208893, 2.2343385, -7.4881387, -21.203339, 2.2174644, -7.4881387, -21.067278, 2.256766, -7.512275, -21.090775, 2.2606108, -7.512275, -21.208893, 2.2343385, -7.4881387, -21.11427, 2.264242, -7.4881387, -21.21466, 2.2512126, -7.512275, -21.208893, 2.2343385, -7.512275, -21.090775, 2.2606108, -7.4881387, -21.11427, 2.264242, -7.4881387, -21.11427, 2.264242, -7.464002, -21.088425, 2.6722112, -7.464002, -21.090775, 2.2606108, -7.4881387, -21.11427, 2.264242, -7.4881387, -21.111706, 2.6679392, -7.464002, -21.088425, 2.6722112, -7.464002, -21.090775, 2.2606108, -7.4881387, -21.064928, 2.6762695, -7.4881387, -21.067278, 2.256766, -7.464002, -21.090775, 2.2606108, -7.464002, -21.088425, 2.6722112, -7.4881387, -21.064928, 2.6762695, -7.4881387, -21.067278, 2.256766, -7.512275, -21.088425, 2.6722112, -7.512275, -21.090775, 2.2606108, -7.4881387, -21.067278, 2.256766, -7.4881387, -21.064928, 2.6762695, -7.512275, -21.088425, 2.6722112, -7.512275, -21.090775, 2.2606108, -7.4881387, -21.111706, 2.6679392, -7.4881387, -21.11427, 2.264242, -7.512275, -21.090775, 2.2606108, -7.512275, -21.088425, 2.6722112, -7.4881387, -21.111706, 2.6679392, -7.4881387, -21.111706, 2.6679392, -7.464002, -21.219572, 2.7106586, -7.464002, -21.088425, 2.6722112, -7.4881387, -21.111706, 2.6679392, -7.4881387, -21.224485, 2.6935709, -7.464002, -21.219572, 2.7106586, -7.464002, -21.088425, 2.6722112, -7.4881387, -21.214874, 2.7275326, -7.4881387, -21.064928, 2.6762695, -7.464002, -21.088425, 2.6722112, -7.464002, -21.219572, 2.7106586, -7.4881387, -21.214874, 2.7275326, -7.4881387, -21.064928, 2.6762695, -7.512275, -21.219572, 2.7106586, -7.512275, -21.088425, 2.6722112, -7.4881387, -21.064928, 2.6762695, -7.4881387, -21.214874, 2.7275326, -7.512275, -21.219572, 2.7106586, -7.512275, -21.088425, 2.6722112, -7.4881387, -21.224485, 2.6935709, -7.4881387, -21.111706, 2.6679392, -7.512275, -21.088425, 2.6722112, -7.512275, -21.219572, 2.7106586, -7.4881387, -21.224485, 2.6935709, -7.4881387, -21.224485, 2.6935709, -7.464002, -21.355633, 2.6756287, -7.464002, -21.219572, 2.7106586, -7.4881387, -21.224485, 2.6935709, -7.4881387, -21.333633, 2.66858, -7.464002, -21.355633, 2.6756287, -7.464002, -21.219572, 2.7106586, -7.4881387, -21.377848, 2.682464, -7.4881387, -21.214874, 2.7275326, -7.464002, -21.219572, 2.7106586, -7.464002, -21.355633, 2.6756287, -7.4881387, -21.377848, 2.682464, -7.4881387, -21.214874, 2.7275326, -7.512275, -21.355633, 2.6756287, -7.512275, -21.219572, 2.7106586, -7.4881387, -21.214874, 2.7275326, -7.4881387, -21.377848, 2.682464, -7.512275, -21.355633, 2.6756287, -7.512275, -21.219572, 2.7106586, -7.4881387, -21.333633, 2.66858, -7.4881387, -21.224485, 2.6935709, -7.512275, -21.219572, 2.7106586, -7.512275, -21.355633, 2.6756287, -7.4881387, -21.333633, 2.66858, -3.7905703, -21.320818, 1.4850421, -3.7692103, -21.335342, 0.9713427, -3.7692103, -21.34047, 1.4933724, -3.7905703, -21.320818, 1.4850421, -3.7905703, -21.316118, 0.98031366, -3.7692103, -21.335342, 0.9713427, -3.7905703, -21.316118, 0.98031366, -3.7692103, -21.210388, 0.95169187, -3.7692103, -21.335342, 0.9713427, -3.7905703, -21.316118, 0.98031366, -3.7905703, -21.215515, 0.9724107, -3.7692103, -21.210388, 0.95169187, -3.7692103, -21.34047, 1.4933724, -3.7905703, -21.35478, 0.9623716, -3.7905703, -21.360119, 1.5019164, -3.7692103, -21.34047, 1.4933724, -3.7692103, -21.335342, 0.9713427, -3.7905703, -21.35478, 0.9623716, -3.7692103, -21.335342, 0.9713427, -3.7905703, -21.205261, 0.93097293, -3.7905703, -21.35478, 0.9623716, -3.7692103, -21.335342, 0.9713427, -3.7692103, -21.210388, 0.95169187, -3.7905703, -21.205261, 0.93097293, -3.7905703, -21.360119, 1.5019164, -3.8119302, -21.335342, 0.9713427, -3.8119302, -21.34047, 1.4933724, -3.7905703, -21.360119, 1.5019164, -3.7905703, -21.35478, 0.9623716, -3.8119302, -21.335342, 0.9713427, -3.7905703, -21.35478, 0.9623716, -3.8119302, -21.210388, 0.95169187, -3.8119302, -21.335342, 0.9713427, -3.7905703, -21.35478, 0.9623716, -3.7905703, -21.205261, 0.93097293, -3.8119302, -21.210388, 0.95169187, -3.8119302, -21.34047, 1.4933724, -3.7905703, -21.316118, 0.98031366, -3.7905703, -21.320818, 1.4850421, -3.8119302, -21.34047, 1.4933724, -3.8119302, -21.335342, 0.9713427, -3.7905703, -21.316118, 0.98031366, -3.8119302, -21.335342, 0.9713427, -3.7905703, -21.215515, 0.9724107, -3.7905703, -21.316118, 0.98031366, -3.8119302, -21.335342, 0.9713427, -3.8119302, -21.210388, 0.95169187, -3.7905703, -21.215515, 0.9724107, -3.7905703, -21.215515, 0.9724107, -3.7692103, -21.105513, 0.9839448, -3.7692103, -21.210388, 0.95169187, -3.7905703, -21.215515, 0.9724107, -3.7905703, -21.126446, 0.9884304, -3.7692103, -21.105513, 0.9839448, -3.7905703, -21.126446, 0.9884304, -3.7692103, -21.10359, 1.489314, -3.7692103, -21.105513, 0.9839448, -3.7905703, -21.126446, 0.9884304, -3.7905703, -21.12431, 1.4841876, -3.7692103, -21.10359, 1.489314, -3.7905703, -21.12431, 1.4841876, -3.7692103, -21.219786, 1.5363052, -3.7692103, -21.10359, 1.489314, -3.7905703, -21.12431, 1.4841876, -3.7905703, -21.224058, 1.5153728, -3.7692103, -21.219786, 1.5363052, -3.7692103, -21.210388, 0.95169187, -3.7905703, -21.084793, 0.9792458, -3.7905703, -21.205261, 0.93097293, -3.7692103, -21.210388, 0.95169187, -3.7692103, -21.105513, 0.9839448, -3.7905703, -21.084793, 0.9792458, -3.7692103, -21.105513, 0.9839448, -3.7905703, -21.082657, 1.4942267, -3.7905703, -21.084793, 0.9792458, -3.7692103, -21.105513, 0.9839448, -3.7692103, -21.10359, 1.489314, -3.7905703, -21.082657, 1.4942267, -3.7692103, -21.10359, 1.489314, -3.7905703, -21.215515, 1.5574512, -3.7905703, -21.082657, 1.4942267, -3.7692103, -21.10359, 1.489314, -3.7692103, -21.219786, 1.5363052, -3.7905703, -21.215515, 1.5574512, -3.7905703, -21.205261, 0.93097293, -3.8119302, -21.105513, 0.9839448, -3.8119302, -21.210388, 0.95169187, -3.7905703, -21.205261, 0.93097293, -3.7905703, -21.084793, 0.9792458, -3.8119302, -21.105513, 0.9839448, -3.8119302, -21.210388, 0.95169187, -3.7905703, -21.126446, 0.9884304, -3.7905703, -21.215515, 0.9724107, -3.8119302, -21.210388, 0.95169187, -3.8119302, -21.105513, 0.9839448, -3.7905703, -21.126446, 0.9884304, -3.8119302, -21.105513, 0.9839448, -3.7905703, -21.12431, 1.4841876, -3.7905703, -21.126446, 0.9884304, -3.8119302, -21.105513, 0.9839448, -3.8119302, -21.10359, 1.489314, -3.7905703, -21.12431, 1.4841876, -3.8119302, -21.10359, 1.489314, -3.7905703, -21.224058, 1.5153728, -3.7905703, -21.12431, 1.4841876, -3.8119302, -21.10359, 1.489314, -3.8119302, -21.219786, 1.5363052, -3.7905703, -21.224058, 1.5153728, -3.7905703, -21.084793, 0.9792458, -3.8119302, -21.10359, 1.489314, -3.8119302, -21.105513, 0.9839448, -3.7905703, -21.084793, 0.9792458, -3.7905703, -21.082657, 1.4942267, -3.8119302, -21.10359, 1.489314, -3.7905703, -21.082657, 1.4942267, -3.8119302, -21.219786, 1.5363052, -3.8119302, -21.10359, 1.489314, -3.7905703, -21.082657, 1.4942267, -3.7905703, -21.215515, 1.5574512, -3.8119302, -21.219786, 1.5363052, -3.7905703, -21.224058, 1.5153728, -3.7692103, -21.34047, 1.4933724, -3.7692103, -21.219786, 1.5363052, -3.7905703, -21.224058, 1.5153728, -3.7905703, -21.320818, 1.4850421, -3.7692103, -21.34047, 1.4933724, -3.7692103, -21.219786, 1.5363052, -3.7905703, -21.360119, 1.5019164, -3.7905703, -21.215515, 1.5574512, -3.7692103, -21.219786, 1.5363052, -3.7692103, -21.34047, 1.4933724, -3.7905703, -21.360119, 1.5019164, -3.7905703, -21.215515, 1.5574512, -3.8119302, -21.34047, 1.4933724, -3.8119302, -21.219786, 1.5363052, -3.7905703, -21.215515, 1.5574512, -3.7905703, -21.360119, 1.5019164, -3.8119302, -21.34047, 1.4933724, -3.8119302, -21.219786, 1.5363052, -3.7905703, -21.320818, 1.4850421, -3.7905703, -21.224058, 1.5153728, -3.8119302, -21.219786, 1.5363052, -3.8119302, -21.34047, 1.4933724, -3.7905703, -21.320818, 1.4850421, -3.8458915, -21.320818, 2.7324455, -3.824532, -21.335342, 2.218746, -3.824532, -21.340467, 2.7409892, -3.8458915, -21.320818, 2.7324455, -3.8458915, -21.316118, 2.227717, -3.824532, -21.335342, 2.218746, -3.8458915, -21.316118, 2.227717, -3.824532, -21.210388, 2.199095, -3.824532, -21.335342, 2.218746, -3.8458915, -21.316118, 2.227717, -3.8458915, -21.215515, 2.2200274, -3.824532, -21.210388, 2.199095, -3.824532, -21.340467, 2.7409892, -3.8458915, -21.354778, 2.209775, -3.8458915, -21.360119, 2.7495332, -3.824532, -21.340467, 2.7409892, -3.824532, -21.335342, 2.218746, -3.8458915, -21.354778, 2.209775, -3.824532, -21.335342, 2.218746, -3.8458915, -21.205261, 2.1783762, -3.8458915, -21.354778, 2.209775, -3.824532, -21.335342, 2.218746, -3.824532, -21.210388, 2.199095, -3.8458915, -21.205261, 2.1783762, -3.8458915, -21.360119, 2.7495332, -3.8672514, -21.335342, 2.218746, -3.8672514, -21.340467, 2.7409892, -3.8458915, -21.360119, 2.7495332, -3.8458915, -21.354778, 2.209775, -3.8672514, -21.335342, 2.218746, -3.8458915, -21.354778, 2.209775, -3.8672514, -21.210388, 2.199095, -3.8672514, -21.335342, 2.218746, -3.8458915, -21.354778, 2.209775, -3.8458915, -21.205261, 2.1783762, -3.8672514, -21.210388, 2.199095, -3.8672514, -21.340467, 2.7409892, -3.8458915, -21.316118, 2.227717, -3.8458915, -21.320818, 2.7324455, -3.8672514, -21.340467, 2.7409892, -3.8672514, -21.335342, 2.218746, -3.8458915, -21.316118, 2.227717, -3.8672514, -21.335342, 2.218746, -3.8458915, -21.215515, 2.2200274, -3.8458915, -21.316118, 2.227717, -3.8672514, -21.335342, 2.218746, -3.8672514, -21.210388, 2.199095, -3.8458915, -21.215515, 2.2200274, -3.8458915, -21.215515, 2.2200274, -3.824532, -21.105513, 2.231348, -3.824532, -21.210388, 2.199095, -3.8458915, -21.215515, 2.2200274, -3.8458915, -21.126444, 2.2360473, -3.824532, -21.105513, 2.231348, -3.8458915, -21.126444, 2.2360473, -3.824532, -21.10359, 2.7367172, -3.824532, -21.105513, 2.231348, -3.8458915, -21.126444, 2.2360473, -3.8458915, -21.124308, 2.731591, -3.824532, -21.10359, 2.7367172, -3.8458915, -21.124308, 2.731591, -3.824532, -21.219786, 2.7839222, -3.824532, -21.10359, 2.7367172, -3.8458915, -21.124308, 2.731591, -3.8458915, -21.224058, 2.7629898, -3.824532, -21.219786, 2.7839222, -3.824532, -21.210388, 2.199095, -3.8458915, -21.084793, 2.2268624, -3.8458915, -21.205261, 2.1783762, -3.824532, -21.210388, 2.199095, -3.824532, -21.105513, 2.231348, -3.8458915, -21.084793, 2.2268624, -3.824532, -21.105513, 2.231348, -3.8458915, -21.082657, 2.7418437, -3.8458915, -21.084793, 2.2268624, -3.824532, -21.105513, 2.231348, -3.824532, -21.10359, 2.7367172, -3.8458915, -21.082657, 2.7418437, -3.824532, -21.10359, 2.7367172, -3.8458915, -21.215513, 2.8048546, -3.8458915, -21.082657, 2.7418437, -3.824532, -21.10359, 2.7367172, -3.824532, -21.219786, 2.7839222, -3.8458915, -21.215513, 2.8048546, -3.8458915, -21.205261, 2.1783762, -3.8672514, -21.105513, 2.231348, -3.8672514, -21.210388, 2.199095, -3.8458915, -21.205261, 2.1783762, -3.8458915, -21.084793, 2.2268624, -3.8672514, -21.105513, 2.231348, -3.8672514, -21.210388, 2.199095, -3.8458915, -21.126444, 2.2360473, -3.8458915, -21.215515, 2.2200274, -3.8672514, -21.210388, 2.199095, -3.8672514, -21.105513, 2.231348, -3.8458915, -21.126444, 2.2360473, -3.8672514, -21.105513, 2.231348, -3.8458915, -21.124308, 2.731591, -3.8458915, -21.126444, 2.2360473, -3.8672514, -21.105513, 2.231348, -3.8672514, -21.10359, 2.7367172, -3.8458915, -21.124308, 2.731591, -3.8672514, -21.10359, 2.7367172, -3.8458915, -21.224058, 2.7629898, -3.8458915, -21.124308, 2.731591, -3.8672514, -21.10359, 2.7367172, -3.8672514, -21.219786, 2.7839222, -3.8458915, -21.224058, 2.7629898, -3.8458915, -21.084793, 2.2268624, -3.8672514, -21.10359, 2.7367172, -3.8672514, -21.105513, 2.231348, -3.8458915, -21.084793, 2.2268624, -3.8458915, -21.082657, 2.7418437, -3.8672514, -21.10359, 2.7367172, -3.8458915, -21.082657, 2.7418437, -3.8672514, -21.219786, 2.7839222, -3.8672514, -21.10359, 2.7367172, -3.8458915, -21.082657, 2.7418437, -3.8458915, -21.215513, 2.8048546, -3.8672514, -21.219786, 2.7839222, -3.8458915, -21.224058, 2.7629898, -3.824532, -21.340467, 2.7409892, -3.824532, -21.219786, 2.7839222, -3.8458915, -21.224058, 2.7629898, -3.8458915, -21.320818, 2.7324455, -3.824532, -21.340467, 2.7409892, -3.824532, -21.219786, 2.7839222, -3.8458915, -21.360119, 2.7495332, -3.8458915, -21.215513, 2.8048546, -3.824532, -21.219786, 2.7839222, -3.824532, -21.340467, 2.7409892, -3.8458915, -21.360119, 2.7495332, -3.8458915, -21.215513, 2.8048546, -3.8672514, -21.340467, 2.7409892, -3.8672514, -21.219786, 2.7839222, -3.8458915, -21.215513, 2.8048546, -3.8458915, -21.360119, 2.7495332, -3.8672514, -21.340467, 2.7409892, -3.8672514, -21.219786, 2.7839222, -3.8458915, -21.320818, 2.7324455, -3.8458915, -21.224058, 2.7629898, -3.8672514, -21.219786, 2.7839222, -3.8672514, -21.340467, 2.7409892, -3.8458915, -21.320818, 2.7324455, -3.774764, -21.320818, 2.140356, -3.7534046, -21.335342, 1.6268702, -3.7534046, -21.340467, 2.1489, -3.774764, -21.320818, 2.140356, -3.774764, -21.316118, 1.6358411, -3.7534046, -21.335342, 1.6268702, -3.774764, -21.316118, 1.6358411, -3.7534046, -21.210388, 1.6072192, -3.7534046, -21.335342, 1.6268702, -3.774764, -21.316118, 1.6358411, -3.774764, -21.215515, 1.6279382, -3.7534046, -21.210388, 1.6072192, -3.7534046, -21.340467, 2.1489, -3.774764, -21.35478, 1.6176856, -3.774764, -21.360119, 2.1574438, -3.7534046, -21.340467, 2.1489, -3.7534046, -21.335342, 1.6268702, -3.774764, -21.35478, 1.6176856, -3.7534046, -21.335342, 1.6268702, -3.774764, -21.205261, 1.5865004, -3.774764, -21.35478, 1.6176856, -3.7534046, -21.335342, 1.6268702, -3.7534046, -21.210388, 1.6072192, -3.774764, -21.205261, 1.5865004, -3.774764, -21.360119, 2.1574438, -3.796124, -21.335342, 1.6268702, -3.796124, -21.340467, 2.1489, -3.774764, -21.360119, 2.1574438, -3.774764, -21.35478, 1.6176856, -3.796124, -21.335342, 1.6268702, -3.774764, -21.35478, 1.6176856, -3.796124, -21.210388, 1.6072192, -3.796124, -21.335342, 1.6268702, -3.774764, -21.35478, 1.6176856, -3.774764, -21.205261, 1.5865004, -3.796124, -21.210388, 1.6072192, -3.796124, -21.340467, 2.1489, -3.774764, -21.316118, 1.6358411, -3.774764, -21.320818, 2.140356, -3.796124, -21.340467, 2.1489, -3.796124, -21.335342, 1.6268702, -3.774764, -21.316118, 1.6358411, -3.796124, -21.335342, 1.6268702, -3.774764, -21.215515, 1.6279382, -3.774764, -21.316118, 1.6358411, -3.796124, -21.335342, 1.6268702, -3.796124, -21.210388, 1.6072192, -3.774764, -21.215515, 1.6279382, -3.774764, -21.215515, 1.6279382, -3.7534046, -21.105513, 1.6392586, -3.7534046, -21.210388, 1.6072192, -3.774764, -21.215515, 1.6279382, -3.774764, -21.126446, 1.6439579, -3.7534046, -21.105513, 1.6392586, -3.774764, -21.126446, 1.6439579, -3.7534046, -21.10359, 2.144628, -3.7534046, -21.105513, 1.6392586, -3.774764, -21.126446, 1.6439579, -3.774764, -21.12431, 2.1395016, -3.7534046, -21.10359, 2.144628, -3.774764, -21.12431, 2.1395016, -3.7534046, -21.219786, 2.1918328, -3.7534046, -21.10359, 2.144628, -3.774764, -21.12431, 2.1395016, -3.774764, -21.224058, 2.1709003, -3.7534046, -21.219786, 2.1918328, -3.7534046, -21.210388, 1.6072192, -3.774764, -21.084793, 1.6347731, -3.774764, -21.205261, 1.5865004, -3.7534046, -21.210388, 1.6072192, -3.7534046, -21.105513, 1.6392586, -3.774764, -21.084793, 1.6347731, -3.7534046, -21.105513, 1.6392586, -3.774764, -21.082657, 2.1497543, -3.774764, -21.084793, 1.6347731, -3.7534046, -21.105513, 1.6392586, -3.7534046, -21.10359, 2.144628, -3.774764, -21.082657, 2.1497543, -3.7534046, -21.10359, 2.144628, -3.774764, -21.215515, 2.2127652, -3.774764, -21.082657, 2.1497543, -3.7534046, -21.10359, 2.144628, -3.7534046, -21.219786, 2.1918328, -3.774764, -21.215515, 2.2127652, -3.774764, -21.205261, 1.5865004, -3.796124, -21.105513, 1.6392586, -3.796124, -21.210388, 1.6072192, -3.774764, -21.205261, 1.5865004, -3.774764, -21.084793, 1.6347731, -3.796124, -21.105513, 1.6392586, -3.796124, -21.210388, 1.6072192, -3.774764, -21.126446, 1.6439579, -3.774764, -21.215515, 1.6279382, -3.796124, -21.210388, 1.6072192, -3.796124, -21.105513, 1.6392586, -3.774764, -21.126446, 1.6439579, -3.796124, -21.105513, 1.6392586, -3.774764, -21.12431, 2.1395016, -3.774764, -21.126446, 1.6439579, -3.796124, -21.105513, 1.6392586, -3.796124, -21.10359, 2.144628, -3.774764, -21.12431, 2.1395016, -3.796124, -21.10359, 2.144628, -3.774764, -21.224058, 2.1709003, -3.774764, -21.12431, 2.1395016, -3.796124, -21.10359, 2.144628, -3.796124, -21.219786, 2.1918328, -3.774764, -21.224058, 2.1709003, -3.774764, -21.084793, 1.6347731, -3.796124, -21.10359, 2.144628, -3.796124, -21.105513, 1.6392586, -3.774764, -21.084793, 1.6347731, -3.774764, -21.082657, 2.1497543, -3.796124, -21.10359, 2.144628, -3.774764, -21.082657, 2.1497543, -3.796124, -21.219786, 2.1918328, -3.796124, -21.10359, 2.144628, -3.774764, -21.082657, 2.1497543, -3.774764, -21.215515, 2.2127652, -3.796124, -21.219786, 2.1918328, -3.774764, -21.224058, 2.1709003, -3.7534046, -21.340467, 2.1489, -3.7534046, -21.219786, 2.1918328, -3.774764, -21.224058, 2.1709003, -3.774764, -21.320818, 2.140356, -3.7534046, -21.340467, 2.1489, -3.7534046, -21.219786, 2.1918328, -3.774764, -21.360119, 2.1574438, -3.774764, -21.215515, 2.2127652, -3.7534046, -21.219786, 2.1918328, -3.7534046, -21.340467, 2.1489, -3.774764, -21.360119, 2.1574438, -3.774764, -21.215515, 2.2127652, -3.796124, -21.340467, 2.1489, -3.796124, -21.219786, 2.1918328, -3.774764, -21.215515, 2.2127652, -3.774764, -21.360119, 2.1574438, -3.796124, -21.340467, 2.1489, -3.796124, -21.219786, 2.1918328, -3.774764, -21.320818, 2.140356, -3.774764, -21.224058, 2.1709003, -3.796124, -21.219786, 2.1918328, -3.796124, -21.340467, 2.1489, -3.774764, -21.320818, 2.140356, -7.4558854, -21.333633, -0.46060777, -7.431749, -21.35008, -0.89848065, -7.431749, -21.355635, -0.45334554, -7.4558854, -21.333633, -0.46060777, -7.4558854, -21.328295, -0.89057755, -7.431749, -21.35008, -0.89848065, -7.431749, -21.355635, -0.45334554, -7.4558854, -21.371868, -0.9061701, -7.4558854, -21.37785, -0.4460833, -7.431749, -21.355635, -0.45334554, -7.431749, -21.35008, -0.89848065, -7.4558854, -21.371868, -0.9061701, -7.4558854, -21.37785, -0.4460833, -7.480022, -21.35008, -0.89848065, -7.480022, -21.355635, -0.45334554, -7.4558854, -21.37785, -0.4460833, -7.4558854, -21.371868, -0.9061701, -7.480022, -21.35008, -0.89848065, -7.480022, -21.355635, -0.45334554, -7.4558854, -21.328295, -0.89057755, -7.4558854, -21.333633, -0.46060777, -7.480022, -21.355635, -0.45334554, -7.480022, -21.35008, -0.89848065, -7.4558854, -21.328295, -0.89057755, -7.4558854, -21.328295, -0.89057755, -7.431749, -21.208895, -0.9149277, -7.431749, -21.35008, -0.89848065, -7.4558854, -21.328295, -0.89057755, -7.4558854, -21.21466, -0.8974128, -7.431749, -21.208895, -0.9149277, -7.431749, -21.35008, -0.89848065, -7.4558854, -21.20334, -0.9326565, -7.4558854, -21.371868, -0.9061701, -7.431749, -21.35008, -0.89848065, -7.431749, -21.208895, -0.9149277, -7.4558854, -21.20334, -0.9326565, -7.4558854, -21.371868, -0.9061701, -7.480022, -21.208895, -0.9149277, -7.480022, -21.35008, -0.89848065, -7.4558854, -21.371868, -0.9061701, -7.4558854, -21.20334, -0.9326565, -7.480022, -21.208895, -0.9149277, -7.480022, -21.35008, -0.89848065, -7.4558854, -21.21466, -0.8974128, -7.4558854, -21.328295, -0.89057755, -7.480022, -21.35008, -0.89848065, -7.480022, -21.208895, -0.9149277, -7.4558854, -21.21466, -0.8974128, -7.4558854, -21.21466, -0.8974128, -7.431749, -21.090775, -0.88758755, -7.431749, -21.208895, -0.9149277, -7.4558854, -21.21466, -0.8974128, -7.4558854, -21.114271, -0.8837426, -7.431749, -21.090775, -0.88758755, -7.431749, -21.208895, -0.9149277, -7.4558854, -21.06728, -0.89164567, -7.4558854, -21.20334, -0.9326565, -7.431749, -21.208895, -0.9149277, -7.431749, -21.090775, -0.88758755, -7.4558854, -21.06728, -0.89164567, -7.4558854, -21.20334, -0.9326565, -7.480022, -21.090775, -0.88758755, -7.480022, -21.208895, -0.9149277, -7.4558854, -21.20334, -0.9326565, -7.4558854, -21.06728, -0.89164567, -7.480022, -21.090775, -0.88758755, -7.480022, -21.208895, -0.9149277, -7.4558854, -21.114271, -0.8837426, -7.4558854, -21.21466, -0.8974128, -7.480022, -21.208895, -0.9149277, -7.480022, -21.090775, -0.88758755, -7.4558854, -21.114271, -0.8837426, -7.4558854, -21.114271, -0.8837426, -7.431749, -21.088425, -0.45697713, -7.431749, -21.090775, -0.88758755, -7.4558854, -21.114271, -0.8837426, -7.4558854, -21.111708, -0.46124887, -7.431749, -21.088425, -0.45697713, -7.4558854, -21.111708, -0.46124887, -7.431749, -21.219574, -0.416821, -7.431749, -21.088425, -0.45697713, -7.4558854, -21.111708, -0.46124887, -7.4558854, -21.224487, -0.43454933, -7.431749, -21.219574, -0.416821, -7.431749, -21.090775, -0.88758755, -7.4558854, -21.06493, -0.45249128, -7.4558854, -21.06728, -0.89164567, -7.431749, -21.090775, -0.88758755, -7.431749, -21.088425, -0.45697713, -7.4558854, -21.06493, -0.45249128, -7.431749, -21.088425, -0.45697713, -7.4558854, -21.214874, -0.39887857, -7.4558854, -21.06493, -0.45249128, -7.431749, -21.088425, -0.45697713, -7.431749, -21.219574, -0.416821, -7.4558854, -21.214874, -0.39887857, -7.4558854, -21.06728, -0.89164567, -7.480022, -21.088425, -0.45697713, -7.480022, -21.090775, -0.88758755, -7.4558854, -21.06728, -0.89164567, -7.4558854, -21.06493, -0.45249128, -7.480022, -21.088425, -0.45697713, -7.4558854, -21.06493, -0.45249128, -7.480022, -21.219574, -0.416821, -7.480022, -21.088425, -0.45697713, -7.4558854, -21.06493, -0.45249128, -7.4558854, -21.214874, -0.39887857, -7.480022, -21.219574, -0.416821, -7.480022, -21.090775, -0.88758755, -7.4558854, -21.111708, -0.46124887, -7.4558854, -21.114271, -0.8837426, -7.480022, -21.090775, -0.88758755, -7.480022, -21.088425, -0.45697713, -7.4558854, -21.111708, -0.46124887, -7.480022, -21.088425, -0.45697713, -7.4558854, -21.224487, -0.43454933, -7.4558854, -21.111708, -0.46124887, -7.480022, -21.088425, -0.45697713, -7.480022, -21.219574, -0.416821, -7.4558854, -21.224487, -0.43454933, -7.4558854, -21.224487, -0.43454933, -7.431749, -21.355635, -0.45334554, -7.431749, -21.219574, -0.416821, -7.4558854, -21.224487, -0.43454933, -7.4558854, -21.333633, -0.46060777, -7.431749, -21.355635, -0.45334554, -7.431749, -21.219574, -0.416821, -7.4558854, -21.37785, -0.4460833, -7.4558854, -21.214874, -0.39887857, -7.431749, -21.219574, -0.416821, -7.431749, -21.355635, -0.45334554, -7.4558854, -21.37785, -0.4460833, -7.4558854, -21.214874, -0.39887857, -7.480022, -21.355635, -0.45334554, -7.480022, -21.219574, -0.416821, -7.4558854, -21.214874, -0.39887857, -7.4558854, -21.37785, -0.4460833, -7.480022, -21.355635, -0.45334554, -7.480022, -21.219574, -0.416821, -7.4558854, -21.333633, -0.46060777, -7.4558854, -21.224487, -0.43454933, -7.480022, -21.219574, -0.416821, -7.480022, -21.355635, -0.45334554, -7.4558854, -21.333633, -0.46060777, -3.8775039, -21.320818, 0.85066056, -3.8561444, -21.335342, 0.33696115, -3.8561444, -21.34047, 0.85920453, -3.8775039, -21.320818, 0.85066056, -3.8775039, -21.316118, 0.34593213, -3.8561444, -21.335342, 0.33696115, -3.8775039, -21.316118, 0.34593213, -3.8561444, -21.210388, 0.31752384, -3.8561444, -21.335342, 0.33696115, -3.8775039, -21.316118, 0.34593213, -3.8775039, -21.215515, 0.33824265, -3.8561444, -21.210388, 0.31752384, -3.8561444, -21.34047, 0.85920453, -3.8775039, -21.35478, 0.32799017, -3.8775039, -21.360119, 0.8677484, -3.8561444, -21.34047, 0.85920453, -3.8561444, -21.335342, 0.33696115, -3.8775039, -21.35478, 0.32799017, -3.8561444, -21.335342, 0.33696115, -3.8775039, -21.205263, 0.29680502, -3.8775039, -21.35478, 0.32799017, -3.8561444, -21.335342, 0.33696115, -3.8561444, -21.210388, 0.31752384, -3.8775039, -21.205263, 0.29680502, -3.8775039, -21.360119, 0.8677484, -3.8988638, -21.335342, 0.33696115, -3.8988638, -21.34047, 0.85920453, -3.8775039, -21.360119, 0.8677484, -3.8775039, -21.35478, 0.32799017, -3.8988638, -21.335342, 0.33696115, -3.8775039, -21.35478, 0.32799017, -3.8988638, -21.210388, 0.31752384, -3.8988638, -21.335342, 0.33696115, -3.8775039, -21.35478, 0.32799017, -3.8775039, -21.205263, 0.29680502, -3.8988638, -21.210388, 0.31752384, -3.8988638, -21.34047, 0.85920453, -3.8775039, -21.316118, 0.34593213, -3.8775039, -21.320818, 0.85066056, -3.8988638, -21.34047, 0.85920453, -3.8988638, -21.335342, 0.33696115, -3.8775039, -21.316118, 0.34593213, -3.8988638, -21.335342, 0.33696115, -3.8775039, -21.215515, 0.33824265, -3.8775039, -21.316118, 0.34593213, -3.8988638, -21.335342, 0.33696115, -3.8988638, -21.210388, 0.31752384, -3.8775039, -21.215515, 0.33824265, -3.8775039, -21.215515, 0.33824265, -3.8561444, -21.105513, 0.34956324, -3.8561444, -21.210388, 0.31752384, -3.8775039, -21.215515, 0.33824265, -3.8775039, -21.126446, 0.35404897, -3.8561444, -21.105513, 0.34956324, -3.8775039, -21.126446, 0.35404897, -3.8561444, -21.10359, 0.85493267, -3.8561444, -21.105513, 0.34956324, -3.8775039, -21.126446, 0.35404897, -3.8775039, -21.12431, 0.8498062, -3.8561444, -21.10359, 0.85493267, -3.8775039, -21.12431, 0.8498062, -3.8561444, -21.219788, 0.9021374, -3.8561444, -21.10359, 0.85493267, -3.8775039, -21.12431, 0.8498062, -3.8775039, -21.224058, 0.88120484, -3.8561444, -21.219788, 0.9021374, -3.8561444, -21.210388, 0.31752384, -3.8775039, -21.084793, 0.34507775, -3.8775039, -21.205263, 0.29680502, -3.8561444, -21.210388, 0.31752384, -3.8561444, -21.105513, 0.34956324, -3.8775039, -21.084793, 0.34507775, -3.8561444, -21.105513, 0.34956324, -3.8775039, -21.082657, 0.8600589, -3.8775039, -21.084793, 0.34507775, -3.8561444, -21.105513, 0.34956324, -3.8561444, -21.10359, 0.85493267, -3.8775039, -21.082657, 0.8600589, -3.8561444, -21.10359, 0.85493267, -3.8775039, -21.215515, 0.92306983, -3.8775039, -21.082657, 0.8600589, -3.8561444, -21.10359, 0.85493267, -3.8561444, -21.219788, 0.9021374, -3.8775039, -21.215515, 0.92306983, -3.8775039, -21.205263, 0.29680502, -3.8988638, -21.105513, 0.34956324, -3.8988638, -21.210388, 0.31752384, -3.8775039, -21.205263, 0.29680502, -3.8775039, -21.084793, 0.34507775, -3.8988638, -21.105513, 0.34956324, -3.8988638, -21.210388, 0.31752384, -3.8775039, -21.126446, 0.35404897, -3.8775039, -21.215515, 0.33824265, -3.8988638, -21.210388, 0.31752384, -3.8988638, -21.105513, 0.34956324, -3.8775039, -21.126446, 0.35404897, -3.8988638, -21.105513, 0.34956324, -3.8775039, -21.12431, 0.8498062, -3.8775039, -21.126446, 0.35404897, -3.8988638, -21.105513, 0.34956324, -3.8988638, -21.10359, 0.85493267, -3.8775039, -21.12431, 0.8498062, -3.8988638, -21.10359, 0.85493267, -3.8775039, -21.224058, 0.88120484, -3.8775039, -21.12431, 0.8498062, -3.8988638, -21.10359, 0.85493267, -3.8988638, -21.219788, 0.9021374, -3.8775039, -21.224058, 0.88120484, -3.8775039, -21.084793, 0.34507775, -3.8988638, -21.10359, 0.85493267, -3.8988638, -21.105513, 0.34956324, -3.8775039, -21.084793, 0.34507775, -3.8775039, -21.082657, 0.8600589, -3.8988638, -21.10359, 0.85493267, -3.8775039, -21.082657, 0.8600589, -3.8988638, -21.219788, 0.9021374, -3.8988638, -21.10359, 0.85493267, -3.8775039, -21.082657, 0.8600589, -3.8775039, -21.215515, 0.92306983, -3.8988638, -21.219788, 0.9021374, -3.8775039, -21.224058, 0.88120484, -3.8561444, -21.34047, 0.85920453, -3.8561444, -21.219788, 0.9021374, -3.8775039, -21.224058, 0.88120484, -3.8775039, -21.320818, 0.85066056, -3.8561444, -21.34047, 0.85920453, -3.8561444, -21.219788, 0.9021374, -3.8775039, -21.360119, 0.8677484, -3.8775039, -21.215515, 0.92306983, -3.8561444, -21.219788, 0.9021374, -3.8561444, -21.34047, 0.85920453, -3.8775039, -21.360119, 0.8677484, -3.8775039, -21.215515, 0.92306983, -3.8988638, -21.34047, 0.85920453, -3.8988638, -21.219788, 0.9021374, -3.8775039, -21.215515, 0.92306983, -3.8775039, -21.360119, 0.8677484, -3.8988638, -21.34047, 0.85920453, -3.8988638, -21.219788, 0.9021374, -3.8775039, -21.320818, 0.85066056, -3.8775039, -21.224058, 0.88120484, -3.8988638, -21.219788, 0.9021374, -3.8988638, -21.34047, 0.85920453, -3.8775039, -21.320818, 0.85066056, -3.7194428, -21.320816, 3.3595648, -3.698083, -21.335342, 2.8460789, -3.698083, -21.340467, 3.3681085, -3.7194428, -21.320816, 3.3595648, -3.7194428, -21.316118, 2.8550498, -3.698083, -21.335342, 2.8460789, -3.7194428, -21.316118, 2.8550498, -3.698083, -21.210388, 2.826428, -3.698083, -21.335342, 2.8460789, -3.7194428, -21.316118, 2.8550498, -3.7194428, -21.215513, 2.8471467, -3.698083, -21.210388, 2.826428, -3.698083, -21.340467, 3.3681085, -3.7194428, -21.354778, 2.836894, -3.7194428, -21.360119, 3.3768659, -3.698083, -21.340467, 3.3681085, -3.698083, -21.335342, 2.8460789, -3.7194428, -21.354778, 2.836894, -3.698083, -21.335342, 2.8460789, -3.7194428, -21.205261, 2.805709, -3.7194428, -21.354778, 2.836894, -3.698083, -21.335342, 2.8460789, -3.698083, -21.210388, 2.826428, -3.7194428, -21.205261, 2.805709, -3.7194428, -21.360119, 3.3768659, -3.7408023, -21.335342, 2.8460789, -3.7408023, -21.340467, 3.3681085, -3.7194428, -21.360119, 3.3768659, -3.7194428, -21.354778, 2.836894, -3.7408023, -21.335342, 2.8460789, -3.7194428, -21.354778, 2.836894, -3.7408023, -21.210388, 2.826428, -3.7408023, -21.335342, 2.8460789, -3.7194428, -21.354778, 2.836894, -3.7194428, -21.205261, 2.805709, -3.7408023, -21.210388, 2.826428, -3.7408023, -21.340467, 3.3681085, -3.7194428, -21.316118, 2.8550498, -3.7194428, -21.320816, 3.3595648, -3.7408023, -21.340467, 3.3681085, -3.7408023, -21.335342, 2.8460789, -3.7194428, -21.316118, 2.8550498, -3.7408023, -21.335342, 2.8460789, -3.7194428, -21.215513, 2.8471467, -3.7194428, -21.316118, 2.8550498, -3.7408023, -21.335342, 2.8460789, -3.7408023, -21.210388, 2.826428, -3.7194428, -21.215513, 2.8471467, -3.7194428, -21.215513, 2.8471467, -3.698083, -21.105513, 2.8586807, -3.698083, -21.210388, 2.826428, -3.7194428, -21.215513, 2.8471467, -3.7194428, -21.126444, 2.8631663, -3.698083, -21.105513, 2.8586807, -3.7194428, -21.126444, 2.8631663, -3.698083, -21.10359, 3.3640501, -3.698083, -21.105513, 2.8586807, -3.7194428, -21.126444, 2.8631663, -3.7194428, -21.124308, 3.358924, -3.698083, -21.10359, 3.3640501, -3.7194428, -21.124308, 3.358924, -3.698083, -21.219786, 3.411255, -3.698083, -21.10359, 3.3640501, -3.7194428, -21.124308, 3.358924, -3.7194428, -21.224058, 3.3903227, -3.698083, -21.219786, 3.411255, -3.698083, -21.210388, 2.826428, -3.7194428, -21.084793, 2.8539817, -3.7194428, -21.205261, 2.805709, -3.698083, -21.210388, 2.826428, -3.698083, -21.105513, 2.8586807, -3.7194428, -21.084793, 2.8539817, -3.698083, -21.105513, 2.8586807, -3.7194428, -21.082657, 3.3691764, -3.7194428, -21.084793, 2.8539817, -3.698083, -21.105513, 2.8586807, -3.698083, -21.10359, 3.3640501, -3.7194428, -21.082657, 3.3691764, -3.698083, -21.10359, 3.3640501, -3.7194428, -21.215513, 3.431974, -3.7194428, -21.082657, 3.3691764, -3.698083, -21.10359, 3.3640501, -3.698083, -21.219786, 3.411255, -3.7194428, -21.215513, 3.431974, -3.7194428, -21.205261, 2.805709, -3.7408023, -21.105513, 2.8586807, -3.7408023, -21.210388, 2.826428, -3.7194428, -21.205261, 2.805709, -3.7194428, -21.084793, 2.8539817, -3.7408023, -21.105513, 2.8586807, -3.7408023, -21.210388, 2.826428, -3.7194428, -21.126444, 2.8631663, -3.7194428, -21.215513, 2.8471467, -3.7408023, -21.210388, 2.826428, -3.7408023, -21.105513, 2.8586807, -3.7194428, -21.126444, 2.8631663, -3.7408023, -21.105513, 2.8586807, -3.7194428, -21.124308, 3.358924, -3.7194428, -21.126444, 2.8631663, -3.7408023, -21.105513, 2.8586807, -3.7408023, -21.10359, 3.3640501, -3.7194428, -21.124308, 3.358924, -3.7408023, -21.10359, 3.3640501, -3.7194428, -21.224058, 3.3903227, -3.7194428, -21.124308, 3.358924, -3.7408023, -21.10359, 3.3640501, -3.7408023, -21.219786, 3.411255, -3.7194428, -21.224058, 3.3903227, -3.7194428, -21.084793, 2.8539817, -3.7408023, -21.10359, 3.3640501, -3.7408023, -21.105513, 2.8586807, -3.7194428, -21.084793, 2.8539817, -3.7194428, -21.082657, 3.3691764, -3.7408023, -21.10359, 3.3640501, -3.7194428, -21.082657, 3.3691764, -3.7408023, -21.219786, 3.411255, -3.7408023, -21.10359, 3.3640501, -3.7194428, -21.082657, 3.3691764, -3.7194428, -21.215513, 3.431974, -3.7408023, -21.219786, 3.411255, -3.7194428, -21.224058, 3.3903227, -3.698083, -21.340467, 3.3681085, -3.698083, -21.219786, 3.411255, -3.7194428, -21.224058, 3.3903227, -3.7194428, -21.320816, 3.3595648, -3.698083, -21.340467, 3.3681085, -3.698083, -21.219786, 3.411255, -3.7194428, -21.360119, 3.3768659, -3.7194428, -21.215513, 3.431974, -3.698083, -21.219786, 3.411255, -3.698083, -21.340467, 3.3681085, -3.7194428, -21.360119, 3.3768659, -3.7194428, -21.215513, 3.431974, -3.7408023, -21.340467, 3.3681085, -3.7408023, -21.219786, 3.411255, -3.7194428, -21.215513, 3.431974, -3.7194428, -21.360119, 3.3768659, -3.7408023, -21.340467, 3.3681085, -3.7408023, -21.219786, 3.411255, -3.7194428, -21.320816, 3.3595648, -3.7194428, -21.224058, 3.3903227, -3.7408023, -21.219786, 3.411255, -3.7408023, -21.340467, 3.3681085, -3.7194428, -21.320816, 3.3595648, -7.4172244, -21.333633, 4.035811, -7.393088, -21.35008, 3.6370263, -7.393088, -21.355633, 4.0424323, -7.4172244, -21.333633, 4.035811, -7.4172244, -21.328293, 3.6438615, -7.393088, -21.35008, 3.6370263, -7.393088, -21.355633, 4.0424323, -7.4172244, -21.371866, 3.6299777, -7.4172244, -21.377848, 4.049054, -7.393088, -21.355633, 4.0424323, -7.393088, -21.35008, 3.6370263, -7.4172244, -21.371866, 3.6299777, -7.4172244, -21.377848, 4.049054, -7.441361, -21.35008, 3.6370263, -7.441361, -21.355633, 4.0424323, -7.4172244, -21.377848, 4.049054, -7.4172244, -21.371866, 3.6299777, -7.441361, -21.35008, 3.6370263, -7.441361, -21.355633, 4.0424323, -7.4172244, -21.328293, 3.6438615, -7.4172244, -21.333633, 4.035811, -7.441361, -21.355633, 4.0424323, -7.441361, -21.35008, 3.6370263, -7.4172244, -21.328293, 3.6438615, -7.4172244, -21.328293, 3.6438615, -7.393088, -21.208893, 3.621861, -7.393088, -21.35008, 3.6370263, -7.4172244, -21.328293, 3.6438615, -7.4172244, -21.214659, 3.6378808, -7.393088, -21.208893, 3.621861, -7.393088, -21.35008, 3.6370263, -7.4172244, -21.203339, 3.6056278, -7.4172244, -21.371866, 3.6299777, -7.393088, -21.35008, 3.6370263, -7.393088, -21.208893, 3.621861, -7.4172244, -21.203339, 3.6056278, -7.4172244, -21.371866, 3.6299777, -7.441361, -21.208893, 3.621861, -7.441361, -21.35008, 3.6370263, -7.4172244, -21.371866, 3.6299777, -7.4172244, -21.203339, 3.6056278, -7.441361, -21.208893, 3.621861, -7.441361, -21.35008, 3.6370263, -7.4172244, -21.214659, 3.6378808, -7.4172244, -21.328293, 3.6438615, -7.441361, -21.35008, 3.6370263, -7.441361, -21.208893, 3.621861, -7.4172244, -21.214659, 3.6378808, -7.4172244, -21.214659, 3.6378808, -7.393088, -21.090773, 3.6466384, -7.393088, -21.208893, 3.621861, -7.4172244, -21.214659, 3.6378808, -7.4172244, -21.11427, 3.6502695, -7.393088, -21.090773, 3.6466384, -7.393088, -21.208893, 3.621861, -7.4172244, -21.067278, 3.6432207, -7.4172244, -21.203339, 3.6056278, -7.393088, -21.208893, 3.621861, -7.393088, -21.090773, 3.6466384, -7.4172244, -21.067278, 3.6432207, -7.4172244, -21.203339, 3.6056278, -7.441361, -21.090773, 3.6466384, -7.441361, -21.208893, 3.621861, -7.4172244, -21.203339, 3.6056278, -7.4172244, -21.067278, 3.6432207, -7.441361, -21.090773, 3.6466384, -7.441361, -21.208893, 3.621861, -7.4172244, -21.11427, 3.6502695, -7.4172244, -21.214659, 3.6378808, -7.441361, -21.208893, 3.621861, -7.441361, -21.090773, 3.6466384, -7.4172244, -21.11427, 3.6502695, -7.4172244, -21.11427, 3.6502695, -7.393088, -21.088425, 4.0392284, -7.393088, -21.090773, 3.6466384, -7.4172244, -21.11427, 3.6502695, -7.4172244, -21.111706, 4.03517, -7.393088, -21.088425, 4.0392284, -7.393088, -21.090773, 3.6466384, -7.4172244, -21.064928, 4.043073, -7.4172244, -21.067278, 3.6432207, -7.393088, -21.090773, 3.6466384, -7.393088, -21.088425, 4.0392284, -7.4172244, -21.064928, 4.043073, -7.4172244, -21.067278, 3.6432207, -7.441361, -21.088425, 4.0392284, -7.441361, -21.090773, 3.6466384, -7.4172244, -21.067278, 3.6432207, -7.4172244, -21.064928, 4.043073, -7.441361, -21.088425, 4.0392284, -7.441361, -21.090773, 3.6466384, -7.4172244, -21.111706, 4.03517, -7.4172244, -21.11427, 3.6502695, -7.441361, -21.090773, 3.6466384, -7.441361, -21.088425, 4.0392284, -7.4172244, -21.111706, 4.03517, -7.4172244, -21.111706, 4.03517, -7.393088, -21.219572, 4.0757537, -7.393088, -21.088425, 4.0392284, -7.4172244, -21.111706, 4.03517, -7.4172244, -21.224485, 4.0595202, -7.393088, -21.219572, 4.0757537, -7.393088, -21.088425, 4.0392284, -7.4172244, -21.214872, 4.0919867, -7.4172244, -21.064928, 4.043073, -7.393088, -21.088425, 4.0392284, -7.393088, -21.219572, 4.0757537, -7.4172244, -21.214872, 4.0919867, -7.4172244, -21.064928, 4.043073, -7.441361, -21.219572, 4.0757537, -7.441361, -21.088425, 4.0392284, -7.4172244, -21.064928, 4.043073, -7.4172244, -21.214872, 4.0919867, -7.441361, -21.219572, 4.0757537, -7.441361, -21.088425, 4.0392284, -7.4172244, -21.224485, 4.0595202, -7.4172244, -21.111706, 4.03517, -7.441361, -21.088425, 4.0392284, -7.441361, -21.219572, 4.0757537, -7.4172244, -21.224485, 4.0595202, -7.4172244, -21.224485, 4.0595202, -7.393088, -21.355633, 4.0424323, -7.393088, -21.219572, 4.0757537, -7.4172244, -21.224485, 4.0595202, -7.4172244, -21.333633, 4.035811, -7.393088, -21.355633, 4.0424323, -7.393088, -21.219572, 4.0757537, -7.4172244, -21.377848, 4.049054, -7.4172244, -21.214872, 4.0919867, -7.393088, -21.219572, 4.0757537, -7.393088, -21.355633, 4.0424323, -7.4172244, -21.377848, 4.049054, -7.4172244, -21.214872, 4.0919867, -7.441361, -21.355633, 4.0424323, -7.441361, -21.219572, 4.0757537, -7.4172244, -21.214872, 4.0919867, -7.4172244, -21.377848, 4.049054, -7.441361, -21.355633, 4.0424323, -7.441361, -21.219572, 4.0757537, -7.4172244, -21.333633, 4.035811, -7.4172244, -21.224485, 4.0595202, -7.441361, -21.219572, 4.0757537, -7.441361, -21.355633, 4.0424323, -7.4172244, -21.333633, 4.035811, -7.4558854, -21.333632, 4.726582, -7.431749, -21.350079, 4.2887096, -7.431749, -21.355633, 4.7338443, -7.4558854, -21.333632, 4.726582, -7.4558854, -21.328293, 4.2966127, -7.431749, -21.350079, 4.2887096, -7.431749, -21.355633, 4.7338443, -7.4558854, -21.371866, 4.281234, -7.4558854, -21.377846, 4.7411065, -7.431749, -21.355633, 4.7338443, -7.431749, -21.350079, 4.2887096, -7.4558854, -21.371866, 4.281234, -7.4558854, -21.377846, 4.7411065, -7.480022, -21.350079, 4.2887096, -7.480022, -21.355633, 4.7338443, -7.4558854, -21.377846, 4.7411065, -7.4558854, -21.371866, 4.281234, -7.480022, -21.350079, 4.2887096, -7.480022, -21.355633, 4.7338443, -7.4558854, -21.328293, 4.2966127, -7.4558854, -21.333632, 4.726582, -7.480022, -21.355633, 4.7338443, -7.480022, -21.350079, 4.2887096, -7.4558854, -21.328293, 4.2966127, -7.4558854, -21.328293, 4.2966127, -7.431749, -21.208893, 4.272262, -7.431749, -21.350079, 4.2887096, -7.4558854, -21.328293, 4.2966127, -7.4558854, -21.214659, 4.2899904, -7.431749, -21.208893, 4.272262, -7.431749, -21.350079, 4.2887096, -7.4558854, -21.203339, 4.254534, -7.4558854, -21.371866, 4.281234, -7.431749, -21.350079, 4.2887096, -7.431749, -21.208893, 4.272262, -7.4558854, -21.203339, 4.254534, -7.4558854, -21.371866, 4.281234, -7.480022, -21.208893, 4.272262, -7.480022, -21.350079, 4.2887096, -7.4558854, -21.371866, 4.281234, -7.4558854, -21.203339, 4.254534, -7.480022, -21.208893, 4.272262, -7.480022, -21.350079, 4.2887096, -7.4558854, -21.214659, 4.2899904, -7.4558854, -21.328293, 4.2966127, -7.480022, -21.350079, 4.2887096, -7.480022, -21.208893, 4.272262, -7.4558854, -21.214659, 4.2899904, -7.4558854, -21.214659, 4.2899904, -7.431749, -21.090773, 4.2996025, -7.431749, -21.208893, 4.272262, -7.4558854, -21.214659, 4.2899904, -7.4558854, -21.11427, 4.3034472, -7.431749, -21.090773, 4.2996025, -7.431749, -21.208893, 4.272262, -7.4558854, -21.067278, 4.295544, -7.4558854, -21.203339, 4.254534, -7.431749, -21.208893, 4.272262, -7.431749, -21.090773, 4.2996025, -7.4558854, -21.067278, 4.295544, -7.4558854, -21.203339, 4.254534, -7.480022, -21.090773, 4.2996025, -7.480022, -21.208893, 4.272262, -7.4558854, -21.203339, 4.254534, -7.4558854, -21.067278, 4.295544, -7.480022, -21.090773, 4.2996025, -7.480022, -21.208893, 4.272262, -7.4558854, -21.11427, 4.3034472, -7.4558854, -21.214659, 4.2899904, -7.480022, -21.208893, 4.272262, -7.480022, -21.090773, 4.2996025, -7.4558854, -21.11427, 4.3034472, -7.4558854, -21.11427, 4.3034472, -7.431749, -21.088423, 4.730213, -7.431749, -21.090773, 4.2996025, -7.4558854, -21.11427, 4.3034472, -7.4558854, -21.111706, 4.7259407, -7.431749, -21.088423, 4.730213, -7.4558854, -21.111706, 4.7259407, -7.431749, -21.219572, 4.770369, -7.431749, -21.088423, 4.730213, -7.4558854, -21.111706, 4.7259407, -7.4558854, -21.224485, 4.7526407, -7.431749, -21.219572, 4.770369, -7.431749, -21.090773, 4.2996025, -7.4558854, -21.064928, 4.7346983, -7.4558854, -21.067278, 4.295544, -7.431749, -21.090773, 4.2996025, -7.431749, -21.088423, 4.730213, -7.4558854, -21.064928, 4.7346983, -7.431749, -21.088423, 4.730213, -7.4558854, -21.214872, 4.788311, -7.4558854, -21.064928, 4.7346983, -7.431749, -21.088423, 4.730213, -7.431749, -21.219572, 4.770369, -7.4558854, -21.214872, 4.788311, -7.4558854, -21.067278, 4.295544, -7.480022, -21.088423, 4.730213, -7.480022, -21.090773, 4.2996025, -7.4558854, -21.067278, 4.295544, -7.4558854, -21.064928, 4.7346983, -7.480022, -21.088423, 4.730213, -7.4558854, -21.064928, 4.7346983, -7.480022, -21.219572, 4.770369, -7.480022, -21.088423, 4.730213, -7.4558854, -21.064928, 4.7346983, -7.4558854, -21.214872, 4.788311, -7.480022, -21.219572, 4.770369, -7.480022, -21.090773, 4.2996025, -7.4558854, -21.111706, 4.7259407, -7.4558854, -21.11427, 4.3034472, -7.480022, -21.090773, 4.2996025, -7.480022, -21.088423, 4.730213, -7.4558854, -21.111706, 4.7259407, -7.480022, -21.088423, 4.730213, -7.4558854, -21.224485, 4.7526407, -7.4558854, -21.111706, 4.7259407, -7.480022, -21.088423, 4.730213, -7.480022, -21.219572, 4.770369, -7.4558854, -21.224485, 4.7526407, -7.4558854, -21.224485, 4.7526407, -7.431749, -21.355633, 4.7338443, -7.431749, -21.219572, 4.770369, -7.4558854, -21.224485, 4.7526407, -7.4558854, -21.333632, 4.726582, -7.431749, -21.355633, 4.7338443, -7.431749, -21.219572, 4.770369, -7.4558854, -21.377846, 4.7411065, -7.4558854, -21.214872, 4.788311, -7.431749, -21.219572, 4.770369, -7.431749, -21.355633, 4.7338443, -7.4558854, -21.377846, 4.7411065, -7.4558854, -21.214872, 4.788311, -7.480022, -21.355633, 4.7338443, -7.480022, -21.219572, 4.770369, -7.4558854, -21.214872, 4.788311, -7.4558854, -21.377846, 4.7411065, -7.480022, -21.355633, 4.7338443, -7.480022, -21.219572, 4.770369, -7.4558854, -21.333632, 4.726582, -7.4558854, -21.224485, 4.7526407, -7.480022, -21.219572, 4.770369, -7.480022, -21.355633, 4.7338443, -7.4558854, -21.333632, 4.726582, -3.7589583, -21.320816, 4.7411065, -3.7375984, -21.33534, 4.2274075, -3.7375984, -21.340467, 4.7496505, -3.7589583, -21.320816, 4.7411065, -3.7589583, -21.316118, 4.236378, -3.7375984, -21.33534, 4.2274075, -3.7589583, -21.316118, 4.236378, -3.7375984, -21.210388, 4.2079697, -3.7375984, -21.33534, 4.2274075, -3.7589583, -21.316118, 4.236378, -3.7589583, -21.215513, 4.2284746, -3.7375984, -21.210388, 4.2079697, -3.7375984, -21.340467, 4.7496505, -3.7589583, -21.354778, 4.2184362, -3.7589583, -21.360119, 4.758194, -3.7375984, -21.340467, 4.7496505, -3.7375984, -21.33534, 4.2274075, -3.7589583, -21.354778, 4.2184362, -3.7375984, -21.33534, 4.2274075, -3.7589583, -21.205261, 4.1870375, -3.7589583, -21.354778, 4.2184362, -3.7375984, -21.33534, 4.2274075, -3.7375984, -21.210388, 4.2079697, -3.7589583, -21.205261, 4.1870375, -3.7589583, -21.360119, 4.758194, -3.7803178, -21.33534, 4.2274075, -3.7803178, -21.340467, 4.7496505, -3.7589583, -21.360119, 4.758194, -3.7589583, -21.354778, 4.2184362, -3.7803178, -21.33534, 4.2274075, -3.7589583, -21.354778, 4.2184362, -3.7803178, -21.210388, 4.2079697, -3.7803178, -21.33534, 4.2274075, -3.7589583, -21.354778, 4.2184362, -3.7589583, -21.205261, 4.1870375, -3.7803178, -21.210388, 4.2079697, -3.7803178, -21.340467, 4.7496505, -3.7589583, -21.316118, 4.236378, -3.7589583, -21.320816, 4.7411065, -3.7803178, -21.340467, 4.7496505, -3.7803178, -21.33534, 4.2274075, -3.7589583, -21.316118, 4.236378, -3.7803178, -21.33534, 4.2274075, -3.7589583, -21.215513, 4.2284746, -3.7589583, -21.316118, 4.236378, -3.7803178, -21.33534, 4.2274075, -3.7803178, -21.210388, 4.2079697, -3.7589583, -21.215513, 4.2284746, -3.7589583, -21.215513, 4.2284746, -3.7375984, -21.10551, 4.2400093, -3.7375984, -21.210388, 4.2079697, -3.7589583, -21.215513, 4.2284746, -3.7589583, -21.126444, 4.2444944, -3.7375984, -21.10551, 4.2400093, -3.7589583, -21.126444, 4.2444944, -3.7375984, -21.103588, 4.7453785, -3.7375984, -21.10551, 4.2400093, -3.7589583, -21.126444, 4.2444944, -3.7589583, -21.124308, 4.740252, -3.7375984, -21.103588, 4.7453785, -3.7589583, -21.124308, 4.740252, -3.7375984, -21.219786, 4.7925835, -3.7375984, -21.103588, 4.7453785, -3.7589583, -21.124308, 4.740252, -3.7589583, -21.224058, 4.7716503, -3.7375984, -21.219786, 4.7925835, -3.7375984, -21.210388, 4.2079697, -3.7589583, -21.084793, 4.23531, -3.7589583, -21.205261, 4.1870375, -3.7375984, -21.210388, 4.2079697, -3.7375984, -21.10551, 4.2400093, -3.7589583, -21.084793, 4.23531, -3.7375984, -21.10551, 4.2400093, -3.7589583, -21.082657, 4.7505045, -3.7589583, -21.084793, 4.23531, -3.7375984, -21.10551, 4.2400093, -3.7375984, -21.103588, 4.7453785, -3.7589583, -21.082657, 4.7505045, -3.7375984, -21.103588, 4.7453785, -3.7589583, -21.215513, 4.8135157, -3.7589583, -21.082657, 4.7505045, -3.7375984, -21.103588, 4.7453785, -3.7375984, -21.219786, 4.7925835, -3.7589583, -21.215513, 4.8135157, -3.7589583, -21.205261, 4.1870375, -3.7803178, -21.10551, 4.2400093, -3.7803178, -21.210388, 4.2079697, -3.7589583, -21.205261, 4.1870375, -3.7589583, -21.084793, 4.23531, -3.7803178, -21.10551, 4.2400093, -3.7803178, -21.210388, 4.2079697, -3.7589583, -21.126444, 4.2444944, -3.7589583, -21.215513, 4.2284746, -3.7803178, -21.210388, 4.2079697, -3.7803178, -21.10551, 4.2400093, -3.7589583, -21.126444, 4.2444944, -3.7803178, -21.10551, 4.2400093, -3.7589583, -21.124308, 4.740252, -3.7589583, -21.126444, 4.2444944, -3.7803178, -21.10551, 4.2400093, -3.7803178, -21.103588, 4.7453785, -3.7589583, -21.124308, 4.740252, -3.7803178, -21.103588, 4.7453785, -3.7589583, -21.224058, 4.7716503, -3.7589583, -21.124308, 4.740252, -3.7803178, -21.103588, 4.7453785, -3.7803178, -21.219786, 4.7925835, -3.7589583, -21.224058, 4.7716503, -3.7589583, -21.084793, 4.23531, -3.7803178, -21.103588, 4.7453785, -3.7803178, -21.10551, 4.2400093, -3.7589583, -21.084793, 4.23531, -3.7589583, -21.082657, 4.7505045, -3.7803178, -21.103588, 4.7453785, -3.7589583, -21.082657, 4.7505045, -3.7803178, -21.219786, 4.7925835, -3.7803178, -21.103588, 4.7453785, -3.7589583, -21.082657, 4.7505045, -3.7589583, -21.215513, 4.8135157, -3.7803178, -21.219786, 4.7925835, -3.7589583, -21.224058, 4.7716503, -3.7375984, -21.340467, 4.7496505, -3.7375984, -21.219786, 4.7925835, -3.7589583, -21.224058, 4.7716503, -3.7589583, -21.320816, 4.7411065, -3.7375984, -21.340467, 4.7496505, -3.7375984, -21.219786, 4.7925835, -3.7589583, -21.360119, 4.758194, -3.7589583, -21.215513, 4.8135157, -3.7375984, -21.219786, 4.7925835, -3.7375984, -21.340467, 4.7496505, -3.7589583, -21.360119, 4.758194, -3.7589583, -21.215513, 4.8135157, -3.7803178, -21.340467, 4.7496505, -3.7803178, -21.219786, 4.7925835, -3.7589583, -21.215513, 4.8135157, -3.7589583, -21.360119, 4.758194, -3.7803178, -21.340467, 4.7496505, -3.7803178, -21.219786, 4.7925835, -3.7589583, -21.320816, 4.7411065, -3.7589583, -21.224058, 4.7716503, -3.7803178, -21.219786, 4.7925835, -3.7803178, -21.340467, 4.7496505, -3.7589583, -21.320816, 4.7411065, -3.7589583, -21.320816, 5.3611774, -3.7375984, -21.33534, 4.8476915, -3.7375984, -21.340467, 5.3697214, -3.7589583, -21.320816, 5.3611774, -3.7589583, -21.316116, 4.8566623, -3.7375984, -21.33534, 4.8476915, -3.7589583, -21.316116, 4.8566623, -3.7375984, -21.210386, 4.82804, -3.7375984, -21.33534, 4.8476915, -3.7589583, -21.316116, 4.8566623, -3.7589583, -21.215513, 4.8487587, -3.7375984, -21.210386, 4.82804, -3.7375984, -21.340467, 5.3697214, -3.7589583, -21.354778, 4.8387203, -3.7589583, -21.360119, 5.378265, -3.7375984, -21.340467, 5.3697214, -3.7375984, -21.33534, 4.8476915, -3.7589583, -21.354778, 4.8387203, -3.7375984, -21.33534, 4.8476915, -3.7589583, -21.205261, 4.8073215, -3.7589583, -21.354778, 4.8387203, -3.7375984, -21.33534, 4.8476915, -3.7375984, -21.210386, 4.82804, -3.7589583, -21.205261, 4.8073215, -3.7589583, -21.360119, 5.378265, -3.7803178, -21.33534, 4.8476915, -3.7803178, -21.340467, 5.3697214, -3.7589583, -21.360119, 5.378265, -3.7589583, -21.354778, 4.8387203, -3.7803178, -21.33534, 4.8476915, -3.7589583, -21.354778, 4.8387203, -3.7803178, -21.210386, 4.82804, -3.7803178, -21.33534, 4.8476915, -3.7589583, -21.354778, 4.8387203, -3.7589583, -21.205261, 4.8073215, -3.7803178, -21.210386, 4.82804, -3.7803178, -21.340467, 5.3697214, -3.7589583, -21.316116, 4.8566623, -3.7589583, -21.320816, 5.3611774, -3.7803178, -21.340467, 5.3697214, -3.7803178, -21.33534, 4.8476915, -3.7589583, -21.316116, 4.8566623, -3.7803178, -21.33534, 4.8476915, -3.7589583, -21.215513, 4.8487587, -3.7589583, -21.316116, 4.8566623, -3.7803178, -21.33534, 4.8476915, -3.7803178, -21.210386, 4.82804, -3.7589583, -21.215513, 4.8487587, -3.7589583, -21.215513, 4.8487587, -3.7375984, -21.10551, 4.8602934, -3.7375984, -21.210386, 4.82804, -3.7589583, -21.215513, 4.8487587, -3.7589583, -21.126444, 4.8647785, -3.7375984, -21.10551, 4.8602934, -3.7589583, -21.126444, 4.8647785, -3.7375984, -21.103588, 5.3656626, -3.7375984, -21.10551, 4.8602934, -3.7589583, -21.126444, 4.8647785, -3.7589583, -21.124308, 5.3605366, -3.7375984, -21.103588, 5.3656626, -3.7589583, -21.124308, 5.3605366, -3.7375984, -21.219786, 5.412654, -3.7375984, -21.103588, 5.3656626, -3.7589583, -21.124308, 5.3605366, -3.7589583, -21.224056, 5.3917212, -3.7375984, -21.219786, 5.412654, -3.7375984, -21.210386, 4.82804, -3.7589583, -21.084793, 4.855594, -3.7589583, -21.205261, 4.8073215, -3.7375984, -21.210386, 4.82804, -3.7375984, -21.10551, 4.8602934, -3.7589583, -21.084793, 4.855594, -3.7375984, -21.10551, 4.8602934, -3.7589583, -21.082657, 5.370575, -3.7589583, -21.084793, 4.855594, -3.7375984, -21.10551, 4.8602934, -3.7375984, -21.103588, 5.3656626, -3.7589583, -21.082657, 5.370575, -3.7375984, -21.103588, 5.3656626, -3.7589583, -21.215513, 5.433586, -3.7589583, -21.082657, 5.370575, -3.7375984, -21.103588, 5.3656626, -3.7375984, -21.219786, 5.412654, -3.7589583, -21.215513, 5.433586, -3.7589583, -21.205261, 4.8073215, -3.7803178, -21.10551, 4.8602934, -3.7803178, -21.210386, 4.82804, -3.7589583, -21.205261, 4.8073215, -3.7589583, -21.084793, 4.855594, -3.7803178, -21.10551, 4.8602934, -3.7803178, -21.210386, 4.82804, -3.7589583, -21.126444, 4.8647785, -3.7589583, -21.215513, 4.8487587, -3.7803178, -21.210386, 4.82804, -3.7803178, -21.10551, 4.8602934, -3.7589583, -21.126444, 4.8647785, -3.7803178, -21.10551, 4.8602934, -3.7589583, -21.124308, 5.3605366, -3.7589583, -21.126444, 4.8647785, -3.7803178, -21.10551, 4.8602934, -3.7803178, -21.103588, 5.3656626, -3.7589583, -21.124308, 5.3605366, -3.7803178, -21.103588, 5.3656626, -3.7589583, -21.224056, 5.3917212, -3.7589583, -21.124308, 5.3605366, -3.7803178, -21.103588, 5.3656626, -3.7803178, -21.219786, 5.412654, -3.7589583, -21.224056, 5.3917212, -3.7589583, -21.084793, 4.855594, -3.7803178, -21.103588, 5.3656626, -3.7803178, -21.10551, 4.8602934, -3.7589583, -21.084793, 4.855594, -3.7589583, -21.082657, 5.370575, -3.7803178, -21.103588, 5.3656626, -3.7589583, -21.082657, 5.370575, -3.7803178, -21.219786, 5.412654, -3.7803178, -21.103588, 5.3656626, -3.7589583, -21.082657, 5.370575, -3.7589583, -21.215513, 5.433586, -3.7803178, -21.219786, 5.412654, -3.7589583, -21.224056, 5.3917212, -3.7375984, -21.340467, 5.3697214, -3.7375984, -21.219786, 5.412654, -3.7589583, -21.224056, 5.3917212, -3.7589583, -21.320816, 5.3611774, -3.7375984, -21.340467, 5.3697214, -3.7375984, -21.219786, 5.412654, -3.7589583, -21.360119, 5.378265, -3.7589583, -21.215513, 5.433586, -3.7375984, -21.219786, 5.412654, -3.7375984, -21.340467, 5.3697214, -3.7589583, -21.360119, 5.378265, -3.7589583, -21.215513, 5.433586, -3.7803178, -21.340467, 5.3697214, -3.7803178, -21.219786, 5.412654, -3.7589583, -21.215513, 5.433586, -3.7589583, -21.360119, 5.378265, -3.7803178, -21.340467, 5.3697214, -3.7803178, -21.219786, 5.412654, -3.7589583, -21.320816, 5.3611774, -3.7589583, -21.224056, 5.3917212, -3.7803178, -21.219786, 5.412654, -3.7803178, -21.340467, 5.3697214, -3.7589583, -21.320816, 5.3611774, -7.3817677, -21.333632, 5.409023, -7.357631, -21.350079, 4.8643517, -7.357631, -21.355633, 5.418207, -7.3817677, -21.333632, 5.409023, -7.3817677, -21.328293, 4.8739634, -7.357631, -21.350079, 4.8643517, -7.3817677, -21.328293, 4.8739634, -7.357631, -21.208893, 4.8436327, -7.357631, -21.350079, 4.8643517, -7.3817677, -21.328293, 4.8739634, -7.3817677, -21.214659, 4.8654194, -7.357631, -21.208893, 4.8436327, -7.357631, -21.355633, 5.418207, -7.3817677, -21.371866, 4.85474, -7.3817677, -21.377846, 5.4271784, -7.357631, -21.355633, 5.418207, -7.357631, -21.350079, 4.8643517, -7.3817677, -21.371866, 4.85474, -7.357631, -21.350079, 4.8643517, -7.3817677, -21.203339, 4.8216324, -7.3817677, -21.371866, 4.85474, -7.357631, -21.350079, 4.8643517, -7.357631, -21.208893, 4.8436327, -7.3817677, -21.203339, 4.8216324, -7.3817677, -21.377846, 5.4271784, -7.4059043, -21.350079, 4.8643517, -7.4059043, -21.355633, 5.418207, -7.3817677, -21.377846, 5.4271784, -7.3817677, -21.371866, 4.85474, -7.4059043, -21.350079, 4.8643517, -7.3817677, -21.371866, 4.85474, -7.4059043, -21.208893, 4.8436327, -7.4059043, -21.350079, 4.8643517, -7.3817677, -21.371866, 4.85474, -7.3817677, -21.203339, 4.8216324, -7.4059043, -21.208893, 4.8436327, -7.4059043, -21.355633, 5.418207, -7.3817677, -21.328293, 4.8739634, -7.3817677, -21.333632, 5.409023, -7.4059043, -21.355633, 5.418207, -7.4059043, -21.350079, 4.8643517, -7.3817677, -21.328293, 4.8739634, -7.4059043, -21.350079, 4.8643517, -7.3817677, -21.214659, 4.8654194, -7.3817677, -21.328293, 4.8739634, -7.4059043, -21.350079, 4.8643517, -7.4059043, -21.208893, 4.8436327, -7.3817677, -21.214659, 4.8654194, -7.3817677, -21.214659, 4.8654194, -7.357631, -21.090773, 4.8775945, -7.357631, -21.208893, 4.8436327, -7.3817677, -21.214659, 4.8654194, -7.3817677, -21.11427, 4.8825073, -7.357631, -21.090773, 4.8775945, -7.3817677, -21.11427, 4.8825073, -7.357631, -21.088423, 5.4137216, -7.357631, -21.090773, 4.8775945, -7.3817677, -21.11427, 4.8825073, -7.3817677, -21.111706, 5.4083815, -7.357631, -21.088423, 5.4137216, -7.3817677, -21.111706, 5.4083815, -7.357631, -21.219572, 5.463703, -7.357631, -21.088423, 5.4137216, -7.3817677, -21.111706, 5.4083815, -7.3817677, -21.224483, 5.441489, -7.357631, -21.219572, 5.463703, -7.357631, -21.208893, 4.8436327, -7.3817677, -21.067278, 4.8726816, -7.3817677, -21.203339, 4.8216324, -7.357631, -21.208893, 4.8436327, -7.357631, -21.090773, 4.8775945, -7.3817677, -21.067278, 4.8726816, -7.357631, -21.090773, 4.8775945, -7.3817677, -21.064928, 5.4190617, -7.3817677, -21.067278, 4.8726816, -7.357631, -21.090773, 4.8775945, -7.357631, -21.088423, 5.4137216, -7.3817677, -21.064928, 5.4190617, -7.357631, -21.088423, 5.4137216, -7.3817677, -21.214872, 5.485917, -7.3817677, -21.064928, 5.4190617, -7.357631, -21.088423, 5.4137216, -7.357631, -21.219572, 5.463703, -7.3817677, -21.214872, 5.485917, -7.3817677, -21.203339, 4.8216324, -7.4059043, -21.090773, 4.8775945, -7.4059043, -21.208893, 4.8436327, -7.3817677, -21.203339, 4.8216324, -7.3817677, -21.067278, 4.8726816, -7.4059043, -21.090773, 4.8775945, -7.4059043, -21.208893, 4.8436327, -7.3817677, -21.11427, 4.8825073, -7.3817677, -21.214659, 4.8654194, -7.4059043, -21.208893, 4.8436327, -7.4059043, -21.090773, 4.8775945, -7.3817677, -21.11427, 4.8825073, -7.4059043, -21.090773, 4.8775945, -7.3817677, -21.111706, 5.4083815, -7.3817677, -21.11427, 4.8825073, -7.4059043, -21.090773, 4.8775945, -7.4059043, -21.088423, 5.4137216, -7.3817677, -21.111706, 5.4083815, -7.4059043, -21.088423, 5.4137216, -7.3817677, -21.224483, 5.441489, -7.3817677, -21.111706, 5.4083815, -7.4059043, -21.088423, 5.4137216, -7.4059043, -21.219572, 5.463703, -7.3817677, -21.224483, 5.441489, -7.3817677, -21.067278, 4.8726816, -7.4059043, -21.088423, 5.4137216, -7.4059043, -21.090773, 4.8775945, -7.3817677, -21.067278, 4.8726816, -7.3817677, -21.064928, 5.4190617, -7.4059043, -21.088423, 5.4137216, -7.3817677, -21.064928, 5.4190617, -7.4059043, -21.219572, 5.463703, -7.4059043, -21.088423, 5.4137216, -7.3817677, -21.064928, 5.4190617, -7.3817677, -21.214872, 5.485917, -7.4059043, -21.219572, 5.463703, -7.3817677, -21.224483, 5.441489, -7.357631, -21.355633, 5.418207, -7.357631, -21.219572, 5.463703, -7.3817677, -21.224483, 5.441489, -7.3817677, -21.333632, 5.409023, -7.357631, -21.355633, 5.418207, -7.357631, -21.219572, 5.463703, -7.3817677, -21.377846, 5.4271784, -7.3817677, -21.214872, 5.485917, -7.357631, -21.219572, 5.463703, -7.357631, -21.355633, 5.418207, -7.3817677, -21.377846, 5.4271784, -7.3817677, -21.214872, 5.485917, -7.4059043, -21.355633, 5.418207, -7.4059043, -21.219572, 5.463703, -7.3817677, -21.214872, 5.485917, -7.3817677, -21.377846, 5.4271784, -7.4059043, -21.355633, 5.418207, -7.4059043, -21.219572, 5.463703, -7.3817677, -21.333632, 5.409023, -7.3817677, -21.224483, 5.441489, -7.4059043, -21.219572, 5.463703, -7.4059043, -21.355633, 5.418207, -7.3817677, -21.333632, 5.409023, 16.86181, -22.803505, -1.1805243, 12.459326, -22.631578, -0.992887, 16.845665, -22.437832, -1.1752877, 16.86181, -22.803505, -1.1805243, 12.4754715, -22.996815, -0.99855995, 12.459326, -22.631578, -0.992887, 21.372076, -22.244087, -0.9867778, 16.86181, -22.803505, -1.1805243, 16.845665, -22.437832, -1.1752877, 21.372076, -22.244087, -0.9867778, 21.38822, -22.609324, -0.9924512, 16.86181, -22.803505, -1.1805243, 16.86181, -22.78867, -2.160163, 12.4754715, -22.996815, -0.99855995, 16.86181, -22.803505, -1.1805243, 16.86181, -22.78867, -2.160163, 12.4754715, -22.984161, -1.8285255, 12.4754715, -22.996815, -0.99855995, 16.86181, -22.803505, -1.1805243, 21.38822, -22.592306, -2.12569, 16.86181, -22.78867, -2.160163, 16.86181, -22.803505, -1.1805243, 21.38822, -22.601032, -1.5496888, 21.38822, -22.592306, -2.12569, 21.38822, -22.601032, -1.5496888, 16.86181, -22.803505, -1.1805243, 21.38822, -22.609324, -0.9924512, 12.4754715, -22.984161, -1.8285255, 12.459326, -22.631578, -0.992887, 12.4754715, -22.996815, -0.99855995, 12.4754715, -22.984161, -1.8285255, 12.459326, -22.618923, -1.8228531, 12.459326, -22.631578, -0.992887, 21.372076, -22.236668, -1.4776883, 21.20582, -22.351868, -1.5763068, 21.38822, -22.601032, -1.5496888, 16.845665, -22.426924, -1.9096894, 16.849592, -22.514633, -2.155799, 17.977158, -22.374123, -2.1461992, 16.845665, -22.426924, -1.9096894, 15.749081, -22.472305, -2.0715804, 16.849592, -22.514633, -2.155799, 16.845665, -22.426924, -1.9096894, 12.459326, -22.618923, -1.8228531, 15.749081, -22.472305, -2.0715804, 16.845665, -22.426924, -1.9096894, 12.459326, -22.631578, -0.992887, 12.459326, -22.618923, -1.8228531, 12.459326, -22.631578, -0.992887, 16.845665, -22.426924, -1.9096894, 16.845665, -22.437832, -1.1752877, 17.977158, -22.374123, -2.1461992, 16.845665, -22.437832, -1.1752877, 16.845665, -22.426924, -1.9096894, 16.845665, -22.437832, -1.1752877, 21.372076, -22.236668, -1.4776883, 21.372076, -22.244087, -0.9867778, 16.845665, -22.437832, -1.1752877, 20.594036, -22.268959, -1.5780525, 21.372076, -22.236668, -1.4776883, 17.977158, -22.374123, -2.1461992, 20.594036, -22.268959, -1.5780525, 16.845665, -22.437832, -1.1752877, 21.20582, -22.351868, -1.5763068, 21.372076, -22.236668, -1.4776883, 20.594036, -22.268959, -1.5780525, 21.372076, -22.232304, -1.7539072, 21.20582, -22.351868, -1.5763068, 20.594036, -22.268959, -1.5780525, 20.594036, -22.268959, -1.5780525, 17.977158, -22.374123, -2.1461992, 21.372076, -22.232304, -1.7539072, 21.372076, -22.232304, -1.7539072, 17.977158, -22.374123, -2.1461992, 21.37251, -22.227068, -2.1200175, 21.38822, -22.609324, -0.9924512, 21.372076, -22.236668, -1.4776883, 21.38822, -22.601032, -1.5496888, 21.38822, -22.609324, -0.9924512, 21.372076, -22.244087, -0.9867778, 21.372076, -22.236668, -1.4776883, 21.372076, -22.232304, -1.7539072, 21.38822, -22.592306, -2.12569, 21.38822, -22.601032, -1.5496888, 21.372076, -22.232304, -1.7539072, 21.37251, -22.227068, -2.1200175, 21.38822, -22.592306, -2.12569, 21.20582, -22.351868, -1.5763068, 21.372076, -22.232304, -1.7539072, 21.38822, -22.601032, -1.5496888, 21.37251, -22.227068, -2.1200175, 16.86181, -22.78867, -2.160163, 21.38822, -22.592306, -2.12569, 16.86181, -22.78867, -2.160163, 21.37251, -22.227068, -2.1200175, 16.849592, -22.514633, -2.155799, 16.849592, -22.514633, -2.155799, 21.37251, -22.227068, -2.1200175, 17.977158, -22.374123, -2.1461992, 16.849592, -22.514633, -2.155799, 12.459326, -22.618923, -1.8228531, 16.86181, -22.78867, -2.160163, 16.86181, -22.78867, -2.160163, 12.459326, -22.618923, -1.8228531, 12.4754715, -22.984161, -1.8285255, 12.459326, -22.618923, -1.8228531, 16.849592, -22.514633, -2.155799, 15.749081, -22.472305, -2.0715804, 13.651039, -22.54256, -3.436966, 12.76609, -22.946634, -3.462275, 13.666748, -22.907797, -3.4426389, 13.651039, -22.54256, -3.436966, 12.749945, -22.581396, -3.4570384, 12.76609, -22.946634, -3.462275, 13.666748, -22.907797, -3.4426389, 21.08582, -22.31085, -3.4526749, 13.651039, -22.54256, -3.436966, 13.651039, -22.54256, -3.436966, 21.08582, -22.31085, -3.4526749, 19.224287, -22.300377, -3.4474387, 21.08582, -22.31085, -3.4526749, 13.666748, -22.907797, -3.4426389, 21.0976, -22.584887, -3.4566026, 12.749945, -22.596233, -2.4743457, 13.651039, -22.54256, -3.436966, 13.651039, -22.557396, -2.4507813, 19.224287, -22.300377, -3.4474387, 13.651039, -22.557396, -2.4507813, 13.651039, -22.54256, -3.436966, 19.224287, -22.300377, -3.4474387, 21.081892, -22.231869, -2.6214004, 13.651039, -22.557396, -2.4507813, 21.081892, -22.231869, -2.6214004, 19.224287, -22.300377, -3.4474387, 21.081892, -22.222704, -3.2436562, 21.081892, -22.222704, -3.2436562, 19.224287, -22.300377, -3.4474387, 21.08582, -22.31085, -3.4526749, 13.651039, -22.54256, -3.436966, 12.749945, -22.596233, -2.4743457, 13.230383, -22.567432, -2.9914374, 13.230383, -22.567432, -2.9914374, 12.749945, -22.596233, -2.4743457, 12.749945, -22.590124, -2.8701282, 12.749945, -22.590124, -2.8701282, 12.838528, -22.724524, -2.981401, 13.230383, -22.567432, -2.9914374, 12.838528, -22.724524, -2.981401, 12.749945, -22.586197, -3.144165, 13.230383, -22.567432, -2.9914374, 13.651039, -22.54256, -3.436966, 13.230383, -22.567432, -2.9914374, 12.749945, -22.586197, -3.144165, 13.651039, -22.54256, -3.436966, 12.749945, -22.586197, -3.144165, 12.749945, -22.581396, -3.4570384, 13.666748, -22.923069, -2.4560184, 12.749945, -22.596233, -2.4743457, 13.651039, -22.557396, -2.4507813, 13.666748, -22.923069, -2.4560184, 12.76609, -22.96147, -2.4795818, 12.749945, -22.596233, -2.4743457, 21.081892, -22.231869, -2.6214004, 13.666748, -22.923069, -2.4560184, 13.651039, -22.557396, -2.4507813, 21.081892, -22.231869, -2.6214004, 21.0976, -22.597105, -2.6270728, 13.666748, -22.923069, -2.4560184, 12.76609, -22.946634, -3.462275, 13.666748, -22.923069, -2.4560184, 13.666748, -22.907797, -3.4426389, 13.666748, -22.923069, -2.4560184, 12.76609, -22.946634, -3.462275, 12.76609, -22.954924, -2.931219, 13.666748, -22.923069, -2.4560184, 12.76609, -22.954924, -2.931219, 12.76609, -22.96147, -2.4795818, 21.0976, -22.597105, -2.6270728, 13.666748, -22.907797, -3.4426389, 13.666748, -22.923069, -2.4560184, 21.0976, -22.597105, -2.6270728, 21.0976, -22.584887, -3.4566026, 13.666748, -22.907797, -3.4426389, 12.749945, -22.586197, -3.144165, 12.838528, -22.724524, -2.981401, 12.76609, -22.954924, -2.931219, 12.838528, -22.724524, -2.981401, 12.749945, -22.590124, -2.8701282, 12.76609, -22.954924, -2.931219, 12.76609, -22.946634, -3.462275, 12.749945, -22.586197, -3.144165, 12.76609, -22.954924, -2.931219, 12.76609, -22.946634, -3.462275, 12.749945, -22.581396, -3.4570384, 12.749945, -22.586197, -3.144165, 12.749945, -22.590124, -2.8701282, 12.76609, -22.96147, -2.4795818, 12.76609, -22.954924, -2.931219, 12.749945, -22.590124, -2.8701282, 12.749945, -22.596233, -2.4743457, 12.76609, -22.96147, -2.4795818, 21.081892, -22.231869, -2.6214004, 21.0976, -22.584887, -3.4566026, 21.0976, -22.597105, -2.6270728, 21.0976, -22.584887, -3.4566026, 21.081892, -22.231869, -2.6214004, 21.08582, -22.31085, -3.4526749, 21.08582, -22.31085, -3.4526749, 21.081892, -22.231869, -2.6214004, 21.081892, -22.222704, -3.2436562, 16.86661, -22.74067, -5.2888975, 12.750381, -22.556524, -5.1012607, 16.850464, -22.375433, -5.2836614, 16.86661, -22.74067, -5.2888975, 12.76609, -22.92176, -5.1069336, 12.750381, -22.556524, -5.1012607, 21.081892, -22.194342, -5.0951514, 16.86661, -22.74067, -5.2888975, 16.850464, -22.375433, -5.2836614, 21.081892, -22.194342, -5.0951514, 21.0976, -22.559578, -5.100825, 16.86661, -22.74067, -5.2888975, 16.86661, -22.725834, -6.2681003, 12.76609, -22.92176, -5.1069336, 16.86661, -22.74067, -5.2888975, 16.86661, -22.725834, -6.2681003, 12.76609, -22.909105, -5.936463, 12.76609, -22.92176, -5.1069336, 16.86661, -22.74067, -5.2888975, 21.0976, -22.54256, -6.2344995, 16.86661, -22.725834, -6.2681003, 16.86661, -22.74067, -5.2888975, 21.0976, -22.551287, -5.658062, 21.0976, -22.54256, -6.2344995, 21.0976, -22.551287, -5.658062, 16.86661, -22.74067, -5.2888975, 21.0976, -22.559578, -5.100825, 12.76609, -22.909105, -5.936463, 12.750381, -22.556524, -5.1012607, 12.76609, -22.92176, -5.1069336, 12.76609, -22.909105, -5.936463, 12.750381, -22.543869, -5.93079, 12.750381, -22.556524, -5.1012607, 21.081892, -22.186922, -5.5856256, 20.926546, -22.301687, -5.6846805, 21.0976, -22.551287, -5.658062, 16.850464, -22.364523, -6.018063, 16.854391, -22.451796, -6.2637362, 17.908213, -22.314777, -6.2541366, 16.850464, -22.364523, -6.018063, 15.825443, -22.406414, -6.179518, 16.854391, -22.451796, -6.2637362, 16.850464, -22.364523, -6.018063, 12.750381, -22.543869, -5.93079, 15.825443, -22.406414, -6.179518, 16.850464, -22.364523, -6.018063, 12.750381, -22.556524, -5.1012607, 12.750381, -22.543869, -5.93079, 12.750381, -22.556524, -5.1012607, 16.850464, -22.364523, -6.018063, 16.850464, -22.375433, -5.2836614, 17.908213, -22.314777, -6.2541366, 16.850464, -22.375433, -5.2836614, 16.850464, -22.364523, -6.018063, 16.850464, -22.375433, -5.2836614, 21.081892, -22.186922, -5.5856256, 21.081892, -22.194342, -5.0951514, 16.850464, -22.375433, -5.2836614, 20.354473, -22.217031, -5.6864257, 21.081892, -22.186922, -5.5856256, 17.908213, -22.314777, -6.2541366, 20.354473, -22.217031, -5.6864257, 16.850464, -22.375433, -5.2836614, 20.926546, -22.301687, -5.6846805, 21.081892, -22.186922, -5.5856256, 20.354473, -22.217031, -5.6864257, 21.081892, -22.182995, -5.862281, 20.926546, -22.301687, -5.6846805, 20.354473, -22.217031, -5.6864257, 20.354473, -22.217031, -5.6864257, 17.908213, -22.314777, -6.2541366, 21.081892, -22.182995, -5.862281, 21.081892, -22.182995, -5.862281, 17.908213, -22.314777, -6.2541366, 21.081892, -22.177322, -6.228827, 21.0976, -22.559578, -5.100825, 21.081892, -22.186922, -5.5856256, 21.0976, -22.551287, -5.658062, 21.0976, -22.559578, -5.100825, 21.081892, -22.194342, -5.0951514, 21.081892, -22.186922, -5.5856256, 21.081892, -22.182995, -5.862281, 21.0976, -22.54256, -6.2344995, 21.0976, -22.551287, -5.658062, 21.081892, -22.182995, -5.862281, 21.081892, -22.177322, -6.228827, 21.0976, -22.54256, -6.2344995, 20.926546, -22.301687, -5.6846805, 21.081892, -22.182995, -5.862281, 21.0976, -22.551287, -5.658062, 21.081892, -22.177322, -6.228827, 16.86661, -22.725834, -6.2681003, 21.0976, -22.54256, -6.2344995, 16.86661, -22.725834, -6.2681003, 21.081892, -22.177322, -6.228827, 16.854391, -22.451796, -6.2637362, 16.854391, -22.451796, -6.2637362, 21.081892, -22.177322, -6.228827, 17.908213, -22.314777, -6.2541366, 16.854391, -22.451796, -6.2637362, 12.750381, -22.543869, -5.93079, 16.86661, -22.725834, -6.2681003, 16.86661, -22.725834, -6.2681003, 12.750381, -22.543869, -5.93079, 12.76609, -22.909105, -5.936463, 12.750381, -22.543869, -5.93079, 16.854391, -22.451796, -6.2637362, 15.825443, -22.406414, -6.179518, 19.724798, -22.63725, -3.9361672, 12.459763, -22.58925, -3.7760215, 19.70909, -22.271578, -3.9304943, 19.724798, -22.63725, -3.9361672, 12.4754715, -22.954489, -3.781694, 12.459763, -22.58925, -3.7760215, 21.37251, -22.199577, -3.9226394, 19.724798, -22.63725, -3.9361672, 19.70909, -22.271578, -3.9304943, 21.37251, -22.199577, -3.9226394, 21.38822, -22.564814, -3.9283128, 19.724798, -22.63725, -3.9361672, 19.724798, -22.621979, -4.944606, 12.4754715, -22.954489, -3.781694, 19.724798, -22.63725, -3.9361672, 19.724798, -22.621979, -4.944606, 12.4754715, -22.939651, -4.764387, 12.4754715, -22.954489, -3.781694, 21.38822, -22.564814, -3.9283128, 19.724798, -22.621979, -4.944606, 19.724798, -22.63725, -3.9361672, 21.38822, -22.564814, -3.9283128, 21.38822, -22.55216, -4.7578416, 19.724798, -22.621979, -4.944606, 21.38822, -22.564814, -3.9283128, 21.37251, -22.186922, -4.752169, 21.38822, -22.55216, -4.7578416, 21.38822, -22.564814, -3.9283128, 21.37251, -22.199577, -3.9226394, 21.37251, -22.186922, -4.752169, 19.70909, -22.260231, -4.6867146, 19.713017, -22.34794, -4.9402423, 20.124945, -22.239286, -4.8926787, 19.70909, -22.260231, -4.6867146, 17.896868, -22.335724, -4.8939877, 19.713017, -22.34794, -4.9402423, 19.70909, -22.260231, -4.6867146, 13.819038, -22.514633, -4.792751, 17.896868, -22.335724, -4.8939877, 20.124945, -22.239286, -4.8926787, 19.70909, -22.271578, -3.9304943, 19.70909, -22.260231, -4.6867146, 20.124945, -22.239286, -4.8926787, 21.37251, -22.199577, -3.9226394, 19.70909, -22.271578, -3.9304943, 21.37251, -22.199577, -3.9226394, 20.124945, -22.239286, -4.8926787, 21.37251, -22.186922, -4.752169, 12.459763, -22.58925, -3.7760215, 19.70909, -22.260231, -4.6867146, 19.70909, -22.271578, -3.9304943, 19.70909, -22.260231, -4.6867146, 12.459763, -22.58925, -3.7760215, 13.819038, -22.514633, -4.792751, 13.819038, -22.514633, -4.792751, 12.459763, -22.58925, -3.7760215, 12.459763, -22.577906, -4.513041, 13.819038, -22.514633, -4.792751, 12.459763, -22.577906, -4.513041, 12.46369, -22.665615, -4.7600236, 21.37251, -22.186922, -4.752169, 19.724798, -22.621979, -4.944606, 21.38822, -22.55216, -4.7578416, 19.724798, -22.621979, -4.944606, 21.37251, -22.186922, -4.752169, 19.713017, -22.34794, -4.9402423, 19.713017, -22.34794, -4.9402423, 21.37251, -22.186922, -4.752169, 20.124945, -22.239286, -4.8926787, 19.713017, -22.34794, -4.9402423, 12.46369, -22.665615, -4.7600236, 19.724798, -22.621979, -4.944606, 19.724798, -22.621979, -4.944606, 12.46369, -22.665615, -4.7600236, 12.4754715, -22.939651, -4.764387, 12.46369, -22.665615, -4.7600236, 19.713017, -22.34794, -4.9402423, 13.819038, -22.514633, -4.792751, 13.819038, -22.514633, -4.792751, 19.713017, -22.34794, -4.9402423, 17.896868, -22.335724, -4.8939877, 12.46369, -22.665615, -4.7600236, 12.4754715, -22.954489, -3.781694, 12.4754715, -22.939651, -4.764387, 12.4754715, -22.954489, -3.781694, 12.46369, -22.665615, -4.7600236, 12.459763, -22.58925, -3.7760215, 12.459763, -22.58925, -3.7760215, 12.46369, -22.665615, -4.7600236, 12.459763, -22.577906, -4.513041, 16.95781, -23.00336, -0.79565, 21.06182, -22.63725, -0.9811053, 16.95781, -22.63725, -0.79565, 16.95781, -23.00336, -0.79565, 21.06182, -23.00336, -0.9811053, 21.06182, -22.63725, -0.9811053, 12.722454, -22.63725, -0.9811053, 16.95781, -23.00336, -0.79565, 16.95781, -22.63725, -0.79565, 12.722454, -22.63725, -0.9811053, 12.722454, -23.00336, -0.9811053, 16.95781, -23.00336, -0.79565, 16.95781, -23.00336, 0.18311548, 21.06182, -23.00336, -0.9811053, 16.95781, -23.00336, -0.79565, 16.95781, -23.00336, 0.18311548, 21.06182, -23.00336, -0.15113974, 21.06182, -23.00336, -0.9811053, 16.95781, -23.00336, -0.79565, 12.722454, -23.00336, 0.15257025, 16.95781, -23.00336, 0.18311548, 16.95781, -23.00336, -0.79565, 12.722454, -23.00336, -0.4238677, 12.722454, -23.00336, 0.15257025, 12.722454, -23.00336, -0.4238677, 16.95781, -23.00336, -0.79565, 12.722454, -23.00336, -0.9811053, 21.06182, -23.00336, -0.15113974, 21.06182, -22.63725, -0.9811053, 21.06182, -23.00336, -0.9811053, 21.06182, -23.00336, -0.15113974, 21.06182, -22.63725, -0.15113974, 21.06182, -22.63725, -0.9811053, 12.722454, -22.63725, -0.49063158, 12.882601, -22.746778, -0.39288568, 12.722454, -23.00336, -0.4238677, 16.95781, -22.63725, -0.06124878, 16.95781, -22.728888, 0.18311548, 15.899189, -22.63725, 0.17569733, 16.95781, -22.63725, -0.06124878, 17.983704, -22.63725, 0.09977007, 16.95781, -22.728888, 0.18311548, 16.95781, -22.63725, -0.06124878, 21.06182, -22.63725, -0.15113974, 17.983704, -22.63725, 0.09977007, 16.95781, -22.63725, -0.06124878, 21.06182, -22.63725, -0.9811053, 21.06182, -22.63725, -0.15113974, 21.06182, -22.63725, -0.9811053, 16.95781, -22.63725, -0.06124878, 16.95781, -22.63725, -0.79565, 15.899189, -22.63725, 0.17569733, 16.95781, -22.63725, -0.79565, 16.95781, -22.63725, -0.06124878, 16.95781, -22.63725, -0.79565, 12.722454, -22.63725, -0.49063158, 12.722454, -22.63725, -0.9811053, 16.95781, -22.63725, -0.79565, 13.450312, -22.63725, -0.39070415, 12.722454, -22.63725, -0.49063158, 15.899189, -22.63725, 0.17569733, 13.450312, -22.63725, -0.39070415, 16.95781, -22.63725, -0.79565, 12.882601, -22.746778, -0.39288568, 12.722454, -22.63725, -0.49063158, 13.450312, -22.63725, -0.39070415, 12.722454, -22.63725, -0.21441269, 12.882601, -22.746778, -0.39288568, 13.450312, -22.63725, -0.39070415, 13.450312, -22.63725, -0.39070415, 15.899189, -22.63725, 0.17569733, 12.722454, -22.63725, -0.21441269, 12.722454, -22.63725, -0.21441269, 15.899189, -22.63725, 0.17569733, 12.722454, -22.63725, 0.15257025, 12.722454, -23.00336, -0.9811053, 12.722454, -22.63725, -0.49063158, 12.722454, -23.00336, -0.4238677, 12.722454, -23.00336, -0.9811053, 12.722454, -22.63725, -0.9811053, 12.722454, -22.63725, -0.49063158, 12.722454, -22.63725, -0.21441269, 12.722454, -23.00336, 0.15257025, 12.722454, -23.00336, -0.4238677, 12.722454, -22.63725, -0.21441269, 12.722454, -22.63725, 0.15257025, 12.722454, -23.00336, 0.15257025, 12.882601, -22.746778, -0.39288568, 12.722454, -22.63725, -0.21441269, 12.722454, -23.00336, -0.4238677, 12.722454, -22.63725, 0.15257025, 16.95781, -23.00336, 0.18311548, 12.722454, -23.00336, 0.15257025, 16.95781, -23.00336, 0.18311548, 12.722454, -22.63725, 0.15257025, 15.899189, -22.63725, 0.17569733, 16.95781, -23.00336, 0.18311548, 15.899189, -22.63725, 0.17569733, 16.95781, -22.728888, 0.18311548, 16.95781, -22.728888, 0.18311548, 21.06182, -23.00336, -0.15113974, 16.95781, -23.00336, 0.18311548, 16.95781, -22.728888, 0.18311548, 21.06182, -22.63725, -0.15113974, 21.06182, -23.00336, -0.15113974, 21.06182, -22.63725, -0.15113974, 16.95781, -22.728888, 0.18311548, 17.983704, -22.63725, 0.09977007, 20.16029, -22.63725, 2.5866122, 21.06182, -23.00336, 2.6058125, 20.16029, -23.00336, 2.5866122, 20.16029, -22.63725, 2.5866122, 21.06182, -22.63725, 2.6058125, 21.06182, -23.00336, 2.6058125, 20.16029, -23.00336, 2.5866122, 14.582241, -22.63725, 2.6010118, 20.16029, -22.63725, 2.5866122, 20.16029, -23.00336, 2.5866122, 12.722454, -22.728888, 2.6058125, 14.582241, -22.63725, 2.6010118, 12.722454, -22.728888, 2.6058125, 20.16029, -23.00336, 2.5866122, 12.722454, -23.00336, 2.6058125, 21.06182, -22.63725, 1.6231189, 20.16029, -22.63725, 2.5866122, 20.16029, -22.63725, 1.6004281, 14.582241, -22.63725, 2.6010118, 20.16029, -22.63725, 1.6004281, 20.16029, -22.63725, 2.5866122, 14.582241, -22.63725, 2.6010118, 12.722454, -22.63725, 1.7762828, 20.16029, -22.63725, 1.6004281, 12.722454, -22.63725, 1.7762828, 14.582241, -22.63725, 2.6010118, 12.722454, -22.63725, 2.398975, 12.722454, -22.63725, 2.398975, 14.582241, -22.63725, 2.6010118, 12.722454, -22.728888, 2.6058125, 20.16029, -22.63725, 2.5866122, 21.06182, -22.63725, 1.6231189, 20.581383, -22.63725, 2.1410842, 20.581383, -22.63725, 2.1410842, 21.06182, -22.63725, 1.6231189, 21.06182, -22.63725, 2.0193381, 21.06182, -22.63725, 2.0193381, 20.979784, -22.776888, 2.128429, 20.581383, -22.63725, 2.1410842, 20.979784, -22.776888, 2.128429, 21.06182, -22.63725, 2.2933755, 20.581383, -22.63725, 2.1410842, 20.16029, -22.63725, 2.5866122, 20.581383, -22.63725, 2.1410842, 21.06182, -22.63725, 2.2933755, 20.16029, -22.63725, 2.5866122, 21.06182, -22.63725, 2.2933755, 21.06182, -22.63725, 2.6058125, 20.16029, -23.00336, 1.6004281, 21.06182, -22.63725, 1.6231189, 20.16029, -22.63725, 1.6004281, 20.16029, -23.00336, 1.6004281, 21.06182, -23.00336, 1.6231189, 21.06182, -22.63725, 1.6231189, 12.722454, -22.63725, 1.7762828, 20.16029, -23.00336, 1.6004281, 20.16029, -22.63725, 1.6004281, 12.722454, -22.63725, 1.7762828, 12.722454, -23.00336, 1.7762828, 20.16029, -23.00336, 1.6004281, 21.06182, -23.00336, 2.6058125, 20.16029, -23.00336, 1.6004281, 20.16029, -23.00336, 2.5866122, 20.16029, -23.00336, 1.6004281, 21.06182, -23.00336, 2.6058125, 21.06182, -23.00336, 2.0747561, 20.16029, -23.00336, 1.6004281, 21.06182, -23.00336, 2.0747561, 21.06182, -23.00336, 1.6231189, 12.722454, -23.00336, 1.7762828, 20.16029, -23.00336, 2.5866122, 20.16029, -23.00336, 1.6004281, 12.722454, -23.00336, 1.7762828, 12.722454, -23.00336, 2.6058125, 20.16029, -23.00336, 2.5866122, 21.06182, -22.63725, 2.2933755, 20.979784, -22.776888, 2.128429, 21.06182, -23.00336, 2.0747561, 20.979784, -22.776888, 2.128429, 21.06182, -22.63725, 2.0193381, 21.06182, -23.00336, 2.0747561, 21.06182, -23.00336, 2.6058125, 21.06182, -22.63725, 2.2933755, 21.06182, -23.00336, 2.0747561, 21.06182, -23.00336, 2.6058125, 21.06182, -22.63725, 2.6058125, 21.06182, -22.63725, 2.2933755, 21.06182, -22.63725, 2.0193381, 21.06182, -23.00336, 1.6231189, 21.06182, -23.00336, 2.0747561, 21.06182, -22.63725, 2.0193381, 21.06182, -22.63725, 1.6231189, 21.06182, -23.00336, 1.6231189, 12.722454, -22.63725, 1.7762828, 12.722454, -23.00336, 2.6058125, 12.722454, -23.00336, 1.7762828, 12.722454, -23.00336, 2.6058125, 12.722454, -22.63725, 1.7762828, 12.722454, -22.63725, 2.398975, 12.722454, -23.00336, 2.6058125, 12.722454, -22.63725, 2.398975, 12.722454, -22.728888, 2.6058125, 20.38851, -22.63725, 3.7669787, 21.352875, -23.00336, 3.786178, 20.38851, -23.00336, 3.7669787, 20.38851, -22.63725, 3.7669787, 21.352875, -22.63725, 3.786178, 21.352875, -23.00336, 3.786178, 20.38851, -23.00336, 3.7669787, 14.420786, -22.63725, 3.7813792, 20.38851, -22.63725, 3.7669787, 20.38851, -23.00336, 3.7669787, 12.431835, -22.728888, 3.786178, 14.420786, -22.63725, 3.7813792, 12.431835, -22.728888, 3.786178, 20.38851, -23.00336, 3.7669787, 12.431835, -23.00336, 3.786178, 21.352875, -22.63725, 2.8034854, 20.38851, -22.63725, 3.7669787, 20.38851, -22.63725, 2.7803578, 14.420786, -22.63725, 3.7813792, 20.38851, -22.63725, 2.7803578, 20.38851, -22.63725, 3.7669787, 14.420786, -22.63725, 3.7813792, 12.431835, -22.63725, 2.9562135, 20.38851, -22.63725, 2.7803578, 12.431835, -22.63725, 2.9562135, 14.420786, -22.63725, 3.7813792, 12.431835, -22.63725, 3.5784698, 12.431835, -22.63725, 3.5784698, 14.420786, -22.63725, 3.7813792, 12.431835, -22.728888, 3.786178, 20.38851, -22.63725, 3.7669787, 21.352875, -22.63725, 2.8034854, 20.838837, -22.63725, 3.321015, 20.838837, -22.63725, 3.321015, 21.352875, -22.63725, 2.8034854, 21.352875, -22.63725, 3.1997046, 21.352875, -22.63725, 3.1997046, 21.264729, -22.776888, 3.3083596, 20.838837, -22.63725, 3.321015, 21.264729, -22.776888, 3.3083596, 21.352875, -22.63725, 3.4733052, 20.838837, -22.63725, 3.321015, 20.38851, -22.63725, 3.7669787, 20.838837, -22.63725, 3.321015, 21.352875, -22.63725, 3.4733052, 20.38851, -22.63725, 3.7669787, 21.352875, -22.63725, 3.4733052, 21.352875, -22.63725, 3.786178, 20.38851, -23.00336, 2.7803578, 21.352875, -22.63725, 2.8034854, 20.38851, -22.63725, 2.7803578, 20.38851, -23.00336, 2.7803578, 21.352875, -23.00336, 2.8034854, 21.352875, -22.63725, 2.8034854, 12.431835, -22.63725, 2.9562135, 20.38851, -23.00336, 2.7803578, 20.38851, -22.63725, 2.7803578, 12.431835, -22.63725, 2.9562135, 12.431835, -23.00336, 2.9562135, 20.38851, -23.00336, 2.7803578, 21.352875, -23.00336, 3.786178, 20.38851, -23.00336, 2.7803578, 20.38851, -23.00336, 3.7669787, 20.38851, -23.00336, 2.7803578, 21.352875, -23.00336, 3.786178, 21.352875, -23.00336, 3.2546868, 20.38851, -23.00336, 2.7803578, 21.352875, -23.00336, 3.2546868, 21.352875, -23.00336, 2.8034854, 12.431835, -23.00336, 2.9562135, 20.38851, -23.00336, 3.7669787, 20.38851, -23.00336, 2.7803578, 12.431835, -23.00336, 2.9562135, 12.431835, -23.00336, 3.786178, 20.38851, -23.00336, 3.7669787, 21.352875, -22.63725, 3.4733052, 21.264729, -22.776888, 3.3083596, 21.352875, -23.00336, 3.2546868, 21.264729, -22.776888, 3.3083596, 21.352875, -22.63725, 3.1997046, 21.352875, -23.00336, 3.2546868, 21.352875, -23.00336, 3.786178, 21.352875, -22.63725, 3.4733052, 21.352875, -23.00336, 3.2546868, 21.352875, -23.00336, 3.786178, 21.352875, -22.63725, 3.786178, 21.352875, -22.63725, 3.4733052, 21.352875, -22.63725, 3.1997046, 21.352875, -23.00336, 2.8034854, 21.352875, -23.00336, 3.2546868, 21.352875, -22.63725, 3.1997046, 21.352875, -22.63725, 2.8034854, 21.352875, -23.00336, 2.8034854, 12.431835, -22.63725, 2.9562135, 12.431835, -23.00336, 3.786178, 12.431835, -23.00336, 2.9562135, 12.431835, -23.00336, 3.786178, 12.431835, -22.63725, 2.9562135, 12.431835, -22.63725, 3.5784698, 12.431835, -23.00336, 3.786178, 12.431835, -22.63725, 3.5784698, 12.431835, -22.728888, 3.786178, 14.157221, -23.00336, 0.4183159, 21.256002, -22.63725, 0.25860643, 14.157221, -22.63725, 0.4183159, 14.157221, -23.00336, 0.4183159, 21.256002, -23.00336, 0.25860643, 21.256002, -22.63725, 0.25860643, 12.528709, -22.63725, 0.41177034, 14.157221, -23.00336, 0.4183159, 14.157221, -22.63725, 0.4183159, 12.528709, -22.63725, 0.41177034, 12.528709, -23.00336, 0.41177034, 14.157221, -23.00336, 0.4183159, 14.157221, -23.00336, 1.4267545, 21.256002, -23.00336, 0.25860643, 14.157221, -23.00336, 0.4183159, 14.157221, -23.00336, 1.4267545, 21.256002, -23.00336, 1.2413001, 21.256002, -23.00336, 0.25860643, 12.528709, -23.00336, 0.41177034, 14.157221, -23.00336, 1.4267545, 14.157221, -23.00336, 0.4183159, 12.528709, -23.00336, 0.41177034, 12.528709, -23.00336, 1.2413001, 14.157221, -23.00336, 1.4267545, 12.528709, -23.00336, 0.41177034, 12.528709, -22.63725, 1.2413001, 12.528709, -23.00336, 1.2413001, 12.528709, -23.00336, 0.41177034, 12.528709, -22.63725, 0.41177034, 12.528709, -22.63725, 1.2413001, 14.157221, -22.63725, 1.1745362, 14.157221, -22.728888, 1.4267545, 13.750093, -22.63725, 1.3805003, 14.157221, -22.63725, 1.1745362, 15.931917, -22.63725, 1.3805003, 14.157221, -22.728888, 1.4267545, 14.157221, -22.63725, 1.1745362, 19.925089, -22.63725, 1.2762094, 15.931917, -22.63725, 1.3805003, 13.750093, -22.63725, 1.3805003, 14.157221, -22.63725, 0.4183159, 14.157221, -22.63725, 1.1745362, 13.750093, -22.63725, 1.3805003, 12.528709, -22.63725, 0.41177034, 14.157221, -22.63725, 0.4183159, 12.528709, -22.63725, 0.41177034, 13.750093, -22.63725, 1.3805003, 12.528709, -22.63725, 1.2413001, 21.256002, -22.63725, 0.25860643, 14.157221, -22.63725, 1.1745362, 14.157221, -22.63725, 0.4183159, 14.157221, -22.63725, 1.1745362, 21.256002, -22.63725, 0.25860643, 19.925089, -22.63725, 1.2762094, 19.925089, -22.63725, 1.2762094, 21.256002, -22.63725, 0.25860643, 21.256002, -22.63725, 0.99606276, 19.925089, -22.63725, 1.2762094, 21.256002, -22.63725, 0.99606276, 21.256002, -22.728888, 1.2413001, 12.528709, -22.63725, 1.2413001, 14.157221, -23.00336, 1.4267545, 12.528709, -23.00336, 1.2413001, 14.157221, -23.00336, 1.4267545, 12.528709, -22.63725, 1.2413001, 13.750093, -22.63725, 1.3805003, 14.157221, -23.00336, 1.4267545, 13.750093, -22.63725, 1.3805003, 14.157221, -22.728888, 1.4267545, 14.157221, -22.728888, 1.4267545, 21.256002, -23.00336, 1.2413001, 14.157221, -23.00336, 1.4267545, 14.157221, -22.728888, 1.4267545, 19.925089, -22.63725, 1.2762094, 21.256002, -23.00336, 1.2413001, 21.256002, -23.00336, 1.2413001, 19.925089, -22.63725, 1.2762094, 21.256002, -22.728888, 1.2413001, 19.925089, -22.63725, 1.2762094, 14.157221, -22.728888, 1.4267545, 15.931917, -22.63725, 1.3805003, 21.256002, -22.728888, 1.2413001, 21.256002, -23.00336, 0.25860643, 21.256002, -23.00336, 1.2413001, 21.256002, -23.00336, 0.25860643, 21.256002, -22.728888, 1.2413001, 21.256002, -22.63725, 0.99606276, 21.256002, -23.00336, 0.25860643, 21.256002, -22.63725, 0.99606276, 21.256002, -22.63725, 0.25860643, 17.195192, -22.439577, -16.726889, 21.299639, -22.073904, -16.912344, 17.195192, -22.073904, -16.726889, 17.195192, -22.439577, -16.726889, 21.299639, -22.439577, -16.912344, 21.299639, -22.073904, -16.912344, 12.960274, -22.073904, -16.912344, 17.195192, -22.439577, -16.726889, 17.195192, -22.073904, -16.726889, 12.960274, -22.073904, -16.912344, 12.960274, -22.439577, -16.912344, 17.195192, -22.439577, -16.726889, 17.195192, -22.439577, -15.748123, 21.299639, -22.439577, -16.912344, 17.195192, -22.439577, -16.726889, 17.195192, -22.439577, -15.748123, 21.299639, -22.439577, -16.082378, 21.299639, -22.439577, -16.912344, 17.195192, -22.439577, -16.726889, 12.960274, -22.439577, -15.779104, 17.195192, -22.439577, -15.748123, 17.195192, -22.439577, -16.726889, 12.960274, -22.439577, -16.355106, 12.960274, -22.439577, -15.779104, 12.960274, -22.439577, -16.355106, 17.195192, -22.439577, -16.726889, 12.960274, -22.439577, -16.912344, 21.299639, -22.439577, -16.082378, 21.299639, -22.073904, -16.912344, 21.299639, -22.439577, -16.912344, 21.299639, -22.439577, -16.082378, 21.299639, -22.073904, -16.082378, 21.299639, -22.073904, -16.912344, 12.960274, -22.073904, -16.422306, 13.119982, -22.182995, -16.32456, 12.960274, -22.439577, -16.355106, 17.195192, -22.073904, -15.992487, 17.195192, -22.165104, -15.748123, 16.136572, -22.073904, -15.755539, 17.195192, -22.073904, -15.992487, 18.221523, -22.073904, -15.831467, 17.195192, -22.165104, -15.748123, 17.195192, -22.073904, -15.992487, 21.299639, -22.073904, -16.082378, 18.221523, -22.073904, -15.831467, 17.195192, -22.073904, -15.992487, 21.299639, -22.073904, -16.912344, 21.299639, -22.073904, -16.082378, 21.299639, -22.073904, -16.912344, 17.195192, -22.073904, -15.992487, 17.195192, -22.073904, -16.726889, 16.136572, -22.073904, -15.755539, 17.195192, -22.073904, -16.726889, 17.195192, -22.073904, -15.992487, 17.195192, -22.073904, -16.726889, 12.960274, -22.073904, -16.422306, 12.960274, -22.073904, -16.912344, 17.195192, -22.073904, -16.726889, 13.688129, -22.073904, -16.321941, 12.960274, -22.073904, -16.422306, 16.136572, -22.073904, -15.755539, 13.688129, -22.073904, -16.321941, 17.195192, -22.073904, -16.726889, 13.119982, -22.182995, -16.32456, 12.960274, -22.073904, -16.422306, 13.688129, -22.073904, -16.321941, 12.960274, -22.073904, -16.14565, 13.119982, -22.182995, -16.32456, 13.688129, -22.073904, -16.321941, 13.688129, -22.073904, -16.321941, 16.136572, -22.073904, -15.755539, 12.960274, -22.073904, -16.14565, 12.960274, -22.073904, -16.14565, 16.136572, -22.073904, -15.755539, 12.960274, -22.073904, -15.779104, 12.960274, -22.439577, -16.912344, 12.960274, -22.073904, -16.422306, 12.960274, -22.439577, -16.355106, 12.960274, -22.439577, -16.912344, 12.960274, -22.073904, -16.912344, 12.960274, -22.073904, -16.422306, 12.960274, -22.073904, -16.14565, 12.960274, -22.439577, -15.779104, 12.960274, -22.439577, -16.355106, 12.960274, -22.073904, -16.14565, 12.960274, -22.073904, -15.779104, 12.960274, -22.439577, -15.779104, 13.119982, -22.182995, -16.32456, 12.960274, -22.073904, -16.14565, 12.960274, -22.439577, -16.355106, 12.960274, -22.073904, -15.779104, 17.195192, -22.439577, -15.748123, 12.960274, -22.439577, -15.779104, 17.195192, -22.439577, -15.748123, 12.960274, -22.073904, -15.779104, 16.136572, -22.073904, -15.755539, 17.195192, -22.439577, -15.748123, 16.136572, -22.073904, -15.755539, 17.195192, -22.165104, -15.748123, 17.195192, -22.165104, -15.748123, 21.299639, -22.439577, -16.082378, 17.195192, -22.439577, -15.748123, 17.195192, -22.165104, -15.748123, 21.299639, -22.073904, -16.082378, 21.299639, -22.439577, -16.082378, 21.299639, -22.073904, -16.082378, 17.195192, -22.165104, -15.748123, 18.221523, -22.073904, -15.831467, 20.39811, -22.073904, -13.344625, 21.299639, -22.439577, -13.325426, 20.39811, -22.439577, -13.344625, 20.39811, -22.073904, -13.344625, 21.299639, -22.073904, -13.325426, 21.299639, -22.439577, -13.325426, 20.39811, -22.439577, -13.344625, 14.819624, -22.073904, -13.330225, 20.39811, -22.073904, -13.344625, 20.39811, -22.439577, -13.344625, 12.960274, -22.165104, -13.325426, 14.819624, -22.073904, -13.330225, 12.960274, -22.165104, -13.325426, 20.39811, -22.439577, -13.344625, 12.960274, -22.439577, -13.325426, 21.299639, -22.073904, -14.308119, 20.39811, -22.073904, -13.344625, 20.39811, -22.073904, -14.331245, 14.819624, -22.073904, -13.330225, 20.39811, -22.073904, -14.331245, 20.39811, -22.073904, -13.344625, 14.819624, -22.073904, -13.330225, 12.960274, -22.073904, -14.154955, 20.39811, -22.073904, -14.331245, 12.960274, -22.073904, -14.154955, 14.819624, -22.073904, -13.330225, 12.960274, -22.073904, -13.5327, 12.960274, -22.073904, -13.5327, 14.819624, -22.073904, -13.330225, 12.960274, -22.165104, -13.325426, 20.39811, -22.073904, -13.344625, 21.299639, -22.073904, -14.308119, 20.818766, -22.073904, -13.7901535, 20.818766, -22.073904, -13.7901535, 21.299639, -22.073904, -14.308119, 21.299639, -22.073904, -13.9119, 21.299639, -22.073904, -13.9119, 21.217165, -22.213541, -13.803246, 20.818766, -22.073904, -13.7901535, 21.217165, -22.213541, -13.803246, 21.299639, -22.073904, -13.6383, 20.818766, -22.073904, -13.7901535, 20.39811, -22.073904, -13.344625, 20.818766, -22.073904, -13.7901535, 21.299639, -22.073904, -13.6383, 20.39811, -22.073904, -13.344625, 21.299639, -22.073904, -13.6383, 21.299639, -22.073904, -13.325426, 20.39811, -22.439577, -14.331245, 21.299639, -22.073904, -14.308119, 20.39811, -22.073904, -14.331245, 20.39811, -22.439577, -14.331245, 21.299639, -22.439577, -14.308119, 21.299639, -22.073904, -14.308119, 12.960274, -22.073904, -14.154955, 20.39811, -22.439577, -14.331245, 20.39811, -22.073904, -14.331245, 12.960274, -22.073904, -14.154955, 12.960274, -22.439577, -14.154955, 20.39811, -22.439577, -14.331245, 21.299639, -22.439577, -13.325426, 20.39811, -22.439577, -14.331245, 20.39811, -22.439577, -13.344625, 20.39811, -22.439577, -14.331245, 21.299639, -22.439577, -13.325426, 21.299639, -22.439577, -13.856482, 20.39811, -22.439577, -14.331245, 21.299639, -22.439577, -13.856482, 21.299639, -22.439577, -14.308119, 12.960274, -22.439577, -14.154955, 20.39811, -22.439577, -13.344625, 20.39811, -22.439577, -14.331245, 12.960274, -22.439577, -14.154955, 12.960274, -22.439577, -13.325426, 20.39811, -22.439577, -13.344625, 21.299639, -22.073904, -13.6383, 21.217165, -22.213541, -13.803246, 21.299639, -22.439577, -13.856482, 21.217165, -22.213541, -13.803246, 21.299639, -22.073904, -13.9119, 21.299639, -22.439577, -13.856482, 21.299639, -22.439577, -13.325426, 21.299639, -22.073904, -13.6383, 21.299639, -22.439577, -13.856482, 21.299639, -22.439577, -13.325426, 21.299639, -22.073904, -13.325426, 21.299639, -22.073904, -13.6383, 21.299639, -22.073904, -13.9119, 21.299639, -22.439577, -14.308119, 21.299639, -22.439577, -13.856482, 21.299639, -22.073904, -13.9119, 21.299639, -22.073904, -14.308119, 21.299639, -22.439577, -14.308119, 12.960274, -22.073904, -14.154955, 12.960274, -22.439577, -13.325426, 12.960274, -22.439577, -14.154955, 12.960274, -22.439577, -13.325426, 12.960274, -22.073904, -14.154955, 12.960274, -22.073904, -13.5327, 12.960274, -22.439577, -13.325426, 12.960274, -22.073904, -13.5327, 12.960274, -22.165104, -13.325426, 13.295837, -22.635942, 4.8980365, 13.527548, -22.543432, 4.8980365, 13.527548, -22.635942, 4.8980365, 13.295837, -22.635942, 4.8980365, 13.295837, -22.543432, 4.8980365, 13.527548, -22.543432, 4.8980365, 13.295837, -22.543432, 4.8980365, 13.527548, -22.543432, -19.742168, 13.527548, -22.543432, 4.8980365, 13.295837, -22.543432, 4.8980365, 13.295837, -22.543432, -19.742168, 13.527548, -22.543432, -19.742168, 13.295837, -22.543432, -19.742168, 13.527548, -22.635942, -19.742168, 13.527548, -22.543432, -19.742168, 13.295837, -22.543432, -19.742168, 13.295837, -22.635942, -19.742168, 13.527548, -22.635942, -19.742168, 13.295837, -22.635942, -19.742168, 13.527548, -22.635942, 4.8980365, 13.527548, -22.635942, -19.742168, 13.295837, -22.635942, -19.742168, 13.295837, -22.635942, 4.8980365, 13.527548, -22.635942, 4.8980365, 13.527548, -22.635942, 4.8980365, 13.527548, -22.543432, -19.742168, 13.527548, -22.635942, -19.742168, 13.527548, -22.635942, 4.8980365, 13.527548, -22.543432, 4.8980365, 13.527548, -22.543432, -19.742168, 13.295837, -22.635942, -19.742168, 13.295837, -22.543432, 4.8980365, 13.295837, -22.635942, 4.8980365, 13.295837, -22.635942, -19.742168, 13.295837, -22.543432, -19.742168, 13.295837, -22.543432, 4.8980365, 14.33395, -22.439577, -18.07831, 21.590258, -22.073904, -18.237583, 14.33395, -22.073904, -18.07831, 14.33395, -22.439577, -18.07831, 21.590258, -22.439577, -18.237583, 21.590258, -22.073904, -18.237583, 12.669218, -22.073904, -18.084854, 14.33395, -22.439577, -18.07831, 14.33395, -22.073904, -18.07831, 12.669218, -22.073904, -18.084854, 12.669218, -22.439577, -18.084854, 14.33395, -22.439577, -18.07831, 14.33395, -22.439577, -17.069435, 21.590258, -22.439577, -18.237583, 14.33395, -22.439577, -18.07831, 14.33395, -22.439577, -17.069435, 21.590258, -22.439577, -17.25489, 21.590258, -22.439577, -18.237583, 12.669218, -22.439577, -18.084854, 14.33395, -22.439577, -17.069435, 14.33395, -22.439577, -18.07831, 12.669218, -22.439577, -18.084854, 12.669218, -22.439577, -17.25489, 14.33395, -22.439577, -17.069435, 12.669218, -22.439577, -18.084854, 12.669218, -22.073904, -17.25489, 12.669218, -22.439577, -17.25489, 12.669218, -22.439577, -18.084854, 12.669218, -22.073904, -18.084854, 12.669218, -22.073904, -17.25489, 14.33395, -22.073904, -17.321653, 14.33395, -22.165104, -17.069435, 13.917658, -22.073904, -17.115688, 14.33395, -22.073904, -17.321653, 16.147917, -22.073904, -17.115688, 14.33395, -22.165104, -17.069435, 14.33395, -22.073904, -17.321653, 20.229671, -22.073904, -17.220417, 16.147917, -22.073904, -17.115688, 13.917658, -22.073904, -17.115688, 14.33395, -22.073904, -18.07831, 14.33395, -22.073904, -17.321653, 13.917658, -22.073904, -17.115688, 12.669218, -22.073904, -18.084854, 14.33395, -22.073904, -18.07831, 12.669218, -22.073904, -18.084854, 13.917658, -22.073904, -17.115688, 12.669218, -22.073904, -17.25489, 21.590258, -22.073904, -18.237583, 14.33395, -22.073904, -17.321653, 14.33395, -22.073904, -18.07831, 14.33395, -22.073904, -17.321653, 21.590258, -22.073904, -18.237583, 20.229671, -22.073904, -17.220417, 20.229671, -22.073904, -17.220417, 21.590258, -22.073904, -18.237583, 21.590258, -22.073904, -17.501, 20.229671, -22.073904, -17.220417, 21.590258, -22.073904, -17.501, 21.590258, -22.165104, -17.25489, 12.669218, -22.073904, -17.25489, 14.33395, -22.439577, -17.069435, 12.669218, -22.439577, -17.25489, 14.33395, -22.439577, -17.069435, 12.669218, -22.073904, -17.25489, 13.917658, -22.073904, -17.115688, 14.33395, -22.439577, -17.069435, 13.917658, -22.073904, -17.115688, 14.33395, -22.165104, -17.069435, 14.33395, -22.165104, -17.069435, 21.590258, -22.439577, -17.25489, 14.33395, -22.439577, -17.069435, 14.33395, -22.165104, -17.069435, 20.229671, -22.073904, -17.220417, 21.590258, -22.439577, -17.25489, 21.590258, -22.439577, -17.25489, 20.229671, -22.073904, -17.220417, 21.590258, -22.165104, -17.25489, 20.229671, -22.073904, -17.220417, 14.33395, -22.165104, -17.069435, 16.147917, -22.073904, -17.115688, 21.590258, -22.165104, -17.25489, 21.590258, -22.439577, -18.237583, 21.590258, -22.439577, -17.25489, 21.590258, -22.439577, -18.237583, 21.590258, -22.165104, -17.25489, 21.590258, -22.073904, -17.501, 21.590258, -22.439577, -18.237583, 21.590258, -22.073904, -17.501, 21.590258, -22.073904, -18.237583, 12.749508, -25.90344, -19.752205, 13.527111, -21.174994, -19.579403, 13.354311, -25.90344, -19.752205, 12.749508, -25.90344, -19.752205, 12.57671, -21.174994, -19.579403, 13.527111, -21.174994, -19.579403, 12.57671, -21.174994, -19.579403, 13.527111, -21.174994, -20.52937, 13.527111, -21.174994, -19.579403, 12.57671, -21.174994, -19.579403, 12.57671, -21.174994, -20.52937, 13.527111, -21.174994, -20.52937, 12.57671, -21.174994, -20.52937, 13.354311, -25.90344, -20.356571, 13.527111, -21.174994, -20.52937, 12.57671, -21.174994, -20.52937, 12.749508, -25.90344, -20.356571, 13.354311, -25.90344, -20.356571, 12.749508, -25.90344, -20.356571, 13.354311, -25.90344, -19.752205, 13.354311, -25.90344, -20.356571, 12.749508, -25.90344, -20.356571, 12.749508, -25.90344, -19.752205, 13.354311, -25.90344, -19.752205, 13.354311, -25.90344, -19.752205, 13.527111, -21.174994, -20.52937, 13.354311, -25.90344, -20.356571, 13.354311, -25.90344, -19.752205, 13.527111, -21.174994, -19.579403, 13.527111, -21.174994, -20.52937, 12.749508, -25.90344, -20.356571, 12.57671, -21.174994, -19.579403, 12.749508, -25.90344, -19.752205, 12.749508, -25.90344, -20.356571, 12.57671, -21.174994, -20.52937, 12.57671, -21.174994, -19.579403, 20.39811, -22.073904, -18.576202, 21.299639, -22.439577, -18.556564, 20.39811, -22.439577, -18.576202, 20.39811, -22.073904, -18.576202, 21.299639, -22.073904, -18.556564, 21.299639, -22.439577, -18.556564, 20.39811, -22.439577, -18.576202, 14.819624, -22.073904, -18.561365, 20.39811, -22.073904, -18.576202, 20.39811, -22.439577, -18.576202, 12.960274, -22.165104, -18.556564, 14.819624, -22.073904, -18.561365, 12.960274, -22.165104, -18.556564, 20.39811, -22.439577, -18.576202, 12.960274, -22.439577, -18.556564, 21.299639, -22.073904, -19.539696, 20.39811, -22.073904, -18.576202, 20.39811, -22.073904, -19.562386, 14.819624, -22.073904, -18.561365, 20.39811, -22.073904, -19.562386, 20.39811, -22.073904, -18.576202, 14.819624, -22.073904, -18.561365, 12.960274, -22.073904, -19.386532, 20.39811, -22.073904, -19.562386, 12.960274, -22.073904, -19.386532, 14.819624, -22.073904, -18.561365, 12.960274, -22.073904, -18.764275, 12.960274, -22.073904, -18.764275, 14.819624, -22.073904, -18.561365, 12.960274, -22.165104, -18.556564, 20.39811, -22.073904, -18.576202, 21.299639, -22.073904, -19.539696, 20.818766, -22.073904, -19.022167, 20.818766, -22.073904, -19.022167, 21.299639, -22.073904, -19.539696, 21.299639, -22.073904, -19.143913, 21.299639, -22.073904, -19.143913, 21.217165, -22.213541, -19.034386, 20.818766, -22.073904, -19.022167, 21.217165, -22.213541, -19.034386, 21.299639, -22.073904, -18.869438, 20.818766, -22.073904, -19.022167, 20.39811, -22.073904, -18.576202, 20.818766, -22.073904, -19.022167, 21.299639, -22.073904, -18.869438, 20.39811, -22.073904, -18.576202, 21.299639, -22.073904, -18.869438, 21.299639, -22.073904, -18.556564, 20.39811, -22.439577, -19.562386, 21.299639, -22.073904, -19.539696, 20.39811, -22.073904, -19.562386, 20.39811, -22.439577, -19.562386, 21.299639, -22.439577, -19.539696, 21.299639, -22.073904, -19.539696, 12.960274, -22.073904, -19.386532, 20.39811, -22.439577, -19.562386, 20.39811, -22.073904, -19.562386, 12.960274, -22.073904, -19.386532, 12.960274, -22.439577, -19.386532, 20.39811, -22.439577, -19.562386, 21.299639, -22.439577, -18.556564, 20.39811, -22.439577, -19.562386, 20.39811, -22.439577, -18.576202, 20.39811, -22.439577, -19.562386, 21.299639, -22.439577, -18.556564, 21.299639, -22.439577, -19.088493, 20.39811, -22.439577, -19.562386, 21.299639, -22.439577, -19.088493, 21.299639, -22.439577, -19.539696, 12.960274, -22.439577, -19.386532, 20.39811, -22.439577, -18.576202, 20.39811, -22.439577, -19.562386, 12.960274, -22.439577, -19.386532, 12.960274, -22.439577, -18.556564, 20.39811, -22.439577, -18.576202, 21.299639, -22.073904, -18.869438, 21.217165, -22.213541, -19.034386, 21.299639, -22.439577, -19.088493, 21.217165, -22.213541, -19.034386, 21.299639, -22.073904, -19.143913, 21.299639, -22.439577, -19.088493, 21.299639, -22.439577, -18.556564, 21.299639, -22.073904, -18.869438, 21.299639, -22.439577, -19.088493, 21.299639, -22.439577, -18.556564, 21.299639, -22.073904, -18.556564, 21.299639, -22.073904, -18.869438, 21.299639, -22.073904, -19.143913, 21.299639, -22.439577, -19.539696, 21.299639, -22.439577, -19.088493, 21.299639, -22.073904, -19.143913, 21.299639, -22.073904, -19.539696, 21.299639, -22.439577, -19.539696, 12.960274, -22.073904, -19.386532, 12.960274, -22.439577, -18.556564, 12.960274, -22.439577, -19.386532, 12.960274, -22.439577, -18.556564, 12.960274, -22.073904, -19.386532, 12.960274, -22.073904, -18.764275, 12.960274, -22.439577, -18.556564, 12.960274, -22.073904, -18.764275, 12.960274, -22.165104, -18.556564, 20.62589, -22.073904, -12.164696, 21.590258, -22.439577, -12.14506, 20.62589, -22.439577, -12.164696, 20.62589, -22.073904, -12.164696, 21.590258, -22.073904, -12.14506, 21.590258, -22.439577, -12.14506, 20.62589, -22.439577, -12.164696, 14.658169, -22.073904, -12.149858, 20.62589, -22.073904, -12.164696, 20.62589, -22.439577, -12.164696, 12.669218, -22.165104, -12.14506, 14.658169, -22.073904, -12.149858, 12.669218, -22.165104, -12.14506, 20.62589, -22.439577, -12.164696, 12.669218, -22.439577, -12.14506, 21.590258, -22.073904, -13.127752, 20.62589, -22.073904, -12.164696, 20.62589, -22.073904, -13.150879, 14.658169, -22.073904, -12.149858, 20.62589, -22.073904, -13.150879, 20.62589, -22.073904, -12.164696, 14.658169, -22.073904, -12.149858, 12.669218, -22.073904, -12.975025, 20.62589, -22.073904, -13.150879, 12.669218, -22.073904, -12.975025, 14.658169, -22.073904, -12.149858, 12.669218, -22.073904, -12.352768, 12.669218, -22.073904, -12.352768, 14.658169, -22.073904, -12.149858, 12.669218, -22.165104, -12.14506, 20.62589, -22.073904, -12.164696, 21.590258, -22.073904, -13.127752, 21.07622, -22.073904, -12.610224, 21.07622, -22.073904, -12.610224, 21.590258, -22.073904, -13.127752, 21.590258, -22.073904, -12.73197, 21.590258, -22.073904, -12.73197, 21.502111, -22.213541, -12.622879, 21.07622, -22.073904, -12.610224, 21.502111, -22.213541, -12.622879, 21.590258, -22.073904, -12.457933, 21.07622, -22.073904, -12.610224, 20.62589, -22.073904, -12.164696, 21.07622, -22.073904, -12.610224, 21.590258, -22.073904, -12.457933, 20.62589, -22.073904, -12.164696, 21.590258, -22.073904, -12.457933, 21.590258, -22.073904, -12.14506, 20.62589, -22.439577, -13.150879, 21.590258, -22.073904, -13.127752, 20.62589, -22.073904, -13.150879, 20.62589, -22.439577, -13.150879, 21.590258, -22.439577, -13.127752, 21.590258, -22.073904, -13.127752, 12.669218, -22.073904, -12.975025, 20.62589, -22.439577, -13.150879, 20.62589, -22.073904, -13.150879, 12.669218, -22.073904, -12.975025, 12.669218, -22.439577, -12.975025, 20.62589, -22.439577, -13.150879, 21.590258, -22.439577, -12.14506, 20.62589, -22.439577, -13.150879, 20.62589, -22.439577, -12.164696, 20.62589, -22.439577, -13.150879, 21.590258, -22.439577, -12.14506, 21.590258, -22.439577, -12.676552, 20.62589, -22.439577, -13.150879, 21.590258, -22.439577, -12.676552, 21.590258, -22.439577, -13.127752, 12.669218, -22.439577, -12.975025, 20.62589, -22.439577, -12.164696, 20.62589, -22.439577, -13.150879, 12.669218, -22.439577, -12.975025, 12.669218, -22.439577, -12.14506, 20.62589, -22.439577, -12.164696, 21.590258, -22.073904, -12.457933, 21.502111, -22.213541, -12.622879, 21.590258, -22.439577, -12.676552, 21.502111, -22.213541, -12.622879, 21.590258, -22.073904, -12.73197, 21.590258, -22.439577, -12.676552, 21.590258, -22.439577, -12.14506, 21.590258, -22.073904, -12.457933, 21.590258, -22.439577, -12.676552, 21.590258, -22.439577, -12.14506, 21.590258, -22.073904, -12.14506, 21.590258, -22.073904, -12.457933, 21.590258, -22.073904, -12.73197, 21.590258, -22.439577, -13.127752, 21.590258, -22.439577, -12.676552, 21.590258, -22.073904, -12.73197, 21.590258, -22.073904, -13.127752, 21.590258, -22.439577, -13.127752, 12.669218, -22.073904, -12.975025, 12.669218, -22.439577, -12.14506, 12.669218, -22.439577, -12.975025, 12.669218, -22.439577, -12.14506, 12.669218, -22.073904, -12.975025, 12.669218, -22.073904, -12.352768, 12.669218, -22.439577, -12.14506, 12.669218, -22.073904, -12.352768, 12.669218, -22.165104, -12.14506, 17.199993, -22.439577, -11.627094, 21.590258, -22.073904, -11.812113, 17.199993, -22.073904, -11.627094, 17.199993, -22.439577, -11.627094, 21.590258, -22.439577, -11.812113, 21.590258, -22.073904, -11.812113, 12.669218, -22.073904, -11.812113, 17.199993, -22.439577, -11.627094, 17.199993, -22.073904, -11.627094, 12.669218, -22.073904, -11.812113, 12.669218, -22.439577, -11.812113, 17.199993, -22.439577, -11.627094, 17.199993, -22.439577, -10.647455, 21.590258, -22.439577, -11.812113, 17.199993, -22.439577, -11.627094, 17.199993, -22.439577, -10.647455, 21.590258, -22.439577, -10.982147, 21.590258, -22.439577, -11.812113, 17.199993, -22.439577, -11.627094, 12.669218, -22.439577, -10.678438, 17.199993, -22.439577, -10.647455, 17.199993, -22.439577, -11.627094, 12.669218, -22.439577, -11.254438, 12.669218, -22.439577, -10.678438, 12.669218, -22.439577, -11.254438, 17.199993, -22.439577, -11.627094, 12.669218, -22.439577, -11.812113, 21.590258, -22.439577, -10.982147, 21.590258, -22.073904, -11.812113, 21.590258, -22.439577, -11.812113, 21.590258, -22.439577, -10.982147, 21.590258, -22.073904, -10.982147, 21.590258, -22.073904, -11.812113, 12.669218, -22.073904, -11.32164, 12.840273, -22.182995, -11.224329, 12.669218, -22.439577, -11.254438, 17.199993, -22.073904, -10.892256, 17.199993, -22.165104, -10.647455, 16.06719, -22.073904, -10.65531, 17.199993, -22.073904, -10.892256, 18.29745, -22.073904, -10.731237, 17.199993, -22.165104, -10.647455, 17.199993, -22.073904, -10.892256, 21.590258, -22.073904, -10.982147, 18.29745, -22.073904, -10.731237, 17.199993, -22.073904, -10.892256, 21.590258, -22.073904, -11.812113, 21.590258, -22.073904, -10.982147, 21.590258, -22.073904, -11.812113, 17.199993, -22.073904, -10.892256, 17.199993, -22.073904, -11.627094, 16.06719, -22.073904, -10.65531, 17.199993, -22.073904, -11.627094, 17.199993, -22.073904, -10.892256, 17.199993, -22.073904, -11.627094, 12.669218, -22.073904, -11.32164, 12.669218, -22.073904, -11.812113, 17.199993, -22.073904, -11.627094, 13.447693, -22.073904, -11.221275, 12.669218, -22.073904, -11.32164, 16.06719, -22.073904, -10.65531, 13.447693, -22.073904, -11.221275, 17.199993, -22.073904, -11.627094, 12.840273, -22.182995, -11.224329, 12.669218, -22.073904, -11.32164, 13.447693, -22.073904, -11.221275, 12.669218, -22.073904, -11.044985, 12.840273, -22.182995, -11.224329, 13.447693, -22.073904, -11.221275, 13.447693, -22.073904, -11.221275, 16.06719, -22.073904, -10.65531, 12.669218, -22.073904, -11.044985, 12.669218, -22.073904, -11.044985, 16.06719, -22.073904, -10.65531, 12.669218, -22.073904, -10.678438, 12.669218, -22.439577, -11.812113, 12.669218, -22.073904, -11.32164, 12.669218, -22.439577, -11.254438, 12.669218, -22.439577, -11.812113, 12.669218, -22.073904, -11.812113, 12.669218, -22.073904, -11.32164, 12.669218, -22.073904, -11.044985, 12.669218, -22.439577, -10.678438, 12.669218, -22.439577, -11.254438, 12.669218, -22.073904, -11.044985, 12.669218, -22.073904, -10.678438, 12.669218, -22.439577, -10.678438, 12.840273, -22.182995, -11.224329, 12.669218, -22.073904, -11.044985, 12.669218, -22.439577, -11.254438, 12.669218, -22.073904, -10.678438, 17.199993, -22.439577, -10.647455, 12.669218, -22.439577, -10.678438, 17.199993, -22.439577, -10.647455, 12.669218, -22.073904, -10.678438, 16.06719, -22.073904, -10.65531, 17.199993, -22.439577, -10.647455, 16.06719, -22.073904, -10.65531, 17.199993, -22.165104, -10.647455, 17.199993, -22.165104, -10.647455, 21.590258, -22.439577, -10.982147, 17.199993, -22.439577, -10.647455, 17.199993, -22.165104, -10.647455, 21.590258, -22.073904, -10.982147, 21.590258, -22.439577, -10.982147, 21.590258, -22.073904, -10.982147, 17.199993, -22.165104, -10.647455, 18.29745, -22.073904, -10.731237, 20.39811, -22.073904, -9.367163, 21.299639, -22.439577, -9.347525, 20.39811, -22.439577, -9.367163, 20.39811, -22.073904, -9.367163, 21.299639, -22.073904, -9.347525, 21.299639, -22.439577, -9.347525, 20.39811, -22.439577, -9.367163, 14.819624, -22.073904, -9.352325, 20.39811, -22.073904, -9.367163, 20.39811, -22.439577, -9.367163, 12.960274, -22.165104, -9.347525, 14.819624, -22.073904, -9.352325, 12.960274, -22.165104, -9.347525, 20.39811, -22.439577, -9.367163, 12.960274, -22.439577, -9.347525, 21.299639, -22.073904, -10.330656, 20.39811, -22.073904, -9.367163, 20.39811, -22.073904, -10.353346, 14.819624, -22.073904, -9.352325, 20.39811, -22.073904, -10.353346, 20.39811, -22.073904, -9.367163, 14.819624, -22.073904, -9.352325, 12.960274, -22.073904, -10.17749, 20.39811, -22.073904, -10.353346, 12.960274, -22.073904, -10.17749, 14.819624, -22.073904, -9.352325, 12.960274, -22.073904, -9.555235, 12.960274, -22.073904, -9.555235, 14.819624, -22.073904, -9.352325, 12.960274, -22.165104, -9.347525, 20.39811, -22.073904, -9.367163, 21.299639, -22.073904, -10.330656, 20.818766, -22.073904, -9.8131275, 20.818766, -22.073904, -9.8131275, 21.299639, -22.073904, -10.330656, 21.299639, -22.073904, -9.934872, 21.299639, -22.073904, -9.934872, 21.217165, -22.213541, -9.825344, 20.818766, -22.073904, -9.8131275, 21.217165, -22.213541, -9.825344, 21.299639, -22.073904, -9.6603985, 20.818766, -22.073904, -9.8131275, 20.39811, -22.073904, -9.367163, 20.818766, -22.073904, -9.8131275, 21.299639, -22.073904, -9.6603985, 20.39811, -22.073904, -9.367163, 21.299639, -22.073904, -9.6603985, 21.299639, -22.073904, -9.347525, 20.39811, -22.439577, -10.353346, 21.299639, -22.073904, -10.330656, 20.39811, -22.073904, -10.353346, 20.39811, -22.439577, -10.353346, 21.299639, -22.439577, -10.330656, 21.299639, -22.073904, -10.330656, 12.960274, -22.073904, -10.17749, 20.39811, -22.439577, -10.353346, 20.39811, -22.073904, -10.353346, 12.960274, -22.073904, -10.17749, 12.960274, -22.439577, -10.17749, 20.39811, -22.439577, -10.353346, 21.299639, -22.439577, -9.347525, 20.39811, -22.439577, -10.353346, 20.39811, -22.439577, -9.367163, 20.39811, -22.439577, -10.353346, 21.299639, -22.439577, -9.347525, 21.299639, -22.439577, -9.879017, 20.39811, -22.439577, -10.353346, 21.299639, -22.439577, -9.879017, 21.299639, -22.439577, -10.330656, 12.960274, -22.439577, -10.17749, 20.39811, -22.439577, -9.367163, 20.39811, -22.439577, -10.353346, 12.960274, -22.439577, -10.17749, 12.960274, -22.439577, -9.347525, 20.39811, -22.439577, -9.367163, 21.299639, -22.073904, -9.6603985, 21.217165, -22.213541, -9.825344, 21.299639, -22.439577, -9.879017, 21.217165, -22.213541, -9.825344, 21.299639, -22.073904, -9.934872, 21.299639, -22.439577, -9.879017, 21.299639, -22.439577, -9.347525, 21.299639, -22.073904, -9.6603985, 21.299639, -22.439577, -9.879017, 21.299639, -22.439577, -9.347525, 21.299639, -22.073904, -9.347525, 21.299639, -22.073904, -9.6603985, 21.299639, -22.073904, -9.934872, 21.299639, -22.439577, -10.330656, 21.299639, -22.439577, -9.879017, 21.299639, -22.073904, -9.934872, 21.299639, -22.073904, -10.330656, 21.299639, -22.439577, -10.330656, 12.960274, -22.073904, -10.17749, 12.960274, -22.439577, -9.347525, 12.960274, -22.439577, -10.17749, 12.960274, -22.439577, -9.347525, 12.960274, -22.073904, -10.17749, 12.960274, -22.073904, -9.555235, 12.960274, -22.439577, -9.347525, 12.960274, -22.073904, -9.555235, 12.960274, -22.165104, -9.347525, 20.474909, -25.90344, -19.689804, 21.125528, -21.174994, -19.768787, 21.204512, -25.90344, -19.689804, 20.474909, -25.90344, -19.689804, 20.553892, -21.174994, -19.768787, 21.125528, -21.174994, -19.768787, 20.553892, -21.174994, -19.768787, 21.125528, -21.174994, -20.340424, 21.125528, -21.174994, -19.768787, 20.553892, -21.174994, -19.768787, 20.553892, -21.174994, -20.340424, 21.125528, -21.174994, -20.340424, 20.553892, -21.174994, -20.340424, 21.204512, -25.90344, -20.419407, 21.125528, -21.174994, -20.340424, 20.553892, -21.174994, -20.340424, 20.474909, -25.90344, -20.419407, 21.204512, -25.90344, -20.419407, 20.474909, -25.90344, -20.419407, 21.204512, -25.90344, -19.689804, 21.204512, -25.90344, -20.419407, 20.474909, -25.90344, -20.419407, 20.474909, -25.90344, -19.689804, 21.204512, -25.90344, -19.689804, 21.204512, -25.90344, -19.689804, 21.125528, -21.174994, -20.340424, 21.204512, -25.90344, -20.419407, 21.204512, -25.90344, -19.689804, 21.125528, -21.174994, -19.768787, 21.125528, -21.174994, -20.340424, 20.474909, -25.90344, -20.419407, 20.553892, -21.174994, -19.768787, 20.474909, -25.90344, -19.689804, 20.474909, -25.90344, -20.419407, 20.553892, -21.174994, -20.340424, 20.553892, -21.174994, -19.768787, 12.886963, -25.90344, 5.2994914, 13.6170025, -21.174994, 5.2994914, 13.6170025, -25.90344, 5.2994914, 12.886963, -25.90344, 5.2994914, 12.886963, -21.174994, 5.2994914, 13.6170025, -21.174994, 5.2994914, 12.886963, -25.90344, 4.5698895, 13.6170025, -25.90344, 5.2994914, 13.6170025, -25.90344, 4.5698895, 12.886963, -25.90344, 4.5698895, 12.886963, -25.90344, 5.2994914, 13.6170025, -25.90344, 5.2994914, 13.6170025, -25.90344, 5.2994914, 13.6170025, -21.174994, 4.5698895, 13.6170025, -25.90344, 4.5698895, 13.6170025, -25.90344, 5.2994914, 13.6170025, -21.174994, 5.2994914, 13.6170025, -21.174994, 4.5698895, 12.886963, -22.357105, 4.5698895, 13.069365, -21.174994, 4.5698895, 12.886963, -21.174994, 4.7522902, 12.886963, -25.90344, 5.2994914, 12.886963, -22.357105, 4.5698895, 12.886963, -21.174994, 4.7522902, 12.886963, -22.357105, 4.5698895, 12.886963, -25.90344, 5.2994914, 12.886963, -25.90344, 4.5698895, 12.886963, -25.90344, 5.2994914, 12.886963, -21.174994, 4.7522902, 12.886963, -21.174994, 5.2994914, 12.886963, -21.174994, 4.7522902, 13.6170025, -21.174994, 5.2994914, 12.886963, -21.174994, 5.2994914, 13.6170025, -21.174994, 5.2994914, 12.886963, -21.174994, 4.7522902, 13.069365, -21.174994, 4.5698895, 13.6170025, -21.174994, 5.2994914, 13.069365, -21.174994, 4.5698895, 13.6170025, -21.174994, 4.5698895, 12.886963, -25.90344, 4.5698895, 13.069365, -21.174994, 4.5698895, 12.886963, -22.357105, 4.5698895, 13.069365, -21.174994, 4.5698895, 12.886963, -25.90344, 4.5698895, 13.6170025, -25.90344, 4.5698895, 13.069365, -21.174994, 4.5698895, 13.6170025, -25.90344, 4.5698895, 13.6170025, -21.174994, 4.5698895, 17.195192, -22.439577, -7.5178485, 21.299639, -22.073904, -7.703304, 17.195192, -22.073904, -7.5178485, 17.195192, -22.439577, -7.5178485, 21.299639, -22.439577, -7.703304, 21.299639, -22.073904, -7.703304, 12.960274, -22.073904, -7.703304, 17.195192, -22.439577, -7.5178485, 17.195192, -22.073904, -7.5178485, 12.960274, -22.073904, -7.703304, 12.960274, -22.439577, -7.703304, 17.195192, -22.439577, -7.5178485, 17.195192, -22.439577, -6.539082, 21.299639, -22.439577, -7.703304, 17.195192, -22.439577, -7.5178485, 17.195192, -22.439577, -6.539082, 21.299639, -22.439577, -6.873338, 21.299639, -22.439577, -7.703304, 17.195192, -22.439577, -7.5178485, 12.960274, -22.439577, -6.570064, 17.195192, -22.439577, -6.539082, 17.195192, -22.439577, -7.5178485, 12.960274, -22.439577, -7.146065, 12.960274, -22.439577, -6.570064, 12.960274, -22.439577, -7.146065, 17.195192, -22.439577, -7.5178485, 12.960274, -22.439577, -7.703304, 21.299639, -22.439577, -6.873338, 21.299639, -22.073904, -7.703304, 21.299639, -22.439577, -7.703304, 21.299639, -22.439577, -6.873338, 21.299639, -22.073904, -6.873338, 21.299639, -22.073904, -7.703304, 12.960274, -22.073904, -7.2123933, 13.119982, -22.182995, -7.11552, 12.960274, -22.439577, -7.146065, 17.195192, -22.073904, -6.783447, 17.195192, -22.165104, -6.539082, 16.136572, -22.073904, -6.5465007, 17.195192, -22.073904, -6.783447, 18.221523, -22.073904, -6.6224284, 17.195192, -22.165104, -6.539082, 17.195192, -22.073904, -6.783447, 21.299639, -22.073904, -6.873338, 18.221523, -22.073904, -6.6224284, 17.195192, -22.073904, -6.783447, 21.299639, -22.073904, -7.703304, 21.299639, -22.073904, -6.873338, 21.299639, -22.073904, -7.703304, 17.195192, -22.073904, -6.783447, 17.195192, -22.073904, -7.5178485, 16.136572, -22.073904, -6.5465007, 17.195192, -22.073904, -7.5178485, 17.195192, -22.073904, -6.783447, 17.195192, -22.073904, -7.5178485, 12.960274, -22.073904, -7.2123933, 12.960274, -22.073904, -7.703304, 17.195192, -22.073904, -7.5178485, 13.688129, -22.073904, -7.112902, 12.960274, -22.073904, -7.2123933, 16.136572, -22.073904, -6.5465007, 13.688129, -22.073904, -7.112902, 17.195192, -22.073904, -7.5178485, 13.119982, -22.182995, -7.11552, 12.960274, -22.073904, -7.2123933, 13.688129, -22.073904, -7.112902, 12.960274, -22.073904, -6.9366107, 13.119982, -22.182995, -7.11552, 13.688129, -22.073904, -7.112902, 13.688129, -22.073904, -7.112902, 16.136572, -22.073904, -6.5465007, 12.960274, -22.073904, -6.9366107, 12.960274, -22.073904, -6.9366107, 16.136572, -22.073904, -6.5465007, 12.960274, -22.073904, -6.570064, 12.960274, -22.439577, -7.703304, 12.960274, -22.073904, -7.2123933, 12.960274, -22.439577, -7.146065, 12.960274, -22.439577, -7.703304, 12.960274, -22.073904, -7.703304, 12.960274, -22.073904, -7.2123933, 12.960274, -22.073904, -6.9366107, 12.960274, -22.439577, -6.570064, 12.960274, -22.439577, -7.146065, 12.960274, -22.073904, -6.9366107, 12.960274, -22.073904, -6.570064, 12.960274, -22.439577, -6.570064, 13.119982, -22.182995, -7.11552, 12.960274, -22.073904, -6.9366107, 12.960274, -22.439577, -7.146065, 12.960274, -22.073904, -6.570064, 17.195192, -22.439577, -6.539082, 12.960274, -22.439577, -6.570064, 17.195192, -22.439577, -6.539082, 12.960274, -22.073904, -6.570064, 16.136572, -22.073904, -6.5465007, 17.195192, -22.439577, -6.539082, 16.136572, -22.073904, -6.5465007, 17.195192, -22.165104, -6.539082, 17.195192, -22.165104, -6.539082, 21.299639, -22.439577, -6.873338, 17.195192, -22.439577, -6.539082, 17.195192, -22.165104, -6.539082, 21.299639, -22.073904, -6.873338, 21.299639, -22.439577, -6.873338, 21.299639, -22.073904, -6.873338, 17.195192, -22.165104, -6.539082, 18.221523, -22.073904, -6.6224284, 14.394604, -22.439577, -15.51292, 21.493383, -22.073904, -15.67263, 14.394604, -22.073904, -15.51292, 14.394604, -22.439577, -15.51292, 21.493383, -22.439577, -15.67263, 21.493383, -22.073904, -15.67263, 12.76609, -22.073904, -15.519905, 14.394604, -22.439577, -15.51292, 14.394604, -22.073904, -15.51292, 12.76609, -22.073904, -15.519905, 12.76609, -22.439577, -15.519905, 14.394604, -22.439577, -15.51292, 14.394604, -22.439577, -14.504482, 21.493383, -22.439577, -15.67263, 14.394604, -22.439577, -15.51292, 14.394604, -22.439577, -14.504482, 21.493383, -22.439577, -14.689938, 21.493383, -22.439577, -15.67263, 12.76609, -22.439577, -15.519905, 14.394604, -22.439577, -14.504482, 14.394604, -22.439577, -15.51292, 12.76609, -22.439577, -15.519905, 12.76609, -22.439577, -14.689938, 14.394604, -22.439577, -14.504482, 12.76609, -22.439577, -15.519905, 12.76609, -22.073904, -14.689938, 12.76609, -22.439577, -14.689938, 12.76609, -22.439577, -15.519905, 12.76609, -22.073904, -15.519905, 12.76609, -22.073904, -14.689938, 14.394604, -22.073904, -14.756702, 14.394604, -22.165104, -14.504482, 13.987476, -22.073904, -14.550737, 14.394604, -22.073904, -14.756702, 16.1693, -22.073904, -14.550737, 14.394604, -22.165104, -14.504482, 14.394604, -22.073904, -14.756702, 20.162472, -22.073904, -14.655029, 16.1693, -22.073904, -14.550737, 13.987476, -22.073904, -14.550737, 14.394604, -22.073904, -15.51292, 14.394604, -22.073904, -14.756702, 13.987476, -22.073904, -14.550737, 12.76609, -22.073904, -15.519905, 14.394604, -22.073904, -15.51292, 12.76609, -22.073904, -15.519905, 13.987476, -22.073904, -14.550737, 12.76609, -22.073904, -14.689938, 21.493383, -22.073904, -15.67263, 14.394604, -22.073904, -14.756702, 14.394604, -22.073904, -15.51292, 14.394604, -22.073904, -14.756702, 21.493383, -22.073904, -15.67263, 20.162472, -22.073904, -14.655029, 20.162472, -22.073904, -14.655029, 21.493383, -22.073904, -15.67263, 21.493383, -22.073904, -14.935175, 20.162472, -22.073904, -14.655029, 21.493383, -22.073904, -14.935175, 21.493383, -22.165104, -14.689938, 12.76609, -22.073904, -14.689938, 14.394604, -22.439577, -14.504482, 12.76609, -22.439577, -14.689938, 14.394604, -22.439577, -14.504482, 12.76609, -22.073904, -14.689938, 13.987476, -22.073904, -14.550737, 14.394604, -22.439577, -14.504482, 13.987476, -22.073904, -14.550737, 14.394604, -22.165104, -14.504482, 14.394604, -22.165104, -14.504482, 21.493383, -22.439577, -14.689938, 14.394604, -22.439577, -14.504482, 14.394604, -22.165104, -14.504482, 20.162472, -22.073904, -14.655029, 21.493383, -22.439577, -14.689938, 21.493383, -22.439577, -14.689938, 20.162472, -22.073904, -14.655029, 21.493383, -22.165104, -14.689938, 20.162472, -22.073904, -14.655029, 14.394604, -22.165104, -14.504482, 16.1693, -22.073904, -14.550737, 21.493383, -22.165104, -14.689938, 21.493383, -22.439577, -15.67263, 21.493383, -22.439577, -14.689938, 21.493383, -22.439577, -15.67263, 21.493383, -22.165104, -14.689938, 21.493383, -22.073904, -14.935175, 21.493383, -22.439577, -15.67263, 21.493383, -22.073904, -14.935175, 21.493383, -22.073904, -15.67263, 14.33395, -22.439577, -8.868834, 21.590258, -22.073904, -9.028543, 14.33395, -22.073904, -8.868834, 14.33395, -22.439577, -8.868834, 21.590258, -22.439577, -9.028543, 21.590258, -22.073904, -9.028543, 12.669218, -22.073904, -8.875814, 14.33395, -22.439577, -8.868834, 14.33395, -22.073904, -8.868834, 12.669218, -22.073904, -8.875814, 12.669218, -22.439577, -8.875814, 14.33395, -22.439577, -8.868834, 14.33395, -22.439577, -7.860395, 21.590258, -22.439577, -9.028543, 14.33395, -22.439577, -8.868834, 14.33395, -22.439577, -7.860395, 21.590258, -22.439577, -8.045849, 21.590258, -22.439577, -9.028543, 12.669218, -22.439577, -8.875814, 14.33395, -22.439577, -7.860395, 14.33395, -22.439577, -8.868834, 12.669218, -22.439577, -8.875814, 12.669218, -22.439577, -8.045849, 14.33395, -22.439577, -7.860395, 12.669218, -22.439577, -8.875814, 12.669218, -22.073904, -8.045849, 12.669218, -22.439577, -8.045849, 12.669218, -22.439577, -8.875814, 12.669218, -22.073904, -8.875814, 12.669218, -22.073904, -8.045849, 14.33395, -22.073904, -8.112614, 14.33395, -22.165104, -7.860395, 13.917658, -22.073904, -7.906649, 14.33395, -22.073904, -8.112614, 16.147917, -22.073904, -7.906649, 14.33395, -22.165104, -7.860395, 14.33395, -22.073904, -8.112614, 20.229671, -22.073904, -8.011377, 16.147917, -22.073904, -7.906649, 13.917658, -22.073904, -7.906649, 14.33395, -22.073904, -8.868834, 14.33395, -22.073904, -8.112614, 13.917658, -22.073904, -7.906649, 12.669218, -22.073904, -8.875814, 14.33395, -22.073904, -8.868834, 12.669218, -22.073904, -8.875814, 13.917658, -22.073904, -7.906649, 12.669218, -22.073904, -8.045849, 21.590258, -22.073904, -9.028543, 14.33395, -22.073904, -8.112614, 14.33395, -22.073904, -8.868834, 14.33395, -22.073904, -8.112614, 21.590258, -22.073904, -9.028543, 20.229671, -22.073904, -8.011377, 20.229671, -22.073904, -8.011377, 21.590258, -22.073904, -9.028543, 21.590258, -22.073904, -8.29196, 20.229671, -22.073904, -8.011377, 21.590258, -22.073904, -8.29196, 21.590258, -22.165104, -8.045849, 12.669218, -22.073904, -8.045849, 14.33395, -22.439577, -7.860395, 12.669218, -22.439577, -8.045849, 14.33395, -22.439577, -7.860395, 12.669218, -22.073904, -8.045849, 13.917658, -22.073904, -7.906649, 14.33395, -22.439577, -7.860395, 13.917658, -22.073904, -7.906649, 14.33395, -22.165104, -7.860395, 14.33395, -22.165104, -7.860395, 21.590258, -22.439577, -8.045849, 14.33395, -22.439577, -7.860395, 14.33395, -22.165104, -7.860395, 20.229671, -22.073904, -8.011377, 21.590258, -22.439577, -8.045849, 21.590258, -22.439577, -8.045849, 20.229671, -22.073904, -8.011377, 21.590258, -22.165104, -8.045849, 20.229671, -22.073904, -8.011377, 14.33395, -22.165104, -7.860395, 16.147917, -22.073904, -7.906649, 21.590258, -22.165104, -8.045849, 21.590258, -22.439577, -9.028543, 21.590258, -22.439577, -8.045849, 21.590258, -22.439577, -9.028543, 21.590258, -22.165104, -8.045849, 21.590258, -22.073904, -8.29196, 21.590258, -22.439577, -9.028543, 21.590258, -22.073904, -8.29196, 21.590258, -22.073904, -9.028543, 20.608437, -25.90344, 5.6272016, 21.338474, -21.174994, 5.6272016, 21.338474, -25.90344, 5.6272016, 20.608437, -25.90344, 5.6272016, 20.608437, -21.723503, 5.6272016, 21.338474, -21.174994, 5.6272016, 20.608437, -21.723503, 5.6272016, 21.338474, -21.174994, 4.8975997, 21.338474, -21.174994, 5.6272016, 20.608437, -21.723503, 5.6272016, 20.608437, -21.174994, 4.8975997, 21.338474, -21.174994, 4.8975997, 20.608437, -21.174994, 4.8975997, 21.338474, -25.90344, 4.8975997, 21.338474, -21.174994, 4.8975997, 20.608437, -21.174994, 4.8975997, 20.608437, -25.90344, 4.8975997, 21.338474, -25.90344, 4.8975997, 20.608437, -25.90344, 4.8975997, 21.338474, -25.90344, 5.6272016, 21.338474, -25.90344, 4.8975997, 20.608437, -25.90344, 4.8975997, 20.608437, -25.90344, 5.6272016, 21.338474, -25.90344, 5.6272016, 21.338474, -25.90344, 5.6272016, 21.338474, -21.174994, 4.8975997, 21.338474, -25.90344, 4.8975997, 21.338474, -25.90344, 5.6272016, 21.338474, -21.174994, 5.6272016, 21.338474, -21.174994, 4.8975997, 20.608437, -25.90344, 4.8975997, 20.608437, -21.723503, 5.6272016, 20.608437, -25.90344, 5.6272016, 20.608437, -25.90344, 4.8975997, 20.608437, -21.174994, 4.8975997, 20.608437, -21.723503, 5.6272016, 20.752874, -22.635942, 4.8980365, 20.984583, -22.543432, 4.8980365, 20.984583, -22.635942, 4.8980365, 20.752874, -22.635942, 4.8980365, 20.752874, -22.543432, 4.8980365, 20.984583, -22.543432, 4.8980365, 20.752874, -22.543432, 4.8980365, 20.984583, -22.543432, -19.742168, 20.984583, -22.543432, 4.8980365, 20.752874, -22.543432, 4.8980365, 20.752874, -22.543432, -19.742168, 20.984583, -22.543432, -19.742168, 20.752874, -22.543432, -19.742168, 20.984583, -22.635942, -19.742168, 20.984583, -22.543432, -19.742168, 20.752874, -22.543432, -19.742168, 20.752874, -22.635942, -19.742168, 20.984583, -22.635942, -19.742168, 20.752874, -22.635942, -19.742168, 20.984583, -22.635942, 4.8980365, 20.984583, -22.635942, -19.742168, 20.752874, -22.635942, -19.742168, 20.752874, -22.635942, 4.8980365, 20.984583, -22.635942, 4.8980365, 20.984583, -22.635942, 4.8980365, 20.984583, -22.543432, -19.742168, 20.984583, -22.635942, -19.742168, 20.984583, -22.635942, 4.8980365, 20.984583, -22.543432, 4.8980365, 20.984583, -22.543432, -19.742168, 20.752874, -22.635942, -19.742168, 20.752874, -22.543432, 4.8980365, 20.752874, -22.635942, 4.8980365, 20.752874, -22.635942, -19.742168, 20.752874, -22.543432, -19.742168, 20.752874, -22.543432, 4.8980365, 12.886963, -25.348385, -5.927299, 13.6170025, -20.619938, -5.927299, 13.6170025, -25.348385, -5.927299, 12.886963, -25.348385, -5.927299, 12.886963, -20.619938, -5.927299, 13.6170025, -20.619938, -5.927299, 12.886963, -25.348385, -6.6573377, 13.6170025, -25.348385, -5.927299, 13.6170025, -25.348385, -6.6573377, 12.886963, -25.348385, -6.6573377, 12.886963, -25.348385, -5.927299, 13.6170025, -25.348385, -5.927299, 13.6170025, -25.348385, -5.927299, 13.6170025, -20.619938, -6.6573377, 13.6170025, -25.348385, -6.6573377, 13.6170025, -25.348385, -5.927299, 13.6170025, -20.619938, -5.927299, 13.6170025, -20.619938, -6.6573377, 12.886963, -21.80205, -6.6573377, 13.069365, -20.619938, -6.6573377, 12.886963, -20.619938, -6.474937, 12.886963, -25.348385, -5.927299, 12.886963, -21.80205, -6.6573377, 12.886963, -20.619938, -6.474937, 12.886963, -21.80205, -6.6573377, 12.886963, -25.348385, -5.927299, 12.886963, -25.348385, -6.6573377, 12.886963, -25.348385, -5.927299, 12.886963, -20.619938, -6.474937, 12.886963, -20.619938, -5.927299, 12.886963, -20.619938, -6.474937, 13.6170025, -20.619938, -5.927299, 12.886963, -20.619938, -5.927299, 13.6170025, -20.619938, -5.927299, 12.886963, -20.619938, -6.474937, 13.069365, -20.619938, -6.6573377, 13.6170025, -20.619938, -5.927299, 13.069365, -20.619938, -6.6573377, 13.6170025, -20.619938, -6.6573377, 12.886963, -25.348385, -6.6573377, 13.069365, -20.619938, -6.6573377, 12.886963, -21.80205, -6.6573377, 13.069365, -20.619938, -6.6573377, 12.886963, -25.348385, -6.6573377, 13.6170025, -25.348385, -6.6573377, 13.069365, -20.619938, -6.6573377, 13.6170025, -25.348385, -6.6573377, 13.6170025, -20.619938, -6.6573377, 12.886963, -26.235077, -13.537062, 13.6170025, -21.50663, -13.537062, 13.6170025, -26.235077, -13.537062, 12.886963, -26.235077, -13.537062, 12.886963, -21.50663, -13.537062, 13.6170025, -21.50663, -13.537062, 12.886963, -26.235077, -14.2666645, 13.6170025, -26.235077, -13.537062, 13.6170025, -26.235077, -14.2666645, 12.886963, -26.235077, -14.2666645, 12.886963, -26.235077, -13.537062, 13.6170025, -26.235077, -13.537062, 13.6170025, -26.235077, -13.537062, 13.6170025, -21.50663, -14.2666645, 13.6170025, -26.235077, -14.2666645, 13.6170025, -26.235077, -13.537062, 13.6170025, -21.50663, -13.537062, 13.6170025, -21.50663, -14.2666645, 12.886963, -22.688742, -14.2666645, 13.069365, -21.50663, -14.2666645, 12.886963, -21.50663, -14.084265, 12.886963, -26.235077, -13.537062, 12.886963, -22.688742, -14.2666645, 12.886963, -21.50663, -14.084265, 12.886963, -22.688742, -14.2666645, 12.886963, -26.235077, -13.537062, 12.886963, -26.235077, -14.2666645, 12.886963, -26.235077, -13.537062, 12.886963, -21.50663, -14.084265, 12.886963, -21.50663, -13.537062, 12.886963, -21.50663, -14.084265, 13.6170025, -21.50663, -13.537062, 12.886963, -21.50663, -13.537062, 13.6170025, -21.50663, -13.537062, 12.886963, -21.50663, -14.084265, 13.069365, -21.50663, -14.2666645, 13.6170025, -21.50663, -13.537062, 13.069365, -21.50663, -14.2666645, 13.6170025, -21.50663, -14.2666645, 12.886963, -26.235077, -14.2666645, 13.069365, -21.50663, -14.2666645, 12.886963, -22.688742, -14.2666645, 13.069365, -21.50663, -14.2666645, 12.886963, -26.235077, -14.2666645, 13.6170025, -26.235077, -14.2666645, 13.069365, -21.50663, -14.2666645, 13.6170025, -26.235077, -14.2666645, 13.6170025, -21.50663, -14.2666645, 21.21673, -25.99464, -5.8286805, 21.946331, -21.266193, -5.8286805, 21.946331, -25.99464, -5.8286805, 21.21673, -25.99464, -5.8286805, 21.21673, -21.266193, -5.8286805, 21.946331, -21.266193, -5.8286805, 21.21673, -25.99464, -6.558719, 21.946331, -25.99464, -5.8286805, 21.946331, -25.99464, -6.558719, 21.21673, -25.99464, -6.558719, 21.21673, -25.99464, -5.8286805, 21.946331, -25.99464, -5.8286805, 21.946331, -25.99464, -5.8286805, 21.946331, -21.266193, -6.558719, 21.946331, -25.99464, -6.558719, 21.946331, -25.99464, -5.8286805, 21.946331, -21.266193, -5.8286805, 21.946331, -21.266193, -6.558719, 21.21673, -22.448305, -6.558719, 21.39913, -21.266193, -6.558719, 21.21673, -21.266193, -6.3763185, 21.21673, -25.99464, -5.8286805, 21.21673, -22.448305, -6.558719, 21.21673, -21.266193, -6.3763185, 21.21673, -22.448305, -6.558719, 21.21673, -25.99464, -5.8286805, 21.21673, -25.99464, -6.558719, 21.21673, -25.99464, -5.8286805, 21.21673, -21.266193, -6.3763185, 21.21673, -21.266193, -5.8286805, 21.21673, -21.266193, -6.3763185, 21.946331, -21.266193, -5.8286805, 21.21673, -21.266193, -5.8286805, 21.946331, -21.266193, -5.8286805, 21.21673, -21.266193, -6.3763185, 21.39913, -21.266193, -6.558719, 21.946331, -21.266193, -5.8286805, 21.39913, -21.266193, -6.558719, 21.946331, -21.266193, -6.558719, 21.21673, -25.99464, -6.558719, 21.39913, -21.266193, -6.558719, 21.21673, -22.448305, -6.558719, 21.39913, -21.266193, -6.558719, 21.21673, -25.99464, -6.558719, 21.946331, -25.99464, -6.558719, 21.39913, -21.266193, -6.558719, 21.946331, -25.99464, -6.558719, 21.946331, -21.266193, -6.558719, 21.21673, -25.99464, -13.537062, 21.946331, -21.266193, -13.537062, 21.946331, -25.99464, -13.537062, 21.21673, -25.99464, -13.537062, 21.21673, -21.266193, -13.537062, 21.946331, -21.266193, -13.537062, 21.21673, -25.99464, -14.2666645, 21.946331, -25.99464, -13.537062, 21.946331, -25.99464, -14.2666645, 21.21673, -25.99464, -14.2666645, 21.21673, -25.99464, -13.537062, 21.946331, -25.99464, -13.537062, 21.946331, -25.99464, -13.537062, 21.946331, -21.266193, -14.2666645, 21.946331, -25.99464, -14.2666645, 21.946331, -25.99464, -13.537062, 21.946331, -21.266193, -13.537062, 21.946331, -21.266193, -14.2666645, 21.21673, -22.448305, -14.2666645, 21.39913, -21.266193, -14.2666645, 21.21673, -21.266193, -14.084265, 21.21673, -25.99464, -13.537062, 21.21673, -22.448305, -14.2666645, 21.21673, -21.266193, -14.084265, 21.21673, -22.448305, -14.2666645, 21.21673, -25.99464, -13.537062, 21.21673, -25.99464, -14.2666645, 21.21673, -25.99464, -13.537062, 21.21673, -21.266193, -14.084265, 21.21673, -21.266193, -13.537062, 21.21673, -21.266193, -14.084265, 21.946331, -21.266193, -13.537062, 21.21673, -21.266193, -13.537062, 21.946331, -21.266193, -13.537062, 21.21673, -21.266193, -14.084265, 21.39913, -21.266193, -14.2666645, 21.946331, -21.266193, -13.537062, 21.39913, -21.266193, -14.2666645, 21.946331, -21.266193, -14.2666645, 21.21673, -25.99464, -14.2666645, 21.39913, -21.266193, -14.2666645, 21.21673, -22.448305, -14.2666645, 21.39913, -21.266193, -14.2666645, 21.21673, -25.99464, -14.2666645, 21.946331, -25.99464, -14.2666645, 21.39913, -21.266193, -14.2666645, 21.946331, -25.99464, -14.2666645, 21.946331, -21.266193, -14.2666645, -13.073534, -0.35833585, 29.034882, -8.669889, -0.18640822, 28.876835, -13.057354, 0.007337749, 29.029753, -13.073534, -0.35833585, 29.034882, -8.686073, -0.5516454, 28.882399, -8.669889, -0.18640822, 28.876835, -17.582396, 0.2010836, 28.810827, -13.073534, -0.35833585, 29.034882, -13.057354, 0.007337749, 29.029753, -17.582396, 0.2010836, 28.810827, -17.59858, -0.16415358, 28.816393, -13.073534, -0.35833585, 29.034882, -13.080118, -0.3434996, 30.014496, -8.686073, -0.5516454, 28.882399, -13.073534, -0.35833585, 29.034882, -13.080118, -0.3434996, 30.014496, -8.69165, -0.538991, 29.712345, -8.686073, -0.5516454, 28.882399, -13.073534, -0.35833585, 29.034882, -17.606195, -0.1471355, 29.949606, -13.080118, -0.3434996, 30.014496, -13.073534, -0.35833585, 29.034882, -17.602324, -0.15586269, 29.373617, -17.606195, -0.1471355, 29.949606, -17.602324, -0.15586269, 29.373617, -13.073534, -0.35833585, 29.034882, -17.59858, -0.16415358, 28.816393, -8.69165, -0.538991, 29.712345, -8.669889, -0.18640822, 28.876835, -8.686073, -0.5516454, 28.882399, -8.69165, -0.538991, 29.712345, -8.675467, -0.17375374, 29.706781, -8.669889, -0.18640822, 28.876835, -17.585695, 0.20850176, 29.301727, -17.420107, 0.093301594, 29.40146, -17.602324, -0.15586269, 29.373617, -13.06229, 0.01824683, 29.764137, -13.067871, -0.06946254, 30.010216, -14.195347, 0.07104677, 29.993038, -13.06229, 0.01824683, 29.764137, -11.966818, -0.027135193, 29.933395, -13.067871, -0.06946254, 30.010216, -13.06229, 0.01824683, 29.764137, -8.675467, -0.17375374, 29.706781, -11.966818, -0.027135193, 29.933395, -13.06229, 0.01824683, 29.764137, -8.669889, -0.18640822, 28.876835, -8.675467, -0.17375374, 29.706781, -8.669889, -0.18640822, 28.876835, -13.06229, 0.01824683, 29.764137, -13.057354, 0.007337749, 29.029753, -14.195347, 0.07104677, 29.993038, -13.057354, 0.007337749, 29.029753, -13.06229, 0.01824683, 29.764137, -13.057354, 0.007337749, 29.029753, -17.585695, 0.20850176, 29.301727, -17.582396, 0.2010836, 28.810827, -13.057354, 0.007337749, 29.029753, -16.80835, 0.17621082, 29.407318, -17.585695, 0.20850176, 29.301727, -14.195347, 0.07104677, 29.993038, -16.80835, 0.17621082, 29.407318, -13.057354, 0.007337749, 29.029753, -17.420107, 0.093301594, 29.40146, -17.585695, 0.20850176, 29.301727, -16.80835, 0.17621082, 29.407318, -17.587553, 0.21286553, 29.57794, -17.420107, 0.093301594, 29.40146, -16.80835, 0.17621082, 29.407318, -16.80835, 0.17621082, 29.407318, -14.195347, 0.07104677, 29.993038, -17.587553, 0.21286553, 29.57794, -17.587553, 0.21286553, 29.57794, -14.195347, 0.07104677, 29.993038, -17.590448, 0.21810168, 29.944038, -17.59858, -0.16415358, 28.816393, -17.585695, 0.20850176, 29.301727, -17.602324, -0.15586269, 29.373617, -17.59858, -0.16415358, 28.816393, -17.582396, 0.2010836, 28.810827, -17.585695, 0.20850176, 29.301727, -17.587553, 0.21286553, 29.57794, -17.606195, -0.1471355, 29.949606, -17.602324, -0.15586269, 29.373617, -17.587553, 0.21286553, 29.57794, -17.590448, 0.21810168, 29.944038, -17.606195, -0.1471355, 29.949606, -17.420107, 0.093301594, 29.40146, -17.587553, 0.21286553, 29.57794, -17.602324, -0.15586269, 29.373617, -17.590448, 0.21810168, 29.944038, -13.080118, -0.3434996, 30.014496, -17.606195, -0.1471355, 29.949606, -13.080118, -0.3434996, 30.014496, -17.590448, 0.21810168, 29.944038, -13.067871, -0.06946254, 30.010216, -13.067871, -0.06946254, 30.010216, -17.590448, 0.21810168, 29.944038, -14.195347, 0.07104677, 29.993038, -13.067871, -0.06946254, 30.010216, -8.675467, -0.17375374, 29.706781, -13.080118, -0.3434996, 30.014496, -13.080118, -0.3434996, 30.014496, -8.675467, -0.17375374, 29.706781, -8.69165, -0.538991, 29.712345, -8.675467, -0.17375374, 29.706781, -13.067871, -0.06946254, 30.010216, -11.966818, -0.027135193, 29.933395, -9.878, -0.097390115, 31.312849, -8.993242, -0.5014638, 31.344105, -9.893747, -0.4626273, 31.318417, -9.878, -0.097390115, 31.312849, -8.977062, -0.13622653, 31.338978, -8.993242, -0.5014638, 31.344105, -9.893747, -0.4626273, 31.318417, -17.31272, 0.1343196, 31.278593, -9.878, -0.097390115, 31.312849, -9.878, -0.097390115, 31.312849, -17.31272, 0.1343196, 31.278593, -15.451195, 0.14479238, 31.285868, -17.31272, 0.1343196, 31.278593, -9.893747, -0.4626273, 31.318417, -17.324528, -0.13971746, 31.28244, -8.970457, -0.15106285, 30.356306, -9.878, -0.097390115, 31.312849, -9.871372, -0.11222637, 30.326687, -15.451195, 0.14479238, 31.285868, -9.871372, -0.11222637, 30.326687, -9.878, -0.097390115, 31.312849, -15.451195, 0.14479238, 31.285868, -17.303205, 0.21330172, 30.447365, -9.871372, -0.11222637, 30.326687, -17.303205, 0.21330172, 30.447365, -15.451195, 0.14479238, 31.285868, -17.307388, 0.22246522, 31.069607, -17.307388, 0.22246522, 31.069607, -15.451195, 0.14479238, 31.285868, -17.31272, 0.1343196, 31.278593, -9.878, -0.097390115, 31.312849, -8.970457, -0.15106285, 30.356306, -9.454359, -0.122262776, 30.87016, -9.454359, -0.122262776, 30.87016, -8.970457, -0.15106285, 30.356306, -8.973118, -0.14495373, 30.75208, -8.973118, -0.14495373, 30.75208, -9.062445, -0.27935404, 30.862755, -9.454359, -0.122262776, 30.87016, -9.062445, -0.27935404, 30.862755, -8.974958, -0.14102644, 31.026112, -9.454359, -0.122262776, 30.87016, -9.878, -0.097390115, 31.312849, -9.454359, -0.122262776, 30.87016, -8.974958, -0.14102644, 31.026112, -9.878, -0.097390115, 31.312849, -8.974958, -0.14102644, 31.026112, -8.977062, -0.13622653, 31.338978, -9.8871155, -0.47789997, 30.331818, -8.970457, -0.15106285, 30.356306, -9.871372, -0.11222637, 30.326687, -9.8871155, -0.47789997, 30.331818, -8.986637, -0.5163001, 30.361433, -8.970457, -0.15106285, 30.356306, -17.303205, 0.21330172, 30.447365, -9.8871155, -0.47789997, 30.331818, -9.871372, -0.11222637, 30.326687, -17.303205, 0.21330172, 30.447365, -17.318953, -0.15193558, 30.45293, -9.8871155, -0.47789997, 30.331818, -8.993242, -0.5014638, 31.344105, -9.8871155, -0.47789997, 30.331818, -9.893747, -0.4626273, 31.318417, -9.8871155, -0.47789997, 30.331818, -8.993242, -0.5014638, 31.344105, -8.989674, -0.50975466, 30.81306, -9.8871155, -0.47789997, 30.331818, -8.989674, -0.50975466, 30.81306, -8.986637, -0.5163001, 30.361433, -17.318953, -0.15193558, 30.45293, -9.893747, -0.4626273, 31.318417, -9.8871155, -0.47789997, 30.331818, -17.318953, -0.15193558, 30.45293, -17.324528, -0.13971746, 31.28244, -9.893747, -0.4626273, 31.318417, -8.974958, -0.14102644, 31.026112, -9.062445, -0.27935404, 30.862755, -8.989674, -0.50975466, 30.81306, -9.062445, -0.27935404, 30.862755, -8.973118, -0.14495373, 30.75208, -8.989674, -0.50975466, 30.81306, -8.993242, -0.5014638, 31.344105, -8.974958, -0.14102644, 31.026112, -8.989674, -0.50975466, 30.81306, -8.993242, -0.5014638, 31.344105, -8.977062, -0.13622653, 31.338978, -8.974958, -0.14102644, 31.026112, -8.973118, -0.14495373, 30.75208, -8.986637, -0.5163001, 30.361433, -8.989674, -0.50975466, 30.81306, -8.973118, -0.14495373, 30.75208, -8.970457, -0.15106285, 30.356306, -8.986637, -0.5163001, 30.361433, -17.303205, 0.21330172, 30.447365, -17.324528, -0.13971746, 31.28244, -17.318953, -0.15193558, 30.45293, -17.324528, -0.13971746, 31.28244, -17.303205, 0.21330172, 30.447365, -17.31272, 0.1343196, 31.278593, -17.31272, 0.1343196, 31.278593, -17.303205, 0.21330172, 30.447365, -17.307388, 0.22246522, 31.069607, -13.105944, -0.29549986, 33.143127, -8.988548, -0.111353934, 32.98316, -13.089764, 0.069737375, 33.138, -13.105944, -0.29549986, 33.143127, -9.004295, -0.47659117, 32.988728, -8.988548, -0.111353934, 32.98316, -17.31983, 0.25082868, 32.92106, -13.105944, -0.29549986, 33.143127, -13.089764, 0.069737375, 33.138, -17.31983, 0.25082868, 32.92106, -17.335577, -0.11440843, 32.926624, -13.105944, -0.29549986, 33.143127, -13.112524, -0.2806636, 34.12231, -9.004295, -0.47659117, 32.988728, -13.105944, -0.29549986, 33.143127, -13.112524, -0.2806636, 34.12231, -9.009869, -0.4639367, 33.818237, -9.004295, -0.47659117, 32.988728, -13.105944, -0.29549986, 33.143127, -17.343197, -0.09739047, 34.060276, -13.112524, -0.2806636, 34.12231, -13.105944, -0.29549986, 33.143127, -17.339323, -0.10611755, 33.483852, -17.343197, -0.09739047, 34.060276, -17.339323, -0.10611755, 33.483852, -13.105944, -0.29549986, 33.143127, -17.335577, -0.11440843, 32.926624, -9.009869, -0.4639367, 33.818237, -8.988548, -0.111353934, 32.98316, -9.004295, -0.47659117, 32.988728, -9.009869, -0.4639367, 33.818237, -8.994122, -0.09869945, 33.812668, -8.988548, -0.111353934, 32.98316, -17.323126, 0.25824696, 33.411522, -17.16845, 0.14348298, 33.51162, -17.339323, -0.10611755, 33.483852, -13.0947, 0.080646336, 33.872387, -13.100277, -0.0066265464, 34.118027, -14.154011, 0.1303919, 34.101345, -13.0947, 0.080646336, 33.872387, -12.070787, 0.038755357, 34.040726, -13.100277, -0.0066265464, 34.118027, -13.0947, 0.080646336, 33.872387, -8.994122, -0.09869945, 33.812668, -12.070787, 0.038755357, 34.040726, -13.0947, 0.080646336, 33.872387, -8.988548, -0.111353934, 32.98316, -8.994122, -0.09869945, 33.812668, -8.988548, -0.111353934, 32.98316, -13.0947, 0.080646336, 33.872387, -13.089764, 0.069737375, 33.138, -14.154011, 0.1303919, 34.101345, -13.089764, 0.069737375, 33.138, -13.0947, 0.080646336, 33.872387, -13.089764, 0.069737375, 33.138, -17.323126, 0.25824696, 33.411522, -17.31983, 0.25082868, 32.92106, -13.089764, 0.069737375, 33.138, -16.596401, 0.22813767, 33.51721, -17.323126, 0.25824696, 33.411522, -14.154011, 0.1303919, 34.101345, -16.596401, 0.22813767, 33.51721, -13.089764, 0.069737375, 33.138, -17.16845, 0.14348298, 33.51162, -17.323126, 0.25824696, 33.411522, -16.596401, 0.22813767, 33.51721, -17.324986, 0.2621742, 33.68817, -17.16845, 0.14348298, 33.51162, -16.596401, 0.22813767, 33.51721, -16.596401, 0.22813767, 33.51721, -14.154011, 0.1303919, 34.101345, -17.324986, 0.2621742, 33.68817, -17.324986, 0.2621742, 33.68817, -14.154011, 0.1303919, 34.101345, -17.32745, 0.26784688, 34.05471, -17.335577, -0.11440843, 32.926624, -17.323126, 0.25824696, 33.411522, -17.339323, -0.10611755, 33.483852, -17.335577, -0.11440843, 32.926624, -17.31983, 0.25082868, 32.92106, -17.323126, 0.25824696, 33.411522, -17.324986, 0.2621742, 33.68817, -17.343197, -0.09739047, 34.060276, -17.339323, -0.10611755, 33.483852, -17.324986, 0.2621742, 33.68817, -17.32745, 0.26784688, 34.05471, -17.343197, -0.09739047, 34.060276, -17.16845, 0.14348298, 33.51162, -17.324986, 0.2621742, 33.68817, -17.339323, -0.10611755, 33.483852, -17.32745, 0.26784688, 34.05471, -13.112524, -0.2806636, 34.12231, -17.343197, -0.09739047, 34.060276, -13.112524, -0.2806636, 34.12231, -17.32745, 0.26784688, 34.05471, -13.100277, -0.0066265464, 34.118027, -13.100277, -0.0066265464, 34.118027, -17.32745, 0.26784688, 34.05471, -14.154011, 0.1303919, 34.101345, -13.100277, -0.0066265464, 34.118027, -8.994122, -0.09869945, 33.812668, -13.112524, -0.2806636, 34.12231, -13.112524, -0.2806636, 34.12231, -8.994122, -0.09869945, 33.812668, -9.009869, -0.4639367, 33.818237, -8.994122, -0.09869945, 33.812668, -13.100277, -0.0066265464, 34.118027, -12.070787, 0.038755357, 34.040726, -15.954979, -0.19208127, 31.771221, -8.68903, -0.14408118, 31.659903, -15.939232, 0.17359239, 31.765654, -15.954979, -0.19208127, 31.771221, -8.704777, -0.50931835, 31.66547, -8.68903, -0.14408118, 31.659903, -17.602564, 0.24559253, 31.74662, -15.954979, -0.19208127, 31.771221, -15.939232, 0.17359239, 31.765654, -17.602564, 0.24559253, 31.74662, -17.61831, -0.11964476, 31.752188, -15.954979, -0.19208127, 31.771221, -15.961756, -0.1768086, 32.779636, -8.704777, -0.50931835, 31.66547, -15.954979, -0.19208127, 31.771221, -15.961756, -0.1768086, 32.779636, -8.71138, -0.49448207, 32.64814, -8.704777, -0.50931835, 31.66547, -17.61831, -0.11964476, 31.752188, -15.961756, -0.1768086, 32.779636, -15.954979, -0.19208127, 31.771221, -17.61831, -0.11964476, 31.752188, -17.623884, -0.10699028, 32.5817, -15.961756, -0.1768086, 32.779636, -17.61831, -0.11964476, 31.752188, -17.608137, 0.25824708, 32.57613, -17.623884, -0.10699028, 32.5817, -17.61831, -0.11964476, 31.752188, -17.602564, 0.24559253, 31.74662, -17.608137, 0.25824708, 32.57613, -15.944313, 0.18493778, 32.52186, -15.949944, 0.09722847, 32.775352, -16.361544, 0.20588332, 32.72502, -15.944313, 0.18493778, 32.52186, -14.133524, 0.109446704, 32.741302, -15.949944, 0.09722847, 32.775352, -15.944313, 0.18493778, 32.52186, -10.055107, -0.069462895, 32.667473, -14.133524, 0.109446704, 32.741302, -16.361544, 0.20588332, 32.72502, -15.939232, 0.17359239, 31.765654, -15.944313, 0.18493778, 32.52186, -16.361544, 0.20588332, 32.72502, -17.602564, 0.24559253, 31.74662, -15.939232, 0.17359239, 31.765654, -17.602564, 0.24559253, 31.74662, -16.361544, 0.20588332, 32.72502, -17.608137, 0.25824708, 32.57613, -8.68903, -0.14408118, 31.659903, -15.944313, 0.18493778, 32.52186, -15.939232, 0.17359239, 31.765654, -15.944313, 0.18493778, 32.52186, -8.68903, -0.14408118, 31.659903, -10.055107, -0.069462895, 32.667473, -10.055107, -0.069462895, 32.667473, -8.68903, -0.14408118, 31.659903, -8.693983, -0.13273573, 32.396904, -10.055107, -0.069462895, 32.667473, -8.693983, -0.13273573, 32.396904, -8.69957, -0.2204451, 32.643856, -17.608137, 0.25824708, 32.57613, -15.961756, -0.1768086, 32.779636, -17.623884, -0.10699028, 32.5817, -15.961756, -0.1768086, 32.779636, -17.608137, 0.25824708, 32.57613, -15.949944, 0.09722847, 32.775352, -15.949944, 0.09722847, 32.775352, -17.608137, 0.25824708, 32.57613, -16.361544, 0.20588332, 32.72502, -15.949944, 0.09722847, 32.775352, -8.69957, -0.2204451, 32.643856, -15.961756, -0.1768086, 32.779636, -15.961756, -0.1768086, 32.779636, -8.69957, -0.2204451, 32.643856, -8.71138, -0.49448207, 32.64814, -8.69957, -0.2204451, 32.643856, -15.949944, 0.09722847, 32.775352, -10.055107, -0.069462895, 32.667473, -10.055107, -0.069462895, 32.667473, -15.949944, 0.09722847, 32.775352, -14.133524, 0.109446704, 32.741302, -8.69957, -0.2204451, 32.643856, -8.704777, -0.50931835, 31.66547, -8.71138, -0.49448207, 32.64814, -8.704777, -0.50931835, 31.66547, -8.69957, -0.2204451, 32.643856, -8.68903, -0.14408118, 31.659903, -8.68903, -0.14408118, 31.659903, -8.69957, -0.2204451, 32.643856, -8.693983, -0.13273573, 32.396904, -13.166946, -0.5581908, 28.64937, -17.27211, -0.19208091, 28.80724, -13.166946, -0.19208091, 28.64937, -13.166946, -0.5581908, 28.64937, -17.27211, -0.5581909, 28.80724, -17.27211, -0.19208091, 28.80724, -8.932932, -0.19208091, 28.863285, -13.166946, -0.5581908, 28.64937, -13.166946, -0.19208091, 28.64937, -8.932932, -0.19208091, 28.863285, -8.932932, -0.5581909, 28.863285, -13.166946, -0.5581908, 28.64937, -13.160368, -0.5581907, 27.670628, -17.27211, -0.5581909, 28.80724, -13.166946, -0.5581908, 28.64937, -13.160368, -0.5581907, 27.670628, -17.266533, -0.5581908, 27.977295, -17.27211, -0.5581909, 28.80724, -13.166946, -0.5581908, 28.64937, -8.925314, -0.55819076, 27.729633, -13.160368, -0.5581907, 27.670628, -13.166946, -0.5581908, 28.64937, -8.929188, -0.5581908, 28.306059, -8.925314, -0.55819076, 27.729633, -8.929188, -0.5581908, 28.306059, -13.166946, -0.5581908, 28.64937, -8.932932, -0.5581909, 28.863285, -17.266533, -0.5581908, 27.977295, -17.27211, -0.19208091, 28.80724, -17.27211, -0.5581909, 28.80724, -17.266533, -0.5581908, 27.977295, -17.266533, -0.1920808, 27.977295, -17.27211, -0.19208091, 28.80724, -8.929636, -0.19208086, 28.372822, -9.089121, -0.30160832, 28.274002, -8.929188, -0.5581908, 28.306059, -13.16201, -0.1920808, 27.914986, -13.160368, -0.28371733, 27.670628, -12.101822, -0.1920808, 27.685158, -13.16201, -0.1920808, 27.914986, -14.1868, -0.1920808, 27.747076, -13.160368, -0.28371733, 27.670628, -13.16201, -0.1920808, 27.914986, -17.266533, -0.1920808, 27.977295, -14.1868, -0.1920808, 27.747076, -13.16201, -0.1920808, 27.914986, -17.27211, -0.19208091, 28.80724, -17.266533, -0.1920808, 27.977295, -17.27211, -0.19208091, 28.80724, -13.16201, -0.1920808, 27.914986, -13.166946, -0.19208091, 28.64937, -12.101822, -0.1920808, 27.685158, -13.166946, -0.19208091, 28.64937, -13.16201, -0.1920808, 27.914986, -13.166946, -0.19208091, 28.64937, -8.929636, -0.19208086, 28.372822, -8.932932, -0.19208091, 28.863285, -13.166946, -0.19208091, 28.64937, -9.656805, -0.19208086, 28.268005, -8.929636, -0.19208086, 28.372822, -12.101822, -0.1920808, 27.685158, -9.656805, -0.19208086, 28.268005, -13.166946, -0.19208091, 28.64937, -9.089121, -0.30160832, 28.274002, -8.929636, -0.19208086, 28.372822, -9.656805, -0.19208086, 28.268005, -8.92778, -0.19208086, 28.09661, -9.089121, -0.30160832, 28.274002, -9.656805, -0.19208086, 28.268005, -9.656805, -0.19208086, 28.268005, -12.101822, -0.1920808, 27.685158, -8.92778, -0.19208086, 28.09661, -8.92778, -0.19208086, 28.09661, -12.101822, -0.1920808, 27.685158, -8.925314, -0.1920808, 27.729633, -8.932932, -0.5581909, 28.863285, -8.929636, -0.19208086, 28.372822, -8.929188, -0.5581908, 28.306059, -8.932932, -0.5581909, 28.863285, -8.932932, -0.19208091, 28.863285, -8.929636, -0.19208086, 28.372822, -8.92778, -0.19208086, 28.09661, -8.925314, -0.55819076, 27.729633, -8.929188, -0.5581908, 28.306059, -8.92778, -0.19208086, 28.09661, -8.925314, -0.1920808, 27.729633, -8.925314, -0.55819076, 27.729633, -9.089121, -0.30160832, 28.274002, -8.92778, -0.19208086, 28.09661, -8.929188, -0.5581908, 28.306059, -8.925314, -0.1920808, 27.729633, -13.160368, -0.5581907, 27.670628, -8.925314, -0.55819076, 27.729633, -13.160368, -0.5581907, 27.670628, -8.925314, -0.1920808, 27.729633, -12.101822, -0.1920808, 27.685158, -13.160368, -0.5581907, 27.670628, -12.101822, -0.1920808, 27.685158, -13.160368, -0.28371733, 27.670628, -13.160368, -0.28371733, 27.670628, -17.266533, -0.5581908, 27.977295, -13.160368, -0.5581907, 27.670628, -13.160368, -0.28371733, 27.670628, -17.266533, -0.1920808, 27.977295, -17.266533, -0.5581908, 27.977295, -17.266533, -0.1920808, 27.977295, -13.160368, -0.28371733, 27.670628, -14.1868, -0.1920808, 27.747076, -16.346624, -0.1920805, 25.245663, -17.248005, -0.55819046, 25.220404, -16.346624, -0.55819046, 25.245663, -16.346624, -0.1920805, 25.245663, -17.248005, -0.1920805, 25.220404, -17.248005, -0.55819046, 25.220404, -16.346624, -0.55819046, 25.245663, -10.768602, -0.1920805, 25.26875, -16.346624, -0.1920805, 25.245663, -16.346624, -0.55819046, 25.245663, -8.908827, -0.28371704, 25.276447, -10.768602, -0.1920805, 25.26875, -8.908827, -0.28371704, 25.276447, -16.346624, -0.55819046, 25.245663, -8.908827, -0.55819046, 25.276447, -17.254608, -0.19208062, 26.203075, -16.346624, -0.1920805, 25.245663, -16.353252, -0.19208062, 26.231823, -10.768602, -0.1920805, 25.26875, -16.353252, -0.19208062, 26.231823, -16.346624, -0.1920805, 25.245663, -10.768602, -0.1920805, 25.26875, -8.914402, -0.19208062, 26.105959, -16.353252, -0.19208062, 26.231823, -8.914402, -0.19208062, 26.105959, -10.768602, -0.1920805, 25.26875, -8.910217, -0.1920805, 25.48328, -8.910217, -0.1920805, 25.48328, -10.768602, -0.1920805, 25.26875, -8.908827, -0.28371704, 25.276447, -16.346624, -0.1920805, 25.245663, -17.254608, -0.19208062, 26.203075, -16.7707, -0.19208056, 25.68835, -16.7707, -0.19208056, 25.68835, -17.254608, -0.19208062, 26.203075, -17.251945, -0.19208056, 25.806864, -17.251945, -0.19208056, 25.806864, -17.169178, -0.33171725, 25.698326, -16.7707, -0.19208056, 25.68835, -17.169178, -0.33171725, 25.698326, -17.250105, -0.1920805, 25.532833, -16.7707, -0.19208056, 25.68835, -16.346624, -0.1920805, 25.245663, -16.7707, -0.19208056, 25.68835, -17.250105, -0.1920805, 25.532833, -16.346624, -0.1920805, 25.245663, -17.250105, -0.1920805, 25.532833, -17.248005, -0.1920805, 25.220404, -16.353252, -0.5581906, 26.231823, -17.254608, -0.19208062, 26.203075, -16.353252, -0.19208062, 26.231823, -16.353252, -0.5581906, 26.231823, -17.254608, -0.5581906, 26.203075, -17.254608, -0.19208062, 26.203075, -8.914402, -0.19208062, 26.105959, -16.353252, -0.5581906, 26.231823, -16.353252, -0.19208062, 26.231823, -8.914402, -0.19208062, 26.105959, -8.914402, -0.5581906, 26.105959, -16.353252, -0.5581906, 26.231823, -17.248005, -0.55819046, 25.220404, -16.353252, -0.5581906, 26.231823, -16.346624, -0.55819046, 25.245663, -16.353252, -0.5581906, 26.231823, -17.248005, -0.55819046, 25.220404, -17.251574, -0.5581905, 25.751448, -16.353252, -0.5581906, 26.231823, -17.251574, -0.5581905, 25.751448, -17.254608, -0.5581906, 26.203075, -8.914402, -0.5581906, 26.105959, -16.346624, -0.55819046, 25.245663, -16.353252, -0.5581906, 26.231823, -8.914402, -0.5581906, 26.105959, -8.908827, -0.55819046, 25.276447, -16.346624, -0.55819046, 25.245663, -17.250105, -0.1920805, 25.532833, -17.169178, -0.33171725, 25.698326, -17.251574, -0.5581905, 25.751448, -17.169178, -0.33171725, 25.698326, -17.251945, -0.19208056, 25.806864, -17.251574, -0.5581905, 25.751448, -17.248005, -0.55819046, 25.220404, -17.250105, -0.1920805, 25.532833, -17.251574, -0.5581905, 25.751448, -17.248005, -0.55819046, 25.220404, -17.248005, -0.1920805, 25.220404, -17.250105, -0.1920805, 25.532833, -17.251945, -0.19208056, 25.806864, -17.254608, -0.5581906, 26.203075, -17.251574, -0.5581905, 25.751448, -17.251945, -0.19208056, 25.806864, -17.254608, -0.19208062, 26.203075, -17.254608, -0.5581906, 26.203075, -8.914402, -0.19208062, 26.105959, -8.908827, -0.55819046, 25.276447, -8.914402, -0.5581906, 26.105959, -8.908827, -0.55819046, 25.276447, -8.914402, -0.19208062, 26.105959, -8.910217, -0.1920805, 25.48328, -8.908827, -0.55819046, 25.276447, -8.910217, -0.1920805, 25.48328, -8.908827, -0.28371704, 25.276447, -16.566906, -0.19208038, 24.06379, -17.53112, -0.55819035, 24.038109, -16.566906, -0.55819035, 24.06379, -16.566906, -0.19208038, 24.06379, -17.53112, -0.19208038, 24.038109, -17.53112, -0.55819035, 24.038109, -16.566906, -0.55819035, 24.06379, -10.599218, -0.19208038, 24.089493, -16.566906, -0.19208038, 24.06379, -16.566906, -0.55819035, 24.06379, -8.610281, -0.28371692, 24.09806, -10.599218, -0.19208038, 24.089493, -8.610281, -0.28371692, 24.09806, -16.566906, -0.55819035, 24.06379, -8.610281, -0.55819035, 24.09806, -17.537725, -0.19208044, 25.020779, -16.566906, -0.19208038, 24.06379, -16.573536, -0.1920805, 25.050386, -10.599218, -0.19208038, 24.089493, -16.573536, -0.1920805, 25.050386, -16.566906, -0.19208038, 24.06379, -10.599218, -0.19208038, 24.089493, -8.61586, -0.19208044, 24.928009, -16.573536, -0.1920805, 25.050386, -8.61586, -0.19208044, 24.928009, -10.599218, -0.19208038, 24.089493, -8.611677, -0.19208038, 24.305765, -8.611677, -0.19208038, 24.305765, -10.599218, -0.19208038, 24.089493, -8.610281, -0.28371692, 24.09806, -16.566906, -0.19208038, 24.06379, -17.537725, -0.19208044, 25.020779, -17.02022, -0.19208038, 24.506718, -17.02022, -0.19208038, 24.506718, -17.537725, -0.19208044, 25.020779, -17.535063, -0.19208044, 24.624569, -17.535063, -0.19208044, 24.624569, -17.446188, -0.33171707, 24.51651, -17.02022, -0.19208038, 24.506718, -17.446188, -0.33171707, 24.51651, -17.533224, -0.19208038, 24.350975, -17.02022, -0.19208038, 24.506718, -16.566906, -0.19208038, 24.06379, -17.02022, -0.19208038, 24.506718, -17.533224, -0.19208038, 24.350975, -16.566906, -0.19208038, 24.06379, -17.533224, -0.19208038, 24.350975, -17.53112, -0.19208038, 24.038109, -16.573536, -0.55819046, 25.050386, -17.537725, -0.19208044, 25.020779, -16.573536, -0.1920805, 25.050386, -16.573536, -0.55819046, 25.050386, -17.537725, -0.55819046, 25.020779, -17.537725, -0.19208044, 25.020779, -8.61586, -0.19208044, 24.928009, -16.573536, -0.55819046, 25.050386, -16.573536, -0.1920805, 25.050386, -8.61586, -0.19208044, 24.928009, -8.61586, -0.5581904, 24.928009, -16.573536, -0.55819046, 25.050386, -17.53112, -0.55819035, 24.038109, -16.573536, -0.55819046, 25.050386, -16.566906, -0.55819035, 24.06379, -16.573536, -0.55819046, 25.050386, -17.53112, -0.55819035, 24.038109, -17.534693, -0.55819035, 24.569588, -16.573536, -0.55819046, 25.050386, -17.534693, -0.55819035, 24.569588, -17.537725, -0.55819046, 25.020779, -8.61586, -0.5581904, 24.928009, -16.566906, -0.55819035, 24.06379, -16.573536, -0.55819046, 25.050386, -8.61586, -0.5581904, 24.928009, -8.610281, -0.55819035, 24.09806, -16.566906, -0.55819035, 24.06379, -17.533224, -0.19208038, 24.350975, -17.446188, -0.33171707, 24.51651, -17.534693, -0.55819035, 24.569588, -17.446188, -0.33171707, 24.51651, -17.535063, -0.19208044, 24.624569, -17.534693, -0.55819035, 24.569588, -17.53112, -0.55819035, 24.038109, -17.533224, -0.19208038, 24.350975, -17.534693, -0.55819035, 24.569588, -17.53112, -0.55819035, 24.038109, -17.53112, -0.19208038, 24.038109, -17.533224, -0.19208038, 24.350975, -17.535063, -0.19208044, 24.624569, -17.537725, -0.55819046, 25.020779, -17.534693, -0.55819035, 24.569588, -17.535063, -0.19208044, 24.624569, -17.537725, -0.19208044, 25.020779, -17.537725, -0.55819046, 25.020779, -8.61586, -0.19208044, 24.928009, -8.610281, -0.55819035, 24.09806, -8.61586, -0.5581904, 24.928009, -8.610281, -0.55819035, 24.09806, -8.61586, -0.19208044, 24.928009, -8.611677, -0.19208038, 24.305765, -8.610281, -0.55819035, 24.09806, -8.611677, -0.19208038, 24.305765, -8.610281, -0.28371692, 24.09806, -10.358263, -0.5581907, 27.454252, -17.457956, -0.1920808, 27.566252, -10.358263, -0.19208074, 27.454252, -10.358263, -0.5581907, 27.454252, -17.457956, -0.5581907, 27.566252, -17.457956, -0.1920808, 27.566252, -8.72983, -0.19208074, 27.471743, -10.358263, -0.5581907, 27.454252, -10.358263, -0.19208074, 27.454252, -8.72983, -0.19208074, 27.471743, -8.72983, -0.5581907, 27.471743, -10.358263, -0.5581907, 27.454252, -10.351484, -0.5581906, 26.445835, -17.457956, -0.5581907, 27.566252, -10.358263, -0.5581907, 27.454252, -10.351484, -0.5581906, 26.445835, -17.451353, -0.5581906, 26.58358, -17.457956, -0.5581907, 27.566252, -8.72983, -0.5581907, 27.471743, -10.351484, -0.5581906, 26.445835, -10.358263, -0.5581907, 27.454252, -8.72983, -0.5581907, 27.471743, -8.724255, -0.5581906, 26.642231, -10.351484, -0.5581906, 26.445835, -8.72983, -0.5581907, 27.471743, -8.724255, -0.19208068, 26.642231, -8.724255, -0.5581906, 26.642231, -8.72983, -0.5581907, 27.471743, -8.72983, -0.19208074, 27.471743, -8.724255, -0.19208068, 26.642231, -10.35318, -0.19208068, 26.69805, -10.351484, -0.28371716, 26.445835, -9.944677, -0.19208062, 26.494825, -10.35318, -0.19208068, 26.69805, -12.1264515, -0.19208062, 26.480164, -10.351484, -0.28371716, 26.445835, -10.35318, -0.19208068, 26.69805, -16.120235, -0.19208068, 26.557617, -12.1264515, -0.19208062, 26.480164, -9.944677, -0.19208062, 26.494825, -10.358263, -0.19208074, 27.454252, -10.35318, -0.19208068, 26.69805, -9.944677, -0.19208062, 26.494825, -8.72983, -0.19208074, 27.471743, -10.358263, -0.19208074, 27.454252, -8.72983, -0.19208074, 27.471743, -9.944677, -0.19208062, 26.494825, -8.724255, -0.19208068, 26.642231, -17.457956, -0.1920808, 27.566252, -10.35318, -0.19208068, 26.69805, -10.358263, -0.19208074, 27.454252, -10.35318, -0.19208068, 26.69805, -17.457956, -0.1920808, 27.566252, -16.120235, -0.19208068, 26.557617, -16.120235, -0.19208068, 26.557617, -17.457956, -0.1920808, 27.566252, -17.453001, -0.19208068, 26.828812, -16.120235, -0.19208068, 26.557617, -17.453001, -0.19208068, 26.828812, -17.451353, -0.28371722, 26.58358, -8.724255, -0.19208068, 26.642231, -10.351484, -0.5581906, 26.445835, -8.724255, -0.5581906, 26.642231, -10.351484, -0.5581906, 26.445835, -8.724255, -0.19208068, 26.642231, -9.944677, -0.19208062, 26.494825, -10.351484, -0.5581906, 26.445835, -9.944677, -0.19208062, 26.494825, -10.351484, -0.28371716, 26.445835, -10.351484, -0.28371716, 26.445835, -17.451353, -0.5581906, 26.58358, -10.351484, -0.5581906, 26.445835, -10.351484, -0.28371716, 26.445835, -16.120235, -0.19208068, 26.557617, -17.451353, -0.5581906, 26.58358, -17.451353, -0.5581906, 26.58358, -16.120235, -0.19208068, 26.557617, -17.451353, -0.28371722, 26.58358, -16.120235, -0.19208068, 26.557617, -10.351484, -0.28371716, 26.445835, -12.1264515, -0.19208062, 26.480164, -17.451353, -0.28371722, 26.58358, -17.457956, -0.5581907, 27.566252, -17.451353, -0.5581906, 26.58358, -17.457956, -0.5581907, 27.566252, -17.451353, -0.28371722, 26.58358, -17.453001, -0.19208068, 26.828812, -17.457956, -0.5581907, 27.566252, -17.453001, -0.19208068, 26.828812, -17.457956, -0.1920808, 27.566252, -13.511387, 0.0055903792, 44.578655, -17.616987, 0.37126416, 44.736523, -13.511387, 0.37126416, 44.578655, -13.511387, 0.0055903792, 44.578655, -17.616987, 0.0055903792, 44.736523, -17.616987, 0.37126416, 44.736523, -9.277809, 0.37126416, 44.792564, -13.511387, 0.0055903792, 44.578655, -13.511387, 0.37126416, 44.578655, -9.277809, 0.37126416, 44.792564, -9.277809, 0.0055903792, 44.792564, -13.511387, 0.0055903792, 44.578655, -13.50481, 0.0055904984, 43.59991, -17.616987, 0.0055903792, 44.736523, -13.511387, 0.0055903792, 44.578655, -13.50481, 0.0055904984, 43.59991, -17.61141, 0.0055904984, 43.906574, -17.616987, 0.0055903792, 44.736523, -13.511387, 0.0055903792, 44.578655, -9.270195, 0.0055904984, 43.65935, -13.50481, 0.0055904984, 43.59991, -13.511387, 0.0055903792, 44.578655, -9.274065, 0.005590439, 44.23534, -9.270195, 0.0055904984, 43.65935, -9.274065, 0.005590439, 44.23534, -13.511387, 0.0055903792, 44.578655, -9.277809, 0.0055903792, 44.792564, -17.61141, 0.0055904984, 43.906574, -17.616987, 0.37126416, 44.736523, -17.616987, 0.0055903792, 44.736523, -17.61141, 0.0055904984, 43.906574, -17.61141, 0.37126416, 43.906574, -17.616987, 0.37126416, 44.736523, -9.274517, 0.37126416, 44.30254, -9.433565, 0.26217288, 44.20372, -9.274065, 0.005590439, 44.23534, -13.506453, 0.37126416, 43.84427, -13.50481, 0.28006393, 43.59991, -12.446262, 0.37126428, 43.61444, -13.506453, 0.37126416, 43.84427, -14.531677, 0.37126428, 43.676357, -13.50481, 0.28006393, 43.59991, -13.506453, 0.37126416, 43.84427, -17.61141, 0.37126416, 43.906574, -14.531677, 0.37126428, 43.676357, -13.506453, 0.37126416, 43.84427, -17.616987, 0.37126416, 44.736523, -17.61141, 0.37126416, 43.906574, -17.616987, 0.37126416, 44.736523, -13.506453, 0.37126416, 43.84427, -13.511387, 0.37126416, 44.578655, -12.446262, 0.37126428, 43.61444, -13.511387, 0.37126416, 44.578655, -13.506453, 0.37126416, 43.84427, -13.511387, 0.37126416, 44.578655, -9.274517, 0.37126416, 44.30254, -9.277809, 0.37126416, 44.792564, -13.511387, 0.37126416, 44.578655, -10.001682, 0.37126416, 44.19729, -9.274517, 0.37126416, 44.30254, -12.446262, 0.37126428, 43.61444, -10.001682, 0.37126416, 44.19729, -13.511387, 0.37126416, 44.578655, -9.433565, 0.26217288, 44.20372, -9.274517, 0.37126416, 44.30254, -10.001682, 0.37126416, 44.19729, -9.272657, 0.37126416, 44.02589, -9.433565, 0.26217288, 44.20372, -10.001682, 0.37126416, 44.19729, -10.001682, 0.37126416, 44.19729, -12.446262, 0.37126428, 43.61444, -9.272657, 0.37126416, 44.02589, -9.272657, 0.37126416, 44.02589, -12.446262, 0.37126428, 43.61444, -9.270195, 0.37126428, 43.65935, -9.277809, 0.0055903792, 44.792564, -9.274517, 0.37126416, 44.30254, -9.274065, 0.005590439, 44.23534, -9.277809, 0.0055903792, 44.792564, -9.277809, 0.37126416, 44.792564, -9.274517, 0.37126416, 44.30254, -9.272657, 0.37126416, 44.02589, -9.270195, 0.0055904984, 43.65935, -9.274065, 0.005590439, 44.23534, -9.272657, 0.37126416, 44.02589, -9.270195, 0.37126428, 43.65935, -9.270195, 0.0055904984, 43.65935, -9.433565, 0.26217288, 44.20372, -9.272657, 0.37126416, 44.02589, -9.274065, 0.005590439, 44.23534, -9.270195, 0.37126428, 43.65935, -13.50481, 0.0055904984, 43.59991, -9.270195, 0.0055904984, 43.65935, -13.50481, 0.0055904984, 43.59991, -9.270195, 0.37126428, 43.65935, -12.446262, 0.37126428, 43.61444, -13.50481, 0.0055904984, 43.59991, -12.446262, 0.37126428, 43.61444, -13.50481, 0.28006393, 43.59991, -13.50481, 0.28006393, 43.59991, -17.61141, 0.0055904984, 43.906574, -13.50481, 0.0055904984, 43.59991, -13.50481, 0.28006393, 43.59991, -17.61141, 0.37126416, 43.906574, -17.61141, 0.0055904984, 43.906574, -17.61141, 0.37126416, 43.906574, -13.50481, 0.28006393, 43.59991, -14.531677, 0.37126428, 43.676357, -16.691502, 0.37126452, 41.174942, -17.592882, 0.0055907965, 41.149685, -16.691502, 0.0055907965, 41.174942, -16.691502, 0.37126452, 41.174942, -17.592882, 0.37126452, 41.149685, -17.592882, 0.0055907965, 41.149685, -16.691502, 0.0055907965, 41.174942, -11.113045, 0.37126452, 41.198032, -16.691502, 0.37126452, 41.174942, -16.691502, 0.0055907965, 41.174942, -9.253704, 0.28006417, 41.20573, -11.113045, 0.37126452, 41.198032, -9.253704, 0.28006417, 41.20573, -16.691502, 0.0055907965, 41.174942, -9.253704, 0.0055907965, 41.20573, -17.599485, 0.3712644, 42.132355, -16.691502, 0.37126452, 41.174942, -16.698133, 0.3712644, 42.16154, -11.113045, 0.37126452, 41.198032, -16.698133, 0.3712644, 42.16154, -16.691502, 0.37126452, 41.174942, -11.113045, 0.37126452, 41.198032, -9.259279, 0.3712644, 42.03524, -16.698133, 0.3712644, 42.16154, -9.259279, 0.3712644, 42.03524, -11.113045, 0.37126452, 41.198032, -9.255098, 0.37126452, 41.413, -9.255098, 0.37126452, 41.413, -11.113045, 0.37126452, 41.198032, -9.253704, 0.28006417, 41.20573, -16.691502, 0.37126452, 41.174942, -17.599485, 0.3712644, 42.132355, -17.115143, 0.37126452, 41.617634, -17.115143, 0.37126452, 41.617634, -17.599485, 0.3712644, 42.132355, -17.596823, 0.37126452, 41.736145, -17.596823, 0.37126452, 41.736145, -17.513622, 0.23162776, 41.628048, -17.115143, 0.37126452, 41.617634, -17.513622, 0.23162776, 41.628048, -17.594984, 0.37126452, 41.46255, -17.115143, 0.37126452, 41.617634, -16.691502, 0.37126452, 41.174942, -17.115143, 0.37126452, 41.617634, -17.594984, 0.37126452, 41.46255, -16.691502, 0.37126452, 41.174942, -17.594984, 0.37126452, 41.46255, -17.592882, 0.37126452, 41.149685, -16.698133, 0.0055906773, 42.16154, -17.599485, 0.3712644, 42.132355, -16.698133, 0.3712644, 42.16154, -16.698133, 0.0055906773, 42.16154, -17.599485, 0.0055906773, 42.132355, -17.599485, 0.3712644, 42.132355, -9.259279, 0.3712644, 42.03524, -16.698133, 0.0055906773, 42.16154, -16.698133, 0.3712644, 42.16154, -9.259279, 0.3712644, 42.03524, -9.259279, 0.005590737, 42.03524, -16.698133, 0.0055906773, 42.16154, -17.592882, 0.0055907965, 41.149685, -16.698133, 0.0055906773, 42.16154, -16.691502, 0.0055907965, 41.174942, -16.698133, 0.0055906773, 42.16154, -17.592882, 0.0055907965, 41.149685, -17.59645, 0.005590737, 41.68073, -16.698133, 0.0055906773, 42.16154, -17.59645, 0.005590737, 41.68073, -17.599485, 0.0055906773, 42.132355, -9.259279, 0.005590737, 42.03524, -16.691502, 0.0055907965, 41.174942, -16.698133, 0.0055906773, 42.16154, -9.259279, 0.005590737, 42.03524, -9.253704, 0.0055907965, 41.20573, -16.691502, 0.0055907965, 41.174942, -17.594984, 0.37126452, 41.46255, -17.513622, 0.23162776, 41.628048, -17.59645, 0.005590737, 41.68073, -17.513622, 0.23162776, 41.628048, -17.596823, 0.37126452, 41.736145, -17.59645, 0.005590737, 41.68073, -17.592882, 0.0055907965, 41.149685, -17.594984, 0.37126452, 41.46255, -17.59645, 0.005590737, 41.68073, -17.592882, 0.0055907965, 41.149685, -17.592882, 0.37126452, 41.149685, -17.594984, 0.37126452, 41.46255, -17.596823, 0.37126452, 41.736145, -17.599485, 0.0055906773, 42.132355, -17.59645, 0.005590737, 41.68073, -17.596823, 0.37126452, 41.736145, -17.599485, 0.3712644, 42.132355, -17.599485, 0.0055906773, 42.132355, -9.259279, 0.3712644, 42.03524, -9.253704, 0.0055907965, 41.20573, -9.259279, 0.005590737, 42.03524, -9.253704, 0.0055907965, 41.20573, -9.259279, 0.3712644, 42.03524, -9.255098, 0.37126452, 41.413, -9.253704, 0.0055907965, 41.20573, -9.255098, 0.37126452, 41.413, -9.253704, 0.28006417, 41.20573, -9.466791, -0.19077104, 22.980423, -9.698496, -0.09826177, 22.978865, -9.698496, -0.19077104, 22.978865, -9.466791, -0.19077104, 22.980423, -9.466791, -0.09826177, 22.980423, -9.698496, -0.09826177, 22.978865, -9.466791, -0.09826177, 22.980423, -9.864088, -0.098264754, 47.618515, -9.698496, -0.09826177, 22.978865, -9.466791, -0.09826177, 22.980423, -9.632383, -0.098264754, 47.62007, -9.864088, -0.098264754, 47.618515, -9.632383, -0.098264754, 47.62007, -9.864088, -0.19077402, 47.618515, -9.864088, -0.098264754, 47.618515, -9.632383, -0.098264754, 47.62007, -9.632383, -0.19077402, 47.62007, -9.864088, -0.19077402, 47.618515, -9.632383, -0.19077402, 47.62007, -9.698496, -0.19077104, 22.978865, -9.864088, -0.19077402, 47.618515, -9.632383, -0.19077402, 47.62007, -9.466791, -0.19077104, 22.980423, -9.698496, -0.19077104, 22.978865, -9.698496, -0.19077104, 22.978865, -9.864088, -0.098264754, 47.618515, -9.864088, -0.19077402, 47.618515, -9.698496, -0.19077104, 22.978865, -9.698496, -0.09826177, 22.978865, -9.864088, -0.098264754, 47.618515, -9.632383, -0.19077402, 47.62007, -9.466791, -0.09826177, 22.980423, -9.466791, -0.19077104, 22.980423, -9.632383, -0.19077402, 47.62007, -9.632383, -0.098264754, 47.62007, -9.466791, -0.09826177, 22.980423, -10.65929, 0.00559026, 45.949276, -17.916506, 0.37126392, 46.05978, -10.65929, 0.37126392, 45.949276, -10.65929, 0.00559026, 45.949276, -17.916506, 0.0055902004, 46.05978, -17.916506, 0.37126392, 46.05978, -8.99464, 0.37126392, 45.967007, -10.65929, 0.00559026, 45.949276, -10.65929, 0.37126392, 45.949276, -8.99464, 0.37126392, 45.967007, -8.99464, 0.00559026, 45.967007, -10.65929, 0.00559026, 45.949276, -10.65251, 0.0055903792, 44.940422, -17.916506, 0.0055902004, 46.05978, -10.65929, 0.00559026, 45.949276, -10.65251, 0.0055903792, 44.940422, -17.909903, 0.0055903196, 45.07711, -17.916506, 0.0055902004, 46.05978, -8.99464, 0.00559026, 45.967007, -10.65251, 0.0055903792, 44.940422, -10.65929, 0.00559026, 45.949276, -8.99464, 0.00559026, 45.967007, -8.989063, 0.0055903196, 45.137062, -10.65251, 0.0055903792, 44.940422, -8.99464, 0.00559026, 45.967007, -8.989063, 0.37126404, 45.137062, -8.989063, 0.0055903196, 45.137062, -8.99464, 0.00559026, 45.967007, -8.99464, 0.37126392, 45.967007, -8.989063, 0.37126404, 45.137062, -10.654205, 0.37126404, 45.192635, -10.65251, 0.2800637, 44.940422, -10.236538, 0.37126404, 44.98947, -10.654205, 0.37126404, 45.192635, -12.466749, 0.37126404, 44.974487, -10.65251, 0.2800637, 44.940422, -10.654205, 0.37126404, 45.192635, -16.549116, 0.37126404, 45.05178, -12.466749, 0.37126404, 44.974487, -10.236538, 0.37126404, 44.98947, -10.65929, 0.37126392, 45.949276, -10.654205, 0.37126404, 45.192635, -10.236538, 0.37126404, 44.98947, -8.99464, 0.37126392, 45.967007, -10.65929, 0.37126392, 45.949276, -8.99464, 0.37126392, 45.967007, -10.236538, 0.37126404, 44.98947, -8.989063, 0.37126404, 45.137062, -17.916506, 0.37126392, 46.05978, -10.654205, 0.37126404, 45.192635, -10.65929, 0.37126392, 45.949276, -10.654205, 0.37126404, 45.192635, -17.916506, 0.37126392, 46.05978, -16.549116, 0.37126404, 45.05178, -16.549116, 0.37126404, 45.05178, -17.916506, 0.37126392, 46.05978, -17.911556, 0.37126404, 45.32321, -16.549116, 0.37126404, 45.05178, -17.911556, 0.37126404, 45.32321, -17.909903, 0.2800637, 45.07711, -8.989063, 0.37126404, 45.137062, -10.65251, 0.0055903792, 44.940422, -8.989063, 0.0055903196, 45.137062, -10.65251, 0.0055903792, 44.940422, -8.989063, 0.37126404, 45.137062, -10.236538, 0.37126404, 44.98947, -10.65251, 0.0055903792, 44.940422, -10.236538, 0.37126404, 44.98947, -10.65251, 0.2800637, 44.940422, -10.65251, 0.2800637, 44.940422, -17.909903, 0.0055903196, 45.07711, -10.65251, 0.0055903792, 44.940422, -10.65251, 0.2800637, 44.940422, -16.549116, 0.37126404, 45.05178, -17.909903, 0.0055903196, 45.07711, -17.909903, 0.0055903196, 45.07711, -16.549116, 0.37126404, 45.05178, -17.909903, 0.2800637, 45.07711, -16.549116, 0.37126404, 45.05178, -10.65251, 0.2800637, 44.940422, -12.466749, 0.37126404, 44.974487, -17.909903, 0.2800637, 45.07711, -17.916506, 0.0055902004, 46.05978, -17.909903, 0.0055903196, 45.07711, -17.916506, 0.0055902004, 46.05978, -17.909903, 0.2800637, 45.07711, -17.911556, 0.37126404, 45.32321, -17.916506, 0.0055902004, 46.05978, -17.911556, 0.37126404, 45.32321, -17.916506, 0.37126392, 46.05978, -9.086136, -3.458273, 47.63378, -9.862558, 1.270175, 47.455757, -9.690924, -3.458273, 47.629715, -9.086136, -3.458273, 47.63378, -8.912178, 1.270175, 47.462143, -9.862558, 1.270175, 47.455757, -8.912178, 1.270175, 47.462143, -9.868942, 1.2701747, 48.4057, -9.862558, 1.270175, 47.455757, -8.912178, 1.270175, 47.462143, -8.918562, 1.2701747, 48.41209, -9.868942, 1.2701747, 48.4057, -8.918562, 1.2701747, 48.41209, -9.694984, -3.458273, 48.234066, -9.868942, 1.2701747, 48.4057, -8.918562, 1.2701747, 48.41209, -9.090197, -3.458273, 48.238132, -9.694984, -3.458273, 48.234066, -9.090197, -3.458273, 48.238132, -9.690924, -3.458273, 47.629715, -9.694984, -3.458273, 48.234066, -9.090197, -3.458273, 48.238132, -9.086136, -3.458273, 47.63378, -9.690924, -3.458273, 47.629715, -9.690924, -3.458273, 47.629715, -9.868942, 1.2701747, 48.4057, -9.694984, -3.458273, 48.234066, -9.690924, -3.458273, 47.629715, -9.862558, 1.270175, 47.455757, -9.868942, 1.2701747, 48.4057, -9.090197, -3.458273, 48.238132, -8.912178, 1.270175, 47.462143, -9.086136, -3.458273, 47.63378, -9.090197, -3.458273, 48.238132, -8.918562, 1.2701747, 48.41209, -8.912178, 1.270175, 47.462143, -16.72666, 0.37126392, 46.406403, -17.628038, 0.0055902004, 46.380707, -16.72666, 0.0055902004, 46.406403, -16.72666, 0.37126392, 46.406403, -17.628038, 0.37126392, 46.380707, -17.628038, 0.0055902004, 46.380707, -16.72666, 0.0055902004, 46.406403, -11.148199, 0.37126392, 46.429054, -16.72666, 0.37126392, 46.406403, -16.72666, 0.0055902004, 46.406403, -9.28886, 0.28006357, 46.436752, -11.148199, 0.37126392, 46.429054, -9.28886, 0.28006357, 46.436752, -16.72666, 0.0055902004, 46.406403, -9.28886, 0.0055902004, 46.436752, -17.634645, 0.3712638, 47.363815, -16.72666, 0.37126392, 46.406403, -16.733288, 0.3712638, 47.392563, -11.148199, 0.37126392, 46.429054, -16.733288, 0.3712638, 47.392563, -16.72666, 0.37126392, 46.406403, -11.148199, 0.37126392, 46.429054, -9.294437, 0.3712638, 47.266697, -16.733288, 0.3712638, 47.392563, -9.294437, 0.3712638, 47.266697, -11.148199, 0.37126392, 46.429054, -9.2902565, 0.37126392, 46.644455, -9.2902565, 0.37126392, 46.644455, -11.148199, 0.37126392, 46.429054, -9.28886, 0.28006357, 46.436752, -16.72666, 0.37126392, 46.406403, -17.634645, 0.3712638, 47.363815, -17.150305, 0.3712638, 46.84953, -17.150305, 0.3712638, 46.84953, -17.634645, 0.3712638, 47.363815, -17.631985, 0.3712638, 46.96804, -17.631985, 0.3712638, 46.96804, -17.548779, 0.23162705, 46.85907, -17.150305, 0.3712638, 46.84953, -17.548779, 0.23162705, 46.85907, -17.63014, 0.37126392, 46.693573, -17.150305, 0.3712638, 46.84953, -16.72666, 0.37126392, 46.406403, -17.150305, 0.3712638, 46.84953, -17.63014, 0.37126392, 46.693573, -16.72666, 0.37126392, 46.406403, -17.63014, 0.37126392, 46.693573, -17.628038, 0.37126392, 46.380707, -16.733288, 0.005590081, 47.392563, -17.634645, 0.3712638, 47.363815, -16.733288, 0.3712638, 47.392563, -16.733288, 0.005590081, 47.392563, -17.634645, 0.005590081, 47.363815, -17.634645, 0.3712638, 47.363815, -9.294437, 0.3712638, 47.266697, -16.733288, 0.005590081, 47.392563, -16.733288, 0.3712638, 47.392563, -9.294437, 0.3712638, 47.266697, -9.294437, 0.005590081, 47.266697, -16.733288, 0.005590081, 47.392563, -17.628038, 0.0055902004, 46.380707, -16.733288, 0.005590081, 47.392563, -16.72666, 0.0055902004, 46.406403, -16.733288, 0.005590081, 47.392563, -17.628038, 0.0055902004, 46.380707, -17.631613, 0.005590141, 46.912624, -16.733288, 0.005590081, 47.392563, -17.631613, 0.005590141, 46.912624, -17.634645, 0.005590081, 47.363815, -9.294437, 0.005590081, 47.266697, -16.72666, 0.0055902004, 46.406403, -16.733288, 0.005590081, 47.392563, -9.294437, 0.005590081, 47.266697, -9.28886, 0.0055902004, 46.436752, -16.72666, 0.0055902004, 46.406403, -17.63014, 0.37126392, 46.693573, -17.548779, 0.23162705, 46.85907, -17.631613, 0.005590141, 46.912624, -17.548779, 0.23162705, 46.85907, -17.631985, 0.3712638, 46.96804, -17.631613, 0.005590141, 46.912624, -17.628038, 0.0055902004, 46.380707, -17.63014, 0.37126392, 46.693573, -17.631613, 0.005590141, 46.912624, -17.628038, 0.0055902004, 46.380707, -17.628038, 0.37126392, 46.380707, -17.63014, 0.37126392, 46.693573, -17.631985, 0.3712638, 46.96804, -17.634645, 0.005590081, 47.363815, -17.631613, 0.005590141, 46.912624, -17.631985, 0.3712638, 46.96804, -17.634645, 0.3712638, 47.363815, -17.634645, 0.005590081, 47.363815, -9.294437, 0.3712638, 47.266697, -9.28886, 0.0055902004, 46.436752, -9.294437, 0.005590081, 47.266697, -9.28886, 0.0055902004, 46.436752, -9.294437, 0.3712638, 47.266697, -9.2902565, 0.37126392, 46.644455, -9.28886, 0.0055902004, 46.436752, -9.2902565, 0.37126392, 46.644455, -9.28886, 0.28006357, 46.436752, -16.91135, 0.37126464, 39.993507, -17.875563, 0.0055909753, 39.967392, -16.91135, 0.0055909753, 39.993507, -16.91135, 0.37126464, 39.993507, -17.875563, 0.37126464, 39.967392, -17.875563, 0.0055909753, 39.967392, -16.91135, 0.0055909753, 39.993507, -10.943661, 0.37126464, 40.01878, -16.91135, 0.37126464, 39.993507, -16.91135, 0.0055909753, 39.993507, -8.954723, 0.28006428, 40.027344, -10.943661, 0.37126464, 40.01878, -8.954723, 0.28006428, 40.027344, -16.91135, 0.0055909753, 39.993507, -8.954723, 0.0055909753, 40.027344, -17.882166, 0.37126452, 40.95006, -16.91135, 0.37126464, 39.993507, -16.917978, 0.37126452, 40.97967, -10.943661, 0.37126464, 40.01878, -16.917978, 0.37126452, 40.97967, -16.91135, 0.37126464, 39.993507, -10.943661, 0.37126464, 40.01878, -8.9603, 0.37126452, 40.857292, -16.917978, 0.37126452, 40.97967, -8.9603, 0.37126452, 40.857292, -10.943661, 0.37126464, 40.01878, -8.95612, 0.37126464, 40.23505, -8.95612, 0.37126464, 40.23505, -10.943661, 0.37126464, 40.01878, -8.954723, 0.28006428, 40.027344, -16.91135, 0.37126464, 39.993507, -17.882166, 0.37126452, 40.95006, -17.364662, 0.37126464, 40.436, -17.364662, 0.37126464, 40.436, -17.882166, 0.37126452, 40.95006, -17.879507, 0.37126464, 40.55429, -17.879507, 0.37126464, 40.55429, -17.79063, 0.23162788, 40.445793, -17.364662, 0.37126464, 40.436, -17.79063, 0.23162788, 40.445793, -17.877665, 0.37126464, 40.28026, -17.364662, 0.37126464, 40.436, -16.91135, 0.37126464, 39.993507, -17.364662, 0.37126464, 40.436, -17.877665, 0.37126464, 40.28026, -16.91135, 0.37126464, 39.993507, -17.877665, 0.37126464, 40.28026, -17.875563, 0.37126464, 39.967392, -16.917978, 0.005590856, 40.97967, -17.882166, 0.37126452, 40.95006, -16.917978, 0.37126452, 40.97967, -16.917978, 0.005590856, 40.97967, -17.882166, 0.005590856, 40.95006, -17.882166, 0.37126452, 40.95006, -8.9603, 0.37126452, 40.857292, -16.917978, 0.005590856, 40.97967, -16.917978, 0.37126452, 40.97967, -8.9603, 0.37126452, 40.857292, -8.9603, 0.005590856, 40.857292, -16.917978, 0.005590856, 40.97967, -17.875563, 0.0055909753, 39.967392, -16.917978, 0.005590856, 40.97967, -16.91135, 0.0055909753, 39.993507, -16.917978, 0.005590856, 40.97967, -17.875563, 0.0055909753, 39.967392, -17.879133, 0.0055909157, 40.49887, -16.917978, 0.005590856, 40.97967, -17.879133, 0.0055909157, 40.49887, -17.882166, 0.005590856, 40.95006, -8.9603, 0.005590856, 40.857292, -16.91135, 0.0055909753, 39.993507, -16.917978, 0.005590856, 40.97967, -8.9603, 0.005590856, 40.857292, -8.954723, 0.0055909753, 40.027344, -16.91135, 0.0055909753, 39.993507, -17.877665, 0.37126464, 40.28026, -17.79063, 0.23162788, 40.445793, -17.879133, 0.0055909157, 40.49887, -17.79063, 0.23162788, 40.445793, -17.879507, 0.37126464, 40.55429, -17.879133, 0.0055909157, 40.49887, -17.875563, 0.0055909753, 39.967392, -17.877665, 0.37126464, 40.28026, -17.879133, 0.0055909157, 40.49887, -17.875563, 0.0055909753, 39.967392, -17.875563, 0.37126464, 39.967392, -17.877665, 0.37126464, 40.28026, -17.879507, 0.37126464, 40.55429, -17.882166, 0.005590856, 40.95006, -17.879133, 0.0055909157, 40.49887, -17.879507, 0.37126464, 40.55429, -17.882166, 0.37126452, 40.95006, -17.882166, 0.005590856, 40.95006, -8.9603, 0.37126452, 40.857292, -8.954723, 0.0055909753, 40.027344, -8.9603, 0.005590856, 40.857292, -8.954723, 0.0055909753, 40.027344, -8.9603, 0.37126452, 40.857292, -8.95612, 0.37126464, 40.23505, -8.954723, 0.0055909753, 40.027344, -8.95612, 0.37126464, 40.23505, -8.954723, 0.28006428, 40.027344, -13.4819145, 0.005591035, 39.478943, -17.873325, 0.37126476, 39.634453, -13.4819145, 0.37126476, 39.478943, -13.4819145, 0.005591035, 39.478943, -17.873325, 0.0055909753, 39.634453, -17.873325, 0.37126476, 39.634453, -8.952486, 0.37126476, 39.694405, -13.4819145, 0.005591035, 39.478943, -13.4819145, 0.37126476, 39.478943, -8.952486, 0.37126476, 39.694405, -8.952486, 0.0055909753, 39.694405, -13.4819145, 0.005591035, 39.478943, -13.47533, 0.005591154, 38.49933, -17.873325, 0.0055909753, 39.634453, -13.4819145, 0.005591035, 39.478943, -13.47533, 0.005591154, 38.49933, -17.867746, 0.0055910945, 38.80451, -17.873325, 0.0055909753, 39.634453, -13.4819145, 0.005591035, 39.478943, -8.944866, 0.005591154, 38.560757, -13.47533, 0.005591154, 38.49933, -13.4819145, 0.005591035, 39.478943, -8.948738, 0.005591035, 39.136745, -8.944866, 0.005591154, 38.560757, -8.948738, 0.005591035, 39.136745, -13.4819145, 0.005591035, 39.478943, -8.952486, 0.0055909753, 39.694405, -17.867746, 0.0055910945, 38.80451, -17.873325, 0.37126476, 39.634453, -17.873325, 0.0055909753, 39.634453, -17.867746, 0.0055910945, 38.80451, -17.867746, 0.37126476, 38.80451, -17.873325, 0.37126476, 39.634453, -8.949188, 0.37126476, 39.203945, -9.119587, 0.26217347, 39.105488, -8.948738, 0.005591035, 39.136745, -13.476976, 0.37126487, 38.74412, -13.47533, 0.28006452, 38.49933, -12.3426075, 0.37126487, 38.514793, -13.476976, 0.37126487, 38.74412, -14.573328, 0.37126487, 38.575733, -13.47533, 0.28006452, 38.49933, -13.476976, 0.37126487, 38.74412, -17.867746, 0.37126476, 38.80451, -14.573328, 0.37126487, 38.575733, -13.476976, 0.37126487, 38.74412, -17.873325, 0.37126476, 39.634453, -17.867746, 0.37126476, 38.80451, -17.873325, 0.37126476, 39.634453, -13.476976, 0.37126487, 38.74412, -13.4819145, 0.37126476, 39.478943, -12.3426075, 0.37126487, 38.514793, -13.4819145, 0.37126476, 39.478943, -13.476976, 0.37126487, 38.74412, -13.4819145, 0.37126476, 39.478943, -8.949188, 0.37126476, 39.203945, -8.952486, 0.37126476, 39.694405, -13.4819145, 0.37126476, 39.478943, -9.726973, 0.37126476, 39.09835, -8.949188, 0.37126476, 39.203945, -12.3426075, 0.37126487, 38.514793, -9.726973, 0.37126476, 39.09835, -13.4819145, 0.37126476, 39.478943, -9.119587, 0.26217347, 39.105488, -8.949188, 0.37126476, 39.203945, -9.726973, 0.37126476, 39.09835, -8.94733, 0.37126476, 38.927296, -9.119587, 0.26217347, 39.105488, -9.726973, 0.37126476, 39.09835, -9.726973, 0.37126476, 39.09835, -12.3426075, 0.37126487, 38.514793, -8.94733, 0.37126476, 38.927296, -8.94733, 0.37126476, 38.927296, -12.3426075, 0.37126487, 38.514793, -8.944866, 0.37126487, 38.560757, -8.952486, 0.0055909753, 39.694405, -8.949188, 0.37126476, 39.203945, -8.948738, 0.005591035, 39.136745, -8.952486, 0.0055909753, 39.694405, -8.952486, 0.37126476, 39.694405, -8.949188, 0.37126476, 39.203945, -8.94733, 0.37126476, 38.927296, -8.944866, 0.005591154, 38.560757, -8.948738, 0.005591035, 39.136745, -8.94733, 0.37126476, 38.927296, -8.944866, 0.37126487, 38.560757, -8.944866, 0.005591154, 38.560757, -9.119587, 0.26217347, 39.105488, -8.94733, 0.37126476, 38.927296, -8.948738, 0.005591035, 39.136745, -8.944866, 0.37126487, 38.560757, -13.47533, 0.005591154, 38.49933, -8.944866, 0.005591154, 38.560757, -13.47533, 0.005591154, 38.49933, -8.944866, 0.37126487, 38.560757, -12.3426075, 0.37126487, 38.514793, -13.47533, 0.005591154, 38.49933, -12.3426075, 0.37126487, 38.514793, -13.47533, 0.28006452, 38.49933, -13.47533, 0.28006452, 38.49933, -17.867746, 0.0055910945, 38.80451, -13.47533, 0.005591154, 38.49933, -13.47533, 0.28006452, 38.49933, -17.867746, 0.37126476, 38.80451, -17.867746, 0.0055910945, 38.80451, -17.867746, 0.37126476, 38.80451, -13.47533, 0.28006452, 38.49933, -14.573328, 0.37126487, 38.575733, -16.664772, 0.371265, 37.19757, -17.566149, 0.0055912733, 37.171875, -16.664772, 0.0055912733, 37.19757, -16.664772, 0.371265, 37.19757, -17.566149, 0.371265, 37.171875, -17.566149, 0.0055912733, 37.171875, -16.664772, 0.0055912733, 37.19757, -11.086311, 0.371265, 37.220222, -16.664772, 0.371265, 37.19757, -16.664772, 0.0055912733, 37.19757, -9.226971, 0.28006464, 37.227917, -11.086311, 0.371265, 37.220222, -9.226971, 0.28006464, 37.227917, -16.664772, 0.0055912733, 37.19757, -9.226971, 0.0055912733, 37.227917, -17.572756, 0.37126487, 38.154984, -16.664772, 0.371265, 37.19757, -16.6714, 0.37126487, 38.18373, -11.086311, 0.371265, 37.220222, -16.6714, 0.37126487, 38.18373, -16.664772, 0.371265, 37.19757, -11.086311, 0.371265, 37.220222, -9.23255, 0.37126487, 38.057865, -16.6714, 0.37126487, 38.18373, -9.23255, 0.37126487, 38.057865, -11.086311, 0.371265, 37.220222, -9.228367, 0.371265, 37.435623, -9.228367, 0.371265, 37.435623, -11.086311, 0.371265, 37.220222, -9.226971, 0.28006464, 37.227917, -16.664772, 0.371265, 37.19757, -17.572756, 0.37126487, 38.154984, -17.088415, 0.371265, 37.640697, -17.088415, 0.371265, 37.640697, -17.572756, 0.37126487, 38.154984, -17.570097, 0.371265, 37.75921, -17.570097, 0.371265, 37.75921, -17.486889, 0.23162824, 37.650238, -17.088415, 0.371265, 37.640697, -17.486889, 0.23162824, 37.650238, -17.56825, 0.371265, 37.48474, -17.088415, 0.371265, 37.640697, -16.664772, 0.371265, 37.19757, -17.088415, 0.371265, 37.640697, -17.56825, 0.371265, 37.48474, -16.664772, 0.371265, 37.19757, -17.56825, 0.371265, 37.48474, -17.566149, 0.371265, 37.171875, -16.6714, 0.005591154, 38.18373, -17.572756, 0.37126487, 38.154984, -16.6714, 0.37126487, 38.18373, -16.6714, 0.005591154, 38.18373, -17.572756, 0.005591154, 38.154984, -17.572756, 0.37126487, 38.154984, -9.23255, 0.37126487, 38.057865, -16.6714, 0.005591154, 38.18373, -16.6714, 0.37126487, 38.18373, -9.23255, 0.37126487, 38.057865, -9.23255, 0.0055912137, 38.057865, -16.6714, 0.005591154, 38.18373, -17.566149, 0.0055912733, 37.171875, -16.6714, 0.005591154, 38.18373, -16.664772, 0.0055912733, 37.19757, -16.6714, 0.005591154, 38.18373, -17.566149, 0.0055912733, 37.171875, -17.569721, 0.0055912137, 37.703354, -16.6714, 0.005591154, 38.18373, -17.569721, 0.0055912137, 37.703354, -17.572756, 0.005591154, 38.154984, -9.23255, 0.0055912137, 38.057865, -16.664772, 0.0055912733, 37.19757, -16.6714, 0.005591154, 38.18373, -9.23255, 0.0055912137, 38.057865, -9.226971, 0.0055912733, 37.227917, -16.664772, 0.0055912733, 37.19757, -17.56825, 0.371265, 37.48474, -17.486889, 0.23162824, 37.650238, -17.569721, 0.0055912137, 37.703354, -17.486889, 0.23162824, 37.650238, -17.570097, 0.371265, 37.75921, -17.569721, 0.0055912137, 37.703354, -17.566149, 0.0055912733, 37.171875, -17.56825, 0.371265, 37.48474, -17.569721, 0.0055912137, 37.703354, -17.566149, 0.0055912733, 37.171875, -17.566149, 0.371265, 37.171875, -17.56825, 0.371265, 37.48474, -17.570097, 0.371265, 37.75921, -17.572756, 0.005591154, 38.154984, -17.569721, 0.0055912137, 37.703354, -17.570097, 0.371265, 37.75921, -17.572756, 0.37126487, 38.154984, -17.572756, 0.005591154, 38.154984, -9.23255, 0.37126487, 38.057865, -9.226971, 0.0055912733, 37.227917, -9.23255, 0.0055912137, 38.057865, -9.226971, 0.0055912733, 37.227917, -9.23255, 0.37126487, 38.057865, -9.228367, 0.371265, 37.435623, -9.226971, 0.0055912733, 37.227917, -9.228367, 0.371265, 37.435623, -9.226971, 0.28006464, 37.227917, -16.810944, -3.458273, 47.519463, -17.46208, 1.270175, 47.59407, -17.54053, -3.458273, 47.51456, -16.810944, -3.458273, 47.519463, -16.890453, 1.270175, 47.59791, -17.46208, 1.270175, 47.59407, -16.890453, 1.270175, 47.59791, -17.465921, 1.270175, 48.165695, -17.46208, 1.270175, 47.59407, -16.890453, 1.270175, 47.59791, -16.894295, 1.270175, 48.16954, -17.465921, 1.270175, 48.165695, -16.894295, 1.270175, 48.16954, -17.545431, -3.458273, 48.24415, -17.465921, 1.270175, 48.165695, -16.894295, 1.270175, 48.16954, -16.815845, -3.458273, 48.24905, -17.545431, -3.458273, 48.24415, -16.815845, -3.458273, 48.24905, -17.54053, -3.458273, 47.51456, -17.545431, -3.458273, 48.24415, -16.815845, -3.458273, 48.24905, -16.810944, -3.458273, 47.519463, -17.54053, -3.458273, 47.51456, -17.54053, -3.458273, 47.51456, -17.465921, 1.270175, 48.165695, -17.545431, -3.458273, 48.24415, -17.54053, -3.458273, 47.51456, -17.46208, 1.270175, 47.59407, -17.465921, 1.270175, 48.165695, -16.815845, -3.458273, 48.24905, -16.890453, 1.270175, 47.59791, -16.810944, -3.458273, 47.519463, -16.815845, -3.458273, 48.24905, -16.894295, 1.270175, 48.16954, -16.890453, 1.270175, 47.59791, -9.055229, -3.45827, 22.581722, -9.785252, 1.2701778, 22.576817, -9.785252, -3.45827, 22.576817, -9.055229, -3.45827, 22.581722, -9.055229, 1.2701778, 22.581722, -9.785252, 1.2701778, 22.576817, -9.060133, -3.45827, 23.31131, -9.785252, -3.45827, 22.576817, -9.790155, -3.45827, 23.306404, -9.060133, -3.45827, 23.31131, -9.055229, -3.45827, 22.581722, -9.785252, -3.45827, 22.576817, -9.785252, -3.45827, 22.576817, -9.790155, 1.2701778, 23.306404, -9.790155, -3.45827, 23.306404, -9.785252, -3.45827, 22.576817, -9.785252, 1.2701778, 22.576817, -9.790155, 1.2701778, 23.306404, -9.060133, 0.08806592, 23.31131, -9.242529, 1.2701778, 23.310083, -9.058907, 1.2701778, 23.128912, -9.055229, -3.45827, 22.581722, -9.060133, 0.08806592, 23.31131, -9.058907, 1.2701778, 23.128912, -9.060133, 0.08806592, 23.31131, -9.055229, -3.45827, 22.581722, -9.060133, -3.45827, 23.31131, -9.055229, -3.45827, 22.581722, -9.058907, 1.2701778, 23.128912, -9.055229, 1.2701778, 22.581722, -9.058907, 1.2701778, 23.128912, -9.785252, 1.2701778, 22.576817, -9.055229, 1.2701778, 22.581722, -9.785252, 1.2701778, 22.576817, -9.058907, 1.2701778, 23.128912, -9.242529, 1.2701778, 23.310083, -9.785252, 1.2701778, 22.576817, -9.242529, 1.2701778, 23.310083, -9.790155, 1.2701778, 23.306404, -9.060133, -3.45827, 23.31131, -9.242529, 1.2701778, 23.310083, -9.060133, 0.08806592, 23.31131, -9.242529, 1.2701778, 23.310083, -9.060133, -3.45827, 23.31131, -9.790155, -3.45827, 23.306404, -9.242529, 1.2701778, 23.310083, -9.790155, -3.45827, 23.306404, -9.790155, 1.2701778, 23.306404, -13.449499, 0.0055915117, 35.369823, -17.5551, 0.37126523, 35.52769, -13.449499, 0.37126523, 35.369823, -13.449499, 0.0055915117, 35.369823, -17.5551, 0.0055915117, 35.52769, -17.5551, 0.37126523, 35.52769, -9.215921, 0.37126523, 35.583733, -13.449499, 0.0055915117, 35.369823, -13.449499, 0.37126523, 35.369823, -9.215921, 0.37126523, 35.583733, -9.215921, 0.005591452, 35.583733, -13.449499, 0.0055915117, 35.369823, -13.442921, 0.005591631, 34.39108, -17.5551, 0.0055915117, 35.52769, -13.449499, 0.0055915117, 35.369823, -13.442921, 0.005591631, 34.39108, -17.54952, 0.0055915713, 34.697742, -17.5551, 0.0055915117, 35.52769, -13.449499, 0.0055915117, 35.369823, -9.208305, 0.005591631, 34.45052, -13.442921, 0.005591631, 34.39108, -13.449499, 0.0055915117, 35.369823, -9.212177, 0.0055915713, 35.02651, -9.208305, 0.005591631, 34.45052, -9.212177, 0.0055915713, 35.02651, -13.449499, 0.0055915117, 35.369823, -9.215921, 0.005591452, 35.583733, -17.54952, 0.0055915713, 34.697742, -17.5551, 0.37126523, 35.52769, -17.5551, 0.0055915117, 35.52769, -17.54952, 0.0055915713, 34.697742, -17.54952, 0.37126535, 34.697742, -17.5551, 0.37126523, 35.52769, -9.212622, 0.37126523, 35.092834, -9.371677, 0.26217395, 34.99489, -9.212177, 0.0055915713, 35.02651, -13.444563, 0.37126535, 34.635437, -13.442921, 0.280065, 34.39108, -12.384375, 0.37126535, 34.40561, -13.444563, 0.37126535, 34.635437, -14.469788, 0.37126535, 34.467525, -13.442921, 0.280065, 34.39108, -13.444563, 0.37126535, 34.635437, -17.54952, 0.37126535, 34.697742, -14.469788, 0.37126535, 34.467525, -13.444563, 0.37126535, 34.635437, -17.5551, 0.37126523, 35.52769, -17.54952, 0.37126535, 34.697742, -17.5551, 0.37126523, 35.52769, -13.444563, 0.37126535, 34.635437, -13.449499, 0.37126523, 35.369823, -12.384375, 0.37126535, 34.40561, -13.449499, 0.37126523, 35.369823, -13.444563, 0.37126535, 34.635437, -13.449499, 0.37126523, 35.369823, -9.212622, 0.37126523, 35.092834, -9.215921, 0.37126523, 35.583733, -13.449499, 0.37126523, 35.369823, -9.939795, 0.37126523, 34.988453, -9.212622, 0.37126523, 35.092834, -12.384375, 0.37126535, 34.40561, -9.939795, 0.37126523, 34.988453, -13.449499, 0.37126523, 35.369823, -9.371677, 0.26217395, 34.99489, -9.212622, 0.37126523, 35.092834, -9.939795, 0.37126523, 34.988453, -9.21077, 0.37126535, 34.81706, -9.371677, 0.26217395, 34.99489, -9.939795, 0.37126523, 34.988453, -9.939795, 0.37126523, 34.988453, -12.384375, 0.37126535, 34.40561, -9.21077, 0.37126535, 34.81706, -9.21077, 0.37126535, 34.81706, -12.384375, 0.37126535, 34.40561, -9.208305, 0.37126535, 34.45052, -9.215921, 0.005591452, 35.583733, -9.212622, 0.37126523, 35.092834, -9.212177, 0.0055915713, 35.02651, -9.215921, 0.005591452, 35.583733, -9.215921, 0.37126523, 35.583733, -9.212622, 0.37126523, 35.092834, -9.21077, 0.37126535, 34.81706, -9.208305, 0.005591631, 34.45052, -9.212177, 0.0055915713, 35.02651, -9.21077, 0.37126535, 34.81706, -9.208305, 0.37126535, 34.45052, -9.208305, 0.005591631, 34.45052, -9.371677, 0.26217395, 34.99489, -9.21077, 0.37126535, 34.81706, -9.212177, 0.0055915713, 35.02651, -9.208305, 0.37126535, 34.45052, -13.442921, 0.005591631, 34.39108, -9.208305, 0.005591631, 34.45052, -13.442921, 0.005591631, 34.39108, -9.208305, 0.37126535, 34.45052, -12.384375, 0.37126535, 34.40561, -13.442921, 0.005591631, 34.39108, -12.384375, 0.37126535, 34.40561, -13.442921, 0.280065, 34.39108, -13.442921, 0.280065, 34.39108, -17.54952, 0.0055915713, 34.697742, -13.442921, 0.005591631, 34.39108, -13.442921, 0.280065, 34.39108, -17.54952, 0.37126535, 34.697742, -17.54952, 0.0055915713, 34.697742, -17.54952, 0.37126535, 34.697742, -13.442921, 0.280065, 34.39108, -14.469788, 0.37126535, 34.467525, -10.702703, 0.005590558, 43.383537, -17.802399, 0.37126428, 43.495537, -10.702703, 0.37126428, 43.383537, -10.702703, 0.005590558, 43.383537, -17.802399, 0.005590558, 43.495537, -17.802399, 0.37126428, 43.495537, -9.074274, 0.37126428, 43.401463, -10.702703, 0.005590558, 43.383537, -10.702703, 0.37126428, 43.383537, -9.074274, 0.37126428, 43.401463, -9.074274, 0.005590558, 43.401463, -10.702703, 0.005590558, 43.383537, -10.695927, 0.0055906773, 42.375122, -17.802399, 0.005590558, 43.495537, -10.702703, 0.005590558, 43.383537, -10.695927, 0.0055906773, 42.375122, -17.795794, 0.0055906773, 42.512863, -17.802399, 0.005590558, 43.495537, -9.074274, 0.005590558, 43.401463, -10.695927, 0.0055906773, 42.375122, -10.702703, 0.005590558, 43.383537, -9.074274, 0.005590558, 43.401463, -9.068697, 0.0055906773, 42.571514, -10.695927, 0.0055906773, 42.375122, -9.074274, 0.005590558, 43.401463, -9.068697, 0.3712644, 42.571514, -9.068697, 0.0055906773, 42.571514, -9.074274, 0.005590558, 43.401463, -9.074274, 0.37126428, 43.401463, -9.068697, 0.3712644, 42.571514, -10.697622, 0.3712644, 42.627335, -10.695927, 0.28006405, 42.375122, -10.289118, 0.3712644, 42.42411, -10.697622, 0.3712644, 42.627335, -12.470892, 0.3712644, 42.409447, -10.695927, 0.28006405, 42.375122, -10.697622, 0.3712644, 42.627335, -16.464678, 0.3712644, 42.4869, -12.470892, 0.3712644, 42.409447, -10.289118, 0.3712644, 42.42411, -10.702703, 0.37126428, 43.383537, -10.697622, 0.3712644, 42.627335, -10.289118, 0.3712644, 42.42411, -9.074274, 0.37126428, 43.401463, -10.702703, 0.37126428, 43.383537, -9.074274, 0.37126428, 43.401463, -10.289118, 0.3712644, 42.42411, -9.068697, 0.3712644, 42.571514, -17.802399, 0.37126428, 43.495537, -10.697622, 0.3712644, 42.627335, -10.702703, 0.37126428, 43.383537, -10.697622, 0.3712644, 42.627335, -17.802399, 0.37126428, 43.495537, -16.464678, 0.3712644, 42.4869, -16.464678, 0.3712644, 42.4869, -17.802399, 0.37126428, 43.495537, -17.797441, 0.3712644, 42.758095, -16.464678, 0.3712644, 42.4869, -17.797441, 0.3712644, 42.758095, -17.795794, 0.28006405, 42.512863, -9.068697, 0.3712644, 42.571514, -10.695927, 0.0055906773, 42.375122, -9.068697, 0.0055906773, 42.571514, -10.695927, 0.0055906773, 42.375122, -9.068697, 0.3712644, 42.571514, -10.289118, 0.3712644, 42.42411, -10.695927, 0.0055906773, 42.375122, -10.289118, 0.3712644, 42.42411, -10.695927, 0.28006405, 42.375122, -10.695927, 0.28006405, 42.375122, -17.795794, 0.0055906773, 42.512863, -10.695927, 0.0055906773, 42.375122, -10.695927, 0.28006405, 42.375122, -16.464678, 0.3712644, 42.4869, -17.795794, 0.0055906773, 42.512863, -17.795794, 0.0055906773, 42.512863, -16.464678, 0.3712644, 42.4869, -17.795794, 0.28006405, 42.512863, -16.464678, 0.3712644, 42.4869, -10.695927, 0.28006405, 42.375122, -12.470892, 0.3712644, 42.409447, -17.795794, 0.28006405, 42.512863, -17.802399, 0.005590558, 43.495537, -17.795794, 0.0055906773, 42.512863, -17.802399, 0.005590558, 43.495537, -17.795794, 0.28006405, 42.512863, -17.797441, 0.3712644, 42.758095, -17.802399, 0.005590558, 43.495537, -17.797441, 0.3712644, 42.758095, -17.802399, 0.37126428, 43.495537, -10.597399, 0.005591333, 36.740005, -17.854618, 0.371265, 36.850945, -10.597399, 0.3712651, 36.740005, -10.597399, 0.005591333, 36.740005, -17.854618, 0.005591333, 36.850945, -17.854618, 0.371265, 36.850945, -8.932753, 0.3712651, 36.758175, -10.597399, 0.005591333, 36.740005, -10.597399, 0.3712651, 36.740005, -8.932753, 0.3712651, 36.758175, -8.932753, 0.005591333, 36.758175, -10.597399, 0.005591333, 36.740005, -10.590622, 0.005591452, 35.73159, -17.854618, 0.005591333, 36.850945, -10.597399, 0.005591333, 36.740005, -10.590622, 0.005591452, 35.73159, -17.848013, 0.005591452, 35.868275, -17.854618, 0.005591333, 36.850945, -8.932753, 0.005591333, 36.758175, -10.590622, 0.005591452, 35.73159, -10.597399, 0.005591333, 36.740005, -8.932753, 0.005591333, 36.758175, -8.927174, 0.005591452, 35.928226, -10.590622, 0.005591452, 35.73159, -8.932753, 0.005591333, 36.758175, -8.927174, 0.3712651, 35.928226, -8.927174, 0.005591452, 35.928226, -8.932753, 0.005591333, 36.758175, -8.932753, 0.3712651, 36.758175, -8.927174, 0.3712651, 35.928226, -10.592318, 0.3712651, 35.983803, -10.590622, 0.28006488, 35.73159, -10.17465, 0.37126523, 35.78064, -10.592318, 0.3712651, 35.983803, -12.40486, 0.37126523, 35.76565, -10.590622, 0.28006488, 35.73159, -10.592318, 0.3712651, 35.983803, -16.487228, 0.3712651, 35.842945, -12.40486, 0.37126523, 35.76565, -10.17465, 0.37126523, 35.78064, -10.597399, 0.3712651, 36.740005, -10.592318, 0.3712651, 35.983803, -10.17465, 0.37126523, 35.78064, -8.932753, 0.3712651, 36.758175, -10.597399, 0.3712651, 36.740005, -8.932753, 0.3712651, 36.758175, -10.17465, 0.37126523, 35.78064, -8.927174, 0.3712651, 35.928226, -17.854618, 0.371265, 36.850945, -10.592318, 0.3712651, 35.983803, -10.597399, 0.3712651, 36.740005, -10.592318, 0.3712651, 35.983803, -17.854618, 0.371265, 36.850945, -16.487228, 0.3712651, 35.842945, -16.487228, 0.3712651, 35.842945, -17.854618, 0.371265, 36.850945, -17.849669, 0.3712651, 36.11438, -16.487228, 0.3712651, 35.842945, -17.849669, 0.3712651, 36.11438, -17.848013, 0.28006476, 35.868275, -8.927174, 0.3712651, 35.928226, -10.590622, 0.005591452, 35.73159, -8.927174, 0.005591452, 35.928226, -10.590622, 0.005591452, 35.73159, -8.927174, 0.3712651, 35.928226, -10.17465, 0.37126523, 35.78064, -10.590622, 0.005591452, 35.73159, -10.17465, 0.37126523, 35.78064, -10.590622, 0.28006488, 35.73159, -10.590622, 0.28006488, 35.73159, -17.848013, 0.005591452, 35.868275, -10.590622, 0.005591452, 35.73159, -10.590622, 0.28006488, 35.73159, -16.487228, 0.3712651, 35.842945, -17.848013, 0.005591452, 35.868275, -17.848013, 0.005591452, 35.868275, -16.487228, 0.3712651, 35.842945, -17.848013, 0.28006476, 35.868275, -16.487228, 0.3712651, 35.842945, -10.590622, 0.28006488, 35.73159, -12.40486, 0.37126523, 35.76565, -17.848013, 0.28006476, 35.868275, -17.854618, 0.005591333, 36.850945, -17.848013, 0.005591452, 35.868275, -17.854618, 0.005591333, 36.850945, -17.848013, 0.28006476, 35.868275, -17.849669, 0.3712651, 36.11438, -17.854618, 0.005591333, 36.850945, -17.849669, 0.3712651, 36.11438, -17.854618, 0.371265, 36.850945, -16.774326, -3.4582698, 22.20213, -17.504349, 1.2701781, 22.197224, -17.504349, -3.4582698, 22.197224, -16.774326, -3.4582698, 22.20213, -16.774326, 0.72166747, 22.20213, -17.504349, 1.2701781, 22.197224, -16.774326, 0.72166747, 22.20213, -17.509253, 1.2701778, 22.926807, -17.504349, 1.2701781, 22.197224, -16.774326, 0.72166747, 22.20213, -16.77923, 1.2701778, 22.931713, -17.509253, 1.2701778, 22.926807, -16.77923, 1.2701778, 22.931713, -17.509253, -3.45827, 22.926807, -17.509253, 1.2701778, 22.926807, -16.77923, 1.2701778, 22.931713, -16.77923, -3.45827, 22.931713, -17.509253, -3.45827, 22.926807, -16.77923, -3.45827, 22.931713, -17.504349, -3.4582698, 22.197224, -17.509253, -3.45827, 22.926807, -16.77923, -3.45827, 22.931713, -16.774326, -3.4582698, 22.20213, -17.504349, -3.4582698, 22.197224, -17.504349, -3.4582698, 22.197224, -17.509253, 1.2701778, 22.926807, -17.509253, -3.45827, 22.926807, -17.504349, -3.4582698, 22.197224, -17.504349, 1.2701781, 22.197224, -17.509253, 1.2701778, 22.926807, -16.77923, -3.45827, 22.931713, -16.774326, 0.72166747, 22.20213, -16.774326, -3.4582698, 22.20213, -16.77923, -3.45827, 22.931713, -16.77923, 1.2701778, 22.931713, -16.774326, 0.72166747, 22.20213, -16.92366, -0.19077104, 22.930307, -17.155365, -0.09826177, 22.928751, -17.155365, -0.19077104, 22.928751, -16.92366, -0.19077104, 22.930307, -16.92366, -0.09826177, 22.930307, -17.155365, -0.09826177, 22.928751, -16.92366, -0.09826177, 22.930307, -17.320957, -0.098264754, 47.5684, -17.155365, -0.09826177, 22.928751, -16.92366, -0.09826177, 22.930307, -17.089252, -0.098264754, 47.569958, -17.320957, -0.098264754, 47.5684, -17.089252, -0.098264754, 47.569958, -17.320957, -0.19077402, 47.5684, -17.320957, -0.098264754, 47.5684, -17.089252, -0.098264754, 47.569958, -17.089252, -0.19077402, 47.569958, -17.320957, -0.19077402, 47.5684, -17.089252, -0.19077402, 47.569958, -17.155365, -0.19077104, 22.928751, -17.320957, -0.19077402, 47.5684, -17.089252, -0.19077402, 47.569958, -16.92366, -0.19077104, 22.930307, -17.155365, -0.19077104, 22.928751, -17.155365, -0.19077104, 22.928751, -17.320957, -0.098264754, 47.5684, -17.320957, -0.19077402, 47.5684, -17.155365, -0.19077104, 22.928751, -17.155365, -0.09826177, 22.928751, -17.320957, -0.098264754, 47.5684, -17.089252, -0.19077402, 47.569958, -16.92366, -0.09826177, 22.930307, -16.92366, -0.19077104, 22.930307, -17.089252, -0.19077402, 47.569958, -17.089252, -0.098264754, 47.569958, -16.92366, -0.09826177, 22.930307, -9.130678, -2.9032154, 33.80826, -9.860701, 1.8252325, 33.803356, -9.860701, -2.9032154, 33.803352, -9.130678, -2.9032154, 33.80826, -9.130678, 1.8252325, 33.80826, -9.860701, 1.8252325, 33.803356, -9.135584, -2.9032154, 34.538284, -9.860701, -2.9032154, 33.803352, -9.865606, -2.9032154, 34.53338, -9.135584, -2.9032154, 34.538284, -9.130678, -2.9032154, 33.80826, -9.860701, -2.9032154, 33.803352, -9.860701, -2.9032154, 33.803352, -9.865606, 1.8252323, 34.53338, -9.865606, -2.9032154, 34.53338, -9.860701, -2.9032154, 33.803352, -9.860701, 1.8252325, 33.803356, -9.865606, 1.8252323, 34.53338, -9.135584, 0.64312047, 34.538284, -9.317982, 1.8252323, 34.537056, -9.134359, 1.8252323, 34.35589, -9.130678, -2.9032154, 33.80826, -9.135584, 0.64312047, 34.538284, -9.134359, 1.8252323, 34.35589, -9.135584, 0.64312047, 34.538284, -9.130678, -2.9032154, 33.80826, -9.135584, -2.9032154, 34.538284, -9.130678, -2.9032154, 33.80826, -9.134359, 1.8252323, 34.35589, -9.130678, 1.8252325, 33.80826, -9.134359, 1.8252323, 34.35589, -9.860701, 1.8252325, 33.803356, -9.130678, 1.8252325, 33.80826, -9.860701, 1.8252325, 33.803356, -9.134359, 1.8252323, 34.35589, -9.317982, 1.8252323, 34.537056, -9.860701, 1.8252325, 33.803356, -9.317982, 1.8252323, 34.537056, -9.865606, 1.8252323, 34.53338, -9.135584, -2.9032154, 34.538284, -9.317982, 1.8252323, 34.537056, -9.135584, 0.64312047, 34.538284, -9.317982, 1.8252323, 34.537056, -9.135584, -2.9032154, 34.538284, -9.865606, -2.9032154, 34.53338, -9.317982, 1.8252323, 34.537056, -9.865606, -2.9032154, 34.53338, -9.865606, 1.8252323, 34.53338, -9.18182, -3.7899094, 41.417854, -9.91184, 0.9385386, 41.41295, -9.91184, -3.7899094, 41.41295, -9.18182, -3.7899094, 41.417854, -9.18182, 0.9385386, 41.417854, -9.91184, 0.9385386, 41.41295, -9.186722, -3.7899094, 42.147438, -9.91184, -3.7899094, 41.41295, -9.916744, -3.7899094, 42.142532, -9.186722, -3.7899094, 42.147438, -9.18182, -3.7899094, 41.417854, -9.91184, -3.7899094, 41.41295, -9.91184, -3.7899094, 41.41295, -9.916744, 0.9385385, 42.142532, -9.916744, -3.7899094, 42.142532, -9.91184, -3.7899094, 41.41295, -9.91184, 0.9385386, 41.41295, -9.916744, 0.9385385, 42.142532, -9.186722, -0.24357355, 42.147438, -9.36912, 0.9385385, 42.146214, -9.185497, 0.9385385, 41.965042, -9.18182, -3.7899094, 41.417854, -9.186722, -0.24357355, 42.147438, -9.185497, 0.9385385, 41.965042, -9.186722, -0.24357355, 42.147438, -9.18182, -3.7899094, 41.417854, -9.186722, -3.7899094, 42.147438, -9.18182, -3.7899094, 41.417854, -9.185497, 0.9385385, 41.965042, -9.18182, 0.9385386, 41.417854, -9.185497, 0.9385385, 41.965042, -9.91184, 0.9385386, 41.41295, -9.18182, 0.9385386, 41.417854, -9.91184, 0.9385386, 41.41295, -9.185497, 0.9385385, 41.965042, -9.36912, 0.9385385, 42.146214, -9.91184, 0.9385386, 41.41295, -9.36912, 0.9385385, 42.146214, -9.916744, 0.9385385, 42.142532, -9.186722, -3.7899094, 42.147438, -9.36912, 0.9385385, 42.146214, -9.186722, -0.24357355, 42.147438, -9.36912, 0.9385385, 42.146214, -9.186722, -3.7899094, 42.147438, -9.916744, -3.7899094, 42.142532, -9.36912, 0.9385385, 42.146214, -9.916744, -3.7899094, 42.142532, -9.916744, 0.9385385, 42.142532, -17.459593, -3.5494714, 33.653664, -18.189178, 1.1789763, 33.64876, -18.189178, -3.5494714, 33.64876, -17.459593, -3.5494714, 33.653664, -17.459593, 1.1789763, 33.653664, -18.189178, 1.1789763, 33.64876, -17.4645, -3.5494716, 34.383686, -18.189178, -3.5494714, 33.64876, -18.194086, -3.5494716, 34.378784, -17.4645, -3.5494716, 34.383686, -17.459593, -3.5494714, 33.653664, -18.189178, -3.5494714, 33.64876, -18.189178, -3.5494714, 33.64876, -18.194086, 1.178976, 34.378784, -18.194086, -3.5494716, 34.378784, -18.189178, -3.5494714, 33.64876, -18.189178, 1.1789763, 33.64876, -18.194086, 1.178976, 34.378784, -17.4645, -0.0031356215, 34.383686, -17.646896, 1.178976, 34.38246, -17.463274, 1.1789763, 34.20129, -17.459593, -3.5494714, 33.653664, -17.4645, -0.0031356215, 34.383686, -17.463274, 1.1789763, 34.20129, -17.4645, -0.0031356215, 34.383686, -17.459593, -3.5494714, 33.653664, -17.4645, -3.5494716, 34.383686, -17.459593, -3.5494714, 33.653664, -17.463274, 1.1789763, 34.20129, -17.459593, 1.1789763, 33.653664, -17.463274, 1.1789763, 34.20129, -18.189178, 1.1789763, 33.64876, -17.459593, 1.1789763, 33.653664, -18.189178, 1.1789763, 33.64876, -17.463274, 1.1789763, 34.20129, -17.646896, 1.178976, 34.38246, -18.189178, 1.1789763, 33.64876, -17.646896, 1.178976, 34.38246, -18.194086, 1.178976, 34.378784, -17.4645, -3.5494716, 34.383686, -17.646896, 1.178976, 34.38246, -17.4645, -0.0031356215, 34.383686, -17.646896, 1.178976, 34.38246, -17.4645, -3.5494716, 34.383686, -18.194086, -3.5494716, 34.378784, -17.646896, 1.178976, 34.38246, -18.194086, -3.5494716, 34.378784, -18.194086, 1.178976, 34.378784, -17.511396, -3.5494723, 41.361874, -18.240982, 1.1789753, 41.35697, -18.240982, -3.5494723, 41.35697, -17.511396, -3.5494723, 41.361874, -17.511396, 1.1789753, 41.361874, -18.240982, 1.1789753, 41.35697, -17.5163, -3.5494723, 42.09146, -18.240982, -3.5494723, 41.35697, -18.245886, -3.5494723, 42.086555, -17.5163, -3.5494723, 42.09146, -17.511396, -3.5494723, 41.361874, -18.240982, -3.5494723, 41.35697, -18.240982, -3.5494723, 41.35697, -18.245886, 1.1789753, 42.086555, -18.245886, -3.5494723, 42.086555, -18.240982, -3.5494723, 41.35697, -18.240982, 1.1789753, 41.35697, -18.245886, 1.1789753, 42.086555, -17.5163, -0.0031365752, 42.09146, -17.698698, 1.1789753, 42.090233, -17.515074, 1.1789753, 41.909065, -17.511396, -3.5494723, 41.361874, -17.5163, -0.0031365752, 42.09146, -17.515074, 1.1789753, 41.909065, -17.5163, -0.0031365752, 42.09146, -17.511396, -3.5494723, 41.361874, -17.5163, -3.5494723, 42.09146, -17.511396, -3.5494723, 41.361874, -17.515074, 1.1789753, 41.909065, -17.511396, 1.1789753, 41.361874, -17.515074, 1.1789753, 41.909065, -18.240982, 1.1789753, 41.35697, -17.511396, 1.1789753, 41.361874, -18.240982, 1.1789753, 41.35697, -17.515074, 1.1789753, 41.909065, -17.698698, 1.1789753, 42.090233, -18.240982, 1.1789753, 41.35697, -17.698698, 1.1789753, 42.090233, -18.245886, 1.1789753, 42.086555, -17.5163, -3.5494723, 42.09146, -17.698698, 1.1789753, 42.090233, -17.5163, -0.0031365752, 42.09146, -17.698698, 1.1789753, 42.090233, -17.5163, -3.5494723, 42.09146, -18.245886, -3.5494723, 42.086555, -17.698698, 1.1789753, 42.090233, -18.245886, -3.5494723, 42.086555, -18.245886, 1.1789753, 42.086555, -12.414185, -22.456995, 9.651152, -10.526909, -22.242655, 9.475412, -12.414185, -22.326996, 9.5211525, -12.414185, -22.456995, 9.651152, -10.526909, -22.391994, 9.624752, -10.526909, -22.242655, 9.475412, -19.07084, -22.391996, 9.624752, -12.414185, -22.456995, 9.651152, -12.414185, -22.326996, 9.5211525, -19.07084, -22.391996, 9.624752, -12.414185, -22.326996, 9.5211525, -19.07084, -22.242657, 9.475412, -12.414185, -22.326996, 9.5211525, -10.526909, -22.03864, 9.420736, -12.414185, -22.14938, 9.473576, -12.414185, -22.326996, 9.5211525, -10.526909, -22.242655, 9.475412, -10.526909, -22.03864, 9.420736, -19.07084, -22.242657, 9.475412, -12.414185, -22.326996, 9.5211525, -12.414185, -22.14938, 9.473576, -19.07084, -22.242657, 9.475412, -12.414185, -22.14938, 9.473576, -19.07084, -22.03864, 9.420735, -12.414185, -22.14938, 9.473576, -10.526909, -21.834621, 9.475412, -12.414185, -21.971802, 9.5211525, -12.414185, -22.14938, 9.473576, -10.526909, -22.03864, 9.420736, -10.526909, -21.834621, 9.475412, -19.07084, -22.03864, 9.420735, -12.414185, -22.14938, 9.473576, -12.414185, -21.971802, 9.5211525, -19.07084, -22.03864, 9.420735, -12.414185, -21.971802, 9.5211525, -19.07084, -21.834623, 9.475412, -12.414185, -21.971802, 9.5211525, -10.526909, -21.685282, 9.624752, -12.414185, -21.841803, 9.651152, -12.414185, -21.971802, 9.5211525, -10.526909, -21.834621, 9.475412, -10.526909, -21.685282, 9.624752, -19.07084, -21.834623, 9.475412, -12.414185, -21.971802, 9.5211525, -12.414185, -21.841803, 9.651152, -19.07084, -21.834623, 9.475412, -12.414185, -21.841803, 9.651152, -19.07084, -21.685282, 9.624752, -12.414185, -21.841803, 9.651152, -10.526909, -21.630606, 9.82877, -12.414185, -21.794186, 9.82877, -12.414185, -21.841803, 9.651152, -10.526909, -21.685282, 9.624752, -10.526909, -21.630606, 9.82877, -19.07084, -21.685282, 9.624752, -12.414185, -21.841803, 9.651152, -12.414185, -21.794186, 9.82877, -19.07084, -21.685282, 9.624752, -12.414185, -21.794186, 9.82877, -19.07084, -21.630606, 9.828769, -12.414185, -21.794186, 9.82877, -10.526909, -21.685282, 10.032785, -12.414185, -21.841803, 10.006346, -12.414185, -21.794186, 9.82877, -10.526909, -21.630606, 9.82877, -10.526909, -21.685282, 10.032785, -19.07084, -21.630606, 9.828769, -12.414185, -21.794186, 9.82877, -12.414185, -21.841803, 10.006346, -19.07084, -21.630606, 9.828769, -12.414185, -21.841803, 10.006346, -19.07084, -21.685282, 10.032785, -12.414185, -21.841803, 10.006346, -10.526909, -21.834621, 10.182125, -12.414185, -21.971802, 10.136345, -12.414185, -21.841803, 10.006346, -10.526909, -21.685282, 10.032785, -10.526909, -21.834621, 10.182125, -19.07084, -21.685282, 10.032785, -12.414185, -21.841803, 10.006346, -12.414185, -21.971802, 10.136345, -19.07084, -21.685282, 10.032785, -12.414185, -21.971802, 10.136345, -19.07084, -21.834623, 10.182125, -12.414185, -21.971802, 10.136345, -10.526909, -22.03864, 10.236803, -12.414185, -22.149378, 10.183962, -12.414185, -21.971802, 10.136345, -10.526909, -21.834621, 10.182125, -10.526909, -22.03864, 10.236803, -19.07084, -21.834623, 10.182125, -12.414185, -21.971802, 10.136345, -12.414185, -22.149378, 10.183962, -19.07084, -21.834623, 10.182125, -12.414185, -22.149378, 10.183962, -19.07084, -22.03864, 10.236801, -12.414185, -22.149378, 10.183962, -10.526909, -22.242655, 10.182125, -12.414185, -22.326996, 10.136345, -12.414185, -22.149378, 10.183962, -10.526909, -22.03864, 10.236803, -10.526909, -22.242655, 10.182125, -19.07084, -22.03864, 10.236801, -12.414185, -22.149378, 10.183962, -12.414185, -22.326996, 10.136345, -19.07084, -22.03864, 10.236801, -12.414185, -22.326996, 10.136345, -19.07084, -22.242657, 10.182125, -12.414185, -22.326996, 10.136345, -10.526909, -22.391994, 10.032785, -12.414185, -22.456995, 10.006346, -12.414185, -22.326996, 10.136345, -10.526909, -22.242655, 10.182125, -10.526909, -22.391994, 10.032785, -19.07084, -22.242657, 10.182125, -12.414185, -22.326996, 10.136345, -12.414185, -22.456995, 10.006346, -19.07084, -22.242657, 10.182125, -12.414185, -22.456995, 10.006346, -19.07084, -22.391996, 10.032785, -12.414185, -22.456995, 10.006346, -10.526909, -22.446672, 9.82877, -12.414185, -22.504572, 9.82877, -12.414185, -22.456995, 10.006346, -10.526909, -22.391994, 10.032785, -10.526909, -22.446672, 9.82877, -19.07084, -22.391996, 10.032785, -12.414185, -22.456995, 10.006346, -12.414185, -22.504572, 9.82877, -19.07084, -22.391996, 10.032785, -12.414185, -22.504572, 9.82877, -19.07084, -22.446672, 9.828769, -12.414185, -22.504572, 9.82877, -10.526909, -22.391994, 9.624752, -12.414185, -22.456995, 9.651152, -12.414185, -22.504572, 9.82877, -10.526909, -22.446672, 9.82877, -10.526909, -22.391994, 9.624752, -19.07084, -22.446672, 9.828769, -12.414185, -22.504572, 9.82877, -12.414185, -22.456995, 9.651152, -19.07084, -22.446672, 9.828769, -12.414185, -22.456995, 9.651152, -19.07084, -22.391996, 9.624752, -19.07084, -22.242657, 9.475412, -19.693949, -22.03864, 9.828769, -19.07084, -22.391996, 9.624752, -19.07084, -22.391996, 9.624752, -19.693949, -22.03864, 9.828769, -19.07084, -22.446672, 9.828769, -19.07084, -22.446672, 9.828769, -19.693949, -22.03864, 9.828769, -19.07084, -22.391996, 10.032785, -19.07084, -22.391996, 10.032785, -19.693949, -22.03864, 9.828769, -19.07084, -22.242657, 10.182125, -19.07084, -22.03864, 9.420735, -19.693949, -22.03864, 9.828769, -19.07084, -22.242657, 9.475412, -19.07084, -21.834623, 9.475412, -19.693949, -22.03864, 9.828769, -19.07084, -22.03864, 9.420735, -19.07084, -21.685282, 9.624752, -19.693949, -22.03864, 9.828769, -19.07084, -21.834623, 9.475412, -19.07084, -21.630606, 9.828769, -19.693949, -22.03864, 9.828769, -19.07084, -21.685282, 9.624752, -19.07084, -21.685282, 10.032785, -19.693949, -22.03864, 9.828769, -19.07084, -21.630606, 9.828769, -19.07084, -21.834623, 10.182125, -19.693949, -22.03864, 9.828769, -19.07084, -21.685282, 10.032785, -19.07084, -22.03864, 10.236801, -19.693949, -22.03864, 9.828769, -19.07084, -21.834623, 10.182125, -19.07084, -22.242657, 10.182125, -19.693949, -22.03864, 9.828769, -19.07084, -22.03864, 10.236801, -10.526909, -22.391994, 9.624752, -9.89662, -22.03864, 9.82877, -10.526909, -22.242655, 9.475412, -10.526909, -22.446672, 9.82877, -9.89662, -22.03864, 9.82877, -10.526909, -22.391994, 9.624752, -10.526909, -22.391994, 10.032785, -9.89662, -22.03864, 9.82877, -10.526909, -22.446672, 9.82877, -10.526909, -22.242655, 10.182125, -9.89662, -22.03864, 9.82877, -10.526909, -22.391994, 10.032785, -10.526909, -22.242655, 9.475412, -9.89662, -22.03864, 9.82877, -10.526909, -22.03864, 9.420736, -10.526909, -22.03864, 9.420736, -9.89662, -22.03864, 9.82877, -10.526909, -21.834621, 9.475412, -10.526909, -21.834621, 9.475412, -9.89662, -22.03864, 9.82877, -10.526909, -21.685282, 9.624752, -10.526909, -21.685282, 9.624752, -9.89662, -22.03864, 9.82877, -10.526909, -21.630606, 9.82877, -10.526909, -21.630606, 9.82877, -9.89662, -22.03864, 9.82877, -10.526909, -21.685282, 10.032785, -10.526909, -21.685282, 10.032785, -9.89662, -22.03864, 9.82877, -10.526909, -21.834621, 10.182125, -10.526909, -21.834621, 10.182125, -9.89662, -22.03864, 9.82877, -10.526909, -22.03864, 10.236803, -10.526909, -22.03864, 10.236803, -9.89662, -22.03864, 9.82877, -10.526909, -22.242655, 10.182125, -14.262087, -22.348663, 7.7697797, -10.526909, -22.242655, 7.6348023, -14.262087, -22.188835, 7.609912, -14.262087, -22.348663, 7.7697797, -10.526909, -22.391994, 7.7841425, -10.526909, -22.242655, 7.6348023, -19.07084, -22.391996, 7.784142, -14.262087, -22.348663, 7.7697797, -14.262087, -22.188835, 7.609912, -19.07084, -22.391996, 7.784142, -14.262087, -22.188835, 7.609912, -19.07084, -22.242657, 7.634802, -14.262087, -22.188835, 7.609912, -10.526909, -22.03864, 7.580126, -14.262087, -21.970457, 7.5514, -14.262087, -22.188835, 7.609912, -10.526909, -22.242655, 7.6348023, -10.526909, -22.03864, 7.580126, -19.07084, -22.242657, 7.634802, -14.262087, -22.188835, 7.609912, -14.262087, -21.970457, 7.5514, -19.07084, -22.242657, 7.634802, -14.262087, -21.970457, 7.5514, -19.07084, -22.03864, 7.5801253, -14.262087, -21.970457, 7.5514, -10.526909, -21.834621, 7.6348023, -14.262087, -21.752077, 7.609912, -14.262087, -21.970457, 7.5514, -10.526909, -22.03864, 7.580126, -10.526909, -21.834621, 7.6348023, -19.07084, -22.03864, 7.5801253, -14.262087, -21.970457, 7.5514, -14.262087, -21.752077, 7.609912, -19.07084, -22.03864, 7.5801253, -14.262087, -21.752077, 7.609912, -19.07084, -21.834623, 7.634802, -14.262087, -21.752077, 7.609912, -10.526909, -21.685282, 7.7841425, -14.262087, -21.592209, 7.769779, -14.262087, -21.752077, 7.609912, -10.526909, -21.834621, 7.6348023, -10.526909, -21.685282, 7.7841425, -19.07084, -21.834623, 7.634802, -14.262087, -21.752077, 7.609912, -14.262087, -21.592209, 7.769779, -19.07084, -21.834623, 7.634802, -14.262087, -21.592209, 7.769779, -19.07084, -21.685282, 7.784142, -14.262087, -21.592209, 7.769779, -10.526909, -21.630606, 7.988159, -14.262087, -21.533697, 7.9881587, -14.262087, -21.592209, 7.769779, -10.526909, -21.685282, 7.7841425, -10.526909, -21.630606, 7.988159, -19.07084, -21.685282, 7.784142, -14.262087, -21.592209, 7.769779, -14.262087, -21.533697, 7.9881587, -19.07084, -21.685282, 7.784142, -14.262087, -21.533697, 7.9881587, -19.07084, -21.630606, 7.9881587, -14.262087, -21.533697, 7.9881587, -10.526909, -21.685282, 8.192176, -14.262087, -21.592209, 8.206538, -14.262087, -21.533697, 7.9881587, -10.526909, -21.630606, 7.988159, -10.526909, -21.685282, 8.192176, -19.07084, -21.630606, 7.9881587, -14.262087, -21.533697, 7.9881587, -14.262087, -21.592209, 8.206538, -19.07084, -21.630606, 7.9881587, -14.262087, -21.592209, 8.206538, -19.07084, -21.685282, 8.192175, -14.262087, -21.592209, 8.206538, -10.526909, -21.834621, 8.3415165, -14.262087, -21.752077, 8.366365, -14.262087, -21.592209, 8.206538, -10.526909, -21.685282, 8.192176, -10.526909, -21.834621, 8.3415165, -19.07084, -21.685282, 8.192175, -14.262087, -21.592209, 8.206538, -14.262087, -21.752077, 8.366365, -19.07084, -21.685282, 8.192175, -14.262087, -21.752077, 8.366365, -19.07084, -21.834623, 8.341516, -14.262087, -21.752077, 8.366365, -10.526909, -22.03864, 8.396193, -14.262087, -21.970457, 8.424917, -14.262087, -21.752077, 8.366365, -10.526909, -21.834621, 8.3415165, -10.526909, -22.03864, 8.396193, -19.07084, -21.834623, 8.341516, -14.262087, -21.752077, 8.366365, -14.262087, -21.970457, 8.424917, -19.07084, -21.834623, 8.341516, -14.262087, -21.970457, 8.424917, -19.07084, -22.03864, 8.396193, -14.262087, -21.970457, 8.424917, -10.526909, -22.242655, 8.3415165, -14.262087, -22.188835, 8.366365, -14.262087, -21.970457, 8.424917, -10.526909, -22.03864, 8.396193, -10.526909, -22.242655, 8.3415165, -19.07084, -22.03864, 8.396193, -14.262087, -21.970457, 8.424917, -14.262087, -22.188835, 8.366365, -19.07084, -22.03864, 8.396193, -14.262087, -22.188835, 8.366365, -19.07084, -22.242657, 8.341516, -14.262087, -22.188835, 8.366365, -10.526909, -22.391994, 8.192176, -14.262087, -22.348663, 8.206538, -14.262087, -22.188835, 8.366365, -10.526909, -22.242655, 8.3415165, -10.526909, -22.391994, 8.192176, -19.07084, -22.242657, 8.341516, -14.262087, -22.188835, 8.366365, -14.262087, -22.348663, 8.206538, -19.07084, -22.242657, 8.341516, -14.262087, -22.348663, 8.206538, -19.07084, -22.391996, 8.192175, -14.262087, -22.348663, 8.206538, -10.526909, -22.446672, 7.988159, -14.262087, -22.407175, 7.9881587, -14.262087, -22.348663, 8.206538, -10.526909, -22.391994, 8.192176, -10.526909, -22.446672, 7.988159, -19.07084, -22.391996, 8.192175, -14.262087, -22.348663, 8.206538, -14.262087, -22.407175, 7.9881587, -19.07084, -22.391996, 8.192175, -14.262087, -22.407175, 7.9881587, -19.07084, -22.446672, 7.9881587, -14.262087, -22.407175, 7.9881587, -10.526909, -22.391994, 7.7841425, -14.262087, -22.348663, 7.7697797, -14.262087, -22.407175, 7.9881587, -10.526909, -22.446672, 7.988159, -10.526909, -22.391994, 7.7841425, -19.07084, -22.446672, 7.9881587, -14.262087, -22.407175, 7.9881587, -14.262087, -22.348663, 7.7697797, -19.07084, -22.446672, 7.9881587, -14.262087, -22.348663, 7.7697797, -19.07084, -22.391996, 7.784142, -19.07084, -22.242657, 7.634802, -19.693949, -22.03864, 7.9881587, -19.07084, -22.391996, 7.784142, -19.07084, -22.391996, 7.784142, -19.693949, -22.03864, 7.9881587, -19.07084, -22.446672, 7.9881587, -19.07084, -22.446672, 7.9881587, -19.693949, -22.03864, 7.9881587, -19.07084, -22.391996, 8.192175, -19.07084, -22.391996, 8.192175, -19.693949, -22.03864, 7.9881587, -19.07084, -22.242657, 8.341516, -19.07084, -22.03864, 7.5801253, -19.693949, -22.03864, 7.9881587, -19.07084, -22.242657, 7.634802, -19.07084, -21.834623, 7.634802, -19.693949, -22.03864, 7.9881587, -19.07084, -22.03864, 7.5801253, -19.07084, -21.685282, 7.784142, -19.693949, -22.03864, 7.9881587, -19.07084, -21.834623, 7.634802, -19.07084, -21.630606, 7.9881587, -19.693949, -22.03864, 7.9881587, -19.07084, -21.685282, 7.784142, -19.07084, -21.685282, 8.192175, -19.693949, -22.03864, 7.9881587, -19.07084, -21.630606, 7.9881587, -19.07084, -21.834623, 8.341516, -19.693949, -22.03864, 7.9881587, -19.07084, -21.685282, 8.192175, -19.07084, -22.03864, 8.396193, -19.693949, -22.03864, 7.9881587, -19.07084, -21.834623, 8.341516, -19.07084, -22.242657, 8.341516, -19.693949, -22.03864, 7.9881587, -19.07084, -22.03864, 8.396193, -10.526909, -22.391994, 7.7841425, -9.89662, -22.03864, 7.988159, -10.526909, -22.242655, 7.6348023, -10.526909, -22.446672, 7.988159, -9.89662, -22.03864, 7.988159, -10.526909, -22.391994, 7.7841425, -10.526909, -22.391994, 8.192176, -9.89662, -22.03864, 7.988159, -10.526909, -22.446672, 7.988159, -10.526909, -22.242655, 8.3415165, -9.89662, -22.03864, 7.988159, -10.526909, -22.391994, 8.192176, -10.526909, -22.242655, 7.6348023, -9.89662, -22.03864, 7.988159, -10.526909, -22.03864, 7.580126, -10.526909, -22.03864, 7.580126, -9.89662, -22.03864, 7.988159, -10.526909, -21.834621, 7.6348023, -10.526909, -21.834621, 7.6348023, -9.89662, -22.03864, 7.988159, -10.526909, -21.685282, 7.7841425, -10.526909, -21.685282, 7.7841425, -9.89662, -22.03864, 7.988159, -10.526909, -21.630606, 7.988159, -10.526909, -21.630606, 7.988159, -9.89662, -22.03864, 7.988159, -10.526909, -21.685282, 8.192176, -10.526909, -21.685282, 8.192176, -9.89662, -22.03864, 7.988159, -10.526909, -21.834621, 8.3415165, -10.526909, -21.834621, 8.3415165, -9.89662, -22.03864, 7.988159, -10.526909, -22.03864, 8.396193, -10.526909, -22.03864, 8.396193, -9.89662, -22.03864, 7.988159, -10.526909, -22.242655, 8.3415165, -12.004166, -22.046726, 10.088959, -12.124956, -19.902678, 9.968168, -12.124956, -22.046726, 9.968168, -12.004166, -22.046726, 10.088959, -12.004166, -19.902678, 10.088959, -12.124956, -19.902678, 9.968168, -12.124956, -22.046726, 9.968168, -12.28997, -19.902678, 9.923944, -12.28997, -22.046726, 9.923944, -12.124956, -22.046726, 9.968168, -12.124956, -19.902678, 9.968168, -12.28997, -19.902678, 9.923944, -12.28997, -22.046726, 9.923944, -12.454985, -19.902678, 9.968168, -12.454985, -22.046726, 9.968168, -12.28997, -22.046726, 9.923944, -12.28997, -19.902678, 9.923944, -12.454985, -19.902678, 9.968168, -12.454985, -22.046726, 9.968168, -12.575773, -19.902678, 10.088959, -12.575773, -22.046726, 10.088959, -12.454985, -22.046726, 9.968168, -12.454985, -19.902678, 9.968168, -12.575773, -19.902678, 10.088959, -12.575773, -22.046726, 10.088959, -12.619997, -19.902678, 10.253973, -12.619997, -22.046726, 10.253973, -12.575773, -22.046726, 10.088959, -12.575773, -19.902678, 10.088959, -12.619997, -19.902678, 10.253973, -12.619997, -22.046726, 10.253973, -12.575773, -19.902678, 10.418985, -12.575773, -22.046726, 10.418987, -12.619997, -22.046726, 10.253973, -12.619997, -19.902678, 10.253973, -12.575773, -19.902678, 10.418985, -12.575773, -22.046726, 10.418987, -12.454985, -19.902678, 10.539776, -12.454985, -22.046726, 10.539778, -12.575773, -22.046726, 10.418987, -12.575773, -19.902678, 10.418985, -12.454985, -19.902678, 10.539776, -12.454985, -22.046726, 10.539778, -12.28997, -19.902678, 10.584, -12.28997, -22.046726, 10.584002, -12.454985, -22.046726, 10.539778, -12.454985, -19.902678, 10.539776, -12.28997, -19.902678, 10.584, -12.28997, -22.046726, 10.584002, -12.124956, -19.902678, 10.539776, -12.124956, -22.046726, 10.539778, -12.28997, -22.046726, 10.584002, -12.28997, -19.902678, 10.584, -12.124956, -19.902678, 10.539776, -12.124956, -22.046726, 10.539778, -12.004166, -19.902678, 10.418985, -12.004166, -22.046726, 10.418987, -12.124956, -22.046726, 10.539778, -12.124956, -19.902678, 10.539776, -12.004166, -19.902678, 10.418985, -12.004166, -22.046726, 10.418987, -11.959942, -19.902678, 10.253973, -11.959942, -22.046726, 10.253973, -12.004166, -22.046726, 10.418987, -12.004166, -19.902678, 10.418985, -11.959942, -19.902678, 10.253973, -11.959942, -22.046726, 10.253973, -12.004166, -19.902678, 10.088959, -12.004166, -22.046726, 10.088959, -11.959942, -22.046726, 10.253973, -11.959942, -19.902678, 10.253973, -12.004166, -19.902678, 10.088959, -12.124956, -22.046726, 9.968168, -12.28997, -22.046726, 10.253973, -12.004166, -22.046726, 10.088959, -12.004166, -22.046726, 10.088959, -12.28997, -22.046726, 10.253973, -11.959942, -22.046726, 10.253973, -12.28997, -22.046726, 9.923944, -12.28997, -22.046726, 10.253973, -12.124956, -22.046726, 9.968168, -11.959942, -22.046726, 10.253973, -12.28997, -22.046726, 10.253973, -12.004166, -22.046726, 10.418987, -12.454985, -22.046726, 9.968168, -12.28997, -22.046726, 10.253973, -12.28997, -22.046726, 9.923944, -12.004166, -22.046726, 10.418987, -12.28997, -22.046726, 10.253973, -12.124956, -22.046726, 10.539778, -12.575773, -22.046726, 10.088959, -12.28997, -22.046726, 10.253973, -12.454985, -22.046726, 9.968168, -12.124956, -22.046726, 10.539778, -12.28997, -22.046726, 10.253973, -12.28997, -22.046726, 10.584002, -12.619997, -22.046726, 10.253973, -12.28997, -22.046726, 10.253973, -12.575773, -22.046726, 10.088959, -12.28997, -22.046726, 10.584002, -12.28997, -22.046726, 10.253973, -12.454985, -22.046726, 10.539778, -12.575773, -22.046726, 10.418987, -12.28997, -22.046726, 10.253973, -12.619997, -22.046726, 10.253973, -12.454985, -22.046726, 10.539778, -12.28997, -22.046726, 10.253973, -12.575773, -22.046726, 10.418987, -12.004166, -19.902678, 10.088959, -12.28997, -19.456135, 10.253971, -12.124956, -19.902678, 9.968168, -12.124956, -19.902678, 9.968168, -12.28997, -19.456135, 10.253971, -12.28997, -19.902678, 9.923944, -11.959942, -19.902678, 10.253973, -12.28997, -19.456135, 10.253971, -12.004166, -19.902678, 10.088959, -12.28997, -19.902678, 9.923944, -12.28997, -19.456135, 10.253971, -12.454985, -19.902678, 9.968168, -12.004166, -19.902678, 10.418985, -12.28997, -19.456135, 10.253971, -11.959942, -19.902678, 10.253973, -12.454985, -19.902678, 9.968168, -12.28997, -19.456135, 10.253971, -12.575773, -19.902678, 10.088959, -12.124956, -19.902678, 10.539776, -12.28997, -19.456135, 10.253971, -12.004166, -19.902678, 10.418985, -12.575773, -19.902678, 10.088959, -12.28997, -19.456135, 10.253971, -12.619997, -19.902678, 10.253973, -12.28997, -19.902678, 10.584, -12.28997, -19.456135, 10.253971, -12.124956, -19.902678, 10.539776, -12.619997, -19.902678, 10.253973, -12.28997, -19.456135, 10.253971, -12.575773, -19.902678, 10.418985, -12.454985, -19.902678, 10.539776, -12.28997, -19.456135, 10.253971, -12.28997, -19.902678, 10.584, -12.575773, -19.902678, 10.418985, -12.28997, -19.456135, 10.253971, -12.454985, -19.902678, 10.539776, -12.004166, -22.046726, 6.859756, -12.124956, -19.902678, 6.7389646, -12.124956, -22.046726, 6.7389655, -12.004166, -22.046726, 6.859756, -12.004166, -19.902678, 6.859755, -12.124956, -19.902678, 6.7389646, -12.124956, -22.046726, 6.7389655, -12.28997, -19.902678, 6.6947412, -12.28997, -22.046726, 6.6947417, -12.124956, -22.046726, 6.7389655, -12.124956, -19.902678, 6.7389646, -12.28997, -19.902678, 6.6947412, -12.28997, -22.046726, 6.6947417, -12.454985, -19.902678, 6.7389646, -12.454985, -22.046726, 6.7389655, -12.28997, -22.046726, 6.6947417, -12.28997, -19.902678, 6.6947412, -12.454985, -19.902678, 6.7389646, -12.454985, -22.046726, 6.7389655, -12.575773, -19.902678, 6.859755, -12.575773, -22.046726, 6.859756, -12.454985, -22.046726, 6.7389655, -12.454985, -19.902678, 6.7389646, -12.575773, -19.902678, 6.859755, -12.575773, -22.046726, 6.859756, -12.619997, -19.902678, 7.024769, -12.619997, -22.046726, 7.02477, -12.575773, -22.046726, 6.859756, -12.575773, -19.902678, 6.859755, -12.619997, -19.902678, 7.024769, -12.619997, -22.046726, 7.02477, -12.575773, -19.902678, 7.1897826, -12.575773, -22.046726, 7.1897836, -12.619997, -22.046726, 7.02477, -12.619997, -19.902678, 7.024769, -12.575773, -19.902678, 7.1897826, -12.575773, -22.046726, 7.1897836, -12.454985, -19.902678, 7.310573, -12.454985, -22.046726, 7.3105736, -12.575773, -22.046726, 7.1897836, -12.575773, -19.902678, 7.1897826, -12.454985, -19.902678, 7.310573, -12.454985, -22.046726, 7.3105736, -12.28997, -19.902678, 7.354797, -12.28997, -22.046726, 7.3547974, -12.454985, -22.046726, 7.3105736, -12.454985, -19.902678, 7.310573, -12.28997, -19.902678, 7.354797, -12.28997, -22.046726, 7.3547974, -12.124956, -19.902678, 7.310573, -12.124956, -22.046726, 7.3105736, -12.28997, -22.046726, 7.3547974, -12.28997, -19.902678, 7.354797, -12.124956, -19.902678, 7.310573, -12.124956, -22.046726, 7.3105736, -12.004166, -19.902678, 7.1897826, -12.004166, -22.046726, 7.1897836, -12.124956, -22.046726, 7.3105736, -12.124956, -19.902678, 7.310573, -12.004166, -19.902678, 7.1897826, -12.004166, -22.046726, 7.1897836, -11.959942, -19.902678, 7.024769, -11.959942, -22.046726, 7.02477, -12.004166, -22.046726, 7.1897836, -12.004166, -19.902678, 7.1897826, -11.959942, -19.902678, 7.024769, -11.959942, -22.046726, 7.02477, -12.004166, -19.902678, 6.859755, -12.004166, -22.046726, 6.859756, -11.959942, -22.046726, 7.02477, -11.959942, -19.902678, 7.024769, -12.004166, -19.902678, 6.859755, -12.124956, -22.046726, 6.7389655, -12.28997, -22.046726, 7.02477, -12.004166, -22.046726, 6.859756, -12.004166, -22.046726, 6.859756, -12.28997, -22.046726, 7.02477, -11.959942, -22.046726, 7.02477, -12.28997, -22.046726, 6.6947417, -12.28997, -22.046726, 7.02477, -12.124956, -22.046726, 6.7389655, -11.959942, -22.046726, 7.02477, -12.28997, -22.046726, 7.02477, -12.004166, -22.046726, 7.1897836, -12.454985, -22.046726, 6.7389655, -12.28997, -22.046726, 7.02477, -12.28997, -22.046726, 6.6947417, -12.004166, -22.046726, 7.1897836, -12.28997, -22.046726, 7.02477, -12.124956, -22.046726, 7.3105736, -12.575773, -22.046726, 6.859756, -12.28997, -22.046726, 7.02477, -12.454985, -22.046726, 6.7389655, -12.124956, -22.046726, 7.3105736, -12.28997, -22.046726, 7.02477, -12.28997, -22.046726, 7.3547974, -12.619997, -22.046726, 7.02477, -12.28997, -22.046726, 7.02477, -12.575773, -22.046726, 6.859756, -12.28997, -22.046726, 7.3547974, -12.28997, -22.046726, 7.02477, -12.454985, -22.046726, 7.3105736, -12.575773, -22.046726, 7.1897836, -12.28997, -22.046726, 7.02477, -12.619997, -22.046726, 7.02477, -12.454985, -22.046726, 7.3105736, -12.28997, -22.046726, 7.02477, -12.575773, -22.046726, 7.1897836, -12.004166, -19.902678, 6.859755, -12.28997, -19.456135, 7.024769, -12.124956, -19.902678, 6.7389646, -12.124956, -19.902678, 6.7389646, -12.28997, -19.456135, 7.024769, -12.28997, -19.902678, 6.6947412, -11.959942, -19.902678, 7.024769, -12.28997, -19.456135, 7.024769, -12.004166, -19.902678, 6.859755, -12.28997, -19.902678, 6.6947412, -12.28997, -19.456135, 7.024769, -12.454985, -19.902678, 6.7389646, -12.004166, -19.902678, 7.1897826, -12.28997, -19.456135, 7.024769, -11.959942, -19.902678, 7.024769, -12.454985, -19.902678, 6.7389646, -12.28997, -19.456135, 7.024769, -12.575773, -19.902678, 6.859755, -12.124956, -19.902678, 7.310573, -12.28997, -19.456135, 7.024769, -12.004166, -19.902678, 7.1897826, -12.575773, -19.902678, 6.859755, -12.28997, -19.456135, 7.024769, -12.619997, -19.902678, 7.024769, -12.28997, -19.902678, 7.354797, -12.28997, -19.456135, 7.024769, -12.124956, -19.902678, 7.310573, -12.619997, -19.902678, 7.024769, -12.28997, -19.456135, 7.024769, -12.575773, -19.902678, 7.1897826, -12.454985, -19.902678, 7.310573, -12.28997, -19.456135, 7.024769, -12.28997, -19.902678, 7.354797, -12.575773, -19.902678, 7.1897826, -12.28997, -19.456135, 7.024769, -12.454985, -19.902678, 7.310573, -12.917406, -22.143438, 6.933488, -12.989674, -20.442587, 6.8666687, -12.989674, -22.143438, 6.8666697, -12.917406, -22.143438, 6.933488, -12.917406, -20.442587, 6.933487, -12.989674, -20.442587, 6.8666687, -12.989674, -22.143438, 6.8666697, -13.088398, -20.442587, 6.8422055, -13.088398, -22.143438, 6.842206, -12.989674, -22.143438, 6.8666697, -12.989674, -20.442587, 6.8666687, -13.088398, -20.442587, 6.8422055, -13.088398, -22.143438, 6.842206, -13.187122, -20.442587, 6.8666687, -13.187122, -22.143438, 6.8666697, -13.088398, -22.143438, 6.842206, -13.088398, -20.442587, 6.8422055, -13.187122, -20.442587, 6.8666687, -13.187122, -22.143438, 6.8666697, -13.259388, -20.442587, 6.933487, -13.259388, -22.143438, 6.933488, -13.187122, -22.143438, 6.8666697, -13.187122, -20.442587, 6.8666687, -13.259388, -20.442587, 6.933487, -13.259388, -22.143438, 6.933488, -13.285847, -20.442587, 7.024769, -13.285847, -22.143438, 7.02477, -13.259388, -22.143438, 6.933488, -13.259388, -20.442587, 6.933487, -13.285847, -20.442587, 7.024769, -13.285847, -22.143438, 7.02477, -13.259388, -20.442587, 7.1160507, -13.259388, -22.143438, 7.116051, -13.285847, -22.143438, 7.02477, -13.285847, -20.442587, 7.024769, -13.259388, -20.442587, 7.1160507, -13.259388, -22.143438, 7.116051, -13.187122, -20.442587, 7.182869, -13.187122, -22.143438, 7.18287, -13.259388, -22.143438, 7.116051, -13.259388, -20.442587, 7.1160507, -13.187122, -20.442587, 7.182869, -13.187122, -22.143438, 7.18287, -13.088398, -20.442587, 7.2073326, -13.088398, -22.143438, 7.207333, -13.187122, -22.143438, 7.18287, -13.187122, -20.442587, 7.182869, -13.088398, -20.442587, 7.2073326, -13.088398, -22.143438, 7.207333, -12.989674, -20.442587, 7.182869, -12.989674, -22.143438, 7.18287, -13.088398, -22.143438, 7.207333, -13.088398, -20.442587, 7.2073326, -12.989674, -20.442587, 7.182869, -12.989674, -22.143438, 7.18287, -12.917406, -20.442587, 7.1160507, -12.917406, -22.143438, 7.116051, -12.989674, -22.143438, 7.18287, -12.989674, -20.442587, 7.182869, -12.917406, -20.442587, 7.1160507, -12.917406, -22.143438, 7.116051, -12.890947, -20.442587, 7.024769, -12.890947, -22.143438, 7.02477, -12.917406, -22.143438, 7.116051, -12.917406, -20.442587, 7.1160507, -12.890947, -20.442587, 7.024769, -12.890947, -22.143438, 7.02477, -12.917406, -20.442587, 6.933487, -12.917406, -22.143438, 6.933488, -12.890947, -22.143438, 7.02477, -12.890947, -20.442587, 7.024769, -12.917406, -20.442587, 6.933487, -12.989674, -22.143438, 6.8666697, -13.088398, -22.143438, 7.02477, -12.917406, -22.143438, 6.933488, -12.917406, -22.143438, 6.933488, -13.088398, -22.143438, 7.02477, -12.890947, -22.143438, 7.02477, -13.088398, -22.143438, 6.842206, -13.088398, -22.143438, 7.02477, -12.989674, -22.143438, 6.8666697, -12.890947, -22.143438, 7.02477, -13.088398, -22.143438, 7.02477, -12.917406, -22.143438, 7.116051, -13.187122, -22.143438, 6.8666697, -13.088398, -22.143438, 7.02477, -13.088398, -22.143438, 6.842206, -12.917406, -22.143438, 7.116051, -13.088398, -22.143438, 7.02477, -12.989674, -22.143438, 7.18287, -13.259388, -22.143438, 6.933488, -13.088398, -22.143438, 7.02477, -13.187122, -22.143438, 6.8666697, -12.989674, -22.143438, 7.18287, -13.088398, -22.143438, 7.02477, -13.088398, -22.143438, 7.207333, -13.285847, -22.143438, 7.02477, -13.088398, -22.143438, 7.02477, -13.259388, -22.143438, 6.933488, -13.088398, -22.143438, 7.207333, -13.088398, -22.143438, 7.02477, -13.187122, -22.143438, 7.18287, -13.259388, -22.143438, 7.116051, -13.088398, -22.143438, 7.02477, -13.285847, -22.143438, 7.02477, -13.187122, -22.143438, 7.18287, -13.088398, -22.143438, 7.02477, -13.259388, -22.143438, 7.116051, -12.917406, -20.442587, 6.933487, -13.088398, -20.08835, 7.024769, -12.989674, -20.442587, 6.8666687, -12.989674, -20.442587, 6.8666687, -13.088398, -20.08835, 7.024769, -13.088398, -20.442587, 6.8422055, -12.890947, -20.442587, 7.024769, -13.088398, -20.08835, 7.024769, -12.917406, -20.442587, 6.933487, -13.088398, -20.442587, 6.8422055, -13.088398, -20.08835, 7.024769, -13.187122, -20.442587, 6.8666687, -12.917406, -20.442587, 7.1160507, -13.088398, -20.08835, 7.024769, -12.890947, -20.442587, 7.024769, -13.187122, -20.442587, 6.8666687, -13.088398, -20.08835, 7.024769, -13.259388, -20.442587, 6.933487, -12.989674, -20.442587, 7.182869, -13.088398, -20.08835, 7.024769, -12.917406, -20.442587, 7.1160507, -13.259388, -20.442587, 6.933487, -13.088398, -20.08835, 7.024769, -13.285847, -20.442587, 7.024769, -13.088398, -20.442587, 7.2073326, -13.088398, -20.08835, 7.024769, -12.989674, -20.442587, 7.182869, -13.285847, -20.442587, 7.024769, -13.088398, -20.08835, 7.024769, -13.259388, -20.442587, 7.1160507, -13.187122, -20.442587, 7.182869, -13.088398, -20.08835, 7.024769, -13.088398, -20.442587, 7.2073326, -13.259388, -20.442587, 7.1160507, -13.088398, -20.08835, 7.024769, -13.187122, -20.442587, 7.182869, 7.7560043, -21.843687, -1.5963855, 7.8594513, -21.712654, -1.5136316, 7.8594513, -21.889545, -1.5601864, 7.7560043, -21.843687, -1.5963855, 7.7198067, -21.712654, -1.5601864, 7.8594513, -21.712654, -1.5136316, 7.7198067, -21.889545, -1.6998296, 7.7560043, -21.843687, -1.5963855, 7.8594513, -21.889545, -1.5601864, 7.7198067, -21.889545, -1.6998296, 7.7198067, -21.712654, -1.5601864, 7.7560043, -21.843687, -1.5963855, 7.7198067, -21.712654, -1.5601864, 7.8594513, -21.392513, -1.5493045, 7.8594513, -21.712654, -1.5136316, 7.8594513, -21.712654, -1.5136316, 7.8594513, -21.392513, -1.5493045, 7.9628983, -21.392513, -1.5855265, 7.7198067, -21.712654, -1.5601864, 7.7560043, -21.392513, -1.5855265, 7.8594513, -21.392513, -1.5493045, 7.8594513, -21.712654, -1.5136316, 7.9628983, -21.392513, -1.5855265, 7.999096, -21.712654, -1.5601864, 7.8594513, -21.889545, -1.5601864, 7.8594513, -21.712654, -1.5136316, 7.999096, -21.712654, -1.5601864, 7.999096, -21.712654, -1.5601864, 7.9628983, -21.392513, -1.5855265, 7.999096, -21.392513, -1.6889691, 7.673259, -21.712656, -1.6998296, 7.7560043, -21.392513, -1.5855265, 7.7198067, -21.712654, -1.5601864, 7.7198067, -21.889545, -1.6998296, 7.673259, -21.712656, -1.6998296, 7.7198067, -21.712654, -1.5601864, 7.673259, -21.712656, -1.6998296, 7.7198067, -21.392513, -1.6889691, 7.7560043, -21.392513, -1.5855265, 7.999096, -21.712654, -1.5601864, 7.999096, -21.392513, -1.6889691, 8.045644, -21.712656, -1.6998296, 8.045644, -21.712656, -1.6998296, 7.999096, -21.392513, -1.6889691, 7.9628983, -21.392513, -1.7924135, 7.8594513, -21.889545, -1.5601864, 7.999096, -21.712654, -1.5601864, 7.9628983, -21.843687, -1.5963855, 7.9628983, -21.843687, -1.5963855, 7.999096, -21.712654, -1.5601864, 8.045644, -21.712656, -1.6998296, 7.7198067, -21.889545, -1.6998296, 7.8594513, -21.889545, -1.5601864, 7.8594513, -21.948505, -1.6998296, 7.8594513, -21.948505, -1.6998296, 7.8594513, -21.889545, -1.5601864, 7.9628983, -21.843687, -1.5963855, 7.7560043, -21.843687, -1.8032722, 7.673259, -21.712656, -1.6998296, 7.7198067, -21.889545, -1.6998296, 7.7560043, -21.843687, -1.8032722, 7.7198067, -21.889545, -1.6998296, 7.8594513, -21.948505, -1.6998296, 7.7198067, -21.712656, -1.8394728, 7.7198067, -21.392513, -1.6889691, 7.673259, -21.712656, -1.6998296, 7.7560043, -21.843687, -1.8032722, 7.7198067, -21.712656, -1.8394728, 7.673259, -21.712656, -1.6998296, 7.7198067, -21.712656, -1.8394728, 7.7560043, -21.392513, -1.7924135, 7.7198067, -21.392513, -1.6889691, 7.7560043, -21.843687, -1.8032722, 7.8594513, -21.948505, -1.6998296, 7.8594513, -21.889545, -1.8394728, 7.7198067, -21.712656, -1.8394728, 7.7560043, -21.843687, -1.8032722, 7.8594513, -21.889545, -1.8394728, 7.8594513, -21.948505, -1.6998296, 7.9628983, -21.843687, -1.5963855, 7.999096, -21.889545, -1.6998296, 7.8594513, -21.889545, -1.8394728, 7.8594513, -21.948505, -1.6998296, 7.999096, -21.889545, -1.6998296, 7.9628983, -21.843687, -1.5963855, 8.045644, -21.712656, -1.6998296, 7.999096, -21.889545, -1.6998296, 7.8594513, -21.889545, -1.8394728, 7.999096, -21.889545, -1.6998296, 7.9628983, -21.843687, -1.8032722, 7.7560043, -21.392513, -1.7924135, 7.7198067, -21.712656, -1.8394728, 7.8594513, -21.712656, -1.8860278, 7.7198067, -21.712656, -1.8394728, 7.8594513, -21.889545, -1.8394728, 7.8594513, -21.712656, -1.8860278, 7.8594513, -21.712656, -1.8860278, 7.8594513, -21.889545, -1.8394728, 7.9628983, -21.843687, -1.8032722, 7.7560043, -21.392513, -1.7924135, 7.8594513, -21.712656, -1.8860278, 7.8594513, -21.392513, -1.8286123, 7.999096, -21.889545, -1.6998296, 8.045644, -21.712656, -1.6998296, 7.999096, -21.712656, -1.8394728, 7.999096, -21.889545, -1.6998296, 7.999096, -21.712656, -1.8394728, 7.9628983, -21.843687, -1.8032722, 7.8594513, -21.712656, -1.8860278, 7.9628983, -21.843687, -1.8032722, 7.999096, -21.712656, -1.8394728, 7.8594513, -21.392513, -1.8286123, 7.8594513, -21.712656, -1.8860278, 7.999096, -21.712656, -1.8394728, 8.045644, -21.712656, -1.6998296, 7.9628983, -21.392513, -1.7924135, 7.999096, -21.712656, -1.8394728, 7.8594513, -21.392513, -1.8286123, 7.999096, -21.712656, -1.8394728, 7.9628983, -21.392513, -1.7924135, 7.597028, -21.442598, -1.34617, 7.8594513, -21.312298, -1.1490684, 7.8594513, -21.49598, -1.2661133, 7.597028, -21.442598, -1.34617, 7.505172, -21.314877, -1.2550125, 7.8594513, -21.312298, -1.1490684, 7.8594513, -21.49598, -1.2661133, 7.8594513, -21.312298, -1.1490684, 8.213731, -21.314877, -1.2550125, 7.505172, -21.409956, -1.6840334, 7.505172, -21.314877, -1.2550125, 7.597028, -21.442598, -1.34617, 7.505172, -21.409956, -1.6840334, 7.597028, -21.442598, -1.34617, 7.8594513, -21.49598, -1.2661133, 7.505172, -21.409956, -1.6840334, 7.387093, -21.22724, -1.6845381, 7.505172, -21.314877, -1.2550125, 7.8594513, -21.49598, -1.2661133, 8.213731, -21.314877, -1.2550125, 8.121874, -21.442598, -1.34617, 8.121874, -21.442598, -1.34617, 8.213731, -21.314877, -1.2550125, 8.331823, -21.22724, -1.6845381, 7.505172, -21.409956, -1.6840334, 7.8594513, -21.49598, -1.2661133, 7.8594513, -21.492252, -1.6844721, 7.8594513, -21.492252, -1.6844721, 7.8594513, -21.49598, -1.2661133, 8.121874, -21.442598, -1.34617, 7.597028, -21.339413, -1.9443204, 7.387093, -21.22724, -1.6845381, 7.505172, -21.409956, -1.6840334, 7.597028, -21.339413, -1.9443204, 7.505172, -21.409956, -1.6840334, 7.8594513, -21.492252, -1.6844721, 7.597028, -21.339413, -1.9443204, 7.505172, -21.222763, -2.0274482, 7.387093, -21.22724, -1.6845381, 8.121874, -21.442598, -1.34617, 8.331823, -21.22724, -1.6845381, 8.213731, -21.409956, -1.6840334, 7.8594513, -21.492252, -1.6844721, 8.121874, -21.442598, -1.34617, 8.213731, -21.409956, -1.6840334, 8.213731, -21.409956, -1.6840334, 8.331823, -21.22724, -1.6845381, 8.213731, -21.222763, -2.0274482, 7.597028, -21.339413, -1.9443204, 7.8594513, -21.492252, -1.6844721, 7.8594513, -21.4032, -2.0336347, 7.505172, -21.222763, -2.0274482, 7.597028, -21.339413, -1.9443204, 7.8594513, -21.4032, -2.0336347, 7.8594513, -21.4032, -2.0336347, 7.8594513, -21.492252, -1.6844721, 8.213731, -21.409956, -1.6840334, 7.505172, -21.222763, -2.0274482, 7.8594513, -21.4032, -2.0336347, 7.8594513, -21.227156, -2.1436162, 8.213731, -21.409956, -1.6840334, 8.213731, -21.222763, -2.0274482, 8.121874, -21.339413, -1.9443204, 7.8594513, -21.4032, -2.0336347, 8.213731, -21.409956, -1.6840334, 8.121874, -21.339413, -1.9443204, 7.8594513, -21.227156, -2.1436162, 8.121874, -21.339413, -1.9443204, 8.213731, -21.222763, -2.0274482, 7.8594513, -21.227156, -2.1436162, 7.8594513, -21.4032, -2.0336347, 8.121874, -21.339413, -1.9443204, 7.8594513, -21.312298, -1.1490684, 8.121874, -21.111137, -1.4137647, 8.213731, -21.314877, -1.2550125, 8.213731, -21.314877, -1.2550125, 8.121874, -21.111137, -1.4137647, 8.213731, -21.024748, -1.6911418, 7.8594513, -21.312298, -1.1490684, 7.8594513, -21.038862, -1.3319969, 8.121874, -21.111137, -1.4137647, 7.8594513, -21.038862, -1.3319969, 8.213731, -21.024748, -1.6911418, 8.121874, -21.111137, -1.4137647, 8.213731, -21.314877, -1.2550125, 8.213731, -21.024748, -1.6911418, 8.331823, -21.22724, -1.6845381, 7.505172, -21.314877, -1.2550125, 7.8594513, -21.038862, -1.3319969, 7.8594513, -21.312298, -1.1490684, 7.505172, -21.314877, -1.2550125, 7.597028, -21.111137, -1.4137647, 7.8594513, -21.038862, -1.3319969, 7.387093, -21.22724, -1.6845381, 7.597028, -21.111137, -1.4137647, 7.505172, -21.314877, -1.2550125, 7.8594513, -21.038862, -1.3319969, 7.8594513, -20.941704, -1.6914926, 8.213731, -21.024748, -1.6911418, 7.597028, -21.111137, -1.4137647, 7.8594513, -20.941704, -1.6914926, 7.8594513, -21.038862, -1.3319969, 8.331823, -21.22724, -1.6845381, 8.213731, -21.024748, -1.6911418, 8.121874, -21.092463, -1.9232578, 7.8594513, -20.941704, -1.6914926, 8.121874, -21.092463, -1.9232578, 8.213731, -21.024748, -1.6911418, 8.331823, -21.22724, -1.6845381, 8.121874, -21.092463, -1.9232578, 8.213731, -21.222763, -2.0274482, 7.387093, -21.22724, -1.6845381, 7.505172, -21.024748, -1.6911418, 7.597028, -21.111137, -1.4137647, 7.597028, -21.111137, -1.4137647, 7.505172, -21.024748, -1.6911418, 7.8594513, -20.941704, -1.6914926, 7.505172, -21.222763, -2.0274482, 7.505172, -21.024748, -1.6911418, 7.387093, -21.22724, -1.6845381, 7.8594513, -21.02841, -2.012529, 8.213731, -21.222763, -2.0274482, 8.121874, -21.092463, -1.9232578, 7.8594513, -20.941704, -1.6914926, 7.8594513, -21.02841, -2.012529, 8.121874, -21.092463, -1.9232578, 7.505172, -21.024748, -1.6911418, 7.8594513, -21.02841, -2.012529, 7.8594513, -20.941704, -1.6914926, 7.8594513, -21.02841, -2.012529, 7.8594513, -21.227156, -2.1436162, 8.213731, -21.222763, -2.0274482, 7.505172, -21.222763, -2.0274482, 7.597028, -21.092463, -1.9232578, 7.505172, -21.024748, -1.6911418, 7.505172, -21.024748, -1.6911418, 7.597028, -21.092463, -1.9232578, 7.8594513, -21.02841, -2.012529, 7.597028, -21.092463, -1.9232578, 7.505172, -21.222763, -2.0274482, 7.8594513, -21.227156, -2.1436162, 7.597028, -21.092463, -1.9232578, 7.8594513, -21.227156, -2.1436162, 7.8594513, -21.02841, -2.012529, 7.7984443, -21.95358, -2.1591706, 7.8594513, -21.864279, -2.1397543, 7.8594513, -21.971691, -2.1298366, 7.7984443, -21.95358, -2.1591706, 7.7770944, -21.873667, -2.165554, 7.8594513, -21.864279, -2.1397543, 7.7770944, -21.999872, -2.2072396, 7.7984443, -21.95358, -2.1591706, 7.8594513, -21.971691, -2.1298366, 7.7770944, -21.999872, -2.2072396, 7.7770944, -21.873667, -2.165554, 7.7984443, -21.95358, -2.1591706, 7.7770944, -21.873667, -2.165554, 7.8594513, -21.694061, -2.224133, 7.8594513, -21.864279, -2.1397543, 7.8594513, -21.864279, -2.1397543, 7.8594513, -21.694061, -2.224133, 7.9204583, -21.701368, -2.2442064, 7.7770944, -21.873667, -2.165554, 7.7984443, -21.701368, -2.2442064, 7.8594513, -21.694061, -2.224133, 7.8594513, -21.864279, -2.1397543, 7.9204583, -21.701368, -2.2442064, 7.941808, -21.873667, -2.165554, 7.8594513, -21.971691, -2.1298366, 7.8594513, -21.864279, -2.1397543, 7.941808, -21.873667, -2.165554, 7.941808, -21.873667, -2.165554, 7.9204583, -21.701368, -2.2442064, 7.941808, -21.722242, -2.3015342, 7.7496324, -21.901846, -2.2429338, 7.7984443, -21.701368, -2.2442064, 7.7770944, -21.873667, -2.165554, 7.7770944, -21.999872, -2.2072396, 7.7496324, -21.901846, -2.2429338, 7.7770944, -21.873667, -2.165554, 7.7496324, -21.901846, -2.2429338, 7.7770944, -21.722242, -2.3015342, 7.7984443, -21.701368, -2.2442064, 7.941808, -21.873667, -2.165554, 7.941808, -21.722242, -2.3015342, 7.96927, -21.901846, -2.2429338, 7.96927, -21.901846, -2.2429338, 7.941808, -21.722242, -2.3015342, 7.9204583, -21.743116, -2.3588605, 7.8594513, -21.971691, -2.1298366, 7.941808, -21.873667, -2.165554, 7.9204583, -21.95358, -2.1591706, 7.9204583, -21.95358, -2.1591706, 7.941808, -21.873667, -2.165554, 7.96927, -21.901846, -2.2429338, 7.7770944, -21.999872, -2.2072396, 7.8594513, -21.971691, -2.1298366, 7.8594513, -22.032564, -2.1953483, 7.8594513, -22.032564, -2.1953483, 7.8594513, -21.971691, -2.1298366, 7.9204583, -21.95358, -2.1591706, 7.7984443, -21.995344, -2.2738247, 7.7496324, -21.901846, -2.2429338, 7.7770944, -21.999872, -2.2072396, 7.7984443, -21.995344, -2.2738247, 7.7770944, -21.999872, -2.2072396, 7.8594513, -22.032564, -2.1953483, 7.7770944, -21.930044, -2.320335, 7.7770944, -21.722242, -2.3015342, 7.7496324, -21.901846, -2.2429338, 7.7984443, -21.995344, -2.2738247, 7.7770944, -21.930044, -2.320335, 7.7496324, -21.901846, -2.2429338, 7.7770944, -21.930044, -2.320335, 7.7984443, -21.743116, -2.3588605, 7.7770944, -21.722242, -2.3015342, 7.7984443, -21.995344, -2.2738247, 7.8594513, -22.032564, -2.1953483, 7.8594513, -22.02807, -2.2846193, 7.7770944, -21.930044, -2.320335, 7.7984443, -21.995344, -2.2738247, 7.8594513, -22.02807, -2.2846193, 7.8594513, -22.032564, -2.1953483, 7.9204583, -21.95358, -2.1591706, 7.941808, -21.999872, -2.2072396, 7.8594513, -22.02807, -2.2846193, 7.8594513, -22.032564, -2.1953483, 7.941808, -21.999872, -2.2072396, 7.9204583, -21.95358, -2.1591706, 7.96927, -21.901846, -2.2429338, 7.941808, -21.999872, -2.2072396, 7.8594513, -22.02807, -2.2846193, 7.941808, -21.999872, -2.2072396, 7.9204583, -21.995344, -2.2738247, 7.7984443, -21.743116, -2.3588605, 7.7770944, -21.930044, -2.320335, 7.8594513, -21.939434, -2.3461366, 7.7770944, -21.930044, -2.320335, 7.8594513, -22.02807, -2.2846193, 7.8594513, -21.939434, -2.3461366, 7.8594513, -21.939434, -2.3461366, 7.8594513, -22.02807, -2.2846193, 7.9204583, -21.995344, -2.2738247, 7.7984443, -21.743116, -2.3588605, 7.8594513, -21.939434, -2.3461366, 7.8594513, -21.750423, -2.3789139, 7.941808, -21.999872, -2.2072396, 7.96927, -21.901846, -2.2429338, 7.941808, -21.930044, -2.320335, 7.941808, -21.999872, -2.2072396, 7.941808, -21.930044, -2.320335, 7.9204583, -21.995344, -2.2738247, 7.8594513, -21.939434, -2.3461366, 7.9204583, -21.995344, -2.2738247, 7.941808, -21.930044, -2.320335, 7.8594513, -21.750423, -2.3789139, 7.8594513, -21.939434, -2.3461366, 7.941808, -21.930044, -2.320335, 7.96927, -21.901846, -2.2429338, 7.9204583, -21.743116, -2.3588605, 7.941808, -21.930044, -2.320335, 7.8594513, -21.750423, -2.3789139, 7.941808, -21.930044, -2.320335, 7.9204583, -21.743116, -2.3588605, 7.7046704, -21.680813, -2.1014476, 7.8594513, -21.56882, -2.0185182, 7.8594513, -21.694244, -2.0463152, 7.7046704, -21.680813, -2.1014476, 7.6505113, -21.591642, -2.0767002, 7.8594513, -21.56882, -2.0185182, 7.8594513, -21.694244, -2.0463152, 7.8594513, -21.56882, -2.0185182, 8.068392, -21.591642, -2.0767002, 7.6505113, -21.730915, -2.2952814, 7.6505113, -21.591642, -2.0767002, 7.7046704, -21.680813, -2.1014476, 7.6505113, -21.730915, -2.2952814, 7.7046704, -21.680813, -2.1014476, 7.8594513, -21.694244, -2.0463152, 7.6505113, -21.730915, -2.2952814, 7.5808535, -21.62976, -2.3324466, 7.6505113, -21.591642, -2.0767002, 7.8594513, -21.694244, -2.0463152, 8.068392, -21.591642, -2.0767002, 8.014233, -21.680813, -2.1014476, 8.014233, -21.680813, -2.1014476, 8.068392, -21.591642, -2.0767002, 8.138048, -21.62976, -2.3324466, 7.6505113, -21.730915, -2.2952814, 7.8594513, -21.694244, -2.0463152, 7.8594513, -21.776608, -2.278893, 7.8594513, -21.776608, -2.278893, 7.8594513, -21.694244, -2.0463152, 8.014233, -21.680813, -2.1014476, 7.7046704, -21.744349, -2.4537702, 7.5808535, -21.62976, -2.3324466, 7.6505113, -21.730915, -2.2952814, 7.7046704, -21.744349, -2.4537702, 7.6505113, -21.730915, -2.2952814, 7.8594513, -21.776608, -2.278893, 7.7046704, -21.744349, -2.4537702, 7.6505113, -21.696476, -2.5233836, 7.5808535, -21.62976, -2.3324466, 8.014233, -21.680813, -2.1014476, 8.138048, -21.62976, -2.3324466, 8.068392, -21.730915, -2.2952814, 7.8594513, -21.776608, -2.278893, 8.014233, -21.680813, -2.1014476, 8.068392, -21.730915, -2.2952814, 8.068392, -21.730915, -2.2952814, 8.138048, -21.62976, -2.3324466, 8.068392, -21.696476, -2.5233836, 7.7046704, -21.744349, -2.4537702, 7.8594513, -21.776608, -2.278893, 7.8594513, -21.79773, -2.490386, 7.6505113, -21.696476, -2.5233836, 7.7046704, -21.744349, -2.4537702, 7.8594513, -21.79773, -2.490386, 7.8594513, -21.79773, -2.490386, 7.8594513, -21.776608, -2.278893, 8.068392, -21.730915, -2.2952814, 7.6505113, -21.696476, -2.5233836, 7.8594513, -21.79773, -2.490386, 7.8594513, -21.722359, -2.586853, 8.068392, -21.730915, -2.2952814, 8.068392, -21.696476, -2.5233836, 8.014233, -21.744349, -2.4537702, 7.8594513, -21.79773, -2.490386, 8.068392, -21.730915, -2.2952814, 8.014233, -21.744349, -2.4537702, 7.8594513, -21.722359, -2.586853, 8.014233, -21.744349, -2.4537702, 8.068392, -21.696476, -2.5233836, 7.8594513, -21.722359, -2.586853, 7.8594513, -21.79773, -2.490386, 8.014233, -21.744349, -2.4537702, 7.8594513, -21.56882, -2.0185182, 8.014233, -21.510761, -2.2058134, 8.068392, -21.591642, -2.0767002, 8.068392, -21.591642, -2.0767002, 8.014233, -21.510761, -2.2058134, 8.068392, -21.51887, -2.3769612, 7.8594513, -21.56882, -2.0185182, 7.8594513, -21.4542, -2.1750765, 8.014233, -21.510761, -2.2058134, 7.8594513, -21.4542, -2.1750765, 8.068392, -21.51887, -2.3769612, 8.014233, -21.510761, -2.2058134, 8.068392, -21.591642, -2.0767002, 8.068392, -21.51887, -2.3769612, 8.138048, -21.62976, -2.3324466, 7.6505113, -21.591642, -2.0767002, 7.8594513, -21.4542, -2.1750765, 7.8594513, -21.56882, -2.0185182, 7.6505113, -21.591642, -2.0767002, 7.7046704, -21.510761, -2.2058134, 7.8594513, -21.4542, -2.1750765, 7.5808535, -21.62976, -2.3324466, 7.7046704, -21.510761, -2.2058134, 7.6505113, -21.591642, -2.0767002, 7.8594513, -21.4542, -2.1750765, 7.8594513, -21.47291, -2.3939195, 8.068392, -21.51887, -2.3769612, 7.7046704, -21.510761, -2.2058134, 7.8594513, -21.47291, -2.3939195, 7.8594513, -21.4542, -2.1750765, 8.138048, -21.62976, -2.3324466, 8.068392, -21.51887, -2.3769612, 8.014233, -21.603245, -2.491922, 7.8594513, -21.47291, -2.3939195, 8.014233, -21.603245, -2.491922, 8.068392, -21.51887, -2.3769612, 8.138048, -21.62976, -2.3324466, 8.014233, -21.603245, -2.491922, 8.068392, -21.696476, -2.5233836, 7.5808535, -21.62976, -2.3324466, 7.6505113, -21.51887, -2.3769612, 7.7046704, -21.510761, -2.2058134, 7.7046704, -21.510761, -2.2058134, 7.6505113, -21.51887, -2.3769612, 7.8594513, -21.47291, -2.3939195, 7.6505113, -21.696476, -2.5233836, 7.6505113, -21.51887, -2.3769612, 7.5808535, -21.62976, -2.3324466, 7.8594513, -21.585766, -2.5543175, 8.068392, -21.696476, -2.5233836, 8.014233, -21.603245, -2.491922, 7.8594513, -21.47291, -2.3939195, 7.8594513, -21.585766, -2.5543175, 8.014233, -21.603245, -2.491922, 7.6505113, -21.51887, -2.3769612, 7.8594513, -21.585766, -2.5543175, 7.8594513, -21.47291, -2.3939195, 7.8594513, -21.585766, -2.5543175, 7.8594513, -21.722359, -2.586853, 8.068392, -21.696476, -2.5233836, 7.6505113, -21.696476, -2.5233836, 7.7046704, -21.603245, -2.491922, 7.6505113, -21.51887, -2.3769612, 7.6505113, -21.51887, -2.3769612, 7.7046704, -21.603245, -2.491922, 7.8594513, -21.585766, -2.5543175, 7.7046704, -21.603245, -2.491922, 7.6505113, -21.696476, -2.5233836, 7.8594513, -21.722359, -2.586853, 7.7046704, -21.603245, -2.491922, 7.8594513, -21.722359, -2.586853, 7.8594513, -21.585766, -2.5543175, -3.1935778, 3.8995895, -1.8595574, -2.9311557, 3.6870894, -1.6457057, -2.9311557, 3.8599355, -1.9618971, -3.1935778, 3.8995895, -1.8595574, -3.2854238, 3.7667134, -1.6248863, -2.9311557, 3.6870894, -1.6457057, -2.9311557, 3.8599355, -1.9618971, -2.9311557, 3.6870894, -1.6457057, -2.5768762, 3.7667134, -1.6248863, -2.9311557, 3.8599355, -1.9618971, -2.5768762, 3.7667134, -1.6248863, -2.6687322, 3.8995895, -1.8595574, -2.9311557, 3.6870894, -1.6457057, -2.6687322, 3.6513314, -1.305656, -2.5768762, 3.7667134, -1.6248863, -2.9311557, 3.6870894, -1.6457057, -2.9311557, 3.579767, -1.2413225, -2.6687322, 3.6513314, -1.305656, -3.2854238, 3.7667134, -1.6248863, -2.9311557, 3.579767, -1.2413225, -2.9311557, 3.6870894, -1.6457057, -3.2854238, 3.7667134, -1.6248863, -3.1935778, 3.6513314, -1.305656, -2.9311557, 3.579767, -1.2413225, -3.0859365, 3.6335888, -2.4534812, -2.9311557, 3.5589857, -2.2920804, -2.9311557, 3.5909512, -2.5021868, -3.0859365, 3.6335888, -2.4534812, -3.1401029, 3.6073158, -2.2966237, -2.9311557, 3.5589857, -2.2920804, -2.9311557, 3.5909512, -2.5021868, -2.9311557, 3.5589857, -2.2920804, -2.722207, 3.6073158, -2.2966237, -2.9311557, 3.5909512, -2.5021868, -2.722207, 3.6073158, -2.2966237, -2.7763748, 3.6335888, -2.4534812, -2.9311557, 3.5589857, -2.2920804, -2.7763748, 3.6077993, -2.096417, -2.722207, 3.6073158, -2.2966237, -2.9311557, 3.5589857, -2.2920804, -2.9311557, 3.5811186, -2.046321, -2.7763748, 3.6077993, -2.096417, -3.1401029, 3.6073158, -2.2966237, -2.9311557, 3.5811186, -2.046321, -2.9311557, 3.5589857, -2.2920804, -3.1401029, 3.6073158, -2.2966237, -3.0859365, 3.6077993, -2.096417, -2.9311557, 3.5811186, -2.046321, -3.1935806, 3.6513338, -1.3056598, -2.931157, 3.7287045, -1.0824075, -2.931157, 3.5797653, -1.2413273, -2.931157, 3.5797653, -1.2413273, -2.931157, 3.7287045, -1.0824075, -2.5768776, 3.7524617, -1.1856833, -3.1935806, 3.6513338, -1.3056598, -3.2854366, 3.7524617, -1.1856833, -2.931157, 3.7287045, -1.0824075, -2.931157, 3.5797653, -1.2413273, -2.5768776, 3.7524617, -1.1856833, -2.668735, 3.6513338, -1.3056598, -3.2854366, 3.766717, -1.6248941, -3.2854366, 3.7524617, -1.1856833, -3.1935806, 3.6513338, -1.3056598, -2.668735, 3.6513338, -1.3056598, -2.5768776, 3.7524617, -1.1856833, -2.4587846, 3.9438598, -1.5800798, -3.2854366, 3.766717, -1.6248941, -3.4035153, 3.9438598, -1.5800798, -3.2854366, 3.7524617, -1.1856833, -2.668735, 3.6513338, -1.3056598, -2.4587846, 3.9438598, -1.5800798, -2.5768776, 3.766717, -1.6248941, -3.1935806, 3.8995967, -1.8595555, -3.4035153, 3.9438598, -1.5800798, -3.2854366, 3.766717, -1.6248941, -2.5768776, 3.766717, -1.6248941, -2.4587846, 3.9438598, -1.5800798, -2.5768776, 4.0332108, -1.9111595, -3.1935806, 3.8995967, -1.8595555, -3.2854366, 4.0332108, -1.9111595, -3.4035153, 3.9438598, -1.5800798, -2.5768776, 3.766717, -1.6248941, -2.5768776, 4.0332108, -1.9111595, -2.668735, 3.8995967, -1.8595555, -3.2854366, 4.0332108, -1.9111595, -3.1935806, 3.8995967, -1.8595555, -2.931157, 3.8599317, -1.9618936, -2.931157, 4.0577416, -2.0247965, -2.668735, 3.8995967, -1.8595555, -2.5768776, 4.0332108, -1.9111595, -3.2854366, 4.0332108, -1.9111595, -2.931157, 3.8599317, -1.9618936, -2.931157, 4.0577416, -2.0247965, -2.931157, 4.0577416, -2.0247965, -2.931157, 3.8599317, -1.9618936, -2.668735, 3.8995967, -1.8595555, -2.931157, 3.7287045, -1.0824075, -2.668735, 3.9892077, -1.288969, -2.5768776, 3.7524617, -1.1856833, -2.5768776, 3.7524617, -1.1856833, -2.668735, 3.9892077, -1.288969, -2.5768776, 4.141674, -1.5362737, -2.931157, 3.7287045, -1.0824075, -2.931157, 4.0389485, -1.191823, -2.668735, 3.9892077, -1.288969, -2.931157, 4.0389485, -1.191823, -2.5768776, 4.141674, -1.5362737, -2.668735, 3.9892077, -1.288969, -2.5768776, 3.7524617, -1.1856833, -2.5768776, 4.141674, -1.5362737, -2.4587846, 3.9438598, -1.5800798, -3.2854366, 3.7524617, -1.1856833, -2.931157, 4.0389485, -1.191823, -2.931157, 3.7287045, -1.0824075, -3.2854366, 3.7524617, -1.1856833, -3.1935806, 3.9892077, -1.288969, -2.931157, 4.0389485, -1.191823, -3.4035153, 3.9438598, -1.5800798, -3.1935806, 3.9892077, -1.288969, -3.2854366, 3.7524617, -1.1856833, -2.931157, 4.0389485, -1.191823, -2.931157, 4.2222066, -1.5160246, -2.5768776, 4.141674, -1.5362737, -3.1935806, 3.9892077, -1.288969, -2.931157, 4.2222066, -1.5160246, -2.931157, 4.0389485, -1.191823, -2.4587846, 3.9438598, -1.5800798, -2.5768776, 4.141674, -1.5362737, -2.668735, 4.1336055, -1.777915, -2.931157, 4.2222066, -1.5160246, -2.668735, 4.1336055, -1.777915, -2.5768776, 4.141674, -1.5362737, -2.4587846, 3.9438598, -1.5800798, -2.668735, 4.1336055, -1.777915, -2.5768776, 4.0332108, -1.9111595, -3.4035153, 3.9438598, -1.5800798, -3.2854366, 4.141674, -1.5362737, -3.1935806, 3.9892077, -1.288969, -3.1935806, 3.9892077, -1.288969, -3.2854366, 4.141674, -1.5362737, -2.931157, 4.2222066, -1.5160246, -3.2854366, 4.0332108, -1.9111595, -3.2854366, 4.141674, -1.5362737, -3.4035153, 3.9438598, -1.5800798, -2.931157, 4.2177896, -1.8485272, -2.5768776, 4.0332108, -1.9111595, -2.668735, 4.1336055, -1.777915, -2.931157, 4.2222066, -1.5160246, -2.931157, 4.2177896, -1.8485272, -2.668735, 4.1336055, -1.777915, -3.2854366, 4.141674, -1.5362737, -2.931157, 4.2177896, -1.8485272, -2.931157, 4.2222066, -1.5160246, -2.931157, 4.2177896, -1.8485272, -2.931157, 4.0577416, -2.0247965, -2.5768776, 4.0332108, -1.9111595, -3.2854366, 4.0332108, -1.9111595, -3.1935806, 4.1336055, -1.777915, -3.2854366, 4.141674, -1.5362737, -3.2854366, 4.141674, -1.5362737, -3.1935806, 4.1336055, -1.777915, -2.931157, 4.2177896, -1.8485272, -3.1935806, 4.1336055, -1.777915, -3.2854366, 4.0332108, -1.9111595, -2.931157, 4.0577416, -2.0247965, -3.1935806, 4.1336055, -1.777915, -2.931157, 4.0577416, -2.0247965, -2.931157, 4.2177896, -1.8485272, -3.034594, 3.324797, -1.6474974, -2.9311528, 3.431215, -1.5348387, -2.9311528, 3.2713995, -1.6237905, -3.034594, 3.324797, -1.6474974, -3.0708017, 3.4427564, -1.5799403, -2.9311528, 3.431215, -1.5348387, -3.0708017, 3.3060207, -1.7590828, -3.034594, 3.324797, -1.6474974, -2.9311528, 3.2713995, -1.6237905, -3.0708017, 3.3060207, -1.7590828, -3.0708017, 3.4427564, -1.5799403, -3.034594, 3.324797, -1.6474974, -3.0708017, 3.4427564, -1.5799403, -2.9311528, 3.7502108, -1.490046, -2.9311528, 3.431215, -1.5348387, -2.9311528, 3.431215, -1.5348387, -2.9311528, 3.7502108, -1.490046, -2.8277116, 3.759186, -1.5251193, -3.0708017, 3.4427564, -1.5799403, -3.034594, 3.759186, -1.5251193, -2.9311528, 3.7502108, -1.490046, -2.9311528, 3.431215, -1.5348387, -2.8277116, 3.759186, -1.5251193, -2.791504, 3.4427564, -1.5799403, -2.9311528, 3.2713995, -1.6237905, -2.9311528, 3.431215, -1.5348387, -2.791504, 3.4427564, -1.5799403, -2.791504, 3.4427564, -1.5799403, -2.8277116, 3.759186, -1.5251193, -2.791504, 3.784829, -1.6253259, -3.1173468, 3.477378, -1.7152324, -3.034594, 3.759186, -1.5251193, -3.0708017, 3.4427564, -1.5799403, -3.0708017, 3.3060207, -1.7590828, -3.1173468, 3.477378, -1.7152324, -3.0708017, 3.4427564, -1.5799403, -3.1173468, 3.477378, -1.7152324, -3.0708017, 3.784829, -1.6253259, -3.034594, 3.759186, -1.5251193, -2.791504, 3.4427564, -1.5799403, -2.791504, 3.784829, -1.6253259, -2.7449532, 3.477378, -1.7152324, -2.7449532, 3.477378, -1.7152324, -2.791504, 3.784829, -1.6253259, -2.8277116, 3.8104749, -1.7255449, -2.9311528, 3.2713995, -1.6237905, -2.791504, 3.4427564, -1.5799403, -2.8277116, 3.324797, -1.6474974, -2.8277116, 3.324797, -1.6474974, -2.791504, 3.4427564, -1.5799403, -2.7449532, 3.477378, -1.7152324, -3.0708017, 3.3060207, -1.7590828, -2.9311528, 3.2713995, -1.6237905, -2.9311528, 3.2488918, -1.7737021, -2.9311528, 3.2488918, -1.7737021, -2.9311528, 3.2713995, -1.6237905, -2.8277116, 3.324797, -1.6474974, -3.034594, 3.3760855, -1.8479218, -3.1173468, 3.477378, -1.7152324, -3.0708017, 3.3060207, -1.7590828, -3.034594, 3.3760855, -1.8479218, -3.0708017, 3.3060207, -1.7590828, -2.9311528, 3.2488918, -1.7737021, -3.0708017, 3.511996, -1.8505123, -3.0708017, 3.784829, -1.6253259, -3.1173468, 3.477378, -1.7152324, -3.034594, 3.3760855, -1.8479218, -3.0708017, 3.511996, -1.8505123, -3.1173468, 3.477378, -1.7152324, -3.0708017, 3.511996, -1.8505123, -3.034594, 3.8104749, -1.7255449, -3.0708017, 3.784829, -1.6253259, -3.034594, 3.3760855, -1.8479218, -2.9311528, 3.2488918, -1.7737021, -2.9311528, 3.3406389, -1.8943624, -3.0708017, 3.511996, -1.8505123, -3.034594, 3.3760855, -1.8479218, -2.9311528, 3.3406389, -1.8943624, -2.9311528, 3.2488918, -1.7737021, -2.8277116, 3.324797, -1.6474974, -2.791504, 3.3060207, -1.7590828, -2.9311528, 3.3406389, -1.8943624, -2.9311528, 3.2488918, -1.7737021, -2.791504, 3.3060207, -1.7590828, -2.8277116, 3.324797, -1.6474974, -2.7449532, 3.477378, -1.7152324, -2.791504, 3.3060207, -1.7590828, -2.9311528, 3.3406389, -1.8943624, -2.791504, 3.3060207, -1.7590828, -2.8277116, 3.3760855, -1.8479218, -3.034594, 3.8104749, -1.7255449, -3.0708017, 3.511996, -1.8505123, -2.9311528, 3.5235374, -1.8956139, -3.0708017, 3.511996, -1.8505123, -2.9311528, 3.3406389, -1.8943624, -2.9311528, 3.5235374, -1.8956139, -2.9311528, 3.5235374, -1.8956139, -2.9311528, 3.3406389, -1.8943624, -2.8277116, 3.3760855, -1.8479218, -3.034594, 3.8104749, -1.7255449, -2.9311528, 3.5235374, -1.8956139, -2.9311528, 3.8194501, -1.7606182, -2.791504, 3.3060207, -1.7590828, -2.7449532, 3.477378, -1.7152324, -2.791504, 3.511996, -1.8505123, -2.791504, 3.3060207, -1.7590828, -2.791504, 3.511996, -1.8505123, -2.8277116, 3.3760855, -1.8479218, -2.9311528, 3.5235374, -1.8956139, -2.8277116, 3.3760855, -1.8479218, -2.791504, 3.511996, -1.8505123, -2.9311528, 3.8194501, -1.7606182, -2.9311528, 3.5235374, -1.8956139, -2.791504, 3.511996, -1.8505123, -2.7449532, 3.477378, -1.7152324, -2.8277116, 3.8104749, -1.7255449, -2.791504, 3.511996, -1.8505123, -2.9311528, 3.8194501, -1.7606182, -2.791504, 3.511996, -1.8505123, -2.8277116, 3.8104749, -1.7255449, -2.9921641, 3.357846, -2.219953, -2.9311528, 3.439559, -2.179008, -2.9311528, 3.3330348, -2.1960335, -2.9921641, 3.357846, -2.219953, -3.0135126, 3.436851, -2.2063189, -2.9311528, 3.439559, -2.179008, -3.0135126, 3.324916, -2.2780023, -2.9921641, 3.357846, -2.219953, -2.9311528, 3.3330348, -2.1960335, -3.0135126, 3.324916, -2.2780023, -3.0135126, 3.436851, -2.2063189, -2.9921641, 3.357846, -2.219953, -3.0135126, 3.436851, -2.2063189, -2.9311528, 3.6253839, -2.2185574, -2.9311528, 3.439559, -2.179008, -2.9311528, 3.439559, -2.179008, -2.9311528, 3.6253839, -2.2185574, -2.8701415, 3.6232789, -2.239798, -3.0135126, 3.436851, -2.2063189, -2.9921641, 3.6232789, -2.239798, -2.9311528, 3.6253839, -2.2185574, -2.9311528, 3.439559, -2.179008, -2.8701415, 3.6232789, -2.239798, -2.848793, 3.436851, -2.2063189, -2.9311528, 3.3330348, -2.1960335, -2.9311528, 3.439559, -2.179008, -2.848793, 3.436851, -2.2063189, -2.848793, 3.436851, -2.2063189, -2.8701415, 3.6232789, -2.239798, -2.848793, 3.617262, -2.3005147, -3.0409703, 3.428742, -2.2882862, -2.9921641, 3.6232789, -2.239798, -3.0135126, 3.436851, -2.2063189, -3.0135126, 3.324916, -2.2780023, -3.0409703, 3.428742, -2.2882862, -3.0135126, 3.436851, -2.2063189, -3.0409703, 3.428742, -2.2882862, -3.0135126, 3.617262, -2.3005147, -2.9921641, 3.6232789, -2.239798, -2.848793, 3.436851, -2.2063189, -2.848793, 3.617262, -2.3005147, -2.8213353, 3.428742, -2.2882862, -2.8213353, 3.428742, -2.2882862, -2.848793, 3.617262, -2.3005147, -2.8701415, 3.6112561, -2.361228, -2.9311528, 3.3330348, -2.1960335, -2.848793, 3.436851, -2.2063189, -2.8701415, 3.357846, -2.219953, -2.8701415, 3.357846, -2.219953, -2.848793, 3.436851, -2.2063189, -2.8213353, 3.428742, -2.2882862, -3.0135126, 3.324916, -2.2780023, -2.9311528, 3.3330348, -2.1960335, -2.9311528, 3.2903087, -2.274579, -2.9311528, 3.2903087, -2.274579, -2.9311528, 3.3330348, -2.1960335, -2.8701415, 3.357846, -2.219953, -2.9921641, 3.345823, -2.3413825, -3.0409703, 3.428742, -2.2882862, -3.0135126, 3.324916, -2.2780023, -2.9921641, 3.345823, -2.3413825, -3.0135126, 3.324916, -2.2780023, -2.9311528, 3.2903087, -2.274579, -3.0135126, 3.4206212, -2.370242, -3.0135126, 3.617262, -2.3005147, -3.0409703, 3.428742, -2.2882862, -2.9921641, 3.345823, -2.3413825, -3.0135126, 3.4206212, -2.370242, -3.0409703, 3.428742, -2.2882862, -3.0135126, 3.4206212, -2.370242, -2.9921641, 3.6112561, -2.361228, -3.0135126, 3.617262, -2.3005147, -2.9921641, 3.345823, -2.3413825, -2.9311528, 3.2903087, -2.274579, -2.9311528, 3.3167953, -2.3599591, -3.0135126, 3.4206212, -2.370242, -2.9921641, 3.345823, -2.3413825, -2.9311528, 3.3167953, -2.3599591, -2.9311528, 3.2903087, -2.274579, -2.8701415, 3.357846, -2.219953, -2.848793, 3.324916, -2.2780023, -2.9311528, 3.3167953, -2.3599591, -2.9311528, 3.2903087, -2.274579, -2.848793, 3.324916, -2.2780023, -2.8701415, 3.357846, -2.219953, -2.8213353, 3.428742, -2.2882862, -2.848793, 3.324916, -2.2780023, -2.9311528, 3.3167953, -2.3599591, -2.848793, 3.324916, -2.2780023, -2.8701415, 3.345823, -2.3413825, -2.9921641, 3.6112561, -2.361228, -3.0135126, 3.4206212, -2.370242, -2.9311528, 3.417915, -2.3975658, -3.0135126, 3.4206212, -2.370242, -2.9311528, 3.3167953, -2.3599591, -2.9311528, 3.417915, -2.3975658, -2.9311528, 3.417915, -2.3975658, -2.9311528, 3.3167953, -2.3599591, -2.8701415, 3.345823, -2.3413825, -2.9921641, 3.6112561, -2.361228, -2.9311528, 3.417915, -2.3975658, -2.9311528, 3.609141, -2.3824706, -2.848793, 3.324916, -2.2780023, -2.8213353, 3.428742, -2.2882862, -2.848793, 3.4206212, -2.370242, -2.848793, 3.324916, -2.2780023, -2.848793, 3.4206212, -2.370242, -2.8701415, 3.345823, -2.3413825, -2.9311528, 3.417915, -2.3975658, -2.8701415, 3.345823, -2.3413825, -2.848793, 3.4206212, -2.370242, -2.9311528, 3.609141, -2.3824706, -2.9311528, 3.417915, -2.3975658, -2.848793, 3.4206212, -2.370242, -2.8213353, 3.428742, -2.2882862, -2.8701415, 3.6112561, -2.361228, -2.848793, 3.4206212, -2.370242, -2.9311528, 3.609141, -2.3824706, -2.848793, 3.4206212, -2.370242, -2.8701415, 3.6112561, -2.361228, -3.085928, 3.6077986, -2.0964143, -2.9311543, 3.695728, -1.988307, -2.9311543, 3.5811217, -2.0463157, -2.9311543, 3.5811217, -2.0463157, -2.9311543, 3.695728, -1.988307, -2.7222042, 3.6880543, -2.0503378, -3.085928, 3.6077986, -2.0964143, -3.1401043, 3.6880543, -2.0503378, -2.9311543, 3.695728, -1.988307, -2.9311543, 3.5811217, -2.0463157, -2.7222042, 3.6880543, -2.0503378, -2.7763805, 3.6077986, -2.0964143, -3.1401043, 3.6073084, -2.2966123, -3.1401043, 3.6880543, -2.0503378, -3.085928, 3.6077986, -2.0964143, -2.7763805, 3.6077986, -2.0964143, -2.7222042, 3.6880543, -2.0503378, -2.6525536, 3.7145243, -2.3075337, -3.1401043, 3.6073084, -2.2966123, -3.2097464, 3.7145243, -2.3075337, -3.1401043, 3.6880543, -2.0503378, -2.7763805, 3.6077986, -2.0964143, -2.6525536, 3.7145243, -2.3075337, -2.7222042, 3.6073084, -2.2966123, -3.085928, 3.6335886, -2.4534798, -3.2097464, 3.7145243, -2.3075337, -3.1401043, 3.6073084, -2.2966123, -2.7222042, 3.6073084, -2.2966123, -2.6525536, 3.7145243, -2.3075337, -2.7222042, 3.697219, -2.5090442, -3.085928, 3.6335886, -2.4534798, -3.1401043, 3.697219, -2.5090442, -3.2097464, 3.7145243, -2.3075337, -2.7222042, 3.6073084, -2.2966123, -2.7222042, 3.697219, -2.5090442, -2.7763805, 3.6335886, -2.4534798, -3.1401043, 3.697219, -2.5090442, -3.085928, 3.6335886, -2.4534798, -2.9311543, 3.5909529, -2.5021935, -2.9311543, 3.687878, -2.5769706, -2.7763805, 3.6335886, -2.4534798, -2.7222042, 3.697219, -2.5090442, -3.1401043, 3.697219, -2.5090442, -2.9311543, 3.5909529, -2.5021935, -2.9311543, 3.687878, -2.5769706, -2.9311543, 3.687878, -2.5769706, -2.9311543, 3.5909529, -2.5021935, -2.7763805, 3.6335886, -2.4534798, -2.9311543, 3.695728, -1.988307, -2.7763805, 3.7984102, -2.1553535, -2.7222042, 3.6880543, -2.0503378, -2.7222042, 3.6880543, -2.0503378, -2.7763805, 3.7984102, -2.1553535, -2.7222042, 3.8329906, -2.3231764, -2.9311543, 3.695728, -1.988307, -2.9311543, 3.845578, -2.1115575, -2.7763805, 3.7984102, -2.1553535, -2.9311543, 3.845578, -2.1115575, -2.7222042, 3.8329906, -2.3231764, -2.7763805, 3.7984102, -2.1553535, -2.7222042, 3.6880543, -2.0503378, -2.7222042, 3.8329906, -2.3231764, -2.6525536, 3.7145243, -2.3075337, -3.1401043, 3.6880543, -2.0503378, -2.9311543, 3.845578, -2.1115575, -2.9311543, 3.695728, -1.988307, -3.1401043, 3.6880543, -2.0503378, -3.085928, 3.7984102, -2.1553535, -2.9311543, 3.845578, -2.1115575, -3.2097464, 3.7145243, -2.3075337, -3.085928, 3.7984102, -2.1553535, -3.1401043, 3.6880543, -2.0503378, -2.9311543, 3.845578, -2.1115575, -2.9311543, 3.8817086, -2.3282094, -2.7222042, 3.8329906, -2.3231764, -3.085928, 3.7984102, -2.1553535, -2.9311543, 3.8817086, -2.3282094, -2.9311543, 3.845578, -2.1115575, -2.6525536, 3.7145243, -2.3075337, -2.7222042, 3.8329906, -2.3231764, -2.7763805, 3.7797475, -2.4554658, -2.9311543, 3.8817086, -2.3282094, -2.7763805, 3.7797475, -2.4554658, -2.7222042, 3.8329906, -2.3231764, -2.6525536, 3.7145243, -2.3075337, -2.7763805, 3.7797475, -2.4554658, -2.7222042, 3.697219, -2.5090442, -3.2097464, 3.7145243, -2.3075337, -3.1401043, 3.8329906, -2.3231764, -3.085928, 3.7984102, -2.1553535, -3.085928, 3.7984102, -2.1553535, -3.1401043, 3.8329906, -2.3231764, -2.9311543, 3.8817086, -2.3282094, -3.1401043, 3.697219, -2.5090442, -3.1401043, 3.8329906, -2.3231764, -3.2097464, 3.7145243, -2.3075337, -2.9311543, 3.812152, -2.5115814, -2.7222042, 3.697219, -2.5090442, -2.7763805, 3.7797475, -2.4554658, -2.9311543, 3.8817086, -2.3282094, -2.9311543, 3.812152, -2.5115814, -2.7763805, 3.7797475, -2.4554658, -3.1401043, 3.8329906, -2.3231764, -2.9311543, 3.812152, -2.5115814, -2.9311543, 3.8817086, -2.3282094, -2.9311543, 3.812152, -2.5115814, -2.9311543, 3.687878, -2.5769706, -2.7222042, 3.697219, -2.5090442, -3.1401043, 3.697219, -2.5090442, -3.085928, 3.7797475, -2.4554658, -3.1401043, 3.8329906, -2.3231764, -3.1401043, 3.8329906, -2.3231764, -3.085928, 3.7797475, -2.4554658, -2.9311543, 3.812152, -2.5115814, -3.085928, 3.7797475, -2.4554658, -3.1401043, 3.697219, -2.5090442, -2.9311543, 3.687878, -2.5769706, -3.085928, 3.7797475, -2.4554658, -2.9311543, 3.687878, -2.5769706, -2.9311543, 3.812152, -2.5115814, -16.306217, 3.8995876, -8.693363, -16.639778, 3.6870875, -8.751106, -16.484772, 3.8599336, -8.475517, -16.306217, 3.8995876, -8.693363, -16.341208, 3.7667115, -8.942926, -16.639778, 3.6870875, -8.751106, -16.484772, 3.8599336, -8.475517, -16.639778, 3.6870875, -8.751106, -16.958773, 3.7667115, -8.595573, -16.484772, 3.8599336, -8.475517, -16.958773, 3.7667115, -8.595573, -16.763668, 3.8995876, -8.436068, -16.639778, 3.6870875, -8.751106, -17.035208, 3.6513293, -8.918842, -16.958773, 3.7667115, -8.595573, -16.639778, 3.6870875, -8.751106, -16.83802, 3.579765, -9.103563, -17.035208, 3.6513293, -8.918842, -16.341208, 3.7667115, -8.942926, -16.83802, 3.579765, -9.103563, -16.639778, 3.6870875, -8.751106, -16.341208, 3.7667115, -8.942926, -16.577757, 3.6513293, -9.17614, -16.83802, 3.579765, -9.103563, -16.108875, 3.6335871, -8.122934, -16.322905, 3.5589838, -8.187733, -16.219904, 3.5909493, -8.004604, -16.108875, 3.6335871, -8.122934, -16.138561, 3.607314, -8.286205, -16.322905, 3.5589838, -8.187733, -16.219904, 3.5909493, -8.004604, -16.322905, 3.5589838, -8.187733, -16.502796, 3.607314, -8.081339, -16.219904, 3.5909493, -8.004604, -16.502796, 3.607314, -8.081339, -16.378687, 3.6335871, -7.9711776, -16.322905, 3.5589838, -8.187733, -16.553732, 3.6077974, -8.2823925, -16.502796, 3.607314, -8.081339, -16.322905, 3.5589838, -8.187733, -16.443384, 3.5811167, -8.401934, -16.553732, 3.6077974, -8.2823925, -16.138561, 3.607314, -8.286205, -16.443384, 3.5811167, -8.401934, -16.322905, 3.5589838, -8.187733, -16.138561, 3.607314, -8.286205, -16.28392, 3.6077974, -8.434149, -16.443384, 3.5811167, -8.401934, -16.577753, 3.651332, -9.176138, -16.915924, 3.7287025, -9.242073, -16.838017, 3.5797634, -9.1035595, -16.838017, 3.5797634, -9.1035595, -16.915924, 3.7287025, -9.242073, -17.174082, 3.7524595, -8.97838, -16.577753, 3.651332, -9.176138, -16.556507, 3.7524595, -9.325739, -16.915924, 3.7287025, -9.242073, -16.838017, 3.5797634, -9.1035595, -17.174082, 3.7524595, -8.97838, -17.035204, 3.651332, -8.91884, -16.341192, 3.766715, -8.942926, -16.556507, 3.7524595, -9.325739, -16.577753, 3.651332, -9.176138, -17.035204, 3.651332, -8.91884, -17.174082, 3.7524595, -8.97838, -17.083666, 3.943858, -8.576735, -16.341192, 3.766715, -8.942926, -16.260246, 3.943858, -9.039871, -16.556507, 3.7524595, -9.325739, -17.035204, 3.651332, -8.91884, -17.083666, 3.943858, -8.576735, -16.958767, 3.7667148, -8.595568, -16.306215, 3.8995948, -8.693367, -16.260246, 3.943858, -9.039871, -16.341192, 3.766715, -8.942926, -16.958767, 3.7667148, -8.595568, -17.083666, 3.943858, -8.576735, -16.81843, 4.033209, -8.346062, -16.306215, 3.8995948, -8.693367, -16.200855, 4.033209, -8.6934185, -16.260246, 3.943858, -9.039871, -16.958767, 3.7667148, -8.595568, -16.81843, 4.033209, -8.346062, -16.763666, 3.8995945, -8.4360695, -16.200855, 4.033209, -8.6934185, -16.306215, 3.8995948, -8.693367, -16.484772, 3.8599298, -8.475521, -16.453936, 4.0577397, -8.420694, -16.763666, 3.8995945, -8.4360695, -16.81843, 4.033209, -8.346062, -16.200855, 4.033209, -8.6934185, -16.484772, 3.8599298, -8.475521, -16.453936, 4.0577397, -8.420694, -16.453936, 4.0577397, -8.420694, -16.484772, 3.8599298, -8.475521, -16.763666, 3.8995945, -8.4360695, -16.915924, 3.7287025, -9.242073, -17.043386, 3.9892056, -8.933388, -17.174082, 3.7524595, -8.97838, -17.174082, 3.7524595, -8.97838, -17.043386, 3.9892056, -8.933388, -17.00221, 4.141672, -8.672808, -16.915924, 3.7287025, -9.242073, -16.862286, 4.038946, -9.146708, -17.043386, 3.9892056, -8.933388, -16.862286, 4.038946, -9.146708, -17.00221, 4.141672, -8.672808, -17.043386, 3.9892056, -8.933388, -17.174082, 3.7524595, -8.97838, -17.00221, 4.141672, -8.672808, -17.083666, 3.943858, -8.576735, -16.556507, 3.7524595, -9.325739, -16.862286, 4.038946, -9.146708, -16.915924, 3.7287025, -9.242073, -16.556507, 3.7524595, -9.325739, -16.585936, 3.9892056, -9.190685, -16.862286, 4.038946, -9.146708, -16.260246, 3.943858, -9.039871, -16.585936, 3.9892056, -9.190685, -16.556507, 3.7524595, -9.325739, -16.862286, 4.038946, -9.146708, -16.703352, 4.2222047, -8.864136, -17.00221, 4.141672, -8.672808, -16.585936, 3.9892056, -9.190685, -16.703352, 4.2222047, -8.864136, -16.862286, 4.038946, -9.146708, -17.083666, 3.943858, -8.576735, -17.00221, 4.141672, -8.672808, -16.803688, 4.1336036, -8.507227, -16.703352, 4.2222047, -8.864136, -16.803688, 4.1336036, -8.507227, -17.00221, 4.141672, -8.672808, -17.083666, 3.943858, -8.576735, -16.803688, 4.1336036, -8.507227, -16.81843, 4.033209, -8.346062, -16.260246, 3.943858, -9.039871, -16.384638, 4.141672, -9.020166, -16.585936, 3.9892056, -9.190685, -16.585936, 3.9892056, -9.190685, -16.384638, 4.141672, -9.020166, -16.703352, 4.2222047, -8.864136, -16.200855, 4.033209, -8.6934185, -16.384638, 4.141672, -9.020166, -16.260246, 3.943858, -9.039871, -16.540348, 4.2177877, -8.574329, -16.81843, 4.033209, -8.346062, -16.803688, 4.1336036, -8.507227, -16.703352, 4.2222047, -8.864136, -16.540348, 4.2177877, -8.574329, -16.803688, 4.1336036, -8.507227, -16.384638, 4.141672, -9.020166, -16.540348, 4.2177877, -8.574329, -16.703352, 4.2222047, -8.864136, -16.540348, 4.2177877, -8.574329, -16.453936, 4.0577397, -8.420694, -16.81843, 4.033209, -8.346062, -16.200855, 4.033209, -8.6934185, -16.346237, 4.1336036, -8.764523, -16.384638, 4.141672, -9.020166, -16.384638, 4.141672, -9.020166, -16.346237, 4.1336036, -8.764523, -16.540348, 4.2177877, -8.574329, -16.346237, 4.1336036, -8.764523, -16.200855, 4.033209, -8.6934185, -16.453936, 4.0577397, -8.420694, -16.346237, 4.1336036, -8.764523, -16.453936, 4.0577397, -8.420694, -16.540348, 4.2177877, -8.574329, -16.548744, 3.324795, -8.800255, -16.694132, 3.4312131, -8.847736, -16.650524, 3.2713976, -8.770206, -16.548744, 3.324795, -8.800255, -16.550304, 3.4427547, -8.876886, -16.694132, 3.4312131, -8.847736, -16.462482, 3.3060188, -8.720747, -16.548744, 3.324795, -8.800255, -16.650524, 3.2713976, -8.770206, -16.462482, 3.3060188, -8.720747, -16.550304, 3.4427547, -8.876886, -16.548744, 3.324795, -8.800255, -16.550304, 3.4427547, -8.876886, -16.716091, 3.7502089, -8.886778, -16.694132, 3.4312131, -8.847736, -16.694132, 3.4312131, -8.847736, -16.716091, 3.7502089, -8.886778, -16.789055, 3.7591841, -8.805498, -16.550304, 3.4427547, -8.876886, -16.608738, 3.7591841, -8.906918, -16.716091, 3.7502089, -8.886778, -16.694132, 3.4312131, -8.847736, -16.789055, 3.7591841, -8.805498, -16.793737, 3.4427545, -8.739965, -16.650524, 3.2713976, -8.770206, -16.694132, 3.4312131, -8.847736, -16.793737, 3.4427545, -8.739965, -16.793737, 3.4427545, -8.739965, -16.789055, 3.7591841, -8.805498, -16.771488, 3.784827, -8.700407, -16.44341, 3.477376, -8.781784, -16.608738, 3.7591841, -8.906918, -16.550304, 3.4427547, -8.876886, -16.462482, 3.3060188, -8.720747, -16.44341, 3.477376, -8.781784, -16.550304, 3.4427547, -8.876886, -16.44341, 3.477376, -8.781784, -16.528055, 3.784827, -8.837328, -16.608738, 3.7591841, -8.906918, -16.793737, 3.4427545, -8.739965, -16.771488, 3.784827, -8.700407, -16.767986, 3.477376, -8.599226, -16.767986, 3.477376, -8.599226, -16.771488, 3.784827, -8.700407, -16.6908, 3.810473, -8.630808, -16.650524, 3.2713976, -8.770206, -16.793737, 3.4427545, -8.739965, -16.729061, 3.324795, -8.698833, -16.729061, 3.324795, -8.698833, -16.793737, 3.4427545, -8.739965, -16.767986, 3.477376, -8.599226, -16.462482, 3.3060188, -8.720747, -16.650524, 3.2713976, -8.770206, -16.577034, 3.2488902, -8.639545, -16.577034, 3.2488902, -8.639545, -16.650524, 3.2713976, -8.770206, -16.729061, 3.324795, -8.698833, -16.450489, 3.3760836, -8.6255665, -16.44341, 3.477376, -8.781784, -16.462482, 3.3060188, -8.720747, -16.450489, 3.3760836, -8.6255665, -16.462482, 3.3060188, -8.720747, -16.577034, 3.2488902, -8.639545, -16.417662, 3.5119941, -8.641058, -16.528055, 3.784827, -8.837328, -16.44341, 3.477376, -8.781784, -16.450489, 3.3760836, -8.6255665, -16.417662, 3.5119941, -8.641058, -16.44341, 3.477376, -8.781784, -16.417662, 3.5119941, -8.641058, -16.510483, 3.810473, -8.732229, -16.528055, 3.784827, -8.837328, -16.450489, 3.3760836, -8.6255665, -16.577034, 3.2488902, -8.639545, -16.517881, 3.340637, -8.534378, -16.417662, 3.5119941, -8.641058, -16.450489, 3.3760836, -8.6255665, -16.517881, 3.340637, -8.534378, -16.577034, 3.2488902, -8.639545, -16.729061, 3.324795, -8.698833, -16.705917, 3.3060188, -8.583826, -16.517881, 3.340637, -8.534378, -16.577034, 3.2488902, -8.639545, -16.705917, 3.3060188, -8.583826, -16.729061, 3.324795, -8.698833, -16.767986, 3.477376, -8.599226, -16.705917, 3.3060188, -8.583826, -16.517881, 3.340637, -8.534378, -16.705917, 3.3060188, -8.583826, -16.630806, 3.3760836, -8.524145, -16.510483, 3.810473, -8.732229, -16.417662, 3.5119941, -8.641058, -16.517267, 3.5235355, -8.533287, -16.417662, 3.5119941, -8.641058, -16.517881, 3.340637, -8.534378, -16.517267, 3.5235355, -8.533287, -16.517267, 3.5235355, -8.533287, -16.517881, 3.340637, -8.534378, -16.630806, 3.3760836, -8.524145, -16.510483, 3.810473, -8.732229, -16.517267, 3.5235355, -8.533287, -16.583447, 3.8194482, -8.6509495, -16.705917, 3.3060188, -8.583826, -16.767986, 3.477376, -8.599226, -16.661095, 3.5119941, -8.504137, -16.705917, 3.3060188, -8.583826, -16.661095, 3.5119941, -8.504137, -16.630806, 3.3760836, -8.524145, -16.517267, 3.5235355, -8.533287, -16.630806, 3.3760836, -8.524145, -16.661095, 3.5119941, -8.504137, -16.583447, 3.8194482, -8.6509495, -16.517267, 3.5235355, -8.533287, -16.661095, 3.5119941, -8.504137, -16.767986, 3.477376, -8.599226, -16.6908, 3.810473, -8.630808, -16.661095, 3.5119941, -8.504137, -16.583447, 3.8194482, -8.6509495, -16.661095, 3.5119941, -8.504137, -16.6908, 3.810473, -8.630808, -16.30509, 3.357844, -8.280506, -16.37834, 3.439557, -8.2862835, -16.369993, 3.333033, -8.271444, -16.30509, 3.357844, -8.280506, -16.293167, 3.436849, -8.302855, -16.37834, 3.439557, -8.2862835, -16.258024, 3.324914, -8.240377, -16.30509, 3.357844, -8.280506, -16.369993, 3.333033, -8.271444, -16.258024, 3.324914, -8.240377, -16.293167, 3.436849, -8.302855, -16.30509, 3.357844, -8.280506, -16.293167, 3.436849, -8.302855, -16.358952, 3.625382, -8.251812, -16.37834, 3.439557, -8.2862835, -16.37834, 3.439557, -8.2862835, -16.358952, 3.625382, -8.251812, -16.401714, 3.6232772, -8.20339, -16.293167, 3.436849, -8.302855, -16.29536, 3.6232772, -8.263208, -16.358952, 3.625382, -8.251812, -16.37834, 3.439557, -8.2862835, -16.401714, 3.6232772, -8.20339, -16.436735, 3.436849, -8.222103, -16.369993, 3.333033, -8.271444, -16.37834, 3.439557, -8.2862835, -16.436735, 3.436849, -8.222103, -16.436735, 3.436849, -8.222103, -16.401714, 3.6232772, -8.20339, -16.390556, 3.61726, -8.140003, -16.229052, 3.4287403, -8.244873, -16.29536, 3.6232772, -8.263208, -16.293167, 3.436849, -8.302855, -16.258024, 3.324914, -8.240377, -16.229052, 3.4287403, -8.244873, -16.293167, 3.436849, -8.302855, -16.229052, 3.4287403, -8.244873, -16.246988, 3.61726, -8.220755, -16.29536, 3.6232772, -8.263208, -16.436735, 3.436849, -8.222103, -16.390556, 3.61726, -8.140003, -16.420483, 3.4287403, -8.137201, -16.420483, 3.4287403, -8.137201, -16.390556, 3.61726, -8.140003, -16.342186, 3.6112542, -8.097551, -16.369993, 3.333033, -8.271444, -16.436735, 3.436849, -8.222103, -16.411444, 3.357844, -8.220686, -16.411444, 3.357844, -8.220686, -16.436735, 3.436849, -8.222103, -16.420483, 3.4287403, -8.137201, -16.258024, 3.324914, -8.240377, -16.369993, 3.333033, -8.271444, -16.331488, 3.290307, -8.202984, -16.331488, 3.290307, -8.202984, -16.369993, 3.333033, -8.271444, -16.411444, 3.357844, -8.220686, -16.245562, 3.3458211, -8.174669, -16.229052, 3.4287403, -8.244873, -16.258024, 3.324914, -8.240377, -16.245562, 3.3458211, -8.174669, -16.258024, 3.324914, -8.240377, -16.331488, 3.290307, -8.202984, -16.212805, 3.4206195, -8.159981, -16.246988, 3.61726, -8.220755, -16.229052, 3.4287403, -8.244873, -16.245562, 3.3458211, -8.174669, -16.212805, 3.4206195, -8.159981, -16.229052, 3.4287403, -8.244873, -16.212805, 3.4206195, -8.159981, -16.235832, 3.6112542, -8.1573715, -16.246988, 3.61726, -8.220755, -16.245562, 3.3458211, -8.174669, -16.331488, 3.290307, -8.202984, -16.28963, 3.3167934, -8.128569, -16.212805, 3.4206195, -8.159981, -16.245562, 3.3458211, -8.174669, -16.28963, 3.3167934, -8.128569, -16.331488, 3.290307, -8.202984, -16.411444, 3.357844, -8.220686, -16.401594, 3.324914, -8.159626, -16.28963, 3.3167934, -8.128569, -16.331488, 3.290307, -8.202984, -16.401594, 3.324914, -8.159626, -16.411444, 3.357844, -8.220686, -16.420483, 3.4287403, -8.137201, -16.401594, 3.324914, -8.159626, -16.28963, 3.3167934, -8.128569, -16.401594, 3.324914, -8.159626, -16.351915, 3.3458211, -8.114849, -16.235832, 3.6112542, -8.1573715, -16.212805, 3.4206195, -8.159981, -16.271194, 3.4179132, -8.095791, -16.212805, 3.4206195, -8.159981, -16.28963, 3.3167934, -8.128569, -16.271194, 3.4179132, -8.095791, -16.271194, 3.4179132, -8.095791, -16.28963, 3.3167934, -8.128569, -16.351915, 3.3458211, -8.114849, -16.235832, 3.6112542, -8.1573715, -16.271194, 3.4179132, -8.095791, -16.278595, 3.6091392, -8.108948, -16.401594, 3.324914, -8.159626, -16.420483, 3.4287403, -8.137201, -16.356375, 3.4206195, -8.079229, -16.401594, 3.324914, -8.159626, -16.356375, 3.4206195, -8.079229, -16.351915, 3.3458211, -8.114849, -16.271194, 3.4179132, -8.095791, -16.351915, 3.3458211, -8.114849, -16.356375, 3.4206195, -8.079229, -16.278595, 3.6091392, -8.108948, -16.271194, 3.4179132, -8.095791, -16.356375, 3.4206195, -8.079229, -16.420483, 3.4287403, -8.137201, -16.342186, 3.6112542, -8.097551, -16.356375, 3.4206195, -8.079229, -16.278595, 3.6091392, -8.108948, -16.356375, 3.4206195, -8.079229, -16.342186, 3.6112542, -8.097551, -16.283928, 3.6077967, -8.434147, -16.471827, 3.6957262, -8.4524975, -16.443388, 3.5811198, -8.4019375, -16.443388, 3.5811198, -8.4019375, -16.471827, 3.6957262, -8.4524975, -16.623535, 3.6880524, -8.295998, -16.283928, 3.6077967, -8.434147, -16.259296, 3.6880524, -8.500866, -16.471827, 3.6957262, -8.4524975, -16.443388, 3.5811198, -8.4019375, -16.623535, 3.6880524, -8.295998, -16.553728, 3.6077967, -8.282396, -16.138565, 3.6073067, -8.286215, -16.259296, 3.6880524, -8.500866, -16.283928, 3.6077967, -8.434147, -16.553728, 3.6077967, -8.282396, -16.623535, 3.6880524, -8.295998, -16.558157, 3.7145224, -8.0376835, -16.138565, 3.6073067, -8.286215, -16.072512, 3.7145224, -8.310837, -16.259296, 3.6880524, -8.500866, -16.553728, 3.6077967, -8.282396, -16.558157, 3.7145224, -8.0376835, -16.502804, 3.6073067, -8.0813465, -16.108883, 3.6335866, -8.122932, -16.072512, 3.7145224, -8.310837, -16.138565, 3.6073067, -8.286215, -16.502804, 3.6073067, -8.0813465, -16.558157, 3.7145224, -8.0376835, -16.398663, 3.697217, -7.896193, -16.108883, 3.6335866, -8.122932, -16.034424, 3.697217, -8.101061, -16.072512, 3.7145224, -8.310837, -16.502804, 3.6073067, -8.0813465, -16.398663, 3.697217, -7.896193, -16.378683, 3.6335866, -7.9711814, -16.034424, 3.697217, -8.101061, -16.108883, 3.6335866, -8.122932, -16.219902, 3.5909512, -8.004599, -16.183245, 3.687876, -7.939423, -16.378683, 3.6335866, -7.9711814, -16.398663, 3.697217, -7.896193, -16.034424, 3.697217, -8.101061, -16.219902, 3.5909512, -8.004599, -16.183245, 3.687876, -7.939423, -16.183245, 3.687876, -7.939423, -16.219902, 3.5909512, -8.004599, -16.378683, 3.6335866, -7.9711814, -16.471827, 3.6957262, -8.4524975, -16.524834, 3.7984083, -8.231026, -16.623535, 3.6880524, -8.295998, -16.623535, 3.6880524, -8.295998, -16.524834, 3.7984083, -8.231026, -16.48978, 3.8329887, -8.058193, -16.471827, 3.6957262, -8.4524975, -16.411404, 3.845576, -8.345074, -16.524834, 3.7984083, -8.231026, -16.411404, 3.845576, -8.345074, -16.48978, 3.8329887, -8.058193, -16.524834, 3.7984083, -8.231026, -16.623535, 3.6880524, -8.295998, -16.48978, 3.8329887, -8.058193, -16.558157, 3.7145224, -8.0376835, -16.259296, 3.6880524, -8.500866, -16.411404, 3.845576, -8.345074, -16.471827, 3.6957262, -8.4524975, -16.259296, 3.6880524, -8.500866, -16.255035, 3.7984083, -8.382776, -16.411404, 3.845576, -8.345074, -16.072512, 3.7145224, -8.310837, -16.255035, 3.7984083, -8.382776, -16.259296, 3.6880524, -8.500866, -16.411404, 3.845576, -8.345074, -16.305195, 3.881707, -8.156242, -16.48978, 3.8329887, -8.058193, -16.255035, 3.7984083, -8.382776, -16.305195, 3.881707, -8.156242, -16.411404, 3.845576, -8.345074, -16.558157, 3.7145224, -8.0376835, -16.48978, 3.8329887, -8.058193, -16.377708, 3.7797456, -7.9694505, -16.305195, 3.881707, -8.156242, -16.377708, 3.7797456, -7.9694505, -16.48978, 3.8329887, -8.058193, -16.558157, 3.7145224, -8.0376835, -16.377708, 3.7797456, -7.9694505, -16.398663, 3.697217, -7.896193, -16.072512, 3.7145224, -8.310837, -16.125544, 3.8329887, -8.263062, -16.255035, 3.7984083, -8.382776, -16.255035, 3.7984083, -8.382776, -16.125544, 3.8329887, -8.263062, -16.305195, 3.881707, -8.156242, -16.034424, 3.697217, -8.101061, -16.125544, 3.8329887, -8.263062, -16.072512, 3.7145224, -8.310837, -16.2153, 3.8121502, -7.9964156, -16.398663, 3.697217, -7.896193, -16.377708, 3.7797456, -7.9694505, -16.305195, 3.881707, -8.156242, -16.2153, 3.8121502, -7.9964156, -16.377708, 3.7797456, -7.9694505, -16.125544, 3.8329887, -8.263062, -16.2153, 3.8121502, -7.9964156, -16.305195, 3.881707, -8.156242, -16.2153, 3.8121502, -7.9964156, -16.183245, 3.687876, -7.939423, -16.398663, 3.697217, -7.896193, -16.034424, 3.697217, -8.101061, -16.10791, 3.7797456, -8.121201, -16.125544, 3.8329887, -8.263062, -16.125544, 3.8329887, -8.263062, -16.10791, 3.7797456, -8.121201, -16.2153, 3.8121502, -7.9964156, -16.10791, 3.7797456, -8.121201, -16.034424, 3.697217, -8.101061, -16.183245, 3.687876, -7.939423, -16.10791, 3.7797456, -8.121201, -16.183245, 3.687876, -7.939423, -16.2153, 3.8121502, -7.9964156, -7.086538, 9.0531025, 23.60468, -7.939819, 8.776951, 23.477636, -7.89693, 8.906714, 23.382841, -7.086538, 9.0531025, 23.60468, -7.1825204, 8.414909, 24.04463, -7.939819, 8.776951, 23.477636, -6.961786, 8.872082, 22.884235, -7.2900796, 8.958991, 23.246565, -7.2749104, 8.879946, 22.997782, -6.961786, 8.872082, 22.884235, -7.086538, 9.0531025, 23.60468, -7.2900796, 8.958991, 23.246565, -3.8860898, 6.9690914, 23.62356, -4.5446486, 7.7101564, 23.798996, -4.6237864, 7.655897, 23.206228, -3.8860898, 6.9690914, 23.62356, -3.8783517, 6.953966, 23.7307, -4.5446486, 7.7101564, 23.798996, -4.5446486, 7.7101564, 23.798996, -4.823362, 7.815732, 23.123234, -4.6237864, 7.655897, 23.206228, -4.5446486, 7.7101564, 23.798996, -4.899761, 7.976705, 23.460878, -4.823362, 7.815732, 23.123234, -4.899761, 7.976705, 23.460878, -4.5446486, 7.7101564, 23.798996, -5.2783494, 8.404766, 23.83276, -4.899761, 7.976705, 23.460878, -5.2783494, 8.404766, 23.83276, -5.3587403, 8.23149, 22.899555, -4.899761, 7.976705, 23.460878, -5.3587403, 8.23149, 22.899555, -5.0027404, 7.957439, 23.048418, -5.3587403, 8.23149, 22.899555, -5.5498886, 8.408549, 23.109316, -5.46656, 8.274823, 22.889973, -5.3587403, 8.23149, 22.899555, -5.2783494, 8.404766, 23.83276, -5.5498886, 8.408549, 23.109316, -6.134132, 8.667774, 22.83608, -6.545529, 8.861699, 23.146437, -6.347387, 8.715011, 22.84835, -6.134132, 8.667774, 22.83608, -6.2255015, 8.901371, 23.757235, -6.545529, 8.861699, 23.146437, -3.9216104, 6.895205, 23.810205, -4.5446486, 7.7101564, 23.798996, -3.8783517, 6.953966, 23.7307, -4.5446486, 7.7101564, 23.798996, -3.9216104, 6.895205, 23.810205, -4.32818, 7.252925, 23.874067, -4.32818, 7.252925, 23.874067, -3.9216104, 6.895205, 23.810205, -4.2883744, 7.0421944, 23.9518, -4.5446486, 7.7101564, 23.798996, -5.1261964, 7.754751, 24.078827, -5.2783494, 8.404766, 23.83276, -4.5446486, 7.7101564, 23.798996, -4.9056582, 7.542821, 24.083008, -5.1261964, 7.754751, 24.078827, -5.6396194, 7.681168, 24.366714, -6.2255015, 8.901371, 23.757235, -5.2783494, 8.404766, 23.83276, -6.2255015, 8.901371, 23.757235, -5.6396194, 7.681168, 24.366714, -6.046368, 7.8717294, 24.331638, -6.2255015, 8.901371, 23.757235, -6.046368, 7.8717294, 24.331638, -6.119331, 8.248653, 24.137571, -6.7146773, 8.708108, 23.8794, -7.086538, 9.0531025, 23.60468, -6.2255015, 8.901371, 23.757235, -7.086538, 9.0531025, 23.60468, -6.7146773, 8.708108, 23.8794, -7.0044417, 8.349307, 24.104824, -7.086538, 9.0531025, 23.60468, -7.0044417, 8.349307, 24.104824, -7.1825204, 8.414909, 24.04463, -6.2255015, 8.901371, 23.757235, -5.5498886, 8.408549, 23.109316, -5.2783494, 8.404766, 23.83276, -5.953386, 8.703066, 23.382, -5.5498886, 8.408549, 23.109316, -6.2255015, 8.901371, 23.757235, -5.5498886, 8.408549, 23.109316, -5.953386, 8.703066, 23.382, -5.8336997, 8.425533, 22.857294, -5.5498886, 8.408549, 23.109316, -5.8336997, 8.425533, 22.857294, -5.650786, 8.361013, 22.874142, -6.2255015, 8.901371, 23.757235, -5.9328055, 8.570662, 22.853338, -5.953386, 8.703066, 23.382, -6.2255015, 8.901371, 23.757235, -6.134132, 8.667774, 22.83608, -5.9328055, 8.570662, 22.853338, -6.119331, 8.248653, 24.137571, -6.4117084, 8.071957, 24.301369, -6.2255015, 8.901371, 23.757235, -6.119331, 8.248653, 24.137571, -6.237124, 7.9882894, 24.31635, -6.4117084, 8.071957, 24.301369, -7.086538, 9.0531025, 23.60468, -6.545529, 8.861699, 23.146437, -6.2255015, 8.901371, 23.757235, -6.545529, 8.861699, 23.146437, -7.086538, 9.0531025, 23.60468, -6.961786, 8.872082, 22.884235, -6.545529, 8.861699, 23.146437, -6.961786, 8.872082, 22.884235, -6.66091, 8.812481, 22.867199, -6.7146773, 8.708108, 23.8794, -6.4117084, 8.071957, 24.301369, -6.875569, 8.223388, 24.143358, -6.7146773, 8.708108, 23.8794, -6.2255015, 8.901371, 23.757235, -6.4117084, 8.071957, 24.301369, -7.89693, 8.906714, 23.382841, -7.2900796, 8.958991, 23.246565, -7.086538, 9.0531025, 23.60468, -7.2900796, 8.958991, 23.246565, -7.89693, 8.906714, 23.382841, -7.890431, 8.871303, 23.22045, -7.2900796, 8.958991, 23.246565, -7.890431, 8.871303, 23.22045, -7.484878, 8.8925495, 23.073898, -5.1261964, 7.754751, 24.078827, -5.6396194, 7.681168, 24.366714, -5.2783494, 8.404766, 23.83276, -5.1261964, 7.754751, 24.078827, -5.328693, 7.544381, 24.286783, -5.6396194, 7.681168, 24.366714, -4.9056582, 7.542821, 24.083008, -5.1280284, 7.4066963, 24.234045, -5.1261964, 7.754751, 24.078827, -4.9056582, 7.542821, 24.083008, -5.0212817, 7.379748, 24.207062, -5.1280284, 7.4066963, 24.234045, -4.9056582, 7.542821, 24.083008, -4.5446486, 7.7101564, 23.798996, -4.804087, 7.2903175, 24.15141, -4.32818, 7.252925, 23.874067, -4.804087, 7.2903175, 24.15141, -4.5446486, 7.7101564, 23.798996, -4.32818, 7.252925, 23.874067, -4.4737935, 7.144829, 24.02375, -4.804087, 7.2903175, 24.15141, -8.469263, 8.833129, 23.903402, -7.7564616, 8.8668, 23.1668, -7.7024093, 8.948188, 23.326448, -8.469263, 8.833129, 23.903402, -8.792166, 8.398045, 23.2395, -7.7564616, 8.8668, 23.1668, -7.939649, 8.319658, 24.36807, -8.019506, 8.693222, 23.9122, -7.814714, 8.502601, 24.04807, -7.939649, 8.319658, 24.36807, -8.469263, 8.833129, 23.903402, -8.019506, 8.693222, 23.9122, -10.742025, 5.3900876, 25.65433, -10.427696, 6.4519587, 25.310745, -9.86124, 6.2139215, 25.59392, -10.742025, 5.3900876, 25.65433, -10.839937, 5.4104342, 25.586737, -10.427696, 6.4519587, 25.310745, -10.427696, 6.4519587, 25.310745, -9.6490345, 6.4258494, 25.54795, -9.86124, 6.2139215, 25.59392, -10.427696, 6.4519587, 25.310745, -9.8865795, 6.741735, 25.338587, -9.6490345, 6.4258494, 25.54795, -9.8865795, 6.741735, 25.338587, -10.427696, 6.4519587, 25.310745, -9.939594, 7.468337, 24.97506, -9.8865795, 6.741735, 25.338587, -9.939594, 7.468337, 24.97506, -9.078133, 6.986556, 25.424217, -9.8865795, 6.741735, 25.338587, -9.078133, 6.986556, 25.424217, -9.458067, 6.6153927, 25.506601, -9.078133, 6.986556, 25.424217, -9.126747, 7.324047, 25.200722, -8.992649, 7.0699244, 25.362774, -9.078133, 6.986556, 25.424217, -9.939594, 7.468337, 24.97506, -9.126747, 7.324047, 25.200722, -8.48115, 7.732603, 24.99367, -8.460228, 8.226148, 24.537516, -8.340681, 7.875271, 24.831814, -8.48115, 7.732603, 24.99367, -9.20825, 8.35639, 24.448666, -8.460228, 8.226148, 24.537516, -10.878963, 5.39891, 25.472626, -10.427696, 6.4519587, 25.310745, -10.839937, 5.4104342, 25.586737, -10.427696, 6.4519587, 25.310745, -10.878963, 5.39891, 25.472626, -10.647385, 5.933868, 25.242573, -10.647385, 5.933868, 25.242573, -10.878963, 5.39891, 25.472626, -10.741941, 5.7328005, 25.138784, -10.427696, 6.4519587, 25.310745, -10.264824, 6.8368664, 24.649649, -9.939594, 7.468337, 24.97506, -10.427696, 6.4519587, 25.310745, -10.423819, 6.5334654, 24.740517, -10.264824, 6.8368664, 24.649649, -10.154926, 7.080727, 23.99825, -9.20825, 8.35639, 24.448666, -9.939594, 7.468337, 24.97506, -9.20825, 8.35639, 24.448666, -10.154926, 7.080727, 23.99825, -9.836353, 7.4272223, 23.768997, -9.20825, 8.35639, 24.448666, -9.836353, 7.4272223, 23.768997, -9.618614, 7.784581, 23.992184, -8.975733, 8.430757, 23.866367, -8.469263, 8.833129, 23.903402, -9.20825, 8.35639, 24.448666, -8.469263, 8.833129, 23.903402, -8.975733, 8.430757, 23.866367, -8.970964, 8.277404, 23.316208, -8.469263, 8.833129, 23.903402, -8.970964, 8.277404, 23.316208, -8.792166, 8.398045, 23.2395, -9.20825, 8.35639, 24.448666, -9.126747, 7.324047, 25.200722, -9.939594, 7.468337, 24.97506, -9.079264, 7.896097, 24.814846, -9.126747, 7.324047, 25.200722, -9.20825, 8.35639, 24.448666, -9.126747, 7.324047, 25.200722, -9.079264, 7.896097, 24.814846, -8.702198, 7.3584385, 25.153973, -9.126747, 7.324047, 25.200722, -8.702198, 7.3584385, 25.153973, -8.848383, 7.227356, 25.258986, -9.20825, 8.35639, 24.448666, -8.638075, 7.5534444, 25.106686, -9.079264, 7.896097, 24.814846, -9.20825, 8.35639, 24.448666, -8.48115, 7.732603, 24.99367, -8.638075, 7.5534444, 25.106686, -9.618614, 7.784581, 23.992184, -9.555359, 7.787944, 23.5661, -9.20825, 8.35639, 24.448666, -9.618614, 7.784581, 23.992184, -9.691614, 7.632971, 23.664253, -9.555359, 7.787944, 23.5661, -8.469263, 8.833129, 23.903402, -8.460228, 8.226148, 24.537516, -9.20825, 8.35639, 24.448666, -8.460228, 8.226148, 24.537516, -8.469263, 8.833129, 23.903402, -7.939649, 8.319658, 24.36807, -8.460228, 8.226148, 24.537516, -7.939649, 8.319658, 24.36807, -8.1381, 8.120274, 24.596785, -8.975733, 8.430757, 23.866367, -9.555359, 7.787944, 23.5661, -9.08618, 8.070576, 23.364449, -8.975733, 8.430757, 23.866367, -9.20825, 8.35639, 24.448666, -9.555359, 7.787944, 23.5661, -7.7024093, 8.948188, 23.326448, -8.019506, 8.693222, 23.9122, -8.469263, 8.833129, 23.903402, -8.019506, 8.693222, 23.9122, -7.7024093, 8.948188, 23.326448, -7.56801, 8.854256, 23.41686, -8.019506, 8.693222, 23.9122, -7.56801, 8.854256, 23.41686, -7.7330556, 8.652529, 23.835022, -10.264824, 6.8368664, 24.649649, -10.154926, 7.080727, 23.99825, -9.939594, 7.468337, 24.97506, -10.264824, 6.8368664, 24.649649, -10.304508, 6.7830296, 24.250587, -10.154926, 7.080727, 23.99825, -10.423819, 6.5334654, 24.740517, -10.394926, 6.530945, 24.408104, -10.264824, 6.8368664, 24.649649, -10.423819, 6.5334654, 24.740517, -10.448719, 6.45382, 24.497004, -10.394926, 6.530945, 24.408104, -10.423819, 6.5334654, 24.740517, -10.427696, 6.4519587, 25.310745, -10.554361, 6.258996, 24.674118, -10.647385, 5.933868, 25.242573, -10.554361, 6.258996, 24.674118, -10.427696, 6.4519587, 25.310745, -10.647385, 5.933868, 25.242573, -10.675802, 5.9358487, 24.97307, -10.554361, 6.258996, 24.674118, -8.476179, 9.272415, 23.238873, -7.6357913, 8.757383, 23.254288, -7.649511, 8.880784, 23.39443, -8.476179, 9.272415, 23.238873, -8.520136, 8.706246, 22.59189, -7.6357913, 8.757383, 23.254288, -8.663195, 8.882344, 23.984976, -8.29641, 9.024534, 23.588913, -8.32843, 8.858036, 23.843124, -8.663195, 8.882344, 23.984976, -8.476179, 9.272415, 23.238873, -8.29641, 9.024534, 23.588913, -12.152782, 7.7485704, 22.986092, -11.339409, 8.419413, 22.91118, -11.277941, 8.172669, 23.538235, -12.152782, 7.7485704, 22.986092, -12.161711, 7.7648354, 22.866318, -11.339409, 8.419413, 22.91118, -11.339409, 8.419413, 22.91118, -11.045532, 8.272723, 23.64941, -11.277941, 8.172669, 23.538235, -11.339409, 8.419413, 22.91118, -10.934807, 8.523428, 23.311256, -11.045532, 8.272723, 23.64941, -10.934807, 8.523428, 23.311256, -11.339409, 8.419413, 22.91118, -10.46002, 9.004967, 22.97543, -10.934807, 8.523428, 23.311256, -10.46002, 9.004967, 22.97543, -10.420095, 8.532848, 23.947876, -10.934807, 8.523428, 23.311256, -10.420095, 8.532848, 23.947876, -10.836201, 8.361673, 23.749374, -10.420095, 8.532848, 23.947876, -10.197205, 8.742559, 23.74126, -10.297283, 8.550915, 23.961588, -10.420095, 8.532848, 23.947876, -10.46002, 9.004967, 22.97543, -10.197205, 8.742559, 23.74126, -9.557905, 8.814163, 24.051355, -9.097107, 9.033176, 23.725506, -9.326338, 8.822926, 24.033926, -9.557905, 8.814163, 24.051355, -9.396812, 9.323492, 23.09922, -9.097107, 9.033176, 23.725506, -12.129438, 7.7163987, 22.76176, -11.339409, 8.419413, 22.91118, -12.161711, 7.7648354, 22.866318, -11.339409, 8.419413, 22.91118, -12.129438, 7.7163987, 22.76176, -11.6488285, 8.007675, 22.739779, -11.6488285, 8.007675, 22.739779, -12.129438, 7.7163987, 22.76176, -11.723551, 7.814352, 22.611177, -11.339409, 8.419413, 22.91118, -10.748026, 8.414791, 22.562681, -10.46002, 9.004967, 22.97543, -11.339409, 8.419413, 22.91118, -11.012053, 8.2395935, 22.52716, -10.748026, 8.414791, 22.562681, -10.238874, 8.305614, 22.187637, -9.396812, 9.323492, 23.09922, -10.46002, 9.004967, 22.97543, -9.396812, 9.323492, 23.09922, -10.238874, 8.305614, 22.187637, -9.780174, 8.406629, 22.240479, -9.396812, 9.323492, 23.09922, -9.780174, 8.406629, 22.240479, -9.642679, 8.753303, 22.532566, -8.943731, 9.065945, 22.87788, -8.476179, 9.272415, 23.238873, -9.396812, 9.323492, 23.09922, -8.476179, 9.272415, 23.238873, -8.943731, 9.065945, 22.87788, -8.7198925, 8.690582, 22.52244, -8.476179, 9.272415, 23.238873, -8.7198925, 8.690582, 22.52244, -8.520136, 8.706246, 22.59189, -9.396812, 9.323492, 23.09922, -10.197205, 8.742559, 23.74126, -10.46002, 9.004967, 22.97543, -9.730011, 9.053403, 23.47832, -10.197205, 8.742559, 23.74126, -9.396812, 9.323492, 23.09922, -10.197205, 8.742559, 23.74126, -9.730011, 9.053403, 23.47832, -9.879805, 8.6168785, 24.008417, -10.197205, 8.742559, 23.74126, -9.879805, 8.6168785, 24.008417, -10.089674, 8.597132, 23.985575, -9.396812, 9.323492, 23.09922, -9.784039, 8.756422, 24.024965, -9.730011, 9.053403, 23.47832, -9.396812, 9.323492, 23.09922, -9.557905, 8.814163, 24.051355, -9.784039, 8.756422, 24.024965, -9.642679, 8.753303, 22.532566, -9.374041, 8.548035, 22.28962, -9.396812, 9.323492, 23.09922, -9.642679, 8.753303, 22.532566, -9.570545, 8.498457, 22.26675, -9.374041, 8.548035, 22.28962, -8.476179, 9.272415, 23.238873, -9.097107, 9.033176, 23.725506, -9.396812, 9.323492, 23.09922, -9.097107, 9.033176, 23.725506, -8.476179, 9.272415, 23.238873, -8.663195, 8.882344, 23.984976, -9.097107, 9.033176, 23.725506, -8.663195, 8.882344, 23.984976, -8.990536, 8.872201, 24.00973, -8.943731, 9.065945, 22.87788, -9.374041, 8.548035, 22.28962, -8.84972, 8.556498, 22.469631, -8.943731, 9.065945, 22.87788, -9.396812, 9.323492, 23.09922, -9.374041, 8.548035, 22.28962, -7.649511, 8.880784, 23.39443, -8.29641, 9.024534, 23.588913, -8.476179, 9.272415, 23.238873, -8.29641, 9.024534, 23.588913, -7.649511, 8.880784, 23.39443, -7.667808, 8.801199, 23.562954, -8.29641, 9.024534, 23.588913, -7.667808, 8.801199, 23.562954, -8.106319, 8.869322, 23.749159, -10.748026, 8.414791, 22.562681, -10.238874, 8.305614, 22.187637, -10.46002, 9.004967, 22.97543, -10.748026, 8.414791, 22.562681, -10.583004, 8.204302, 22.268263, -10.238874, 8.305614, 22.187637, -11.012053, 8.2395935, 22.52716, -10.796698, 8.076697, 22.316998, -10.748026, 8.414791, 22.562681, -11.012053, 8.2395935, 22.52716, -10.918375, 8.067935, 22.346127, -10.796698, 8.076697, 22.316998, -11.012053, 8.2395935, 22.52716, -11.339409, 8.419413, 22.91118, -11.160143, 8.010557, 22.403072, -11.6488285, 8.007675, 22.739779, -11.160143, 8.010557, 22.403072, -11.339409, 8.419413, 22.91118, -11.6488285, 8.007675, 22.739779, -11.5230255, 7.8992805, 22.537394, -11.160143, 8.010557, 22.403072, -8.041105, 9.099136, 22.774368, -7.6169944, 8.80678, 23.443369, -7.7392535, 8.897409, 23.481745, -8.041105, 9.099136, 22.774368, -7.5259223, 8.667595, 22.517582, -7.6169944, 8.80678, 23.443369, -8.604433, 8.708588, 23.005474, -8.175547, 8.90155, 23.08837, -8.352665, 8.7482605, 23.189362, -8.604433, 8.708588, 23.005474, -8.041105, 9.099136, 22.774368, -8.175547, 8.90155, 23.08837, -9.354351, 7.2679915, 20.05077, -9.012537, 7.976405, 20.566238, -9.399052, 7.74749, 20.912569, -9.354351, 7.2679915, 20.05077, -9.275749, 7.2862973, 19.989244, -9.012537, 7.976405, 20.566238, -9.012537, 7.976405, 20.566238, -9.383741, 7.8629084, 21.12708, -9.399052, 7.74749, 20.912569, -9.012537, 7.976405, 20.566238, -9.122709, 8.10707, 21.038918, -9.383741, 7.8629084, 21.12708, -9.122709, 8.10707, 21.038918, -9.012537, 7.976405, 20.566238, -8.725763, 8.597912, 21.202042, -9.122709, 8.10707, 21.038918, -8.725763, 8.597912, 21.202042, -9.341703, 8.161026, 21.703133, -9.122709, 8.10707, 21.038918, -9.341703, 8.161026, 21.703133, -9.369871, 7.9649425, 21.320047, -9.341703, 8.161026, 21.703133, -9.114939, 8.379078, 21.764282, -9.299545, 8.194818, 21.797089, -9.341703, 8.161026, 21.703133, -8.725763, 8.597912, 21.202042, -9.114939, 8.379078, 21.764282, -9.049728, 8.516345, 22.375086, -8.632957, 8.781511, 22.557295, -8.934408, 8.559859, 22.53762, -9.049728, 8.516345, 22.375086, -8.364826, 9.012768, 22.024788, -8.632957, 8.781511, 22.557295, -9.180586, 7.258568, 19.97211, -9.012537, 7.976405, 20.566238, -9.275749, 7.2862973, 19.989244, -9.012537, 7.976405, 20.566238, -9.180586, 7.258568, 19.97211, -8.98185, 7.591978, 20.29632, -8.98185, 7.591978, 20.29632, -9.180586, 7.258568, 19.97211, -8.903774, 7.424042, 20.197647, -9.012537, 7.976405, 20.566238, -8.491125, 8.092604, 20.86079, -8.725763, 8.597912, 21.202042, -9.012537, 7.976405, 20.566238, -8.566002, 7.9071417, 20.66232, -8.491125, 8.092604, 20.86079, -7.9790645, 8.107249, 21.086702, -8.364826, 9.012768, 22.024788, -8.725763, 8.597912, 21.202042, -8.364826, 9.012768, 22.024788, -7.9790645, 8.107249, 21.086702, -7.822355, 8.259277, 21.4402, -8.364826, 9.012768, 22.024788, -7.822355, 8.259277, 21.4402, -8.002892, 8.544012, 21.647385, -7.964889, 8.880724, 22.295406, -8.041105, 9.099136, 22.774368, -8.364826, 9.012768, 22.024788, -8.041105, 9.099136, 22.774368, -7.964889, 8.880724, 22.295406, -7.5640388, 8.629003, 22.34164, -8.041105, 9.099136, 22.774368, -7.5640388, 8.629003, 22.34164, -7.5259223, 8.667595, 22.517582, -8.364826, 9.012768, 22.024788, -9.114939, 8.379078, 21.764282, -8.725763, 8.597912, 21.202042, -8.749628, 8.718971, 21.97248, -9.114939, 8.379078, 21.764282, -8.364826, 9.012768, 22.024788, -9.114939, 8.379078, 21.764282, -8.749628, 8.718971, 21.97248, -9.156193, 8.312938, 22.116726, -9.114939, 8.379078, 21.764282, -9.156193, 8.312938, 22.116726, -9.228645, 8.264259, 21.957209, -8.364826, 9.012768, 22.024788, -9.126802, 8.436518, 22.200216, -8.749628, 8.718971, 21.97248, -8.364826, 9.012768, 22.024788, -9.049728, 8.516345, 22.375086, -9.126802, 8.436518, 22.200216, -8.002892, 8.544012, 21.647385, -7.684996, 8.432556, 21.75747, -8.364826, 9.012768, 22.024788, -8.002892, 8.544012, 21.647385, -7.7519794, 8.363534, 21.605556, -7.684996, 8.432556, 21.75747, -8.041105, 9.099136, 22.774368, -8.632957, 8.781511, 22.557295, -8.364826, 9.012768, 22.024788, -8.632957, 8.781511, 22.557295, -8.041105, 9.099136, 22.774368, -8.604433, 8.708588, 23.005474, -8.632957, 8.781511, 22.557295, -8.604433, 8.708588, 23.005474, -8.767645, 8.649889, 22.776098, -7.964889, 8.880724, 22.295406, -7.684996, 8.432556, 21.75747, -7.5840287, 8.511244, 22.2162, -7.964889, 8.880724, 22.295406, -8.364826, 9.012768, 22.024788, -7.684996, 8.432556, 21.75747, -7.7392535, 8.897409, 23.481745, -8.175547, 8.90155, 23.08837, -8.041105, 9.099136, 22.774368, -8.175547, 8.90155, 23.08837, -7.7392535, 8.897409, 23.481745, -7.856048, 8.8193245, 23.551592, -8.175547, 8.90155, 23.08837, -7.856048, 8.8193245, 23.551592, -8.1856785, 8.794295, 23.313171, -8.491125, 8.092604, 20.86079, -7.9790645, 8.107249, 21.086702, -8.725763, 8.597912, 21.202042, -8.491125, 8.092604, 20.86079, -8.181248, 7.964281, 20.873774, -7.9790645, 8.107249, 21.086702, -8.566002, 7.9071417, 20.66232, -8.305813, 7.8208942, 20.736774, -8.491125, 8.092604, 20.86079, -8.566002, 7.9071417, 20.66232, -8.377768, 7.7919035, 20.663399, -8.305813, 7.8208942, 20.736774, -8.566002, 7.9071417, 20.66232, -9.012537, 7.976405, 20.566238, -8.519827, 7.7004347, 20.51477, -8.98185, 7.591978, 20.29632, -8.519827, 7.7004347, 20.51477, -9.012537, 7.976405, 20.566238, -8.98185, 7.591978, 20.29632, -8.76738, 7.536939, 20.311623, -8.519827, 7.7004347, 20.51477, -7.2060475, 9.208552, 22.897741, -7.80905, 8.817884, 23.60042, -7.899529, 8.892069, 23.45427, -7.2060475, 9.208552, 22.897741, -6.7061973, 8.855337, 23.494766, -7.80905, 8.817884, 23.60042, -7.4934087, 8.594069, 22.34334, -7.539685, 8.893689, 22.84897, -7.65863, 8.6545105, 22.680805, -7.4934087, 8.594069, 22.34334, -7.2060475, 9.208552, 22.897741, -7.539685, 8.893689, 22.84897, -4.068832, 7.336172, 20.780975, -4.714312, 8.10803, 21.257643, -5.132072, 7.6965923, 20.921396, -4.068832, 7.336172, 20.780975, -3.9881473, 7.385569, 20.85462, -4.714312, 8.10803, 21.257643, -4.714312, 8.10803, 21.257643, -5.3909154, 7.790823, 20.987743, -5.132072, 7.6965923, 20.921396, -4.714312, 8.10803, 21.257643, -5.2879725, 8.145002, 21.248096, -5.3909154, 7.790823, 20.987743, -5.2879725, 8.145002, 21.248096, -4.714312, 8.10803, 21.257643, -5.489513, 8.767287, 21.711481, -5.2879725, 8.145002, 21.248096, -5.489513, 8.767287, 21.711481, -6.085754, 8.035226, 21.16589, -5.2879725, 8.145002, 21.248096, -6.085754, 8.035226, 21.16589, -5.623652, 7.8744917, 21.047535, -6.085754, 8.035226, 21.16589, -6.1478257, 8.328001, 21.433554, -6.1905837, 8.063794, 21.235548, -6.085754, 8.035226, 21.16589, -5.489513, 8.767287, 21.711481, -6.1478257, 8.328001, 21.433554, -6.841514, 8.391562, 21.667154, -7.0118194, 8.758585, 22.183632, -7.009152, 8.4349575, 21.841381, -6.841514, 8.391562, 21.667154, -6.416242, 9.177944, 22.323563, -7.0118194, 8.758585, 22.183632, -3.9419742, 7.374406, 20.966194, -4.714312, 8.10803, 21.257643, -3.9881473, 7.385569, 20.85462, -4.714312, 8.10803, 21.257643, -3.9419742, 7.374406, 20.966194, -4.32668, 7.7234807, 21.258965, -4.32668, 7.7234807, 21.258965, -3.9419742, 7.374406, 20.966194, -4.1686845, 7.564969, 21.337112, -4.714312, 8.10803, 21.257643, -4.9478, 8.286828, 21.951738, -5.489513, 8.767287, 21.711481, -4.714312, 8.10803, 21.257643, -4.704924, 8.094104, 21.826122, -4.9478, 8.286828, 21.951738, -5.0908885, 8.360533, 22.620289, -6.416242, 9.177944, 22.323563, -5.489513, 8.767287, 21.711481, -6.416242, 9.177944, 22.323563, -5.0908885, 8.360533, 22.620289, -5.486716, 8.50116, 22.883144, -6.416242, 9.177944, 22.323563, -5.486716, 8.50116, 22.883144, -5.8117423, 8.768128, 22.703707, -6.5980697, 9.059402, 22.89238, -7.2060475, 9.208552, 22.897741, -6.416242, 9.177944, 22.323563, -7.2060475, 9.208552, 22.897741, -6.5980697, 9.059402, 22.89238, -6.507363, 8.83523, 23.408497, -7.2060475, 9.208552, 22.897741, -6.507363, 8.83523, 23.408497, -6.7061973, 8.855337, 23.494766, -6.416242, 9.177944, 22.323563, -6.1478257, 8.328001, 21.433554, -5.489513, 8.767287, 21.711481, -6.3719687, 8.766026, 21.89067, -6.1478257, 8.328001, 21.433554, -6.416242, 9.177944, 22.323563, -6.1478257, 8.328001, 21.433554, -6.3719687, 8.766026, 21.89067, -6.5476384, 8.165707, 21.472878, -6.1478257, 8.328001, 21.433554, -6.5476384, 8.165707, 21.472878, -6.369827, 8.1280155, 21.354618, -6.416242, 9.177944, 22.323563, -6.645247, 8.314198, 21.536797, -6.3719687, 8.766026, 21.89067, -6.416242, 9.177944, 22.323563, -6.841514, 8.391562, 21.667154, -6.645247, 8.314198, 21.536797, -5.8117423, 8.768128, 22.703707, -5.8438954, 8.677977, 23.119993, -6.416242, 9.177944, 22.323563, -5.8117423, 8.768128, 22.703707, -5.6736007, 8.611357, 23.006952, -5.8438954, 8.677977, 23.119993, -7.2060475, 9.208552, 22.897741, -7.0118194, 8.758585, 22.183632, -6.416242, 9.177944, 22.323563, -7.0118194, 8.758585, 22.183632, -7.2060475, 9.208552, 22.897741, -7.4934087, 8.594069, 22.34334, -7.0118194, 8.758585, 22.183632, -7.4934087, 8.594069, 22.34334, -7.256623, 8.534951, 22.097307, -6.5980697, 9.059402, 22.89238, -5.8438954, 8.677977, 23.119993, -6.361113, 8.698025, 23.343914, -6.5980697, 9.059402, 22.89238, -6.416242, 9.177944, 22.323563, -5.8438954, 8.677977, 23.119993, -7.899529, 8.892069, 23.45427, -7.539685, 8.893689, 22.84897, -7.2060475, 9.208552, 22.897741, -7.539685, 8.893689, 22.84897, -7.899529, 8.892069, 23.45427, -7.983706, 8.764886, 23.345701, -7.539685, 8.893689, 22.84897, -7.983706, 8.764886, 23.345701, -7.7710595, 8.722573, 22.907578, -4.9478, 8.286828, 21.951738, -5.0908885, 8.360533, 22.620289, -5.489513, 8.767287, 21.711481, -4.9478, 8.286828, 21.951738, -4.867348, 8.1940365, 22.336489, -5.0908885, 8.360533, 22.620289, -4.704924, 8.094104, 21.826122, -4.7211885, 8.02508, 22.154125, -4.9478, 8.286828, 21.951738, -4.704924, 8.094104, 21.826122, -4.6452146, 7.9936295, 22.056368, -4.7211885, 8.02508, 22.154125, -4.704924, 8.094104, 21.826122, -4.714312, 8.10803, 21.257643, -4.489761, 7.8906374, 21.858315, -4.32668, 7.7234807, 21.258965, -4.489761, 7.8906374, 21.858315, -4.714312, 8.10803, 21.257643, -4.32668, 7.7234807, 21.258965, -4.284569, 7.6962314, 21.524137, -4.489761, 7.8906374, 21.858315, -7.4770913, 9.070688, 24.137522, -7.9792457, 8.86656, 23.280897, -7.798713, 8.910673, 23.258356, -7.4770913, 9.070688, 24.137522, -8.267395, 8.83601, 24.344084, -7.9792457, 8.86656, 23.280897, -6.969793, 8.361493, 23.999329, -7.3750834, 8.766386, 23.809656, -7.2131476, 8.500739, 23.731937, -6.969793, 8.361493, 23.999329, -7.4770913, 9.070688, 24.137522, -7.3750834, 8.766386, 23.809656, -6.8215938, 6.6485844, 27.584244, -6.934275, 7.533578, 26.905539, -6.54954, 7.0755653, 26.591766, -6.8215938, 6.6485844, 27.584244, -6.908404, 6.709503, 27.638208, -6.934275, 7.533578, 26.905539, -6.934275, 7.533578, 26.905539, -6.512714, 7.1929045, 26.339361, -6.54954, 7.0755653, 26.591766, -6.934275, 7.533578, 26.905539, -6.735351, 7.5916777, 26.38232, -6.512714, 7.1929045, 26.339361, -6.735351, 7.5916777, 26.38232, -6.934275, 7.533578, 26.905539, -7.004352, 8.309274, 26.101746, -6.735351, 7.5916777, 26.38232, -7.004352, 8.309274, 26.101746, -6.413199, 7.4994855, 25.660645, -6.735351, 7.5916777, 26.38232, -6.413199, 7.4994855, 25.660645, -6.4796042, 7.2974, 26.112244, -6.413199, 7.4994855, 25.660645, -6.6031613, 7.8468814, 25.541204, -6.4362464, 7.5467825, 25.541874, -6.413199, 7.4994855, 25.660645, -7.004352, 8.309274, 26.101746, -6.6031613, 7.8468814, 25.541204, -6.5875335, 7.9890084, 24.822481, -6.9586644, 8.467667, 24.52183, -6.6856866, 8.076338, 24.609621, -6.5875335, 7.9890084, 24.822481, -7.210817, 8.882824, 25.071764, -6.9586644, 8.467667, 24.52183, -7.030128, 6.721147, 27.639519, -6.934275, 7.533578, 26.905539, -6.908404, 6.709503, 27.638208, -6.934275, 7.533578, 26.905539, -7.030128, 6.721147, 27.639519, -7.122934, 7.142128, 27.21883, -7.122934, 7.142128, 27.21883, -7.030128, 6.721147, 27.639519, -7.2680945, 6.9975395, 27.31846, -6.934275, 7.533578, 26.905539, -7.48521, 7.8700495, 26.46049, -7.004352, 8.309274, 26.101746, -6.934275, 7.533578, 26.905539, -7.476253, 7.6441336, 26.707956, -7.48521, 7.8700495, 26.46049, -8.052195, 8.094164, 26.095999, -7.210817, 8.882824, 25.071764, -7.004352, 8.309274, 26.101746, -7.210817, 8.882824, 25.071764, -8.052195, 8.094164, 26.095999, -8.141077, 8.305193, 25.651417, -7.210817, 8.882824, 25.071764, -8.141077, 8.305193, 25.651417, -7.8344674, 8.5407715, 25.446497, -7.7096314, 8.899331, 24.684853, -7.4770913, 9.070688, 24.137522, -7.210817, 8.882824, 25.071764, -7.4770913, 9.070688, 24.137522, -7.7096314, 8.899331, 24.684853, -8.258791, 8.789434, 24.556768, -7.4770913, 9.070688, 24.137522, -8.258791, 8.789434, 24.556768, -8.267395, 8.83601, 24.344084, -7.210817, 8.882824, 25.071764, -6.6031613, 7.8468814, 25.541204, -7.004352, 8.309274, 26.101746, -6.8924146, 8.3843, 25.220247, -6.6031613, 7.8468814, 25.541204, -7.210817, 8.882824, 25.071764, -6.6031613, 7.8468814, 25.541204, -6.8924146, 8.3843, 25.220247, -6.5150523, 7.712496, 25.137945, -6.6031613, 7.8468814, 25.541204, -6.5150523, 7.712496, 25.137945, -6.4764667, 7.6428747, 25.340647, -7.210817, 8.882824, 25.071764, -6.543115, 7.8768907, 25.041906, -6.8924146, 8.3843, 25.220247, -7.210817, 8.882824, 25.071764, -6.5875335, 7.9890084, 24.822481, -6.543115, 7.8768907, 25.041906, -7.8344674, 8.5407715, 25.446497, -8.223946, 8.544853, 25.256237, -7.210817, 8.882824, 25.071764, -7.8344674, 8.5407715, 25.446497, -8.185364, 8.448042, 25.446867, -8.223946, 8.544853, 25.256237, -7.4770913, 9.070688, 24.137522, -6.9586644, 8.467667, 24.52183, -7.210817, 8.882824, 25.071764, -6.9586644, 8.467667, 24.52183, -7.4770913, 9.070688, 24.137522, -6.969793, 8.361493, 23.999329, -6.9586644, 8.467667, 24.52183, -6.969793, 8.361493, 23.999329, -6.8314404, 8.240372, 24.300121, -7.7096314, 8.899331, 24.684853, -8.223946, 8.544853, 25.256237, -8.244255, 8.633982, 24.69929, -7.7096314, 8.899331, 24.684853, -7.210817, 8.882824, 25.071764, -8.223946, 8.544853, 25.256237, -7.798713, 8.910673, 23.258356, -7.3750834, 8.766386, 23.809656, -7.4770913, 9.070688, 24.137522, -7.3750834, 8.766386, 23.809656, -7.798713, 8.910673, 23.258356, -7.6923747, 8.766327, 23.204716, -7.3750834, 8.766386, 23.809656, -7.6923747, 8.766327, 23.204716, -7.3779397, 8.62144, 23.55421, -7.48521, 7.8700495, 26.46049, -8.052195, 8.094164, 26.095999, -7.004352, 8.309274, 26.101746, -7.48521, 7.8700495, 26.46049, -7.886131, 7.860207, 26.385628, -8.052195, 8.094164, 26.095999, -7.476253, 7.6441336, 26.707956, -7.776336, 7.6484556, 26.566654, -7.48521, 7.8700495, 26.46049, -7.476253, 7.6441336, 26.707956, -7.720366, 7.5934772, 26.668566, -7.776336, 7.6484556, 26.566654, -7.476253, 7.6441336, 26.707956, -6.934275, 7.533578, 26.905539, -7.604976, 7.443248, 26.871801, -7.122934, 7.142128, 27.21883, -7.604976, 7.443248, 26.871801, -6.934275, 7.533578, 26.905539, -7.122934, 7.142128, 27.21883, -7.3896413, 7.171777, 27.159313, -7.604976, 7.443248, 26.871801, -6.0571437, 2.278272, 22.798777, -6.422816, 4.561778, 23.067327, -6.255482, 4.6069903, 22.866049, -6.0571437, 2.278272, 22.798777, -6.2640643, 2.2363775, 23.040073, -6.422816, 4.561778, 23.067327, -6.229696, -0.29725552, 22.954578, -6.2640643, 2.2363775, 23.040073, -6.0571437, 2.278272, 22.798777, -6.229696, -0.29725552, 22.954578, -6.4595838, -0.294353, 23.230642, -6.2640643, 2.2363775, 23.040073, -6.8122897, 2.1787193, 22.89551, -6.9267097, 4.515596, 22.675344, -6.886102, 4.499142, 22.937313, -6.8122897, 2.1787193, 22.89551, -6.8565516, 2.1943433, 22.589626, -6.9267097, 4.515596, 22.675344, -6.34096, 2.278272, 22.29763, -6.2974906, 4.6231685, 22.603962, -6.5006537, 4.606991, 22.43314, -6.34096, 2.278272, 22.29763, -6.0964046, 2.2940338, 22.49008, -6.2974906, 4.6231685, 22.603962, -6.886102, 4.499142, 22.937313, -7.330835, 6.6817102, 22.999025, -7.3017764, 6.6674695, 23.172724, -6.886102, 4.499142, 22.937313, -6.9267097, 4.515596, 22.675344, -7.330835, 6.6817102, 22.999025, -6.255482, 4.6069903, 22.866049, -6.9959083, 6.7194586, 23.261988, -6.883434, 6.7554083, 23.12764, -6.255482, 4.6069903, 22.866049, -6.422816, 4.561778, 23.067327, -6.9959083, 6.7194586, 23.261988, -6.883434, 6.7554083, 23.12764, -6.9959083, 6.7194586, 23.261988, -7.3726697, 7.8587894, 23.408417, -6.883434, 6.7554083, 23.12764, -7.3726697, 7.8587894, 23.408417, -7.2935386, 7.8998566, 23.310549, -6.2640643, 2.2363775, 23.040073, -6.6823287, 4.515596, 23.106857, -6.422816, 4.561778, 23.067327, -6.2640643, 2.2363775, 23.040073, -6.5727344, 2.1943433, 23.090773, -6.6823287, 4.515596, 23.106857, -6.422816, 4.561778, 23.067327, -6.6823287, 4.515596, 23.106857, -7.1677566, 6.6817102, 23.28698, -6.422816, 4.561778, 23.067327, -7.1677566, 6.6817102, 23.28698, -6.9959083, 6.7194586, 23.261988, -6.8565516, 2.1943433, 22.589626, -6.759332, 4.561778, 22.473125, -6.9267097, 4.515596, 22.675344, -6.8565516, 2.1943433, 22.589626, -6.6543117, 2.2363775, 22.350998, -6.759332, 4.561778, 22.473125, -6.9267097, 4.515596, 22.675344, -6.759332, 4.561778, 22.473125, -7.2210193, 6.7194586, 22.864502, -6.9267097, 4.515596, 22.675344, -7.2210193, 6.7194586, 22.864502, -7.330835, 6.6817102, 22.999025, -6.5006537, 4.606991, 22.43314, -6.9114146, 6.7684054, 22.951649, -7.0479617, 6.7554083, 22.837128, -6.5006537, 4.606991, 22.43314, -6.2974906, 4.6231685, 22.603962, -6.9114146, 6.7684054, 22.951649, -6.0964046, 2.2940338, 22.49008, -6.255482, 4.6069903, 22.866049, -6.2974906, 4.6231685, 22.603962, -6.0964046, 2.2940338, 22.49008, -6.0571437, 2.278272, 22.798777, -6.255482, 4.6069903, 22.866049, -6.2974906, 4.6231685, 22.603962, -6.883434, 6.7554083, 23.12764, -6.9114146, 6.7684054, 22.951649, -6.2974906, 4.6231685, 22.603962, -6.255482, 4.6069903, 22.866049, -6.883434, 6.7554083, 23.12764, -6.6543117, 2.2363775, 22.350998, -6.5006537, 4.606991, 22.43314, -6.759332, 4.561778, 22.473125, -6.6543117, 2.2363775, 22.350998, -6.34096, 2.278272, 22.29763, -6.5006537, 4.606991, 22.43314, -6.9183087, -0.294353, 22.420652, -6.34096, 2.278272, 22.29763, -6.6543117, 2.2363775, 22.350998, -6.9183087, -0.294353, 22.420652, -6.563316, -0.29725552, 22.365494, -6.34096, 2.278272, 22.29763, -6.759332, 4.561778, 22.473125, -7.0479617, 6.7554083, 22.837128, -7.2210193, 6.7194586, 22.864502, -6.759332, 4.561778, 22.473125, -6.5006537, 4.606991, 22.43314, -7.0479617, 6.7554083, 22.837128, -7.2210193, 6.7194586, 22.864502, -7.0479617, 6.7554083, 22.837128, -7.4157386, 7.8998566, 23.094776, -7.2210193, 6.7194586, 22.864502, -7.4157386, 7.8998566, 23.094776, -7.5403686, 7.8587894, 23.112305, -7.596041, 7.8030686, 23.339376, -7.8122087, 8.670566, 23.565685, -7.4973254, 7.8185544, 23.425323, -7.596041, 7.8030686, 23.339376, -7.884003, 8.657431, 23.502459, -7.8122087, 8.670566, 23.565685, -7.3726697, 7.8587894, 23.408417, -7.6698213, 8.747442, 23.485046, -7.2935386, 7.8998566, 23.310549, -7.3726697, 7.8587894, 23.408417, -7.724811, 8.710249, 23.555187, -7.6698213, 8.747442, 23.485046, -7.4973254, 7.8185544, 23.425323, -7.724811, 8.710249, 23.555187, -7.3726697, 7.8587894, 23.408417, -7.4973254, 7.8185544, 23.425323, -7.8122087, 8.670566, 23.565685, -7.724811, 8.710249, 23.555187, -7.3161235, 7.9149265, 23.18085, -7.7589135, 8.747442, 23.327732, -7.4157386, 7.8998566, 23.094776, -7.3161235, 7.9149265, 23.18085, -7.6881547, 8.763065, 23.391544, -7.7589135, 8.747442, 23.327732, -7.2935386, 7.8998566, 23.310549, -7.6881547, 8.763065, 23.391544, -7.3161235, 7.9149265, 23.18085, -7.2935386, 7.8998566, 23.310549, -7.6698213, 8.747442, 23.485046, -7.6881547, 8.763065, 23.391544, -7.5403686, 7.8587894, 23.112305, -7.901301, 8.670566, 23.408371, -7.61898, 7.8185544, 23.210514, -7.5403686, 7.8587894, 23.112305, -7.8473487, 8.710249, 23.338818, -7.901301, 8.670566, 23.408371, -7.4157386, 7.8998566, 23.094776, -7.8473487, 8.710249, 23.338818, -7.5403686, 7.8587894, 23.112305, -7.4157386, 7.8998566, 23.094776, -7.7589135, 8.747442, 23.327732, -7.8473487, 8.710249, 23.338818, -6.8164535, -0.2914486, 23.28688, -6.8122897, 2.1787193, 22.89551, -6.5727344, 2.1943433, 23.090773, -6.8164535, -0.2914486, 23.28688, -7.092834, -0.29034328, 23.054392, -6.8122897, 2.1787193, 22.89551, -7.61898, 7.8185544, 23.210514, -7.884003, 8.657431, 23.502459, -7.596041, 7.8030686, 23.339376, -7.61898, 7.8185544, 23.210514, -7.901301, 8.670566, 23.408371, -7.884003, 8.657431, 23.502459, -6.5727344, 2.1943433, 23.090773, -6.886102, 4.499142, 22.937313, -6.6823287, 4.515596, 23.106857, -6.5727344, 2.1943433, 23.090773, -6.8122897, 2.1787193, 22.89551, -6.886102, 4.499142, 22.937313, -7.092834, -0.29034328, 23.054392, -6.8565516, 2.1943433, 22.589626, -6.8122897, 2.1787193, 22.89551, -7.092834, -0.29034328, 23.054392, -7.1500726, -0.2914486, 22.697796, -6.8565516, 2.1943433, 22.589626, -6.563316, -0.29725552, 22.365494, -6.0964046, 2.2940338, 22.49008, -6.34096, 2.278272, 22.29763, -6.563316, -0.29725552, 22.365494, -6.288299, -0.2983632, 22.598755, -6.0964046, 2.2940338, 22.49008, -6.4595838, -0.294353, 23.230642, -6.5727344, 2.1943433, 23.090773, -6.2640643, 2.2363775, 23.040073, -6.4595838, -0.294353, 23.230642, -6.8164535, -0.2914486, 23.28688, -6.5727344, 2.1943433, 23.090773, -7.1500726, -0.2914486, 22.697796, -6.6543117, 2.2363775, 22.350998, -6.8565516, 2.1943433, 22.589626, -7.1500726, -0.2914486, 22.697796, -6.9183087, -0.294353, 22.420652, -6.6543117, 2.2363775, 22.350998, -6.288299, -0.2983632, 22.598755, -6.0571437, 2.278272, 22.798777, -6.0964046, 2.2940338, 22.49008, -6.288299, -0.2983632, 22.598755, -6.229696, -0.29725552, 22.954578, -6.0571437, 2.278272, 22.798777, -6.6823287, 4.515596, 23.106857, -7.3017764, 6.6674695, 23.172724, -7.1677566, 6.6817102, 23.28698, -6.6823287, 4.515596, 23.106857, -6.886102, 4.499142, 22.937313, -7.3017764, 6.6674695, 23.172724, -7.1677566, 6.6817102, 23.28698, -7.596041, 7.8030686, 23.339376, -7.4973254, 7.8185544, 23.425323, -7.1677566, 6.6817102, 23.28698, -7.3017764, 6.6674695, 23.172724, -7.596041, 7.8030686, 23.339376, -7.3017764, 6.6674695, 23.172724, -7.61898, 7.8185544, 23.210514, -7.596041, 7.8030686, 23.339376, -7.3017764, 6.6674695, 23.172724, -7.330835, 6.6817102, 22.999025, -7.61898, 7.8185544, 23.210514, -6.9959083, 6.7194586, 23.261988, -7.4973254, 7.8185544, 23.425323, -7.3726697, 7.8587894, 23.408417, -6.9959083, 6.7194586, 23.261988, -7.1677566, 6.6817102, 23.28698, -7.4973254, 7.8185544, 23.425323, -7.0479617, 6.7554083, 22.837128, -7.3161235, 7.9149265, 23.18085, -7.4157386, 7.8998566, 23.094776, -7.0479617, 6.7554083, 22.837128, -6.9114146, 6.7684054, 22.951649, -7.3161235, 7.9149265, 23.18085, -6.9114146, 6.7684054, 22.951649, -7.2935386, 7.8998566, 23.310549, -7.3161235, 7.9149265, 23.18085, -6.9114146, 6.7684054, 22.951649, -6.883434, 6.7554083, 23.12764, -7.2935386, 7.8998566, 23.310549, -7.330835, 6.6817102, 22.999025, -7.5403686, 7.8587894, 23.112305, -7.61898, 7.8185544, 23.210514, -7.330835, 6.6817102, 22.999025, -7.2210193, 6.7194586, 22.864502, -7.5403686, 7.8587894, 23.112305, -5.520864, 5.50994, 24.639458, -6.0238147, 5.3727474, 24.921116, -6.027886, 5.4678555, 24.868423, -5.520864, 5.50994, 24.639458, -5.4553275, 5.043026, 24.83633, -6.0238147, 5.3727474, 24.921116, -5.780359, 5.49264, 24.220936, -5.780785, 5.505308, 24.545547, -5.885944, 5.489472, 24.411573, -5.780359, 5.49264, 24.220936, -5.520864, 5.50994, 24.639458, -5.780785, 5.505308, 24.545547, -4.172077, 4.097315, 23.081501, -4.3400836, 4.5620866, 23.516861, -4.6323843, 4.612814, 23.259392, -4.172077, 4.097315, 23.081501, -4.1252418, 4.0723934, 23.12863, -4.3400836, 4.5620866, 23.516861, -4.3400836, 4.5620866, 23.516861, -4.7473187, 4.731488, 23.319653, -4.6323843, 4.612814, 23.259392, -4.3400836, 4.5620866, 23.516861, -4.6260543, 4.7886457, 23.530365, -4.7473187, 4.731488, 23.319653, -4.6260543, 4.7886457, 23.530365, -4.3400836, 4.5620866, 23.516861, -4.6092978, 5.019003, 23.91192, -4.6260543, 4.7886457, 23.530365, -4.6092978, 5.019003, 23.91192, -5.05752, 5.0416813, 23.479633, -4.6260543, 4.7886457, 23.530365, -5.05752, 5.0416813, 23.479633, -4.8509307, 4.836937, 23.373531, -5.05752, 5.0416813, 23.479633, -5.044219, 5.1299534, 23.679413, -5.109679, 5.073374, 23.52538, -5.05752, 5.0416813, 23.479633, -4.6092978, 5.019003, 23.91192, -5.044219, 5.1299534, 23.679413, -5.416506, 5.348407, 23.822437, -5.4675636, 5.4387703, 24.16735, -5.5109153, 5.382139, 23.924562, -5.416506, 5.348407, 23.822437, -5.0510015, 5.370203, 24.32837, -5.4675636, 5.4387703, 24.16735, -4.119844, 4.0247717, 23.180462, -4.3400836, 4.5620866, 23.516861, -4.1252418, 4.0723934, 23.12863, -4.3400836, 4.5620866, 23.516861, -4.119844, 4.0247717, 23.180462, -4.253202, 4.254257, 23.418776, -4.253202, 4.254257, 23.418776, -4.119844, 4.0247717, 23.180462, -4.22462, 4.107806, 23.420288, -4.3400836, 4.5620866, 23.516861, -4.504075, 4.5656476, 23.906963, -4.6092978, 5.019003, 23.91192, -4.3400836, 4.5620866, 23.516861, -4.4175224, 4.424284, 23.794865, -4.504075, 4.5656476, 23.906963, -4.644364, 4.490939, 24.260977, -5.0510015, 5.370203, 24.32837, -4.6092978, 5.019003, 23.91192, -5.0510015, 5.370203, 24.32837, -4.644364, 4.490939, 24.260977, -4.8376765, 4.627639, 24.436502, -5.0510015, 5.370203, 24.32837, -4.8376765, 4.627639, 24.436502, -4.9126344, 4.897375, 24.407942, -5.261839, 5.2418065, 24.581022, -5.520864, 5.50994, 24.639458, -5.0510015, 5.370203, 24.32837, -5.520864, 5.50994, 24.639458, -5.261839, 5.2418065, 24.581022, -5.3500004, 4.9882493, 24.782772, -5.520864, 5.50994, 24.639458, -5.3500004, 4.9882493, 24.782772, -5.4553275, 5.043026, 24.83633, -5.0510015, 5.370203, 24.32837, -5.044219, 5.1299534, 23.679413, -4.6092978, 5.019003, 23.91192, -5.09594, 5.2896347, 24.011734, -5.044219, 5.1299534, 23.679413, -5.0510015, 5.370203, 24.32837, -5.044219, 5.1299534, 23.679413, -5.09594, 5.2896347, 24.011734, -5.2869577, 5.1833105, 23.681408, -5.044219, 5.1299534, 23.679413, -5.2869577, 5.1833105, 23.681408, -5.197224, 5.1352034, 23.604895, -5.0510015, 5.370203, 24.32837, -5.321176, 5.2789783, 23.735258, -5.09594, 5.2896347, 24.011734, -5.0510015, 5.370203, 24.32837, -5.416506, 5.348407, 23.822437, -5.321176, 5.2789783, 23.735258, -4.9126344, 4.897375, 24.407942, -5.007563, 4.7688026, 24.597364, -5.0510015, 5.370203, 24.32837, -4.9126344, 4.897375, 24.407942, -4.924829, 4.7089424, 24.521822, -5.007563, 4.7688026, 24.597364, -5.520864, 5.50994, 24.639458, -5.4675636, 5.4387703, 24.16735, -5.0510015, 5.370203, 24.32837, -5.4675636, 5.4387703, 24.16735, -5.520864, 5.50994, 24.639458, -5.780359, 5.49264, 24.220936, -5.4675636, 5.4387703, 24.16735, -5.780359, 5.49264, 24.220936, -5.6462617, 5.4495068, 24.077614, -5.261839, 5.2418065, 24.581022, -5.007563, 4.7688026, 24.597364, -5.284591, 4.8992395, 24.734537, -5.261839, 5.2418065, 24.581022, -5.0510015, 5.370203, 24.32837, -5.007563, 4.7688026, 24.597364, -6.027886, 5.4678555, 24.868423, -5.780785, 5.505308, 24.545547, -5.520864, 5.50994, 24.639458, -5.780785, 5.505308, 24.545547, -6.027886, 5.4678555, 24.868423, -6.0964007, 5.467935, 24.783894, -5.780785, 5.505308, 24.545547, -6.0964007, 5.467935, 24.783894, -5.9559407, 5.492031, 24.540054, -4.504075, 4.5656476, 23.906963, -4.644364, 4.490939, 24.260977, -4.6092978, 5.019003, 23.91192, -4.504075, 4.5656476, 23.906963, -4.5401545, 4.407131, 24.07597, -4.644364, 4.490939, 24.260977, -4.4175224, 4.424284, 23.794865, -4.4788713, 4.3216662, 23.951574, -4.504075, 4.5656476, 23.906963, -4.4175224, 4.424284, 23.794865, -4.4406796, 4.305605, 23.890078, -4.4788713, 4.3216662, 23.951574, -4.4175224, 4.424284, 23.794865, -4.3400836, 4.5620866, 23.516861, -4.367128, 4.250943, 23.76148, -4.253202, 4.254257, 23.418776, -4.367128, 4.250943, 23.76148, -4.3400836, 4.5620866, 23.516861, -4.253202, 4.254257, 23.418776, -4.274289, 4.1678133, 23.544254, -4.367128, 4.250943, 23.76148, -6.100014, 5.3618755, 25.36038, -6.053468, 5.4692774, 24.699776, -5.951238, 5.4974275, 24.761002, -6.100014, 5.3618755, 25.36038, -6.5840898, 5.185566, 25.139408, -6.053468, 5.4692774, 24.699776, -5.702927, 4.9555445, 25.310673, -5.8909087, 5.2601395, 25.158152, -5.754765, 5.1142435, 25.118452, -5.702927, 4.9555445, 25.310673, -6.100014, 5.3618755, 25.36038, -5.8909087, 5.2601395, 25.158152, -6.868545, 2.974114, 26.87804, -6.7395024, 3.6925054, 26.67168, -6.369455, 3.4866214, 26.543037, -6.868545, 2.974114, 26.87804, -6.9426017, 2.9990473, 26.889389, -6.7395024, 3.6925054, 26.67168, -6.7395024, 3.6925054, 26.67168, -6.2608256, 3.6231003, 26.448338, -6.369455, 3.4866214, 26.543037, -6.7395024, 3.6925054, 26.67168, -6.429816, 3.8601167, 26.47786, -6.2608256, 3.6231003, 26.448338, -6.429816, 3.8601167, 26.47786, -6.7395024, 3.6925054, 26.67168, -6.5268407, 4.3764234, 26.390133, -6.429816, 3.8601167, 26.47786, -6.5268407, 4.3764234, 26.390133, -5.9696584, 3.9842505, 26.192686, -6.429816, 3.8601167, 26.47786, -5.9696584, 3.9842505, 26.192686, -6.1631923, 3.745168, 26.363018, -5.9696584, 3.9842505, 26.192686, -6.049317, 4.232349, 26.135853, -5.944036, 4.043989, 26.133595, -5.9696584, 3.9842505, 26.192686, -6.5268407, 4.3764234, 26.390133, -6.049317, 4.232349, 26.135853, -5.773127, 4.5062346, 25.794031, -5.898379, 4.8849564, 25.608694, -5.7558064, 4.6165876, 25.667988, -5.773127, 4.5062346, 25.794031, -6.2885137, 4.9992027, 25.899937, -5.898379, 4.8849564, 25.608694, -7.0106807, 3.0087154, 26.849985, -6.7395024, 3.6925054, 26.67168, -6.9426017, 2.9990473, 26.889389, -6.7395024, 3.6925054, 26.67168, -7.0106807, 3.0087154, 26.849985, -6.9334645, 3.3768253, 26.686901, -6.9334645, 3.3768253, 26.686901, -7.0106807, 3.0087154, 26.849985, -7.0455823, 3.2654228, 26.659414, -6.7395024, 3.6925054, 26.67168, -6.892614, 4.0271807, 26.316252, -6.5268407, 4.3764234, 26.390133, -6.7395024, 3.6925054, 26.67168, -6.9665236, 3.8246672, 26.401512, -6.892614, 4.0271807, 26.316252, -7.0833793, 4.2717676, 25.97569, -6.2885137, 4.9992027, 25.899937, -6.5268407, 4.3764234, 26.390133, -6.2885137, 4.9992027, 25.899937, -7.0833793, 4.2717676, 25.97569, -6.9840283, 4.5172915, 25.75856, -6.2885137, 4.9992027, 25.899937, -6.9840283, 4.5172915, 25.75856, -6.7441907, 4.708605, 25.804724, -6.4090276, 5.1228185, 25.524706, -6.100014, 5.3618755, 25.36038, -6.2885137, 4.9992027, 25.899937, -6.100014, 5.3618755, 25.36038, -6.4090276, 5.1228185, 25.524706, -6.6533313, 5.102206, 25.24277, -6.100014, 5.3618755, 25.36038, -6.6533313, 5.102206, 25.24277, -6.5840898, 5.185566, 25.139408, -6.2885137, 4.9992027, 25.899937, -6.049317, 4.232349, 26.135853, -6.5268407, 4.3764234, 26.390133, -6.123463, 4.6506386, 25.980106, -6.049317, 4.232349, 26.135853, -6.2885137, 4.9992027, 25.899937, -6.049317, 4.232349, 26.135853, -6.123463, 4.6506386, 25.980106, -5.8564105, 4.2503223, 25.933277, -6.049317, 4.232349, 26.135853, -5.8564105, 4.2503223, 25.933277, -5.898976, 4.1555033, 26.03533, -6.2885137, 4.9992027, 25.899937, -5.822971, 4.3798666, 25.900269, -6.123463, 4.6506386, 25.980106, -6.2885137, 4.9992027, 25.899937, -5.773127, 4.5062346, 25.794031, -5.822971, 4.3798666, 25.900269, -6.7441907, 4.708605, 25.804724, -6.8905606, 4.769124, 25.571657, -6.2885137, 4.9992027, 25.899937, -6.7441907, 4.708605, 25.804724, -6.933764, 4.659773, 25.663965, -6.8905606, 4.769124, 25.571657, -6.100014, 5.3618755, 25.36038, -5.898379, 4.8849564, 25.608694, -6.2885137, 4.9992027, 25.899937, -5.898379, 4.8849564, 25.608694, -6.100014, 5.3618755, 25.36038, -5.702927, 4.9555445, 25.310673, -5.898379, 4.8849564, 25.608694, -5.702927, 4.9555445, 25.310673, -5.727136, 4.8010197, 25.48896, -6.4090276, 5.1228185, 25.524706, -6.8905606, 4.769124, 25.571657, -6.712791, 4.966251, 25.297207, -6.4090276, 5.1228185, 25.524706, -6.2885137, 4.9992027, 25.899937, -6.8905606, 4.769124, 25.571657, -5.951238, 5.4974275, 24.761002, -5.8909087, 5.2601395, 25.158152, -6.100014, 5.3618755, 25.36038, -5.8909087, 5.2601395, 25.158152, -5.951238, 5.4974275, 24.761002, -5.857908, 5.4214015, 24.738348, -5.8909087, 5.2601395, 25.158152, -5.857908, 5.4214015, 24.738348, -5.786898, 5.237897, 24.993658, -6.892614, 4.0271807, 26.316252, -7.0833793, 4.2717676, 25.97569, -6.5268407, 4.3764234, 26.390133, -6.892614, 4.0271807, 26.316252, -7.084641, 4.049944, 26.135506, -7.0833793, 4.2717676, 25.97569, -6.9665236, 3.8246672, 26.401512, -7.0913386, 3.8691072, 26.228043, -6.892614, 4.0271807, 26.316252, -6.9665236, 3.8246672, 26.401512, -7.0892367, 3.8087032, 26.28731, -7.0913386, 3.8691072, 26.228043, -6.9665236, 3.8246672, 26.401512, -6.7395024, 3.6925054, 26.67168, -7.0888734, 3.6620417, 26.401033, -6.9334645, 3.3768253, 26.686901, -7.0888734, 3.6620417, 26.401033, -6.7395024, 3.6925054, 26.67168, -6.9334645, 3.3768253, 26.686901, -7.0596833, 3.4167135, 26.568975, -7.0888734, 3.6620417, 26.401033, -6.3319364, 5.7359695, 25.081383, -5.9698243, 5.384118, 24.680239, -5.904365, 5.4435186, 24.765022, -6.3319364, 5.7359695, 25.081383, -6.686463, 5.4666615, 24.73655, -5.9698243, 5.384118, 24.680239, -6.155786, 5.38664, 25.487875, -6.125067, 5.5240107, 25.150925, -6.053208, 5.3827543, 25.27274, -6.155786, 5.38664, 25.487875, -6.3319364, 5.7359695, 25.081383, -6.125067, 5.5240107, 25.150925, -8.413198, 4.890188, 26.407503, -7.970281, 5.3087463, 26.08081, -7.7057996, 5.0614824, 26.335453, -8.413198, 4.890188, 26.407503, -8.465763, 4.9176445, 26.35488, -7.970281, 5.3087463, 26.08081, -7.970281, 5.3087463, 26.08081, -7.5340934, 5.103933, 26.298006, -7.7057996, 5.0614824, 26.335453, -7.970281, 5.3087463, 26.08081, -7.592959, 5.3087974, 26.109215, -7.5340934, 5.103933, 26.298006, -7.592959, 5.3087974, 26.109215, -7.970281, 5.3087463, 26.08081, -7.4463277, 5.651639, 25.785309, -7.592959, 5.3087974, 26.109215, -7.4463277, 5.651639, 25.785309, -7.0733275, 5.2124443, 26.196064, -7.592959, 5.3087974, 26.109215, -7.0733275, 5.2124443, 26.196064, -7.379638, 5.141446, 26.26409, -7.0733275, 5.2124443, 26.196064, -7.0267406, 5.3698435, 26.018854, -7.005255, 5.218994, 26.151365, -7.0733275, 5.2124443, 26.196064, -7.4463277, 5.651639, 25.785309, -7.0267406, 5.3698435, 26.018854, -6.5752587, 5.356027, 25.89963, -6.46051, 5.5302234, 25.563005, -6.4677835, 5.358314, 25.792141, -6.5752587, 5.356027, 25.89963, -6.836881, 5.81112, 25.415369, -6.46051, 5.5302234, 25.563005, -8.498926, 4.900632, 26.286041, -7.970281, 5.3087463, 26.08081, -8.465763, 4.9176445, 26.35488, -7.970281, 5.3087463, 26.08081, -8.498926, 4.900632, 26.286041, -8.239595, 5.077715, 26.094341, -8.239595, 5.077715, 26.094341, -8.498926, 4.900632, 26.286041, -8.351461, 4.9742537, 26.046995, -7.970281, 5.3087463, 26.08081, -7.8256736, 5.34012, 25.656843, -7.4463277, 5.651639, 25.785309, -7.970281, 5.3087463, 26.08081, -7.9896913, 5.2398424, 25.73777, -7.8256736, 5.34012, 25.656843, -7.744165, 5.310528, 25.246101, -6.836881, 5.81112, 25.415369, -7.4463277, 5.651639, 25.785309, -6.836881, 5.81112, 25.415369, -7.744165, 5.310528, 25.246101, -7.485513, 5.35617, 25.082954, -6.836881, 5.81112, 25.415369, -7.485513, 5.35617, 25.082954, -7.2575336, 5.5329638, 25.196087, -6.7352633, 5.6665816, 25.089825, -6.3319364, 5.7359695, 25.081383, -6.836881, 5.81112, 25.415369, -6.3319364, 5.7359695, 25.081383, -6.7352633, 5.6665816, 25.089825, -6.815335, 5.4714, 24.787678, -6.3319364, 5.7359695, 25.081383, -6.815335, 5.4714, 24.787678, -6.686463, 5.4666615, 24.73655, -6.836881, 5.81112, 25.415369, -7.0267406, 5.3698435, 26.018854, -7.4463277, 5.651639, 25.785309, -6.8723903, 5.5936527, 25.718147, -7.0267406, 5.3698435, 26.018854, -6.836881, 5.81112, 25.415369, -7.0267406, 5.3698435, 26.018854, -6.8723903, 5.5936527, 25.718147, -6.7732606, 5.244132, 25.999937, -7.0267406, 5.3698435, 26.018854, -6.7732606, 5.244132, 25.999937, -6.888104, 5.2399597, 26.077604, -6.836881, 5.81112, 25.415369, -6.703796, 5.3285036, 25.979181, -6.8723903, 5.5936527, 25.718147, -6.836881, 5.81112, 25.415369, -6.5752587, 5.356027, 25.89963, -6.703796, 5.3285036, 25.979181, -7.2575336, 5.5329638, 25.196087, -7.249745, 5.4294252, 24.944311, -6.836881, 5.81112, 25.415369, -7.2575336, 5.5329638, 25.196087, -7.3613477, 5.405882, 25.013523, -7.249745, 5.4294252, 24.944311, -6.3319364, 5.7359695, 25.081383, -6.46051, 5.5302234, 25.563005, -6.836881, 5.81112, 25.415369, -6.46051, 5.5302234, 25.563005, -6.3319364, 5.7359695, 25.081383, -6.155786, 5.38664, 25.487875, -6.46051, 5.5302234, 25.563005, -6.155786, 5.38664, 25.487875, -6.3074155, 5.384823, 25.640076, -6.7352633, 5.6665816, 25.089825, -7.249745, 5.4294252, 24.944311, -6.916063, 5.3964624, 24.806072, -6.7352633, 5.6665816, 25.089825, -6.836881, 5.81112, 25.415369, -7.249745, 5.4294252, 24.944311, -5.904365, 5.4435186, 24.765022, -6.125067, 5.5240107, 25.150925, -6.3319364, 5.7359695, 25.081383, -6.125067, 5.5240107, 25.150925, -5.904365, 5.4435186, 24.765022, -5.8518662, 5.369458, 24.847279, -6.125067, 5.5240107, 25.150925, -5.8518662, 5.369458, 24.847279, -5.982039, 5.3976545, 25.132534, -7.8256736, 5.34012, 25.656843, -7.744165, 5.310528, 25.246101, -7.4463277, 5.651639, 25.785309, -7.8256736, 5.34012, 25.656843, -7.8908563, 5.243067, 25.42438, -7.744165, 5.310528, 25.246101, -7.9896913, 5.2398424, 25.73777, -7.989692, 5.1600666, 25.528631, -7.8256736, 5.34012, 25.656843, -7.9896913, 5.2398424, 25.73777, -8.038292, 5.1534004, 25.594398, -7.989692, 5.1600666, 25.528631, -7.9896913, 5.2398424, 25.73777, -7.970281, 5.3087463, 26.08081, -8.13969, 5.114773, 25.721031, -8.239595, 5.077715, 26.094341, -8.13969, 5.114773, 25.721031, -7.970281, 5.3087463, 26.08081, -8.239595, 5.077715, 26.094341, -8.274294, 5.0338635, 25.932472, -8.13969, 5.114773, 25.721031, -6.331285, 5.6798854, 24.653553, -5.876188, 5.388583, 24.768026, -5.910171, 5.4440794, 24.847443, -6.331285, 5.6798854, 24.653553, -6.2332807, 5.427716, 24.268461, -5.876188, 5.388583, 24.768026, -6.555012, 5.4120646, 24.973154, -6.2882495, 5.5129185, 24.845657, -6.350158, 5.405257, 24.957108, -6.555012, 5.4120646, 24.973154, -6.331285, 5.6798854, 24.653553, -6.2882495, 5.5129185, 24.845657, -8.316685, 4.926779, 23.737947, -7.8548923, 5.297988, 23.903517, -7.925697, 5.1127415, 24.21713, -8.316685, 4.926779, 23.737947, -8.301708, 4.9451656, 23.675941, -7.8548923, 5.297988, 23.903517, -7.8548923, 5.297988, 23.903517, -7.815824, 5.15586, 24.324652, -7.925697, 5.1127415, 24.21713, -7.8548923, 5.297988, 23.903517, -7.6972337, 5.3176384, 24.191387, -7.815824, 5.15586, 24.324652, -7.6972337, 5.3176384, 24.191387, -7.8548923, 5.297988, 23.903517, -7.37958, 5.598157, 24.143217, -7.6972337, 5.3176384, 24.191387, -7.37958, 5.598157, 24.143217, -7.52163, 5.2640796, 24.611933, -7.6972337, 5.3176384, 24.191387, -7.52163, 5.2640796, 24.611933, -7.717137, 5.1935024, 24.421171, -7.52163, 5.2640796, 24.611933, -7.3604617, 5.389035, 24.563318, -7.457949, 5.2713842, 24.642237, -7.52163, 5.2640796, 24.611933, -7.37958, 5.598157, 24.143217, -7.3604617, 5.389035, 24.563318, -7.058254, 5.3891068, 24.842972, -6.74797, 5.522382, 24.775219, -6.928924, 5.3911495, 24.875774, -7.058254, 5.3891068, 24.842972, -6.8127713, 5.7382603, 24.422806, -6.74797, 5.522382, 24.775219, -8.2651825, 4.9275074, 23.624132, -7.8548923, 5.297988, 23.903517, -8.301708, 4.9451656, 23.675941, -7.8548923, 5.297988, 23.903517, -8.2651825, 4.9275074, 23.624132, -7.9951816, 5.089792, 23.725204, -7.9951816, 5.089792, 23.725204, -8.2651825, 4.9275074, 23.624132, -8.016663, 4.994527, 23.62873, -7.8548923, 5.297988, 23.903517, -7.4628644, 5.3177576, 23.831608, -7.37958, 5.598157, 24.143217, -7.8548923, 5.297988, 23.903517, -7.6030936, 5.2291493, 23.751238, -7.4628644, 5.3177576, 23.831608, -7.1153607, 5.282588, 23.72141, -6.8127713, 5.7382603, 24.422806, -7.37958, 5.598157, 24.143217, -6.8127713, 5.7382603, 24.422806, -7.1153607, 5.282588, 23.72141, -6.87394, 5.326008, 23.83848, -6.8127713, 5.7382603, 24.422806, -6.87394, 5.326008, 23.83848, -6.8445373, 5.4831157, 24.042107, -6.518, 5.605947, 24.369406, -6.331285, 5.6798854, 24.653553, -6.8127713, 5.7382603, 24.422806, -6.331285, 5.6798854, 24.653553, -6.518, 5.605947, 24.369406, -6.3297257, 5.428781, 24.196327, -6.331285, 5.6798854, 24.653553, -6.3297257, 5.428781, 24.196327, -6.2332807, 5.427716, 24.268461, -6.8127713, 5.7382603, 24.422806, -7.3604617, 5.389035, 24.563318, -7.37958, 5.598157, 24.143217, -7.056313, 5.567637, 24.537035, -7.3604617, 5.389035, 24.563318, -6.8127713, 5.7382603, 24.422806, -7.3604617, 5.389035, 24.563318, -7.056313, 5.567637, 24.537035, -7.24099, 5.2982535, 24.745642, -7.3604617, 5.389035, 24.563318, -7.24099, 5.2982535, 24.745642, -7.3485713, 5.2914233, 24.69535, -6.8127713, 5.7382603, 24.422806, -7.1779733, 5.3646665, 24.78445, -7.056313, 5.567637, 24.537035, -6.8127713, 5.7382603, 24.422806, -7.058254, 5.3891068, 24.842972, -7.1779733, 5.3646665, 24.78445, -6.8445373, 5.4831157, 24.042107, -6.6547856, 5.388571, 23.94828, -6.8127713, 5.7382603, 24.422806, -6.8445373, 5.4831157, 24.042107, -6.7587676, 5.367548, 23.897482, -6.6547856, 5.388571, 23.94828, -6.331285, 5.6798854, 24.653553, -6.74797, 5.522382, 24.775219, -6.8127713, 5.7382603, 24.422806, -6.74797, 5.522382, 24.775219, -6.331285, 5.6798854, 24.653553, -6.555012, 5.4120646, 24.973154, -6.74797, 5.522382, 24.775219, -6.555012, 5.4120646, 24.973154, -6.737456, 5.410923, 24.927305, -6.518, 5.605947, 24.369406, -6.6547856, 5.388571, 23.94828, -6.404985, 5.3717523, 24.133698, -6.518, 5.605947, 24.369406, -6.8127713, 5.7382603, 24.422806, -6.6547856, 5.388571, 23.94828, -5.910171, 5.4440794, 24.847443, -6.2882495, 5.5129185, 24.845657, -6.331285, 5.6798854, 24.653553, -6.2882495, 5.5129185, 24.845657, -5.910171, 5.4440794, 24.847443, -5.947083, 5.38731, 24.924572, -6.2882495, 5.5129185, 24.845657, -5.947083, 5.38731, 24.924572, -6.211325, 5.4130735, 24.94913, -7.4628644, 5.3177576, 23.831608, -7.1153607, 5.282588, 23.72141, -7.37958, 5.598157, 24.143217, -7.4628644, 5.3177576, 23.831608, -7.319452, 5.226307, 23.692755, -7.1153607, 5.282588, 23.72141, -7.6030936, 5.2291493, 23.751238, -7.4537644, 5.1571455, 23.66732, -7.4628644, 5.3177576, 23.831608, -7.6030936, 5.2291493, 23.751238, -7.522962, 5.150751, 23.66025, -7.4537644, 5.1571455, 23.66732, -7.6030936, 5.2291493, 23.751238, -7.8548923, 5.297988, 23.903517, -7.6649528, 5.116803, 23.641397, -7.9951816, 5.089792, 23.725204, -7.6649528, 5.116803, 23.641397, -7.8548923, 5.297988, 23.903517, -7.9951816, 5.089792, 23.725204, -7.8895354, 5.0471697, 23.63519, -7.6649528, 5.116803, 23.641397, -5.857347, 5.7116084, 24.363003, -5.903773, 5.378351, 24.927797, -6.00098, 5.4485216, 24.902779, -5.857347, 5.7116084, 24.363003, -5.4018383, 5.389697, 24.404541, -5.903773, 5.378351, 24.927797, -6.2981954, 5.4044847, 24.163559, -6.076615, 5.5257673, 24.45499, -6.2318177, 5.399699, 24.403456, -6.2981954, 5.4044847, 24.163559, -5.857347, 5.7116084, 24.363003, -6.076615, 5.5257673, 24.45499, -5.4074144, 4.736121, 21.818316, -5.439855, 5.177844, 22.396505, -5.831164, 4.97289, 22.37704, -5.4074144, 4.736121, 21.818316, -5.3315473, 4.755287, 21.823586, -5.439855, 5.177844, 22.396505, -5.439855, 5.177844, 22.396505, -5.9201818, 5.030147, 22.5292, -5.831164, 4.97289, 22.37704, -5.439855, 5.177844, 22.396505, -5.7215886, 5.217056, 22.642551, -5.9201818, 5.030147, 22.5292, -5.7215886, 5.217056, 22.642551, -5.439855, 5.177844, 22.396505, -5.5580716, 5.554124, 23.009472, -5.7215886, 5.217056, 22.642551, -5.5580716, 5.554124, 23.009472, -6.160071, 5.178384, 22.936909, -5.7215886, 5.217056, 22.642551, -6.160071, 5.178384, 22.936909, -6.000282, 5.0809345, 22.665983, -6.160071, 5.178384, 22.936909, -6.046327, 5.3291693, 23.119432, -6.1793313, 5.1894274, 23.018368, -6.160071, 5.178384, 22.936909, -5.5580716, 5.554124, 23.009472, -6.046327, 5.3291693, 23.119432, -6.2826037, 5.3541317, 23.53723, -6.1099467, 5.52, 23.893438, -6.287435, 5.3614902, 23.69768, -6.2826037, 5.3541317, 23.53723, -5.7123218, 5.753208, 23.741987, -6.1099467, 5.52, 23.893438, -5.2635365, 4.7313147, 21.856642, -5.439855, 5.177844, 22.396505, -5.3315473, 4.755287, 21.823586, -5.439855, 5.177844, 22.396505, -5.2635365, 4.7313147, 21.856642, -5.291579, 4.922532, 22.195475, -5.291579, 4.922532, 22.195475, -5.2635365, 4.7313147, 21.856642, -5.19895, 4.8064184, 22.150917, -5.439855, 5.177844, 22.396505, -5.24503, 5.200137, 22.848965, -5.5580716, 5.554124, 23.009472, -5.439855, 5.177844, 22.396505, -5.1995373, 5.0887403, 22.666178, -5.24503, 5.200137, 22.848965, -5.0281267, 5.1566877, 23.240654, -5.7123218, 5.753208, 23.741987, -5.5580716, 5.554124, 23.009472, -5.7123218, 5.753208, 23.741987, -5.0281267, 5.1566877, 23.240654, -5.097282, 5.219322, 23.551094, -5.7123218, 5.753208, 23.741987, -5.097282, 5.219322, 23.551094, -5.3022, 5.4230766, 23.628416, -5.577439, 5.6020293, 24.084873, -5.857347, 5.7116084, 24.363003, -5.7123218, 5.753208, 23.741987, -5.857347, 5.7116084, 24.363003, -5.577439, 5.6020293, 24.084873, -5.342383, 5.384054, 24.275276, -5.857347, 5.7116084, 24.363003, -5.342383, 5.384054, 24.275276, -5.4018383, 5.389697, 24.404541, -5.7123218, 5.753208, 23.741987, -6.046327, 5.3291693, 23.119432, -5.5580716, 5.554124, 23.009472, -5.917007, 5.5500546, 23.476519, -6.046327, 5.3291693, 23.119432, -5.7123218, 5.753208, 23.741987, -6.046327, 5.3291693, 23.119432, -5.917007, 5.5500546, 23.476519, -6.244391, 5.2299757, 23.296265, -6.046327, 5.3291693, 23.119432, -6.244391, 5.2299757, 23.296265, -6.210569, 5.21813, 23.159012, -5.7123218, 5.753208, 23.741987, -6.2491727, 5.318202, 23.382605, -5.917007, 5.5500546, 23.476519, -5.7123218, 5.753208, 23.741987, -6.2826037, 5.3541317, 23.53723, -6.2491727, 5.318202, 23.382605, -5.3022, 5.4230766, 23.628416, -5.154279, 5.307758, 23.83554, -5.7123218, 5.753208, 23.741987, -5.3022, 5.4230766, 23.628416, -5.1251884, 5.2768984, 23.701454, -5.154279, 5.307758, 23.83554, -5.857347, 5.7116084, 24.363003, -6.1099467, 5.52, 23.893438, -5.7123218, 5.753208, 23.741987, -6.1099467, 5.52, 23.893438, -5.857347, 5.7116084, 24.363003, -6.2981954, 5.4044847, 24.163559, -6.1099467, 5.52, 23.893438, -6.2981954, 5.4044847, 24.163559, -6.291105, 5.3954716, 23.937151, -5.577439, 5.6020293, 24.084873, -5.154279, 5.307758, 23.83554, -5.3127255, 5.301915, 24.168657, -5.577439, 5.6020293, 24.084873, -5.7123218, 5.753208, 23.741987, -5.154279, 5.307758, 23.83554, -6.00098, 5.4485216, 24.902779, -6.076615, 5.5257673, 24.45499, -5.857347, 5.7116084, 24.363003, -6.076615, 5.5257673, 24.45499, -6.00098, 5.4485216, 24.902779, -6.1017814, 5.3846993, 24.875137, -6.076615, 5.5257673, 24.45499, -6.1017814, 5.3846993, 24.875137, -6.184852, 5.4140406, 24.567734, -5.24503, 5.200137, 22.848965, -5.0281267, 5.1566877, 23.240654, -5.5580716, 5.554124, 23.009472, -5.24503, 5.200137, 22.848965, -5.0552382, 5.0847697, 22.992046, -5.0281267, 5.1566877, 23.240654, -5.1995373, 5.0887403, 22.666178, -5.0783086, 4.9989347, 22.825645, -5.24503, 5.200137, 22.848965, -5.1995373, 5.0887403, 22.666178, -5.0852733, 4.9907217, 22.742779, -5.0783086, 4.9989347, 22.825645, -5.1995373, 5.0887403, 22.666178, -5.439855, 5.177844, 22.396505, -5.102995, 4.9489727, 22.570704, -5.291579, 4.922532, 22.195475, -5.102995, 4.9489727, 22.570704, -5.439855, 5.177844, 22.396505, -5.291579, 4.922532, 22.195475, -5.163247, 4.866782, 22.303133, -5.102995, 4.9489727, 22.570704, -5.488422, 5.4559135, 25.067163, -6.115338, 5.4586115, 24.851, -6.0311418, 5.4854546, 24.766218, -5.488422, 5.4559135, 25.067163, -5.8165927, 5.2966948, 25.486755, -6.115338, 5.4586115, 24.851, -5.37565, 5.0100093, 24.717901, -5.60895, 5.3052464, 24.837267, -5.5913396, 5.1425714, 24.705996, -5.37565, 5.0100093, 24.717901, -5.488422, 5.4559135, 25.067163, -5.60895, 5.3052464, 24.837267, -3.997026, 3.4084823, 26.23418, -4.2373033, 4.0717287, 26.033955, -4.2301164, 3.8139224, 25.675167, -3.997026, 3.4084823, 26.23418, -4.010387, 3.441938, 26.303183, -4.2373033, 4.0717287, 26.033955, -4.2373033, 4.0717287, 26.033955, -4.3043237, 3.923424, 25.547739, -4.2301164, 3.8139224, 25.675167, -4.2373033, 4.0717287, 26.033955, -4.351472, 4.177483, 25.700325, -4.3043237, 3.923424, 25.547739, -4.351472, 4.177483, 25.700325, -4.2373033, 4.0717287, 26.033955, -4.5209985, 4.6817417, 25.74504, -4.351472, 4.177483, 25.700325, -4.5209985, 4.6817417, 25.74504, -4.504621, 4.2121515, 25.204073, -4.351472, 4.177483, 25.700325, -4.504621, 4.2121515, 25.204073, -4.3712316, 4.021261, 25.432993, -4.504621, 4.2121515, 25.204073, -4.6092005, 4.455448, 25.259403, -4.5602574, 4.259628, 25.160809, -4.504621, 4.2121515, 25.204073, -4.5209985, 4.6817417, 25.74504, -4.6092005, 4.455448, 25.259403, -4.8856854, 4.646908, 24.917786, -5.1403203, 5.003999, 24.975368, -5.0130434, 4.735046, 24.86499, -4.8856854, 4.646908, 24.917786, -4.988566, 5.1979246, 25.387373, -5.1403203, 5.003999, 24.975368, -4.0683527, 3.4522138, 26.357347, -4.2373033, 4.0717287, 26.033955, -4.010387, 3.441938, 26.303183, -4.2373033, 4.0717287, 26.033955, -4.0683527, 3.4522138, 26.357347, -4.242745, 3.782452, 26.231682, -4.242745, 3.782452, 26.231682, -4.0683527, 3.4522138, 26.357347, -4.2885528, 3.6797438, 26.329477, -4.2373033, 4.0717287, 26.033955, -4.656346, 4.3628387, 26.08645, -4.5209985, 4.6817417, 25.74504, -4.2373033, 4.0717287, 26.033955, -4.57377, 4.1835814, 26.181997, -4.656346, 4.3628387, 26.08645, -5.062138, 4.5712886, 26.17474, -4.988566, 5.1979246, 25.387373, -4.5209985, 4.6817417, 25.74504, -4.988566, 5.1979246, 25.387373, -5.062138, 4.5712886, 26.17474, -5.2679048, 4.7707634, 26.016972, -4.988566, 5.1979246, 25.387373, -5.2679048, 4.7707634, 26.016972, -5.1766024, 4.9423556, 25.806808, -5.3932915, 5.275302, 25.41678, -5.488422, 5.4559135, 25.067163, -4.988566, 5.1979246, 25.387373, -5.488422, 5.4559135, 25.067163, -5.3932915, 5.275302, 25.41678, -5.7287784, 5.236825, 25.581738, -5.488422, 5.4559135, 25.067163, -5.7287784, 5.236825, 25.581738, -5.8165927, 5.2966948, 25.486755, -4.988566, 5.1979246, 25.387373, -4.6092005, 4.455448, 25.259403, -4.5209985, 4.6817417, 25.74504, -4.825552, 4.8508716, 25.277138, -4.6092005, 4.455448, 25.259403, -4.988566, 5.1979246, 25.387373, -4.6092005, 4.455448, 25.259403, -4.825552, 4.8508716, 25.277138, -4.749141, 4.4242043, 25.014292, -4.6092005, 4.455448, 25.259403, -4.749141, 4.4242043, 25.014292, -4.653323, 4.3502817, 25.089447, -4.988566, 5.1979246, 25.387373, -4.784744, 4.543359, 24.994701, -4.825552, 4.8508716, 25.277138, -4.988566, 5.1979246, 25.387373, -4.8856854, 4.646908, 24.917786, -4.784744, 4.543359, 24.994701, -5.1766024, 4.9423556, 25.806808, -5.4469156, 4.981415, 25.883078, -4.988566, 5.1979246, 25.387373, -5.1766024, 4.9423556, 25.806808, -5.3591576, 4.891834, 25.949957, -5.4469156, 4.981415, 25.883078, -5.488422, 5.4559135, 25.067163, -5.1403203, 5.003999, 24.975368, -4.988566, 5.1979246, 25.387373, -5.1403203, 5.003999, 24.975368, -5.488422, 5.4559135, 25.067163, -5.37565, 5.0100093, 24.717901, -5.1403203, 5.003999, 24.975368, -5.37565, 5.0100093, 24.717901, -5.1955976, 4.8869286, 24.792862, -5.3932915, 5.275302, 25.41678, -5.4469156, 4.981415, 25.883078, -5.6794295, 5.1171756, 25.630447, -5.3932915, 5.275302, 25.41678, -4.988566, 5.1979246, 25.387373, -5.4469156, 4.981415, 25.883078, -6.0311418, 5.4854546, 24.766218, -5.60895, 5.3052464, 24.837267, -5.488422, 5.4559135, 25.067163, -5.60895, 5.3052464, 24.837267, -6.0311418, 5.4854546, 24.766218, -6.01732, 5.3982096, 24.681461, -5.60895, 5.3052464, 24.837267, -6.01732, 5.3982096, 24.681461, -5.733069, 5.248727, 24.701923, -4.656346, 4.3628387, 26.08645, -5.062138, 4.5712886, 26.17474, -4.5209985, 4.6817417, 25.74504, -4.656346, 4.3628387, 26.08645, -4.8856683, 4.377059, 26.22222, -5.062138, 4.5712886, 26.17474, -4.57377, 4.1835814, 26.181997, -4.779701, 4.213683, 26.243425, -4.656346, 4.3628387, 26.08645, -4.57377, 4.1835814, 26.181997, -4.715779, 4.162856, 26.263649, -4.779701, 4.213683, 26.243425, -4.57377, 4.1835814, 26.181997, -4.2373033, 4.0717287, 26.033955, -4.590958, 4.0354905, 26.29871, -4.242745, 3.782452, 26.231682, -4.590958, 4.0354905, 26.29871, -4.2373033, 4.0717287, 26.033955, -4.242745, 3.782452, 26.231682, -4.395331, 3.8163853, 26.320553, -4.590958, 4.0354905, 26.29871, -6.1042504, 1.2728562, 23.197392, -5.918094, 2.7018955, 23.690025, -5.9148564, 2.7549148, 23.524578, -6.1042504, 1.2728562, 23.197392, -6.1098676, 1.2173094, 23.399563, -5.918094, 2.7018955, 23.690025, -6.4102006, -0.38891935, 23.115858, -6.1098676, 1.2173094, 23.399563, -6.1042504, 1.2728562, 23.197392, -6.4102006, -0.38891935, 23.115858, -6.407615, -0.42018914, 23.34877, -6.1098676, 1.2173094, 23.399563, -6.445969, 1.214475, 23.560837, -6.334398, 2.7400944, 23.713541, -6.206943, 2.6917243, 23.821266, -6.445969, 1.214475, 23.560837, -6.593639, 1.2685848, 23.43337, -6.334398, 2.7400944, 23.713541, -6.45285, 1.3504215, 23.077362, -6.04308, 2.8031602, 23.417374, -6.2159896, 2.8219187, 23.420893, -6.45285, 1.3504215, 23.077362, -6.2506223, 1.3273255, 23.06642, -6.04308, 2.8031602, 23.417374, -6.206943, 2.6917243, 23.821266, -6.1571717, 4.087394, 24.238876, -6.071984, 4.053143, 24.309086, -6.206943, 2.6917243, 23.821266, -6.334398, 2.7400944, 23.713541, -6.1571717, 4.087394, 24.238876, -5.9148564, 2.7549148, 23.524578, -5.878671, 4.066166, 24.22505, -5.875483, 4.1052194, 24.1148, -5.9148564, 2.7549148, 23.524578, -5.918094, 2.7018955, 23.690025, -5.878671, 4.066166, 24.22505, -5.875483, 4.1052194, 24.1148, -5.878671, 4.066166, 24.22505, -5.8760715, 4.7822523, 24.560642, -5.875483, 4.1052194, 24.1148, -5.8760715, 4.7822523, 24.560642, -5.8734727, 4.8202696, 24.482874, -6.1098676, 1.2173094, 23.399563, -6.0342355, 2.6733067, 23.816893, -5.918094, 2.7018955, 23.690025, -6.1098676, 1.2173094, 23.399563, -6.2450395, 1.1910194, 23.5534, -6.0342355, 2.6733067, 23.816893, -5.918094, 2.7018955, 23.690025, -6.0342355, 2.6733067, 23.816893, -5.9568696, 4.0428257, 24.307844, -5.918094, 2.7018955, 23.690025, -5.9568696, 4.0428257, 24.307844, -5.878671, 4.066166, 24.22505, -6.593639, 1.2685848, 23.43337, -6.3314233, 2.7938638, 23.547709, -6.334398, 2.7400944, 23.713541, -6.593639, 1.2685848, 23.43337, -6.589192, 1.3239617, 23.234522, -6.3314233, 2.7938638, 23.547709, -6.334398, 2.7400944, 23.713541, -6.3314233, 2.7938638, 23.547709, -6.1551642, 4.1276875, 24.129848, -6.334398, 2.7400944, 23.713541, -6.1551642, 4.1276875, 24.129848, -6.1571717, 4.087394, 24.238876, -6.2159896, 2.8219187, 23.420893, -5.9612355, 4.1389728, 24.042906, -6.0775657, 4.150184, 24.04522, -6.2159896, 2.8219187, 23.420893, -6.04308, 2.8031602, 23.417374, -5.9612355, 4.1389728, 24.042906, -6.2506223, 1.3273255, 23.06642, -5.9148564, 2.7549148, 23.524578, -6.04308, 2.8031602, 23.417374, -6.2506223, 1.3273255, 23.06642, -6.1042504, 1.2728562, 23.197392, -5.9148564, 2.7549148, 23.524578, -6.04308, 2.8031602, 23.417374, -5.875483, 4.1052194, 24.1148, -5.9612355, 4.1389728, 24.042906, -6.04308, 2.8031602, 23.417374, -5.9148564, 2.7549148, 23.524578, -5.875483, 4.1052194, 24.1148, -6.589192, 1.3239617, 23.234522, -6.2159896, 2.8219187, 23.420893, -6.3314233, 2.7938638, 23.547709, -6.589192, 1.3239617, 23.234522, -6.45285, 1.3504215, 23.077362, -6.2159896, 2.8219187, 23.420893, -6.971047, -0.29482222, 23.15477, -6.45285, 1.3504215, 23.077362, -6.589192, 1.3239617, 23.234522, -6.971047, -0.29482222, 23.15477, -6.8199706, -0.29774308, 22.974768, -6.45285, 1.3504215, 23.077362, -6.3314233, 2.7938638, 23.547709, -6.0775657, 4.150184, 24.04522, -6.1551642, 4.1276875, 24.129848, -6.3314233, 2.7938638, 23.547709, -6.2159896, 2.8219187, 23.420893, -6.0775657, 4.150184, 24.04522, -6.1551642, 4.1276875, 24.129848, -6.0775657, 4.150184, 24.04522, -6.023566, 4.8536663, 24.431192, -6.1551642, 4.1276875, 24.129848, -6.023566, 4.8536663, 24.431192, -6.082048, 4.828084, 24.48972, -6.020826, 4.7619505, 24.618555, -5.936191, 5.2892733, 24.899128, -5.934734, 4.757289, 24.618954, -6.020826, 4.7619505, 24.618555, -5.999312, 5.2915688, 24.898323, -5.936191, 5.2892733, 24.899128, -5.8760715, 4.7822523, 24.560642, -5.8913436, 5.3461533, 24.805635, -5.8734727, 4.8202696, 24.482874, -5.8760715, 4.7822523, 24.560642, -5.8932214, 5.3139095, 24.859932, -5.8913436, 5.3461533, 24.805635, -5.934734, 4.757289, 24.618954, -5.8932214, 5.3139095, 24.859932, -5.8760715, 4.7822523, 24.560642, -5.934734, 4.757289, 24.618954, -5.936191, 5.2892733, 24.899128, -5.8932214, 5.3139095, 24.859932, -5.9370246, 4.8486996, 24.431229, -6.000772, 5.3705015, 24.767956, -6.023566, 4.8536663, 24.431192, -5.9370246, 4.8486996, 24.431229, -5.937638, 5.3697376, 24.769716, -6.000772, 5.3705015, 24.767956, -5.8734727, 4.8202696, 24.482874, -5.937638, 5.3697376, 24.769716, -5.9370246, 4.8486996, 24.431229, -5.8734727, 4.8202696, 24.482874, -5.8913436, 5.3461533, 24.805635, -5.937638, 5.3697376, 24.769716, -6.082048, 4.828084, 24.48972, -6.0456195, 5.3136215, 24.86145, -6.0841565, 4.790536, 24.567505, -6.082048, 4.828084, 24.48972, -6.0437293, 5.3473988, 24.80811, -6.0456195, 5.3136215, 24.86145, -6.023566, 4.8536663, 24.431192, -6.0437293, 5.3473988, 24.80811, -6.082048, 4.828084, 24.48972, -6.023566, 4.8536663, 24.431192, -6.000772, 5.3705015, 24.767956, -6.0437293, 5.3473988, 24.80811, -6.5591636, -0.41737175, 23.530104, -6.445969, 1.214475, 23.560837, -6.2450395, 1.1910194, 23.5534, -6.5591636, -0.41737175, 23.530104, -6.791864, -0.37708354, 23.536917, -6.445969, 1.214475, 23.560837, -6.0841565, 4.790536, 24.567505, -5.999312, 5.2915688, 24.898323, -6.020826, 4.7619505, 24.618555, -6.0841565, 4.790536, 24.567505, -6.0456195, 5.3136215, 24.86145, -5.999312, 5.2915688, 24.898323, -6.2450395, 1.1910194, 23.5534, -6.206943, 2.6917243, 23.821266, -6.0342355, 2.6733067, 23.816893, -6.2450395, 1.1910194, 23.5534, -6.445969, 1.214475, 23.560837, -6.206943, 2.6917243, 23.821266, -6.791864, -0.37708354, 23.536917, -6.593639, 1.2685848, 23.43337, -6.445969, 1.214475, 23.560837, -6.791864, -0.37708354, 23.536917, -6.9689336, -0.32619548, 23.389013, -6.593639, 1.2685848, 23.43337, -6.8199706, -0.29774308, 22.974768, -6.2506223, 1.3273255, 23.06642, -6.45285, 1.3504215, 23.077362, -6.8199706, -0.29774308, 22.974768, -6.5876184, -0.33810782, 22.968916, -6.2506223, 1.3273255, 23.06642, -6.407615, -0.42018914, 23.34877, -6.2450395, 1.1910194, 23.5534, -6.1098676, 1.2173094, 23.399563, -6.407615, -0.42018914, 23.34877, -6.5591636, -0.41737175, 23.530104, -6.2450395, 1.1910194, 23.5534, -6.9689336, -0.32619548, 23.389013, -6.589192, 1.3239617, 23.234522, -6.593639, 1.2685848, 23.43337, -6.9689336, -0.32619548, 23.389013, -6.971047, -0.29482222, 23.15477, -6.589192, 1.3239617, 23.234522, -6.5876184, -0.33810782, 22.968916, -6.1042504, 1.2728562, 23.197392, -6.2506223, 1.3273255, 23.06642, -6.5876184, -0.33810782, 22.968916, -6.4102006, -0.38891935, 23.115858, -6.1042504, 1.2728562, 23.197392, -6.0342355, 2.6733067, 23.816893, -6.071984, 4.053143, 24.309086, -5.9568696, 4.0428257, 24.307844, -6.0342355, 2.6733067, 23.816893, -6.206943, 2.6917243, 23.821266, -6.071984, 4.053143, 24.309086, -5.9568696, 4.0428257, 24.307844, -6.020826, 4.7619505, 24.618555, -5.934734, 4.757289, 24.618954, -5.9568696, 4.0428257, 24.307844, -6.071984, 4.053143, 24.309086, -6.020826, 4.7619505, 24.618555, -6.071984, 4.053143, 24.309086, -6.0841565, 4.790536, 24.567505, -6.020826, 4.7619505, 24.618555, -6.071984, 4.053143, 24.309086, -6.1571717, 4.087394, 24.238876, -6.0841565, 4.790536, 24.567505, -5.878671, 4.066166, 24.22505, -5.934734, 4.757289, 24.618954, -5.8760715, 4.7822523, 24.560642, -5.878671, 4.066166, 24.22505, -5.9568696, 4.0428257, 24.307844, -5.934734, 4.757289, 24.618954, -6.0775657, 4.150184, 24.04522, -5.9370246, 4.8486996, 24.431229, -6.023566, 4.8536663, 24.431192, -6.0775657, 4.150184, 24.04522, -5.9612355, 4.1389728, 24.042906, -5.9370246, 4.8486996, 24.431229, -5.9612355, 4.1389728, 24.042906, -5.8734727, 4.8202696, 24.482874, -5.9370246, 4.8486996, 24.431229, -5.9612355, 4.1389728, 24.042906, -5.875483, 4.1052194, 24.1148, -5.8734727, 4.8202696, 24.482874, -6.1571717, 4.087394, 24.238876, -6.082048, 4.828084, 24.48972, -6.0841565, 4.790536, 24.567505, -6.1571717, 4.087394, 24.238876, -6.1551642, 4.1276875, 24.129848, -6.082048, 4.828084, 24.48972, -7.3456454, 4.1475077, 21.98113, -7.7547154, 4.0165606, 21.935587, -7.73344, 4.0729046, 21.883982, -7.3456454, 4.1475077, 21.98113, -7.39551, 3.8681917, 22.222395, -7.7547154, 4.0165606, 21.935587, -7.2885756, 4.023938, 21.648745, -7.4439178, 4.086134, 21.816298, -7.4376407, 4.0358357, 21.702383, -7.2885756, 4.023938, 21.648745, -7.3456454, 4.1475077, 21.98113, -7.4439178, 4.086134, 21.816298, -5.835222, 3.136388, 22.094479, -6.143434, 3.5016217, 22.14021, -6.182443, 3.446207, 21.86201, -5.835222, 3.136388, 22.094479, -5.831487, 3.134635, 22.146042, -6.143434, 3.5016217, 22.14021, -6.143434, 3.5016217, 22.14021, -6.276529, 3.5192416, 21.814625, -6.182443, 3.446207, 21.86201, -6.143434, 3.5016217, 22.14021, -6.311259, 3.6133804, 21.96652, -6.276529, 3.5192416, 21.814625, -6.311259, 3.6133804, 21.96652, -6.143434, 3.5016217, 22.14021, -6.488027, 3.838162, 22.121197, -6.311259, 3.6133804, 21.96652, -6.488027, 3.838162, 22.121197, -6.5290217, 3.7089415, 21.687683, -6.311259, 3.6133804, 21.96652, -6.5290217, 3.7089415, 21.687683, -6.3611083, 3.5839481, 21.772032, -6.5290217, 3.7089415, 21.687683, -6.61853, 3.8050375, 21.778206, -6.5801196, 3.7298079, 21.680998, -6.5290217, 3.7089415, 21.687683, -6.488027, 3.838162, 22.121197, -6.61853, 3.8050375, 21.778206, -6.895559, 3.9183722, 21.635805, -7.089803, 4.029269, 21.773304, -6.996865, 3.9430032, 21.63935, -6.895559, 3.9183722, 21.635805, -6.936025, 4.07687, 22.060637, -7.089803, 4.029269, 21.773304, -5.852432, 3.11117, 22.186768, -6.143434, 3.5016217, 22.14021, -5.831487, 3.134635, 22.146042, -6.143434, 3.5016217, 22.14021, -5.852432, 3.11117, 22.186768, -6.0435195, 3.2870784, 22.199028, -6.0435195, 3.2870784, 22.199028, -5.852432, 3.11117, 22.186768, -6.0259957, 3.1908565, 22.246626, -6.143434, 3.5016217, 22.14021, -6.4199605, 3.5414572, 22.270983, -6.488027, 3.838162, 22.121197, -6.143434, 3.5016217, 22.14021, -6.316384, 3.4395418, 22.283651, -6.4199605, 3.5414572, 22.270983, -6.6648736, 3.5251694, 22.411572, -6.936025, 4.07687, 22.060637, -6.488027, 3.838162, 22.121197, -6.936025, 4.07687, 22.060637, -6.6648736, 3.5251694, 22.411572, -6.8574367, 3.616784, 22.385473, -6.936025, 4.07687, 22.060637, -6.8574367, 3.616784, 22.385473, -6.8897033, 3.7860932, 22.274248, -7.1705127, 3.995197, 22.128761, -7.3456454, 4.1475077, 21.98113, -6.936025, 4.07687, 22.060637, -7.3456454, 4.1475077, 21.98113, -7.1705127, 3.995197, 22.128761, -7.311005, 3.8388238, 22.254168, -7.3456454, 4.1475077, 21.98113, -7.311005, 3.8388238, 22.254168, -7.39551, 3.8681917, 22.222395, -6.936025, 4.07687, 22.060637, -6.61853, 3.8050375, 21.778206, -6.488027, 3.838162, 22.121197, -6.808315, 3.9616337, 21.892696, -6.61853, 3.8050375, 21.778206, -6.936025, 4.07687, 22.060637, -6.61853, 3.8050375, 21.778206, -6.808315, 3.9616337, 21.892696, -6.754091, 3.8023548, 21.658047, -6.61853, 3.8050375, 21.778206, -6.754091, 3.8023548, 21.658047, -6.667336, 3.7712486, 21.66921, -6.936025, 4.07687, 22.060637, -6.8002677, 3.871698, 21.648817, -6.808315, 3.9616337, 21.892696, -6.936025, 4.07687, 22.060637, -6.895559, 3.9183722, 21.635805, -6.8002677, 3.871698, 21.648817, -6.8897033, 3.7860932, 22.274248, -7.0301766, 3.7129135, 22.36113, -6.936025, 4.07687, 22.060637, -6.8897033, 3.7860932, 22.274248, -6.94754, 3.6726983, 22.372395, -7.0301766, 3.7129135, 22.36113, -7.3456454, 4.1475077, 21.98113, -7.089803, 4.029269, 21.773304, -6.936025, 4.07687, 22.060637, -7.089803, 4.029269, 21.773304, -7.3456454, 4.1475077, 21.98113, -7.2885756, 4.023938, 21.648745, -7.089803, 4.029269, 21.773304, -7.2885756, 4.023938, 21.648745, -7.145592, 3.9925408, 21.643513, -7.1705127, 3.995197, 22.128761, -7.0301766, 3.7129135, 22.36113, -7.250442, 3.7801287, 22.278788, -7.1705127, 3.995197, 22.128761, -6.936025, 4.07687, 22.060637, -7.0301766, 3.7129135, 22.36113, -7.73344, 4.0729046, 21.883982, -7.4439178, 4.086134, 21.816298, -7.3456454, 4.1475077, 21.98113, -7.4439178, 4.086134, 21.816298, -7.73344, 4.0729046, 21.883982, -7.730845, 4.0477705, 21.8088, -7.4439178, 4.086134, 21.816298, -7.730845, 4.0477705, 21.8088, -7.537543, 4.047288, 21.737965, -6.4199605, 3.5414572, 22.270983, -6.6648736, 3.5251694, 22.411572, -6.488027, 3.838162, 22.121197, -6.4199605, 3.5414572, 22.270983, -6.5177665, 3.4538927, 22.380463, -6.6648736, 3.5251694, 22.411572, -6.316384, 3.4395418, 22.283651, -6.4231963, 3.3844132, 22.362364, -6.4199605, 3.5414572, 22.270983, -6.316384, 3.4395418, 22.283651, -6.372542, 3.369453, 22.350878, -6.4231963, 3.3844132, 22.362364, -6.316384, 3.4395418, 22.283651, -6.143434, 3.5016217, 22.14021, -6.269735, 3.3225741, 22.32892, -6.0435195, 3.2870784, 22.199028, -6.269735, 3.3225741, 22.32892, -6.143434, 3.5016217, 22.14021, -6.0435195, 3.2870784, 22.199028, -6.1135287, 3.244587, 22.275616, -6.269735, 3.3225741, 22.32892, -8.006098, 4.0689516, 22.13492, -7.6670833, 4.0418825, 21.783504, -7.640471, 4.0882125, 21.854998, -8.006098, 4.0689516, 22.13492, -8.1642685, 3.8312206, 21.842627, -7.6670833, 4.0418825, 21.783504, -7.756726, 3.8452916, 22.38111, -7.7926917, 3.9996805, 22.145943, -7.6962695, 3.9147148, 22.219965, -7.756726, 3.8452916, 22.38111, -8.006098, 4.0689516, 22.13492, -7.7926917, 3.9996805, 22.145943, -9.112757, 2.5434918, 23.142544, -8.955492, 3.0269203, 22.925161, -8.686771, 2.9242716, 23.071201, -9.112757, 2.5434918, 23.142544, -9.159386, 2.5504227, 23.109524, -8.955492, 3.0269203, 22.925161, -8.955492, 3.0269203, 22.925161, -8.584085, 3.0207791, 23.038433, -8.686771, 2.9242716, 23.071201, -8.955492, 3.0269203, 22.925161, -8.695301, 3.1616163, 22.923185, -8.584085, 3.0207791, 23.038433, -8.695301, 3.1616163, 22.923185, -8.955492, 3.0269203, 22.925161, -8.715704, 3.4878736, 22.713732, -8.695301, 3.1616163, 22.923185, -8.715704, 3.4878736, 22.713732, -8.307899, 3.2759342, 22.950727, -8.695301, 3.1616163, 22.923185, -8.307899, 3.2759342, 22.950727, -8.491686, 3.1070724, 23.009012, -8.307899, 3.2759342, 22.950727, -8.328896, 3.4248629, 22.82755, -8.266613, 3.3116674, 22.91728, -8.307899, 3.2759342, 22.950727, -8.715704, 3.4878736, 22.713732, -8.328896, 3.4248629, 22.82755, -8.018351, 3.603071, 22.708073, -8.005375, 3.8135586, 22.46657, -7.9505553, 3.661367, 22.623951, -8.018351, 3.603071, 22.708073, -8.361177, 3.876412, 22.41829, -8.005375, 3.8135586, 22.46657, -9.178247, 2.5394235, 23.05604, -8.955492, 3.0269203, 22.925161, -9.159386, 2.5504227, 23.109524, -8.955492, 3.0269203, 22.925161, -9.178247, 2.5394235, 23.05604, -9.064192, 2.7795045, 22.919472, -9.064192, 2.7795045, 22.919472, -9.178247, 2.5394235, 23.05604, -9.110924, 2.6796026, 22.880608, -8.955492, 3.0269203, 22.925161, -8.875946, 3.1743643, 22.591955, -8.715704, 3.4878736, 22.713732, -8.955492, 3.0269203, 22.925161, -8.9538765, 3.0363877, 22.650652, -8.875946, 3.1743643, 22.591955, -8.822695, 3.2558434, 22.270594, -8.361177, 3.876412, 22.41829, -8.715704, 3.4878736, 22.713732, -8.361177, 3.876412, 22.41829, -8.822695, 3.2558434, 22.270594, -8.668564, 3.40597, 22.14398, -8.361177, 3.876412, 22.41829, -8.668564, 3.40597, 22.14398, -8.56176, 3.58513, 22.231379, -8.250622, 3.8801494, 22.13827, -8.006098, 4.0689516, 22.13492, -8.361177, 3.876412, 22.41829, -8.006098, 4.0689516, 22.13492, -8.250622, 3.8801494, 22.13827, -8.250301, 3.7793045, 21.885279, -8.006098, 4.0689516, 22.13492, -8.250301, 3.7793045, 21.885279, -8.1642685, 3.8312206, 21.842627, -8.361177, 3.876412, 22.41829, -8.328896, 3.4248629, 22.82755, -8.715704, 3.4878736, 22.713732, -8.302567, 3.6759555, 22.615335, -8.328896, 3.4248629, 22.82755, -8.361177, 3.876412, 22.41829, -8.328896, 3.4248629, 22.82755, -8.302567, 3.6759555, 22.615335, -8.126291, 3.4355674, 22.803347, -8.328896, 3.4248629, 22.82755, -8.126291, 3.4355674, 22.803347, -8.196812, 3.379901, 22.85993, -8.361177, 3.876412, 22.41829, -8.094337, 3.5251052, 22.770916, -8.302567, 3.6759555, 22.615335, -8.361177, 3.876412, 22.41829, -8.018351, 3.603071, 22.708073, -8.094337, 3.5251052, 22.770916, -8.56176, 3.58513, 22.231379, -8.532204, 3.5644715, 22.029161, -8.361177, 3.876412, 22.41829, -8.56176, 3.58513, 22.231379, -8.598177, 3.497055, 22.083708, -8.532204, 3.5644715, 22.029161, -8.006098, 4.0689516, 22.13492, -8.005375, 3.8135586, 22.46657, -8.361177, 3.876412, 22.41829, -8.005375, 3.8135586, 22.46657, -8.006098, 4.0689516, 22.13492, -7.756726, 3.8452916, 22.38111, -8.005375, 3.8135586, 22.46657, -7.756726, 3.8452916, 22.38111, -7.852491, 3.7639642, 22.499866, -8.250622, 3.8801494, 22.13827, -8.532204, 3.5644715, 22.029161, -8.306704, 3.6845965, 21.918798, -8.250622, 3.8801494, 22.13827, -8.361177, 3.876412, 22.41829, -8.532204, 3.5644715, 22.029161, -7.640471, 4.0882125, 21.854998, -7.7926917, 3.9996805, 22.145943, -8.006098, 4.0689516, 22.13492, -7.7926917, 3.9996805, 22.145943, -7.640471, 4.0882125, 21.854998, -7.576958, 4.04729, 21.902573, -7.7926917, 3.9996805, 22.145943, -7.576958, 4.04729, 21.902573, -7.6565347, 3.9742813, 22.111242, -8.875946, 3.1743643, 22.591955, -8.822695, 3.2558434, 22.270594, -8.715704, 3.4878736, 22.713732, -8.875946, 3.1743643, 22.591955, -8.895857, 3.1287508, 22.405542, -8.822695, 3.2558434, 22.270594, -8.9538765, 3.0363877, 22.650652, -8.940609, 3.017987, 22.493166, -8.875946, 3.1743643, 22.591955, -8.9538765, 3.0363877, 22.650652, -8.9667015, 2.9863772, 22.539291, -8.940609, 3.017987, 22.493166, -8.9538765, 3.0363877, 22.650652, -8.955492, 3.0269203, 22.925161, -9.018259, 2.9038734, 22.63329, -9.064192, 2.7795045, 22.919472, -9.018259, 2.9038734, 22.63329, -8.955492, 3.0269203, 22.925161, -9.064192, 2.7795045, 22.919472, -9.078123, 2.7668862, 22.79162, -9.018259, 2.9038734, 22.63329, -8.007105, 4.2432814, 21.79742, -7.6102357, 3.9935734, 21.830496, -7.6156516, 4.0593348, 21.890636, -8.007105, 4.2432814, 21.79742, -8.03323, 3.9421675, 21.519663, -7.6102357, 3.9935734, 21.830496, -8.098074, 4.0979156, 22.171206, -7.9227233, 4.142306, 21.975924, -7.9388556, 4.0766134, 22.104975, -8.098074, 4.0979156, 22.171206, -8.007105, 4.2432814, 21.79742, -7.9227233, 4.142306, 21.975924, -9.771751, 3.535802, 21.75793, -9.379068, 3.8438268, 21.68758, -9.350674, 3.7584422, 21.997433, -9.771751, 3.535802, 21.75793, -9.776064, 3.537459, 21.700321, -9.379068, 3.8438268, 21.68758, -9.379068, 3.8438268, 21.68758, -9.238958, 3.8097954, 22.04487, -9.350674, 3.7584422, 21.997433, -9.379068, 3.8438268, 21.68758, -9.184797, 3.91052, 21.871664, -9.238958, 3.8097954, 22.04487, -9.184797, 3.91052, 21.871664, -9.379068, 3.8438268, 21.68758, -8.955339, 4.1180353, 21.68752, -9.184797, 3.91052, 21.871664, -8.955339, 4.1180353, 21.68752, -8.938385, 3.9436283, 22.172657, -9.184797, 3.91052, 21.871664, -8.938385, 3.9436283, 22.172657, -9.138344, 3.8554869, 22.087576, -8.938385, 3.9436283, 22.172657, -8.830858, 4.0307946, 22.063833, -8.879677, 3.9519649, 22.17815, -8.938385, 3.9436283, 22.172657, -8.955339, 4.1180353, 21.68752, -8.830858, 4.0307946, 22.063833, -8.525064, 4.0757513, 22.206758, -8.3042145, 4.1594357, 22.040773, -8.414618, 4.077264, 22.197893, -8.525064, 4.0757513, 22.206758, -8.445869, 4.2673163, 21.729216, -8.3042145, 4.1594357, 22.040773, -9.761192, 3.5089111, 21.653206, -9.379068, 3.8438268, 21.68758, -9.776064, 3.537459, 21.700321, -9.379068, 3.8438268, 21.68758, -9.761192, 3.5089111, 21.653206, -9.529911, 3.6422298, 21.627573, -9.529911, 3.6422298, 21.627573, -9.761192, 3.5089111, 21.653206, -9.567165, 3.544581, 21.576538, -9.379068, 3.8438268, 21.68758, -9.097656, 3.8193562, 21.5222, -8.955339, 4.1180353, 21.68752, -9.379068, 3.8438268, 21.68758, -9.2248955, 3.7364876, 21.514492, -9.097656, 3.8193562, 21.5222, -8.856268, 3.7445884, 21.349636, -8.445869, 4.2673163, 21.729216, -8.955339, 4.1180353, 21.68752, -8.445869, 4.2673163, 21.729216, -8.856268, 3.7445884, 21.349636, -8.63674, 3.7917051, 21.369219, -8.445869, 4.2673163, 21.729216, -8.63674, 3.7917051, 21.369219, -8.568174, 3.9699275, 21.489882, -8.232094, 4.130494, 21.637142, -8.007105, 4.2432814, 21.79742, -8.445869, 4.2673163, 21.729216, -8.007105, 4.2432814, 21.79742, -8.232094, 4.130494, 21.637142, -8.128689, 3.9327025, 21.48767, -8.007105, 4.2432814, 21.79742, -8.128689, 3.9327025, 21.48767, -8.03323, 3.9421675, 21.519663, -8.445869, 4.2673163, 21.729216, -8.830858, 4.0307946, 22.063833, -8.955339, 4.1180353, 21.68752, -8.606184, 4.161176, 21.922972, -8.830858, 4.0307946, 22.063833, -8.445869, 4.2673163, 21.729216, -8.830858, 4.0307946, 22.063833, -8.606184, 4.161176, 21.922972, -8.680071, 3.982471, 22.196703, -8.830858, 4.0307946, 22.063833, -8.680071, 3.982471, 22.196703, -8.7803135, 3.9735296, 22.187021, -8.445869, 4.2673163, 21.729216, -8.633348, 4.0487413, 22.19735, -8.606184, 4.161176, 21.922972, -8.445869, 4.2673163, 21.729216, -8.525064, 4.0757513, 22.206758, -8.633348, 4.0487413, 22.19735, -8.568174, 3.9699275, 21.489882, -8.441978, 3.8581774, 21.385015, -8.445869, 4.2673163, 21.729216, -8.568174, 3.9699275, 21.489882, -8.53607, 3.8349931, 21.376839, -8.441978, 3.8581774, 21.385015, -8.007105, 4.2432814, 21.79742, -8.3042145, 4.1594357, 22.040773, -8.445869, 4.2673163, 21.729216, -8.3042145, 4.1594357, 22.040773, -8.007105, 4.2432814, 21.79742, -8.098074, 4.0979156, 22.171206, -8.3042145, 4.1594357, 22.040773, -8.098074, 4.0979156, 22.171206, -8.254183, 4.096847, 22.18368, -8.232094, 4.130494, 21.637142, -8.441978, 3.8581774, 21.385015, -8.191664, 3.867425, 21.469576, -8.232094, 4.130494, 21.637142, -8.445869, 4.2673163, 21.729216, -8.441978, 3.8581774, 21.385015, -7.6156516, 4.0593348, 21.890636, -7.9227233, 4.142306, 21.975924, -8.007105, 4.2432814, 21.79742, -7.9227233, 4.142306, 21.975924, -7.6156516, 4.0593348, 21.890636, -7.62472, 4.0303593, 21.974613, -7.9227233, 4.142306, 21.975924, -7.62472, 4.0303593, 21.974613, -7.833011, 4.0754824, 22.059702, -9.097656, 3.8193562, 21.5222, -8.856268, 3.7445884, 21.349636, -8.955339, 4.1180353, 21.68752, -9.097656, 3.8193562, 21.5222, -9.020979, 3.7032843, 21.39327, -8.856268, 3.7445884, 21.349636, -9.2248955, 3.7364876, 21.514492, -9.123741, 3.6469016, 21.423038, -9.097656, 3.8193562, 21.5222, -9.2248955, 3.7364876, 21.514492, -9.181778, 3.6451564, 21.437378, -9.123741, 3.6469016, 21.423038, -9.2248955, 3.7364876, 21.514492, -9.379068, 3.8438268, 21.68758, -9.29739, 3.622695, 21.467472, -9.529911, 3.6422298, 21.627573, -9.29739, 3.622695, 21.467472, -9.379068, 3.8438268, 21.68758, -9.529911, 3.6422298, 21.627573, -9.471037, 3.5795534, 21.537083, -9.29739, 3.622695, 21.467472, -7.801645, 4.134115, 21.58577, -7.6006274, 4.02651, 21.917599, -7.6581864, 4.072356, 21.931242, -7.801645, 4.134115, 21.58577, -7.559606, 3.912532, 21.485746, -7.6006274, 4.02651, 21.917599, -8.072794, 3.9650502, 21.715675, -7.866752, 4.057515, 21.744825, -7.952191, 3.99135, 21.80066, -8.072794, 3.9650502, 21.715675, -7.801645, 4.134115, 21.58577, -7.866752, 4.057515, 21.744825, -8.445419, 3.1368337, 20.389019, -8.276415, 3.4964035, 20.596956, -8.461891, 3.4085104, 20.773108, -8.445419, 3.1368337, 20.389019, -8.407898, 3.1417727, 20.358862, -8.276415, 3.4964035, 20.596956, -8.276415, 3.4964035, 20.596956, -8.453417, 3.4740689, 20.868896, -8.461891, 3.4085104, 20.773108, -8.276415, 3.4964035, 20.596956, -8.327274, 3.583331, 20.814444, -8.453417, 3.4740689, 20.868896, -8.327274, 3.583331, 20.814444, -8.276415, 3.4964035, 20.596956, -8.134125, 3.821342, 20.866423, -8.327274, 3.583331, 20.814444, -8.134125, 3.821342, 20.866423, -8.4303055, 3.644507, 21.12673, -8.327274, 3.583331, 20.814444, -8.4303055, 3.644507, 21.12673, -8.445759, 3.5321927, 20.955154, -8.4303055, 3.644507, 21.12673, -8.320477, 3.7492816, 21.144423, -8.409815, 3.665008, 21.169518, -8.4303055, 3.644507, 21.12673, -8.134125, 3.821342, 20.866423, -8.320477, 3.7492816, 21.144423, -8.287462, 3.8450718, 21.426939, -8.086512, 3.9769306, 21.499489, -8.231916, 3.8731332, 21.501694, -8.287462, 3.8450718, 21.426939, -7.9577355, 4.0573144, 21.235031, -8.086512, 3.9769306, 21.499489, -8.362757, 3.127033, 20.352093, -8.276415, 3.4964035, 20.596956, -8.407898, 3.1417727, 20.358862, -8.276415, 3.4964035, 20.596956, -8.362757, 3.127033, 20.352093, -8.265045, 3.3001463, 20.48862, -8.265045, 3.3001463, 20.48862, -8.362757, 3.127033, 20.352093, -8.229216, 3.2149067, 20.450375, -8.276415, 3.4964035, 20.596956, -8.026518, 3.5625966, 20.730312, -8.134125, 3.821342, 20.866423, -8.276415, 3.4964035, 20.596956, -8.06389, 3.4651048, 20.64575, -8.026518, 3.5625966, 20.730312, -7.781936, 3.5772128, 20.836325, -7.9577355, 4.0573144, 21.235031, -8.134125, 3.821342, 20.866423, -7.9577355, 4.0573144, 21.235031, -7.781936, 3.5772128, 20.836325, -7.705567, 3.6661596, 20.99604, -7.9577355, 4.0573144, 21.235031, -7.705567, 3.6661596, 20.99604, -7.7892184, 3.8130858, 21.079828, -7.7676377, 4.0055275, 21.369812, -7.801645, 4.134115, 21.58577, -7.9577355, 4.0573144, 21.235031, -7.801645, 4.134115, 21.58577, -7.7676377, 4.0055275, 21.369812, -7.5783267, 3.8855352, 21.404331, -7.801645, 4.134115, 21.58577, -7.5783267, 3.8855352, 21.404331, -7.559606, 3.912532, 21.485746, -7.9577355, 4.0573144, 21.235031, -8.320477, 3.7492816, 21.144423, -8.134125, 3.821342, 20.866423, -8.143465, 3.9182801, 21.225508, -8.320477, 3.7492816, 21.144423, -7.9577355, 4.0573144, 21.235031, -8.320477, 3.7492816, 21.144423, -8.143465, 3.9182801, 21.225508, -8.340118, 3.7362518, 21.314922, -8.320477, 3.7492816, 21.144423, -8.340118, 3.7362518, 21.314922, -8.375259, 3.7055726, 21.241833, -7.9577355, 4.0573144, 21.235031, -8.325062, 3.7988772, 21.348167, -8.143465, 3.9182801, 21.225508, -7.9577355, 4.0573144, 21.235031, -8.287462, 3.8450718, 21.426939, -8.325062, 3.7988772, 21.348167, -7.7892184, 3.8130858, 21.079828, -7.6383195, 3.7634745, 21.137505, -7.9577355, 4.0573144, 21.235031, -7.7892184, 3.8130858, 21.079828, -7.6709933, 3.7234988, 21.069057, -7.6383195, 3.7634745, 21.137505, -7.801645, 4.134115, 21.58577, -8.086512, 3.9769306, 21.499489, -7.9577355, 4.0573144, 21.235031, -8.086512, 3.9769306, 21.499489, -7.801645, 4.134115, 21.58577, -8.072794, 3.9650502, 21.715675, -8.086512, 3.9769306, 21.499489, -8.072794, 3.9650502, 21.715675, -8.151386, 3.9267366, 21.61004, -7.7676377, 4.0055275, 21.369812, -7.6383195, 3.7634745, 21.137505, -7.588919, 3.823454, 21.350895, -7.7676377, 4.0055275, 21.369812, -7.9577355, 4.0573144, 21.235031, -7.6383195, 3.7634745, 21.137505, -7.6581864, 4.072356, 21.931242, -7.866752, 4.057515, 21.744825, -7.801645, 4.134115, 21.58577, -7.866752, 4.057515, 21.744825, -7.6581864, 4.072356, 21.931242, -7.71435, 4.039794, 21.968426, -7.866752, 4.057515, 21.744825, -7.71435, 4.039794, 21.968426, -7.87205, 4.018237, 21.856892, -8.026518, 3.5625966, 20.730312, -7.781936, 3.5772128, 20.836325, -8.134125, 3.821342, 20.866423, -8.026518, 3.5625966, 20.730312, -7.8797107, 3.5000882, 20.74282, -7.781936, 3.5772128, 20.836325, -8.06389, 3.4651048, 20.64575, -7.94037, 3.4260588, 20.685284, -8.026518, 3.5625966, 20.730312, -8.06389, 3.4651048, 20.64575, -7.975001, 3.40911, 20.652027, -7.94037, 3.4260588, 20.685284, -8.06389, 3.4651048, 20.64575, -8.276415, 3.4964035, 20.596956, -8.0436325, 3.3592296, 20.586334, -8.265045, 3.3001463, 20.48862, -8.0436325, 3.3592296, 20.586334, -8.276415, 3.4964035, 20.596956, -8.265045, 3.3001463, 20.48862, -8.163176, 3.2732167, 20.498547, -8.0436325, 3.3592296, 20.586334, -7.402509, 4.1859736, 21.63811, -7.6918817, 4.041251, 21.991617, -7.7346835, 4.0696325, 21.918596, -7.402509, 4.1859736, 21.63811, -7.1659408, 4.0452685, 21.938877, -7.6918817, 4.041251, 21.991617, -7.544909, 3.8685284, 21.406876, -7.563997, 4.036748, 21.631306, -7.6227355, 3.9156742, 21.563887, -7.544909, 3.8685284, 21.406876, -7.402509, 4.1859736, 21.63811, -7.563997, 4.036748, 21.631306, -5.9238067, 3.1665137, 20.728191, -6.2251096, 3.5616388, 20.915148, -6.4278474, 3.3525786, 20.777048, -5.9238067, 3.1665137, 20.728191, -5.8848615, 3.193083, 20.760527, -6.2251096, 3.5616388, 20.915148, -6.2251096, 3.5616388, 20.915148, -6.5504594, 3.402594, 20.803858, -6.4278474, 3.3525786, 20.777048, -6.2251096, 3.5616388, 20.915148, -6.4983582, 3.5830135, 20.909115, -6.5504594, 3.402594, 20.803858, -6.4983582, 3.5830135, 20.909115, -6.2251096, 3.5616388, 20.915148, -6.5891337, 3.903202, 21.097126, -6.4983582, 3.5830135, 20.909115, -6.5891337, 3.903202, 21.097126, -6.879663, 3.532806, 20.876286, -6.4983582, 3.5830135, 20.909115, -6.879663, 3.532806, 20.876286, -6.6607127, 3.447071, 20.828083, -6.879663, 3.532806, 20.876286, -6.9066834, 3.6857386, 20.988258, -6.9293284, 3.5507002, 20.90792, -6.879663, 3.532806, 20.876286, -6.5891337, 3.903202, 21.097126, -6.9066834, 3.6857386, 20.988258, -7.2366023, 3.7330508, 21.09622, -7.3143077, 3.9347124, 21.32243, -7.315949, 3.763792, 21.176712, -7.2366023, 3.7330508, 21.09622, -7.02702, 4.1361513, 21.366934, -7.3143077, 3.9347124, 21.32243, -5.862766, 3.1931438, 20.813963, -6.2251096, 3.5616388, 20.915148, -5.8848615, 3.193083, 20.760527, -6.2251096, 3.5616388, 20.915148, -5.862766, 3.1931438, 20.813963, -6.043155, 3.376487, 20.935175, -6.043155, 3.376487, 20.935175, -5.862766, 3.1931438, 20.813963, -5.9688907, 3.3041463, 20.98022, -6.2251096, 3.5616388, 20.915148, -6.3340783, 3.6836305, 21.23523, -6.5891337, 3.903202, 21.097126, -6.2251096, 3.5616388, 20.915148, -6.2198997, 3.5840178, 21.185366, -6.3340783, 3.6836305, 21.23523, -6.400766, 3.7538157, 21.548512, -7.02702, 4.1361513, 21.366934, -6.5891337, 3.903202, 21.097126, -7.02702, 4.1361513, 21.366934, -6.400766, 3.7538157, 21.548512, -6.588054, 3.8369021, 21.666204, -7.02702, 4.1361513, 21.366934, -6.588054, 3.8369021, 21.666204, -6.7412972, 3.9567418, 21.567703, -7.1137557, 4.110402, 21.642786, -7.402509, 4.1859736, 21.63811, -7.02702, 4.1361513, 21.366934, -7.402509, 4.1859736, 21.63811, -7.1137557, 4.110402, 21.642786, -7.0714173, 4.029825, 21.898872, -7.402509, 4.1859736, 21.63811, -7.0714173, 4.029825, 21.898872, -7.1659408, 4.0452685, 21.938877, -7.02702, 4.1361513, 21.366934, -6.9066834, 3.6857386, 20.988258, -6.5891337, 3.903202, 21.097126, -7.0096154, 3.9184318, 21.182732, -6.9066834, 3.6857386, 20.988258, -7.02702, 4.1361513, 21.366934, -6.9066834, 3.6857386, 20.988258, -7.0096154, 3.9184318, 21.182732, -7.098456, 3.6138377, 21.015465, -6.9066834, 3.6857386, 20.988258, -7.098456, 3.6138377, 21.015465, -7.014134, 3.5885832, 20.961206, -7.02702, 4.1361513, 21.366934, -7.1437945, 3.6882315, 21.038242, -7.0096154, 3.9184318, 21.182732, -7.02702, 4.1361513, 21.366934, -7.2366023, 3.7330508, 21.09622, -7.1437945, 3.6882315, 21.038242, -6.7412972, 3.9567418, 21.567703, -6.756685, 3.9355235, 21.769691, -7.02702, 4.1361513, 21.366934, -6.7412972, 3.9567418, 21.567703, -6.6761546, 3.8968792, 21.71939, -6.756685, 3.9355235, 21.769691, -7.402509, 4.1859736, 21.63811, -7.3143077, 3.9347124, 21.32243, -7.02702, 4.1361513, 21.366934, -7.3143077, 3.9347124, 21.32243, -7.402509, 4.1859736, 21.63811, -7.544909, 3.8685284, 21.406876, -7.3143077, 3.9347124, 21.32243, -7.544909, 3.8685284, 21.406876, -7.432817, 3.8261418, 21.293098, -7.1137557, 4.110402, 21.642786, -6.756685, 3.9355235, 21.769691, -7.002805, 3.9603796, 21.87517, -7.1137557, 4.110402, 21.642786, -7.02702, 4.1361513, 21.366934, -6.756685, 3.9355235, 21.769691, -7.7346835, 4.0696325, 21.918596, -7.563997, 4.036748, 21.631306, -7.402509, 4.1859736, 21.63811, -7.563997, 4.036748, 21.631306, -7.7346835, 4.0696325, 21.918596, -7.775924, 4.0044317, 21.873682, -7.563997, 4.036748, 21.631306, -7.775924, 4.0044317, 21.873682, -7.6754994, 3.960377, 21.667994, -6.3340783, 3.6836305, 21.23523, -6.400766, 3.7538157, 21.548512, -6.5891337, 3.903202, 21.097126, -6.3340783, 3.6836305, 21.23523, -6.2958436, 3.6586976, 21.422325, -6.400766, 3.7538157, 21.548512, -6.2198997, 3.5840178, 21.185366, -6.2276845, 3.568183, 21.344408, -6.3340783, 3.6836305, 21.23523, -6.2198997, 3.5840178, 21.185366, -6.1918397, 3.5477042, 21.29962, -6.2276845, 3.568183, 21.344408, -6.2198997, 3.5840178, 21.185366, -6.2251096, 3.5616388, 20.915148, -6.1187816, 3.4875863, 21.210886, -6.043155, 3.376487, 20.935175, -6.1187816, 3.4875863, 21.210886, -6.2251096, 3.5616388, 20.915148, -6.043155, 3.376487, 20.935175, -6.0228896, 3.3768027, 21.062256, -6.1187816, 3.4875863, 21.210886, -7.5309367, 4.1860266, 22.233109, -7.7731357, 4.049283, 21.837759, -7.686767, 4.0676775, 21.824697, -7.5309367, 4.1860266, 22.233109, -7.90918, 4.0913115, 22.343561, -7.7731357, 4.049283, 21.837759, -7.2945504, 3.8389473, 22.203506, -7.4850507, 4.0242515, 22.093157, -7.4099345, 3.8931296, 22.069782, -7.2945504, 3.8389473, 22.203506, -7.5309367, 4.1860266, 22.233109, -7.4850507, 4.0242515, 22.093157, -7.231361, 3.2090497, 23.990551, -7.2794967, 3.594735, 23.623615, -7.099934, 3.3586783, 23.498016, -7.231361, 3.2090497, 23.990551, -7.2722163, 3.2413416, 24.013079, -7.2794967, 3.594735, 23.623615, -7.2794967, 3.594735, 23.623615, -7.0818753, 3.401124, 23.37233, -7.099934, 3.3586783, 23.498016, -7.2794967, 3.594735, 23.623615, -7.1849923, 3.5940344, 23.37246, -7.0818753, 3.401124, 23.37233, -7.1849923, 3.5940344, 23.37246, -7.2794967, 3.594735, 23.623615, -7.3083177, 3.9218946, 23.202938, -7.1849923, 3.5940344, 23.37246, -7.3083177, 3.9218946, 23.202938, -7.0331464, 3.5110173, 23.034817, -7.1849923, 3.5940344, 23.37246, -7.0331464, 3.5110173, 23.034817, -7.0656457, 3.4388018, 23.25929, -7.0331464, 3.5110173, 23.034817, -7.121306, 3.6710267, 22.96056, -7.043958, 3.527542, 22.976107, -7.0331464, 3.5110173, 23.034817, -7.3083177, 3.9218946, 23.202938, -7.121306, 3.6710267, 22.96056, -7.113857, 3.7015529, 22.612543, -7.287684, 3.915894, 22.445786, -7.160318, 3.7328143, 22.507229, -7.113857, 3.7015529, 22.612543, -7.4040046, 4.1427026, 22.68545, -7.287684, 3.915894, 22.445786, -7.3301635, 3.2478483, 24.013186, -7.2794967, 3.594735, 23.623615, -7.2722163, 3.2413416, 24.013079, -7.2794967, 3.594735, 23.623615, -7.3301635, 3.2478483, 24.013186, -7.371898, 3.4266107, 23.792282, -7.371898, 3.4266107, 23.792282, -7.3301635, 3.2478483, 24.013186, -7.442037, 3.3642597, 23.847004, -7.2794967, 3.594735, 23.623615, -7.540323, 3.735655, 23.39579, -7.3083177, 3.9218946, 23.202938, -7.2794967, 3.594735, 23.623615, -7.5373693, 3.641142, 23.524654, -7.540323, 3.735655, 23.39579, -7.8095174, 3.8275523, 23.211908, -7.4040046, 4.1427026, 22.68545, -7.3083177, 3.9218946, 23.202938, -7.4040046, 4.1427026, 22.68545, -7.8095174, 3.8275523, 23.211908, -7.8509803, 3.9055398, 22.990408, -7.4040046, 4.1427026, 22.68545, -7.8509803, 3.9055398, 22.990408, -7.703343, 4.004422, 22.88101, -7.6422763, 4.1345253, 22.501507, -7.5309367, 4.1860266, 22.233109, -7.4040046, 4.1427026, 22.68545, -7.5309367, 4.1860266, 22.233109, -7.6422763, 4.1345253, 22.501507, -7.905112, 4.080037, 22.446768, -7.5309367, 4.1860266, 22.233109, -7.905112, 4.080037, 22.446768, -7.90918, 4.0913115, 22.343561, -7.4040046, 4.1427026, 22.68545, -7.121306, 3.6710267, 22.96056, -7.3083177, 3.9218946, 23.202938, -7.255689, 3.9115663, 22.781116, -7.121306, 3.6710267, 22.96056, -7.4040046, 4.1427026, 22.68545, -7.121306, 3.6710267, 22.96056, -7.255689, 3.9115663, 22.781116, -7.080893, 3.5860498, 22.77619, -7.121306, 3.6710267, 22.96056, -7.080893, 3.5860498, 22.77619, -7.062715, 3.563114, 22.87582, -7.4040046, 4.1427026, 22.68545, -7.0931907, 3.6592827, 22.722273, -7.255689, 3.9115663, 22.781116, -7.4040046, 4.1427026, 22.68545, -7.113857, 3.7015529, 22.612543, -7.0931907, 3.6592827, 22.722273, -7.703343, 4.004422, 22.88101, -7.8892875, 3.9995782, 22.79086, -7.4040046, 4.1427026, 22.68545, -7.703343, 4.004422, 22.88101, -7.8713326, 3.9631367, 22.88616, -7.8892875, 3.9995782, 22.79086, -7.5309367, 4.1860266, 22.233109, -7.287684, 3.915894, 22.445786, -7.4040046, 4.1427026, 22.68545, -7.287684, 3.915894, 22.445786, -7.5309367, 4.1860266, 22.233109, -7.2945504, 3.8389473, 22.203506, -7.287684, 3.915894, 22.445786, -7.2945504, 3.8389473, 22.203506, -7.2290454, 3.7958574, 22.35221, -7.6422763, 4.1345253, 22.501507, -7.8892875, 3.9995782, 22.79086, -7.8991284, 4.0135202, 22.522274, -7.6422763, 4.1345253, 22.501507, -7.4040046, 4.1427026, 22.68545, -7.8892875, 3.9995782, 22.79086, -7.686767, 4.0676775, 21.824697, -7.4850507, 4.0242515, 22.093157, -7.5309367, 4.1860266, 22.233109, -7.4850507, 4.0242515, 22.093157, -7.686767, 4.0676775, 21.824697, -7.63722, 3.9957073, 21.806574, -7.4850507, 4.0242515, 22.093157, -7.63722, 3.9957073, 21.806574, -7.487868, 3.9425092, 21.979464, -7.540323, 3.735655, 23.39579, -7.8095174, 3.8275523, 23.211908, -7.3083177, 3.9218946, 23.202938, -7.540323, 3.735655, 23.39579, -7.7316575, 3.7301946, 23.361069, -7.8095174, 3.8275523, 23.211908, -7.5373693, 3.641142, 23.524654, -7.680619, 3.6382384, 23.457644, -7.540323, 3.735655, 23.39579, -7.5373693, 3.641142, 23.524654, -7.6541924, 3.6169612, 23.508732, -7.680619, 3.6382384, 23.457644, -7.5373693, 3.641142, 23.524654, -7.2794967, 3.594735, 23.623615, -7.599995, 3.5552611, 23.612686, -7.371898, 3.4266107, 23.792282, -7.599995, 3.5552611, 23.612686, -7.2794967, 3.594735, 23.623615, -7.371898, 3.4266107, 23.792282, -7.4989257, 3.4396398, 23.762728, -7.599995, 3.5552611, 23.612686, -6.9064727, 0.8870442, 21.944698, -7.0634227, 1.9859911, 21.955528, -6.983601, 1.9958726, 21.857681, -6.9064727, 0.8870442, 21.944698, -7.0050845, 0.88108003, 22.061377, -7.0634227, 1.9859911, 21.955528, -7.007685, -0.32457638, 22.15034, -7.0050845, 0.88108003, 22.061377, -6.9064727, 0.8870442, 21.944698, -7.007685, -0.32457638, 22.15034, -7.116863, -0.30735517, 22.281223, -7.0050845, 0.88108003, 22.061377, -7.2671094, 0.85050464, 21.996153, -7.3045907, 1.9478768, 21.77239, -7.284966, 1.9531578, 21.8974, -7.2671094, 0.85050464, 21.996153, -7.288546, 0.84261394, 21.850367, -7.3045907, 1.9478768, 21.77239, -7.0425286, 0.86357975, 21.707298, -7.003896, 1.9904655, 21.73263, -7.101132, 1.9756031, 21.652607, -7.0425286, 0.86357975, 21.707298, -6.925528, 0.87903726, 21.79757, -7.003896, 1.9904655, 21.73263, -7.284966, 1.9531578, 21.8974, -7.4806666, 2.9942842, 21.815382, -7.466662, 2.9961905, 21.89844, -7.284966, 1.9531578, 21.8974, -7.3045907, 1.9478768, 21.77239, -7.4806666, 2.9942842, 21.815382, -6.983601, 1.9958726, 21.857681, -7.320312, 3.0230846, 21.937897, -7.2666173, 3.0324101, 21.872292, -6.983601, 1.9958726, 21.857681, -7.0634227, 1.9859911, 21.955528, -7.320312, 3.0230846, 21.937897, -7.2666173, 3.0324101, 21.872292, -7.320312, 3.0230846, 21.937897, -7.4912467, 3.573497, 21.949327, -7.2666173, 3.0324101, 21.872292, -7.4912467, 3.573497, 21.949327, -7.453357, 3.5873647, 21.900778, -7.0050845, 0.88108003, 22.061377, -7.1874385, 1.968081, 21.976803, -7.0634227, 1.9859911, 21.955528, -7.0050845, 0.88108003, 22.061377, -7.15249, 0.8660785, 22.087767, -7.1874385, 1.968081, 21.976803, -7.0634227, 1.9859911, 21.955528, -7.1874385, 1.968081, 21.976803, -7.40249, 3.0077667, 21.95179, -7.0634227, 1.9859911, 21.955528, -7.40249, 3.0077667, 21.95179, -7.320312, 3.0230846, 21.937897, -7.288546, 0.84261394, 21.850367, -7.2247424, 1.9581697, 21.674047, -7.3045907, 1.9478768, 21.77239, -7.288546, 0.84261394, 21.850367, -7.192162, 0.8488163, 21.734951, -7.2247424, 1.9581697, 21.674047, -7.3045907, 1.9478768, 21.77239, -7.2247424, 1.9581697, 21.674047, -7.428226, 3.0044737, 21.749603, -7.3045907, 1.9478768, 21.77239, -7.428226, 3.0044737, 21.749603, -7.4806666, 2.9942842, 21.815382, -7.101132, 1.9756031, 21.652607, -7.2801204, 3.029789, 21.78821, -7.345489, 3.018808, 21.73467, -7.101132, 1.9756031, 21.652607, -7.003896, 1.9904655, 21.73263, -7.2801204, 3.029789, 21.78821, -6.925528, 0.87903726, 21.79757, -6.983601, 1.9958726, 21.857681, -7.003896, 1.9904655, 21.73263, -6.925528, 0.87903726, 21.79757, -6.9064727, 0.8870442, 21.944698, -6.983601, 1.9958726, 21.857681, -7.003896, 1.9904655, 21.73263, -7.2666173, 3.0324101, 21.872292, -7.2801204, 3.029789, 21.78821, -7.003896, 1.9904655, 21.73263, -6.983601, 1.9958726, 21.857681, -7.2666173, 3.0324101, 21.872292, -7.192162, 0.8488163, 21.734951, -7.101132, 1.9756031, 21.652607, -7.2247424, 1.9581697, 21.674047, -7.192162, 0.8488163, 21.734951, -7.0425286, 0.86357975, 21.707298, -7.101132, 1.9756031, 21.652607, -7.3367667, -0.3452804, 21.89752, -7.0425286, 0.86357975, 21.707298, -7.192162, 0.8488163, 21.734951, -7.3367667, -0.3452804, 21.89752, -7.1676164, -0.3521583, 21.871283, -7.0425286, 0.86357975, 21.707298, -7.2247424, 1.9581697, 21.674047, -7.345489, 3.018808, 21.73467, -7.428226, 3.0044737, 21.749603, -7.2247424, 1.9581697, 21.674047, -7.101132, 1.9756031, 21.652607, -7.345489, 3.018808, 21.73467, -7.428226, 3.0044737, 21.749603, -7.345489, 3.018808, 21.73467, -7.5119376, 3.577262, 21.798561, -7.428226, 3.0044737, 21.749603, -7.5119376, 3.577262, 21.798561, -7.5716386, 3.5596325, 21.809055, -7.5982623, 3.5452437, 21.919594, -7.6945357, 3.969666, 21.982683, -7.5509553, 3.5562305, 21.959482, -7.5982623, 3.5452437, 21.919594, -7.7289567, 3.960751, 21.953426, -7.6945357, 3.969666, 21.982683, -7.4912467, 3.573497, 21.949327, -7.6261945, 4.0009108, 21.940428, -7.453357, 3.5873647, 21.900778, -7.4912467, 3.573497, 21.949327, -7.6525865, 3.9872801, 21.975618, -7.6261945, 4.0009108, 21.940428, -7.5509553, 3.5562305, 21.959482, -7.6525865, 3.9872801, 21.975618, -7.4912467, 3.573497, 21.949327, -7.5509553, 3.5562305, 21.959482, -7.6945357, 3.969666, 21.982683, -7.6525865, 3.9872801, 21.975618, -7.4642043, 3.588051, 21.838531, -7.668904, 3.9935448, 21.865906, -7.5119376, 3.577262, 21.798561, -7.4642043, 3.588051, 21.838531, -7.634957, 4.0036774, 21.895311, -7.668904, 3.9935448, 21.865906, -7.453357, 3.5873647, 21.900778, -7.634957, 4.0036774, 21.895311, -7.4642043, 3.588051, 21.838531, -7.453357, 3.5873647, 21.900778, -7.6261945, 4.0009108, 21.940428, -7.634957, 4.0036774, 21.895311, -7.5716386, 3.5596325, 21.809055, -7.737245, 3.9623003, 21.908161, -7.6092744, 3.5461726, 21.857725, -7.5716386, 3.5596325, 21.809055, -7.711328, 3.9771495, 21.873121, -7.737245, 3.9623003, 21.908161, -7.5119376, 3.577262, 21.798561, -7.711328, 3.9771495, 21.873121, -7.5716386, 3.5596325, 21.809055, -7.5119376, 3.577262, 21.798561, -7.668904, 3.9935448, 21.865906, -7.711328, 3.9771495, 21.873121, -7.2869067, -0.3004067, 22.307976, -7.2671094, 0.85050464, 21.996153, -7.15249, 0.8660785, 22.087767, -7.2869067, -0.3004067, 22.307976, -7.4190135, -0.30967426, 22.197882, -7.2671094, 0.85050464, 21.996153, -7.6092744, 3.5461726, 21.857725, -7.7289567, 3.960751, 21.953426, -7.5982623, 3.5452437, 21.919594, -7.6092744, 3.5461726, 21.857725, -7.737245, 3.9623003, 21.908161, -7.7289567, 3.960751, 21.953426, -7.15249, 0.8660785, 22.087767, -7.284966, 1.9531578, 21.8974, -7.1874385, 1.968081, 21.976803, -7.15249, 0.8660785, 22.087767, -7.2671094, 0.85050464, 21.996153, -7.284966, 1.9531578, 21.8974, -7.4190135, -0.30967426, 22.197882, -7.288546, 0.84261394, 21.850367, -7.2671094, 0.85050464, 21.996153, -7.4190135, -0.30967426, 22.197882, -7.446838, -0.32798862, 22.028917, -7.288546, 0.84261394, 21.850367, -7.1676164, -0.3521583, 21.871283, -6.925528, 0.87903726, 21.79757, -7.0425286, 0.86357975, 21.707298, -7.1676164, -0.3521583, 21.871283, -7.036158, -0.3428421, 21.981743, -6.925528, 0.87903726, 21.79757, -7.116863, -0.30735517, 22.281223, -7.15249, 0.8660785, 22.087767, -7.0050845, 0.88108003, 22.061377, -7.116863, -0.30735517, 22.281223, -7.2869067, -0.3004067, 22.307976, -7.15249, 0.8660785, 22.087767, -7.446838, -0.32798862, 22.028917, -7.192162, 0.8488163, 21.734951, -7.288546, 0.84261394, 21.850367, -7.446838, -0.32798862, 22.028917, -7.3367667, -0.3452804, 21.89752, -7.192162, 0.8488163, 21.734951, -7.036158, -0.3428421, 21.981743, -6.9064727, 0.8870442, 21.944698, -6.925528, 0.87903726, 21.79757, -7.036158, -0.3428421, 21.981743, -7.007685, -0.32457638, 22.15034, -6.9064727, 0.8870442, 21.944698, -7.1874385, 1.968081, 21.976803, -7.466662, 2.9961905, 21.89844, -7.40249, 3.0077667, 21.95179, -7.1874385, 1.968081, 21.976803, -7.284966, 1.9531578, 21.8974, -7.466662, 2.9961905, 21.89844, -7.40249, 3.0077667, 21.95179, -7.5982623, 3.5452437, 21.919594, -7.5509553, 3.5562305, 21.959482, -7.40249, 3.0077667, 21.95179, -7.466662, 2.9961905, 21.89844, -7.5982623, 3.5452437, 21.919594, -7.466662, 2.9961905, 21.89844, -7.6092744, 3.5461726, 21.857725, -7.5982623, 3.5452437, 21.919594, -7.466662, 2.9961905, 21.89844, -7.4806666, 2.9942842, 21.815382, -7.6092744, 3.5461726, 21.857725, -7.320312, 3.0230846, 21.937897, -7.5509553, 3.5562305, 21.959482, -7.4912467, 3.573497, 21.949327, -7.320312, 3.0230846, 21.937897, -7.40249, 3.0077667, 21.95179, -7.5509553, 3.5562305, 21.959482, -7.345489, 3.018808, 21.73467, -7.4642043, 3.588051, 21.838531, -7.5119376, 3.577262, 21.798561, -7.345489, 3.018808, 21.73467, -7.2801204, 3.029789, 21.78821, -7.4642043, 3.588051, 21.838531, -7.2801204, 3.029789, 21.78821, -7.453357, 3.5873647, 21.900778, -7.4642043, 3.588051, 21.838531, -7.2801204, 3.029789, 21.78821, -7.2666173, 3.0324101, 21.872292, -7.453357, 3.5873647, 21.900778, -7.4806666, 2.9942842, 21.815382, -7.5716386, 3.5596325, 21.809055, -7.6092744, 3.5461726, 21.857725, -7.4806666, 2.9942842, 21.815382, -7.428226, 3.0044737, 21.749603, -7.5716386, 3.5596325, 21.809055, -25.120148, 13.783545, 12.764626, -26.397978, 13.369994, 12.574373, -26.33375, 13.5643215, 12.432411, -25.120148, 13.783545, 12.764626, -25.263885, 12.827821, 13.423475, -26.397978, 13.369994, 12.574373, -24.933325, 13.512459, 11.685724, -25.424961, 13.642609, 12.2283325, -25.402243, 13.524235, 11.855768, -24.933325, 13.512459, 11.685724, -25.120148, 13.783545, 12.764626, -25.424961, 13.642609, 12.2283325, -20.327318, 10.662638, 12.792898, -21.313543, 11.772419, 13.055622, -21.432056, 11.691162, 12.167927, -20.327318, 10.662638, 12.792898, -20.315731, 10.639986, 12.953346, -21.313543, 11.772419, 13.055622, -21.313543, 11.772419, 13.055622, -21.73093, 11.930523, 12.043638, -21.432056, 11.691162, 12.167927, -21.313543, 11.772419, 13.055622, -21.845343, 12.171588, 12.549276, -21.73093, 11.930523, 12.043638, -21.845343, 12.171588, 12.549276, -21.313543, 11.772419, 13.055622, -22.412296, 12.812631, 13.106188, -21.845343, 12.171588, 12.549276, -22.412296, 12.812631, 13.106188, -22.532686, 12.553142, 11.708666, -21.845343, 12.171588, 12.549276, -22.532686, 12.553142, 11.708666, -21.999557, 12.142736, 11.931597, -22.532686, 12.553142, 11.708666, -22.81894, 12.8182955, 12.022795, -22.69415, 12.618034, 11.694317, -22.532686, 12.553142, 11.708666, -22.412296, 12.812631, 13.106188, -22.81894, 12.8182955, 12.022795, -23.693872, 13.206497, 11.613611, -24.30996, 13.49691, 12.078384, -24.013233, 13.277237, 11.631985, -23.693872, 13.206497, 11.613611, -23.830704, 13.556321, 12.993084, -24.30996, 13.49691, 12.078384, -20.380512, 10.551989, 13.072411, -21.313543, 11.772419, 13.055622, -20.315731, 10.639986, 12.953346, -21.313543, 11.772419, 13.055622, -20.380512, 10.551989, 13.072411, -20.98937, 11.087692, 13.168047, -20.98937, 11.087692, 13.168047, -20.380512, 10.551989, 13.072411, -20.92976, 10.772113, 13.284454, -21.313543, 11.772419, 13.055622, -22.184439, 11.839201, 13.474684, -22.412296, 12.812631, 13.106188, -21.313543, 11.772419, 13.055622, -21.854174, 11.521826, 13.480944, -22.184439, 11.839201, 13.474684, -22.953316, 11.729006, 13.905809, -23.830704, 13.556321, 12.993084, -22.412296, 12.812631, 13.106188, -23.830704, 13.556321, 12.993084, -22.953316, 11.729006, 13.905809, -23.56244, 12.014381, 13.853283, -23.830704, 13.556321, 12.993084, -23.56244, 12.014381, 13.853283, -23.671707, 12.578844, 13.562656, -24.563269, 13.266899, 13.176035, -25.120148, 13.783545, 12.764626, -23.830704, 13.556321, 12.993084, -25.120148, 13.783545, 12.764626, -24.563269, 13.266899, 13.176035, -24.997204, 12.729578, 13.513615, -25.120148, 13.783545, 12.764626, -24.997204, 12.729578, 13.513615, -25.263885, 12.827821, 13.423475, -23.830704, 13.556321, 12.993084, -22.81894, 12.8182955, 12.022795, -22.412296, 12.812631, 13.106188, -23.423197, 13.259348, 12.431152, -22.81894, 12.8182955, 12.022795, -23.830704, 13.556321, 12.993084, -22.81894, 12.8182955, 12.022795, -23.423197, 13.259348, 12.431152, -23.243961, 12.84373, 11.64538, -22.81894, 12.8182955, 12.022795, -23.243961, 12.84373, 11.64538, -22.970037, 12.747108, 11.67061, -23.830704, 13.556321, 12.993084, -23.392378, 13.061067, 11.639456, -23.423197, 13.259348, 12.431152, -23.830704, 13.556321, 12.993084, -23.693872, 13.206497, 11.613611, -23.392378, 13.061067, 11.639456, -23.671707, 12.578844, 13.562656, -24.109556, 12.314231, 13.807953, -23.830704, 13.556321, 12.993084, -23.671707, 12.578844, 13.562656, -23.848108, 12.188936, 13.830387, -24.109556, 12.314231, 13.807953, -25.120148, 13.783545, 12.764626, -24.30996, 13.49691, 12.078384, -23.830704, 13.556321, 12.993084, -24.30996, 13.49691, 12.078384, -25.120148, 13.783545, 12.764626, -24.933325, 13.512459, 11.685724, -24.30996, 13.49691, 12.078384, -24.933325, 13.512459, 11.685724, -24.482748, 13.423203, 11.660212, -24.563269, 13.266899, 13.176035, -24.109556, 12.314231, 13.807953, -24.80421, 12.541008, 13.571323, -24.563269, 13.266899, 13.176035, -23.830704, 13.556321, 12.993084, -24.109556, 12.314231, 13.807953, -26.33375, 13.5643215, 12.432411, -25.424961, 13.642609, 12.2283325, -25.120148, 13.783545, 12.764626, -25.424961, 13.642609, 12.2283325, -26.33375, 13.5643215, 12.432411, -26.324017, 13.5112915, 12.189222, -25.424961, 13.642609, 12.2283325, -26.324017, 13.5112915, 12.189222, -25.71668, 13.54311, 11.969755, -22.184439, 11.839201, 13.474684, -22.953316, 11.729006, 13.905809, -22.412296, 12.812631, 13.106188, -22.184439, 11.839201, 13.474684, -22.487688, 11.524162, 13.78611, -22.953316, 11.729006, 13.905809, -21.854174, 11.521826, 13.480944, -22.187183, 11.317971, 13.70713, -22.184439, 11.839201, 13.474684, -21.854174, 11.521826, 13.480944, -22.027325, 11.277615, 13.666721, -22.187183, 11.317971, 13.70713, -21.854174, 11.521826, 13.480944, -21.313543, 11.772419, 13.055622, -21.702065, 11.143689, 13.583382, -20.98937, 11.087692, 13.168047, -21.702065, 11.143689, 13.583382, -21.313543, 11.772419, 13.055622, -20.98937, 11.087692, 13.168047, -21.207434, 10.925812, 13.392204, -21.702065, 11.143689, 13.583382, -27.190845, 13.454124, 13.211977, -26.123392, 13.504549, 12.108877, -26.042444, 13.6264305, 12.347961, -27.190845, 13.454124, 13.211977, -27.674408, 12.802565, 12.217752, -26.123392, 13.504549, 12.108877, -26.397722, 12.685178, 13.907841, -26.517313, 13.244606, 13.225155, -26.210627, 12.959142, 13.428625, -26.397722, 12.685178, 13.907841, -27.190845, 13.454124, 13.211977, -26.517313, 13.244606, 13.225155, -30.59442, 8.298002, 15.834078, -30.123693, 9.8882065, 15.319544, -29.275402, 9.5317335, 15.74361, -30.59442, 8.298002, 15.834078, -30.741045, 8.328472, 15.732853, -30.123693, 9.8882065, 15.319544, -30.123693, 9.8882065, 15.319544, -28.95761, 9.849106, 15.67477, -29.275402, 9.5317335, 15.74361, -30.123693, 9.8882065, 15.319544, -29.313347, 10.32216, 15.361237, -28.95761, 9.849106, 15.67477, -29.313347, 10.32216, 15.361237, -30.123693, 9.8882065, 15.319544, -29.39274, 11.410282, 14.816835, -29.313347, 10.32216, 15.361237, -29.39274, 11.410282, 14.816835, -28.10266, 10.688791, 15.489471, -29.313347, 10.32216, 15.361237, -28.10266, 10.688791, 15.489471, -28.671627, 10.132956, 15.612846, -28.10266, 10.688791, 15.489471, -28.17546, 11.1942005, 15.154776, -27.974642, 10.813639, 15.397457, -28.10266, 10.688791, 15.489471, -29.39274, 11.410282, 14.816835, -28.17546, 11.1942005, 15.154776, -27.208647, 11.806034, 14.844706, -27.177315, 12.54514, 14.161594, -26.99829, 12.019685, 14.60232, -27.208647, 11.806034, 14.844706, -28.297514, 12.740184, 14.028536, -27.177315, 12.54514, 14.161594, -30.79949, 8.3112135, 15.561966, -30.123693, 9.8882065, 15.319544, -30.741045, 8.328472, 15.732853, -30.123693, 9.8882065, 15.319544, -30.79949, 8.3112135, 15.561966, -30.452688, 9.11234, 15.217451, -30.452688, 9.11234, 15.217451, -30.79949, 8.3112135, 15.561966, -30.594294, 8.811231, 15.062023, -30.123693, 9.8882065, 15.319544, -29.879786, 10.464624, 14.329517, -29.39274, 11.410282, 14.816835, -30.123693, 9.8882065, 15.319544, -30.117891, 10.010266, 14.465597, -29.879786, 10.464624, 14.329517, -29.715208, 10.829817, 13.354015, -28.297514, 12.740184, 14.028536, -29.39274, 11.410282, 14.816835, -28.297514, 12.740184, 14.028536, -29.715208, 10.829817, 13.354015, -29.23813, 11.34871, 13.010698, -28.297514, 12.740184, 14.028536, -29.23813, 11.34871, 13.010698, -28.912056, 11.883873, 13.344931, -27.949308, 12.851552, 13.156515, -27.190845, 13.454124, 13.211977, -28.297514, 12.740184, 14.028536, -27.190845, 13.454124, 13.211977, -27.949308, 12.851552, 13.156515, -27.942167, 12.621899, 12.332624, -27.190845, 13.454124, 13.211977, -27.942167, 12.621899, 12.332624, -27.674408, 12.802565, 12.217752, -28.297514, 12.740184, 14.028536, -28.17546, 11.1942005, 15.154776, -29.39274, 11.410282, 14.816835, -28.104351, 12.050874, 14.57691, -28.17546, 11.1942005, 15.154776, -28.297514, 12.740184, 14.028536, -28.17546, 11.1942005, 15.154776, -28.104351, 12.050874, 14.57691, -27.539679, 11.245704, 15.084768, -28.17546, 11.1942005, 15.154776, -27.539679, 11.245704, 15.084768, -27.758598, 11.0494, 15.242031, -28.297514, 12.740184, 14.028536, -27.44365, 11.537734, 15.013952, -28.104351, 12.050874, 14.57691, -28.297514, 12.740184, 14.028536, -27.208647, 11.806034, 14.844706, -27.44365, 11.537734, 15.013952, -28.912056, 11.883873, 13.344931, -28.817327, 11.888908, 12.70685, -28.297514, 12.740184, 14.028536, -28.912056, 11.883873, 13.344931, -29.021376, 11.656829, 12.85384, -28.817327, 11.888908, 12.70685, -27.190845, 13.454124, 13.211977, -27.177315, 12.54514, 14.161594, -28.297514, 12.740184, 14.028536, -27.177315, 12.54514, 14.161594, -27.190845, 13.454124, 13.211977, -26.397722, 12.685178, 13.907841, -27.177315, 12.54514, 14.161594, -26.397722, 12.685178, 13.907841, -26.694912, 12.386589, 14.250351, -27.949308, 12.851552, 13.156515, -28.817327, 11.888908, 12.70685, -28.11471, 12.312162, 12.404867, -27.949308, 12.851552, 13.156515, -28.297514, 12.740184, 14.028536, -28.817327, 11.888908, 12.70685, -26.042444, 13.6264305, 12.347961, -26.517313, 13.244606, 13.225155, -27.190845, 13.454124, 13.211977, -26.517313, 13.244606, 13.225155, -26.042444, 13.6264305, 12.347961, -25.841175, 13.485764, 12.483356, -26.517313, 13.244606, 13.225155, -25.841175, 13.485764, 12.483356, -26.088339, 13.183667, 13.109575, -29.879786, 10.464624, 14.329517, -29.715208, 10.829817, 13.354015, -29.39274, 11.410282, 14.816835, -29.879786, 10.464624, 14.329517, -29.939215, 10.384001, 13.731905, -29.715208, 10.829817, 13.354015, -30.117891, 10.010266, 14.465597, -30.074621, 10.006492, 13.9677925, -29.879786, 10.464624, 14.329517, -30.117891, 10.010266, 14.465597, -30.15518, 9.890993, 14.100925, -30.074621, 10.006492, 13.9677925, -30.117891, 10.010266, 14.465597, -30.123693, 9.8882065, 15.319544, -30.313383, 9.599236, 14.366161, -30.452688, 9.11234, 15.217451, -30.313383, 9.599236, 14.366161, -30.123693, 9.8882065, 15.319544, -30.452688, 9.11234, 15.217451, -30.495245, 9.115306, 14.813856, -30.313383, 9.599236, 14.366161, -27.201202, 14.111977, 12.216812, -25.942682, 13.340691, 12.239897, -25.963226, 13.52549, 12.449766, -27.201202, 14.111977, 12.216812, -27.26703, 13.264112, 11.247925, -25.942682, 13.340691, 12.239897, -27.481268, 13.527826, 13.334137, -26.931988, 13.740763, 12.7410145, -26.979942, 13.491425, 13.121708, -27.481268, 13.527826, 13.334137, -27.201202, 14.111977, 12.216812, -26.931988, 13.740763, 12.7410145, -32.707096, 11.829945, 11.838261, -31.489027, 12.834562, 11.726076, -31.396978, 12.465054, 12.665121, -32.707096, 11.829945, 11.838261, -32.720463, 11.854302, 11.658894, -31.489027, 12.834562, 11.726076, -31.489027, 12.834562, 11.726076, -31.048937, 12.614889, 12.831612, -31.396978, 12.465054, 12.665121, -31.489027, 12.834562, 11.726076, -30.883116, 12.990331, 12.325209, -31.048937, 12.614889, 12.831612, -30.883116, 12.990331, 12.325209, -31.489027, 12.834562, 11.726076, -30.172102, 13.71146, 11.822292, -30.883116, 12.990331, 12.325209, -30.172102, 13.71146, 11.822292, -30.112314, 13.00444, 13.27858, -30.883116, 12.990331, 12.325209, -30.112314, 13.00444, 13.27858, -30.735453, 12.748096, 12.981314, -30.112314, 13.00444, 13.27858, -29.77852, 13.318491, 12.969162, -29.928392, 13.031496, 13.299112, -30.112314, 13.00444, 13.27858, -30.172102, 13.71146, 11.822292, -29.77852, 13.318491, 12.969162, -28.82114, 13.425723, 13.433544, -28.131073, 13.753705, 12.945568, -28.474356, 13.438845, 13.407442, -28.82114, 13.425723, 13.433544, -28.579897, 14.188468, 12.007677, -28.131073, 13.753705, 12.945568, -32.672134, 11.781767, 11.502314, -31.489027, 12.834562, 11.726076, -32.720463, 11.854302, 11.658894, -31.489027, 12.834562, 11.726076, -32.672134, 11.781767, 11.502314, -31.952402, 12.217968, 11.469395, -31.952402, 12.217968, 11.469395, -32.672134, 11.781767, 11.502314, -32.0643, 11.928456, 11.276808, -31.489027, 12.834562, 11.726076, -30.603403, 12.827642, 11.204182, -30.172102, 13.71146, 11.822292, -31.489027, 12.834562, 11.726076, -30.9988, 12.565276, 11.150988, -30.603403, 12.827642, 11.204182, -29.840925, 12.6641445, 10.642536, -28.579897, 14.188468, 12.007677, -30.172102, 13.71146, 11.822292, -28.579897, 14.188468, 12.007677, -29.840925, 12.6641445, 10.642536, -29.154, 12.815418, 10.721668, -28.579897, 14.188468, 12.007677, -29.154, 12.815418, 10.721668, -28.948093, 13.334579, 11.159084, -27.901386, 13.802778, 11.676207, -27.201202, 14.111977, 12.216812, -28.579897, 14.188468, 12.007677, -27.201202, 14.111977, 12.216812, -27.901386, 13.802778, 11.676207, -27.566175, 13.240652, 11.143919, -27.201202, 14.111977, 12.216812, -27.566175, 13.240652, 11.143919, -27.26703, 13.264112, 11.247925, -28.579897, 14.188468, 12.007677, -29.77852, 13.318491, 12.969162, -30.172102, 13.71146, 11.822292, -29.078878, 13.783996, 12.575394, -29.77852, 13.318491, 12.969162, -28.579897, 14.188468, 12.007677, -29.77852, 13.318491, 12.969162, -29.078878, 13.783996, 12.575394, -29.3032, 13.130279, 13.369244, -29.77852, 13.318491, 12.969162, -29.3032, 13.130279, 13.369244, -29.61749, 13.100707, 13.335033, -28.579897, 14.188468, 12.007677, -29.159786, 13.339252, 13.394022, -29.078878, 13.783996, 12.575394, -28.579897, 14.188468, 12.007677, -28.82114, 13.425723, 13.433544, -29.159786, 13.339252, 13.394022, -28.948093, 13.334579, 11.159084, -28.545794, 13.027181, 10.795259, -28.579897, 14.188468, 12.007677, -28.948093, 13.334579, 11.159084, -28.840069, 12.952937, 10.761011, -28.545794, 13.027181, 10.795259, -27.201202, 14.111977, 12.216812, -28.131073, 13.753705, 12.945568, -28.579897, 14.188468, 12.007677, -28.131073, 13.753705, 12.945568, -27.201202, 14.111977, 12.216812, -27.481268, 13.527826, 13.334137, -28.131073, 13.753705, 12.945568, -27.481268, 13.527826, 13.334137, -27.971476, 13.512636, 13.371208, -27.901386, 13.802778, 11.676207, -28.545794, 13.027181, 10.795259, -27.7606, 13.039855, 11.0648365, -27.901386, 13.802778, 11.676207, -28.579897, 14.188468, 12.007677, -28.545794, 13.027181, 10.795259, -25.963226, 13.52549, 12.449766, -26.931988, 13.740763, 12.7410145, -27.201202, 14.111977, 12.216812, -26.931988, 13.740763, 12.7410145, -25.963226, 13.52549, 12.449766, -25.99063, 13.406307, 12.702139, -26.931988, 13.740763, 12.7410145, -25.99063, 13.406307, 12.702139, -26.647318, 13.508326, 12.980991, -30.603403, 12.827642, 11.204182, -29.840925, 12.6641445, 10.642536, -30.172102, 13.71146, 11.822292, -30.603403, 12.827642, 11.204182, -30.356276, 12.512424, 10.763277, -29.840925, 12.6641445, 10.642536, -30.9988, 12.565276, 11.150988, -30.676294, 12.321331, 10.836258, -30.603403, 12.827642, 11.204182, -30.9988, 12.565276, 11.150988, -30.858511, 12.308209, 10.879881, -30.676294, 12.321331, 10.836258, -30.9988, 12.565276, 11.150988, -31.489027, 12.834562, 11.726076, -31.220568, 12.222282, 10.96516, -31.952402, 12.217968, 11.469395, -31.220568, 12.222282, 10.96516, -31.489027, 12.834562, 11.726076, -31.952402, 12.217968, 11.469395, -31.764006, 12.055641, 11.166313, -31.220568, 12.222282, 10.96516, -26.549658, 13.852484, 11.521194, -25.914532, 13.414665, 12.523054, -26.09762, 13.550388, 12.580524, -26.549658, 13.852484, 11.521194, -25.778147, 13.206228, 11.136642, -25.914532, 13.414665, 12.523054, -27.393269, 13.267618, 11.867287, -26.750992, 13.556589, 11.991425, -27.016235, 13.327029, 12.142666, -27.393269, 13.267618, 11.867287, -26.549658, 13.852484, 11.521194, -26.750992, 13.556589, 11.991425, -28.51631, 11.110254, 7.4424706, -28.004425, 12.171139, 8.214411, -28.58325, 11.828327, 8.733058, -28.51631, 11.110254, 7.4424706, -28.3986, 11.137669, 7.350334, -28.004425, 12.171139, 8.214411, -28.004425, 12.171139, 8.214411, -28.560322, 12.001171, 9.0543, -28.58325, 11.828327, 8.733058, -28.004425, 12.171139, 8.214411, -28.169415, 12.366816, 8.922272, -28.560322, 12.001171, 9.0543, -28.169415, 12.366816, 8.922272, -28.004425, 12.171139, 8.214411, -27.574968, 13.101874, 9.166556, -28.169415, 12.366816, 8.922272, -27.574968, 13.101874, 9.166556, -28.497368, 12.447617, 9.9169655, -28.169415, 12.366816, 8.922272, -28.497368, 12.447617, 9.9169655, -28.539549, 12.153973, 9.343277, -28.497368, 12.447617, 9.9169655, -28.157778, 12.77416, 10.008541, -28.434235, 12.498222, 10.057671, -28.497368, 12.447617, 9.9169655, -27.574968, 13.101874, 9.166556, -28.157778, 12.77416, 10.008541, -28.060122, 12.979725, 10.923248, -27.435986, 13.376825, 11.196117, -27.887424, 13.044889, 11.166651, -28.060122, 12.979725, 10.923248, -27.034447, 13.723143, 10.398659, -27.435986, 13.376825, 11.196117, -28.256086, 11.096142, 7.324676, -28.004425, 12.171139, 8.214411, -28.3986, 11.137669, 7.350334, -28.004425, 12.171139, 8.214411, -28.256086, 11.096142, 7.324676, -27.958471, 11.59544, 7.810196, -27.958471, 11.59544, 7.810196, -28.256086, 11.096142, 7.324676, -27.841549, 11.343948, 7.662429, -28.004425, 12.171139, 8.214411, -27.223587, 12.345152, 8.655518, -27.574968, 13.101874, 9.166556, -28.004425, 12.171139, 8.214411, -27.335718, 12.067413, 8.358295, -27.223587, 12.345152, 8.655518, -26.456749, 12.367084, 8.993832, -27.034447, 13.723143, 10.398659, -27.574968, 13.101874, 9.166556, -27.034447, 13.723143, 10.398659, -26.456749, 12.367084, 8.993832, -26.222069, 12.594754, 9.523212, -27.034447, 13.723143, 10.398659, -26.222069, 12.594754, 9.523212, -26.492432, 13.021158, 9.833479, -26.435522, 13.525401, 10.803925, -26.549658, 13.852484, 11.521194, -27.034447, 13.723143, 10.398659, -26.549658, 13.852484, 11.521194, -26.435522, 13.525401, 10.803925, -25.835228, 13.148436, 10.873161, -26.549658, 13.852484, 11.521194, -25.835228, 13.148436, 10.873161, -25.778147, 13.206228, 11.136642, -27.034447, 13.723143, 10.398659, -28.157778, 12.77416, 10.008541, -27.574968, 13.101874, 9.166556, -27.610704, 13.283167, 10.320328, -28.157778, 12.77416, 10.008541, -27.034447, 13.723143, 10.398659, -28.157778, 12.77416, 10.008541, -27.610704, 13.283167, 10.320328, -28.219557, 12.675113, 10.536343, -28.157778, 12.77416, 10.008541, -28.219557, 12.675113, 10.536343, -28.328056, 12.602215, 10.297457, -27.034447, 13.723143, 10.398659, -28.175543, 12.86018, 10.661373, -27.610704, 13.283167, 10.320328, -27.034447, 13.723143, 10.398659, -28.060122, 12.979725, 10.923248, -28.175543, 12.86018, 10.661373, -26.492432, 13.021158, 9.833479, -26.016369, 12.854247, 9.998339, -27.034447, 13.723143, 10.398659, -26.492432, 13.021158, 9.833479, -26.116678, 12.750883, 9.77084, -26.016369, 12.854247, 9.998339, -26.549658, 13.852484, 11.521194, -27.435986, 13.376825, 11.196117, -27.034447, 13.723143, 10.398659, -27.435986, 13.376825, 11.196117, -26.549658, 13.852484, 11.521194, -27.393269, 13.267618, 11.867287, -27.435986, 13.376825, 11.196117, -27.393269, 13.267618, 11.867287, -27.637686, 13.179714, 11.523783, -26.435522, 13.525401, 10.803925, -26.016369, 12.854247, 9.998339, -25.865164, 12.972085, 10.685308, -26.435522, 13.525401, 10.803925, -27.034447, 13.723143, 10.398659, -26.016369, 12.854247, 9.998339, -26.09762, 13.550388, 12.580524, -26.750992, 13.556589, 11.991425, -26.549658, 13.852484, 11.521194, -26.750992, 13.556589, 11.991425, -26.09762, 13.550388, 12.580524, -26.272526, 13.433453, 12.685123, -26.750992, 13.556589, 11.991425, -26.272526, 13.433453, 12.685123, -26.766165, 13.395969, 12.328079, -27.223587, 12.345152, 8.655518, -26.456749, 12.367084, 8.993832, -27.574968, 13.101874, 9.166556, -27.223587, 12.345152, 8.655518, -26.759527, 12.152982, 8.67496, -26.456749, 12.367084, 8.993832, -27.335718, 12.067413, 8.358295, -26.946072, 11.938253, 8.469797, -27.223587, 12.345152, 8.655518, -27.335718, 12.067413, 8.358295, -27.053827, 11.894838, 8.359913, -26.946072, 11.938253, 8.469797, -27.335718, 12.067413, 8.358295, -28.004425, 12.171139, 8.214411, -27.266567, 11.75786, 8.137337, -27.958471, 11.59544, 7.810196, -27.266567, 11.75786, 8.137337, -28.004425, 12.171139, 8.214411, -27.958471, 11.59544, 7.810196, -27.63729, 11.513017, 7.833111, -27.266567, 11.75786, 8.137337, -25.299118, 14.016339, 11.705952, -26.202145, 13.431294, 12.758247, -26.33764, 13.542391, 12.539379, -25.299118, 14.016339, 11.705952, -24.55057, 13.487381, 12.600025, -26.202145, 13.431294, 12.758247, -25.729456, 13.096121, 10.875708, -25.798758, 13.544817, 11.6329155, -25.976883, 13.186634, 11.381079, -25.729456, 13.096121, 10.875708, -25.299118, 14.016339, 11.705952, -25.798758, 13.544817, 11.6329155, -20.600985, 11.212358, 8.53599, -21.567623, 12.368253, 9.249824, -22.19324, 11.752106, 8.746279, -20.600985, 11.212358, 8.53599, -20.480156, 11.286333, 8.646276, -21.567623, 12.368253, 9.249824, -21.567623, 12.368253, 9.249824, -22.58087, 11.89322, 8.845634, -22.19324, 11.752106, 8.746279, -21.567623, 12.368253, 9.249824, -22.426706, 12.42362, 9.235527, -22.58087, 11.89322, 8.845634, -22.426706, 12.42362, 9.235527, -21.567623, 12.368253, 9.249824, -22.728525, 13.355524, 9.92947, -22.426706, 12.42362, 9.235527, -22.728525, 13.355524, 9.92947, -23.621424, 12.259226, 9.112419, -22.426706, 12.42362, 9.235527, -23.621424, 12.259226, 9.112419, -22.929403, 12.018518, 8.935175, -23.621424, 12.259226, 9.112419, -23.71438, 12.69767, 9.51326, -23.778412, 12.302008, 9.216736, -23.621424, 12.259226, 9.112419, -22.728525, 13.355524, 9.92947, -23.71438, 12.69767, 9.51326, -24.753212, 12.792858, 9.863087, -25.008253, 13.342491, 10.636538, -25.004257, 12.857843, 10.124001, -24.753212, 12.792858, 9.863087, -24.116346, 13.970501, 10.84609, -25.008253, 13.342491, 10.636538, -20.411009, 11.269615, 8.813364, -21.567623, 12.368253, 9.249824, -20.480156, 11.286333, 8.646276, -21.567623, 12.368253, 9.249824, -20.411009, 11.269615, 8.813364, -20.987125, 11.792372, 9.251802, -20.987125, 11.792372, 9.251802, -20.411009, 11.269615, 8.813364, -20.750517, 11.554993, 9.368832, -21.567623, 12.368253, 9.249824, -21.917282, 12.636011, 10.289265, -22.728525, 13.355524, 9.92947, -21.567623, 12.368253, 9.249824, -21.553564, 12.347399, 10.101149, -21.917282, 12.636011, 10.289265, -22.131565, 12.746388, 11.290453, -24.116346, 13.970501, 10.84609, -22.728525, 13.355524, 9.92947, -24.116346, 13.970501, 10.84609, -22.131565, 12.746388, 11.290453, -22.724337, 12.956984, 11.684092, -24.116346, 13.970501, 10.84609, -22.724337, 12.956984, 11.684092, -23.211079, 13.356783, 11.415373, -24.388641, 13.79298, 11.697922, -25.299118, 14.016339, 11.705952, -24.116346, 13.970501, 10.84609, -25.299118, 14.016339, 11.705952, -24.388641, 13.79298, 11.697922, -24.252804, 13.45727, 12.470831, -25.299118, 14.016339, 11.705952, -24.252804, 13.45727, 12.470831, -24.55057, 13.487381, 12.600025, -24.116346, 13.970501, 10.84609, -23.71438, 12.69767, 9.51326, -22.728525, 13.355524, 9.92947, -24.050045, 13.353634, 10.197813, -23.71438, 12.69767, 9.51326, -24.116346, 13.970501, 10.84609, -23.71438, 12.69767, 9.51326, -24.050045, 13.353634, 10.197813, -24.313118, 12.454627, 9.572146, -23.71438, 12.69767, 9.51326, -24.313118, 12.454627, 9.572146, -24.046837, 12.398183, 9.39505, -24.116346, 13.970501, 10.84609, -24.459291, 12.676998, 9.6678705, -24.050045, 13.353634, 10.197813, -24.116346, 13.970501, 10.84609, -24.753212, 12.792858, 9.863087, -24.459291, 12.676998, 9.6678705, -23.211079, 13.356783, 11.415373, -23.25923, 13.221777, 12.038786, -24.116346, 13.970501, 10.84609, -23.211079, 13.356783, 11.415373, -23.004206, 13.122009, 11.869499, -23.25923, 13.221777, 12.038786, -25.299118, 14.016339, 11.705952, -25.008253, 13.342491, 10.636538, -24.116346, 13.970501, 10.84609, -25.008253, 13.342491, 10.636538, -25.299118, 14.016339, 11.705952, -25.729456, 13.096121, 10.875708, -25.008253, 13.342491, 10.636538, -25.729456, 13.096121, 10.875708, -25.374859, 13.007589, 10.507263, -24.388641, 13.79298, 11.697922, -23.25923, 13.221777, 12.038786, -24.033789, 13.251799, 12.374115, -24.388641, 13.79298, 11.697922, -24.116346, 13.970501, 10.84609, -23.25923, 13.221777, 12.038786, -26.33764, 13.542391, 12.539379, -25.798758, 13.544817, 11.6329155, -25.299118, 14.016339, 11.705952, -25.798758, 13.544817, 11.6329155, -26.33764, 13.542391, 12.539379, -26.4637, 13.351927, 12.376793, -25.798758, 13.544817, 11.6329155, -26.4637, 13.351927, 12.376793, -26.145252, 13.288563, 11.72068, -21.917282, 12.636011, 10.289265, -22.131565, 12.746388, 11.290453, -22.728525, 13.355524, 9.92947, -21.917282, 12.636011, 10.289265, -21.7968, 12.497051, 10.865448, -22.131565, 12.746388, 11.290453, -21.553564, 12.347399, 10.101149, -21.57792, 12.244032, 10.592348, -21.917282, 12.636011, 10.289265, -21.553564, 12.347399, 10.101149, -21.464146, 12.196934, 10.445953, -21.57792, 12.244032, 10.592348, -21.553564, 12.347399, 10.101149, -21.567623, 12.368253, 9.249824, -21.231346, 12.042698, 10.149359, -20.987125, 11.792372, 9.251802, -21.231346, 12.042698, 10.149359, -21.567623, 12.368253, 9.249824, -20.987125, 11.792372, 9.251802, -20.92406, 11.751565, 9.648912, -21.231346, 12.042698, 10.149359, -25.705019, 13.809881, 13.562584, -26.45702, 13.504189, 12.279745, -26.186665, 13.570251, 12.245989, -25.705019, 13.809881, 13.562584, -26.888538, 13.45844, 13.87192, -26.45702, 13.504189, 12.279745, -24.945316, 12.747828, 13.355633, -25.55226, 13.354175, 13.0715885, -25.309752, 12.956354, 12.9552, -24.945316, 12.747828, 13.355633, -25.705019, 13.809881, 13.562584, -25.55226, 13.354175, 13.0715885, -24.723381, 10.182662, 18.724218, -24.892126, 11.507984, 17.707823, -24.315966, 10.822086, 17.237934, -24.723381, 10.182662, 18.724218, -24.853382, 10.273891, 18.805033, -24.892126, 11.507984, 17.707823, -24.892126, 11.507984, 17.707823, -24.260817, 10.9978075, 16.859945, -24.315966, 10.822086, 17.237934, -24.892126, 11.507984, 17.707823, -24.594227, 11.594991, 16.92428, -24.260817, 10.9978075, 16.859945, -24.594227, 11.594991, 16.92428, -24.892126, 11.507984, 17.707823, -24.99707, 12.669626, 16.504105, -24.594227, 11.594991, 16.92428, -24.99707, 12.669626, 16.504105, -24.11179, 11.456928, 15.843534, -24.594227, 11.594991, 16.92428, -24.11179, 11.456928, 15.843534, -24.211235, 11.154295, 16.519825, -24.11179, 11.456928, 15.843534, -24.396267, 11.977171, 15.664667, -24.146303, 11.527758, 15.66567, -24.11179, 11.456928, 15.843534, -24.99707, 12.669626, 16.504105, -24.396267, 11.977171, 15.664667, -24.372864, 12.190012, 14.588343, -24.92865, 12.906826, 14.1381035, -24.519852, 12.320793, 14.269573, -24.372864, 12.190012, 14.588343, -25.306261, 13.528545, 14.961657, -24.92865, 12.906826, 14.1381035, -25.035671, 10.291328, 18.806995, -24.892126, 11.507984, 17.707823, -24.853382, 10.273891, 18.805033, -24.892126, 11.507984, 17.707823, -25.035671, 10.291328, 18.806995, -25.174652, 10.921768, 18.176992, -25.174652, 10.921768, 18.176992, -25.035671, 10.291328, 18.806995, -25.392036, 10.70524, 18.326195, -24.892126, 11.507984, 17.707823, -25.717178, 12.011866, 17.041342, -24.99707, 12.669626, 16.504105, -24.892126, 11.507984, 17.707823, -25.703766, 11.673546, 17.411934, -25.717178, 12.011866, 17.041342, -26.566265, 12.347487, 16.495499, -25.306261, 13.528545, 14.961657, -24.99707, 12.669626, 16.504105, -25.306261, 13.528545, 14.961657, -26.566265, 12.347487, 16.495499, -26.699371, 12.663515, 15.829714, -25.306261, 13.528545, 14.961657, -26.699371, 12.663515, 15.829714, -26.24021, 13.016304, 15.522837, -26.053259, 13.553265, 14.382238, -25.705019, 13.809881, 13.562584, -25.306261, 13.528545, 14.961657, -25.705019, 13.809881, 13.562584, -26.053259, 13.553265, 14.382238, -26.875654, 13.388691, 14.190426, -25.705019, 13.809881, 13.562584, -26.875654, 13.388691, 14.190426, -26.888538, 13.45844, 13.87192, -25.306261, 13.528545, 14.961657, -24.396267, 11.977171, 15.664667, -24.99707, 12.669626, 16.504105, -24.82944, 12.781982, 15.184017, -24.396267, 11.977171, 15.664667, -25.306261, 13.528545, 14.961657, -24.396267, 11.977171, 15.664667, -24.82944, 12.781982, 15.184017, -24.26432, 11.775922, 15.060766, -24.396267, 11.977171, 15.664667, -24.26432, 11.775922, 15.060766, -24.206535, 11.67166, 15.364321, -25.306261, 13.528545, 14.961657, -24.306345, 12.02211, 14.9169445, -24.82944, 12.781982, 15.184017, -25.306261, 13.528545, 14.961657, -24.372864, 12.190012, 14.588343, -24.306345, 12.02211, 14.9169445, -26.24021, 13.016304, 15.522837, -26.82347, 13.022417, 15.237913, -25.306261, 13.528545, 14.961657, -26.24021, 13.016304, 15.522837, -26.765692, 12.877438, 15.523392, -26.82347, 13.022417, 15.237913, -25.705019, 13.809881, 13.562584, -24.92865, 12.906826, 14.1381035, -25.306261, 13.528545, 14.961657, -24.92865, 12.906826, 14.1381035, -25.705019, 13.809881, 13.562584, -24.945316, 12.747828, 13.355633, -24.92865, 12.906826, 14.1381035, -24.945316, 12.747828, 13.355633, -24.738127, 12.5664425, 13.806084, -26.053259, 13.553265, 14.382238, -26.82347, 13.022417, 15.237913, -26.853886, 13.155892, 14.403858, -26.053259, 13.553265, 14.382238, -25.306261, 13.528545, 14.961657, -26.82347, 13.022417, 15.237913, -26.186665, 13.570251, 12.245989, -25.55226, 13.354175, 13.0715885, -25.705019, 13.809881, 13.562584, -25.55226, 13.354175, 13.0715885, -26.186665, 13.570251, 12.245989, -26.027418, 13.354084, 12.165661, -25.55226, 13.354175, 13.0715885, -26.027418, 13.354084, 12.165661, -25.556536, 13.13711, 12.689047, -25.717178, 12.011866, 17.041342, -26.566265, 12.347487, 16.495499, -24.99707, 12.669626, 16.504105, -25.717178, 12.011866, 17.041342, -26.317577, 11.997127, 16.929232, -26.566265, 12.347487, 16.495499, -25.703766, 11.673546, 17.411934, -26.153154, 11.680018, 17.200329, -25.717178, 12.011866, 17.041342, -25.703766, 11.673546, 17.411934, -26.069336, 11.597685, 17.352945, -26.153154, 11.680018, 17.200329, -25.703766, 11.673546, 17.411934, -24.892126, 11.507984, 17.707823, -25.896534, 11.372709, 17.657299, -25.174652, 10.921768, 18.176992, -25.896534, 11.372709, 17.657299, -24.892126, 11.507984, 17.707823, -25.174652, 10.921768, 18.176992, -25.57406, 10.966168, 18.087864, -25.896534, 11.372709, 17.657299, -23.578579, 3.6379063, 11.557745, -24.12619, 7.057568, 11.959915, -23.8756, 7.125276, 11.658489, -23.578579, 3.6379063, 11.557745, -23.888453, 3.5751674, 11.919102, -24.12619, 7.057568, 11.959915, -23.836985, -0.21907139, 11.791069, -23.888453, 3.5751674, 11.919102, -23.578579, 3.6379063, 11.557745, -23.836985, -0.21907139, 11.791069, -24.181253, -0.21472502, 12.204487, -23.888453, 3.5751674, 11.919102, -24.709448, 3.4888213, 11.70261, -24.880796, 6.9884076, 11.3729, -24.819984, 6.963768, 11.765211, -24.709448, 3.4888213, 11.70261, -24.77573, 3.5122192, 11.244535, -24.880796, 6.9884076, 11.3729, -24.003609, 3.6379066, 10.807255, -23.93851, 7.1495028, 11.266003, -24.242756, 7.125276, 11.010187, -24.003609, 3.6379066, 10.807255, -23.637373, 3.6615102, 11.095457, -23.93851, 7.1495028, 11.266003, -24.819984, 6.963768, 11.765211, -25.485994, 10.232269, 11.85763, -25.442476, 10.210943, 12.117752, -24.819984, 6.963768, 11.765211, -24.880796, 6.9884076, 11.3729, -25.485994, 10.232269, 11.85763, -23.8756, 7.125276, 11.658489, -24.984426, 10.2888, 12.251429, -24.815989, 10.342636, 12.050236, -23.8756, 7.125276, 11.658489, -24.12619, 7.057568, 11.959915, -24.984426, 10.2888, 12.251429, -24.815989, 10.342636, 12.050236, -24.984426, 10.2888, 12.251429, -25.548643, 11.995004, 12.470713, -24.815989, 10.342636, 12.050236, -25.548643, 11.995004, 12.470713, -25.430141, 12.056503, 12.32415, -23.888453, 3.5751674, 11.919102, -24.514824, 6.9884076, 12.019112, -24.12619, 7.057568, 11.959915, -23.888453, 3.5751674, 11.919102, -24.350702, 3.512219, 11.995026, -24.514824, 6.9884076, 12.019112, -24.12619, 7.057568, 11.959915, -24.514824, 6.9884076, 12.019112, -25.241776, 10.232269, 12.288855, -24.12619, 7.057568, 11.959915, -25.241776, 10.232269, 12.288855, -24.984426, 10.2888, 12.251429, -24.77573, 3.5122192, 11.244535, -24.63014, 7.057568, 11.070068, -24.880796, 6.9884076, 11.3729, -24.77573, 3.5122192, 11.244535, -24.472868, 3.5751677, 10.8871765, -24.63014, 7.057568, 11.070068, -24.880796, 6.9884076, 11.3729, -24.63014, 7.057568, 11.070068, -25.321539, 10.2888, 11.656172, -24.880796, 6.9884076, 11.3729, -25.321539, 10.2888, 11.656172, -25.485994, 10.232269, 11.85763, -24.242756, 7.125276, 11.010187, -24.857891, 10.362101, 11.78668, -25.062378, 10.342636, 11.615177, -24.242756, 7.125276, 11.010187, -23.93851, 7.1495028, 11.266003, -24.857891, 10.362101, 11.78668, -23.637373, 3.6615102, 11.095457, -23.8756, 7.125276, 11.658489, -23.93851, 7.1495028, 11.266003, -23.637373, 3.6615102, 11.095457, -23.578579, 3.6379063, 11.557745, -23.8756, 7.125276, 11.658489, -23.93851, 7.1495028, 11.266003, -24.815989, 10.342636, 12.050236, -24.857891, 10.362101, 11.78668, -23.93851, 7.1495028, 11.266003, -23.8756, 7.125276, 11.658489, -24.815989, 10.342636, 12.050236, -24.472868, 3.5751677, 10.8871765, -24.242756, 7.125276, 11.010187, -24.63014, 7.057568, 11.070068, -24.472868, 3.5751677, 10.8871765, -24.003609, 3.6379066, 10.807255, -24.242756, 7.125276, 11.010187, -24.868216, -0.21472502, 10.9914875, -24.003609, 3.6379066, 10.807255, -24.472868, 3.5751677, 10.8871765, -24.868216, -0.21472502, 10.9914875, -24.336596, -0.21907139, 10.908884, -24.003609, 3.6379066, 10.807255, -24.63014, 7.057568, 11.070068, -25.062378, 10.342636, 11.615177, -25.321539, 10.2888, 11.656172, -24.63014, 7.057568, 11.070068, -24.242756, 7.125276, 11.010187, -25.062378, 10.342636, 11.615177, -25.321539, 10.2888, 11.656172, -25.062378, 10.342636, 11.615177, -25.613142, 12.056503, 12.001019, -25.321539, 10.2888, 11.656172, -25.613142, 12.056503, 12.001019, -25.79978, 11.995004, 12.027269, -25.883152, 11.911559, 12.367321, -26.206875, 13.210678, 12.70623, -25.735323, 11.93475, 12.496033, -25.883152, 11.911559, 12.367321, -26.31439, 13.191008, 12.611546, -26.206875, 13.210678, 12.70623, -25.548643, 11.995004, 12.470713, -25.993643, 13.325804, 12.585468, -25.430141, 12.056503, 12.32415, -25.548643, 11.995004, 12.470713, -26.075993, 13.270106, 12.690508, -25.993643, 13.325804, 12.585468, -25.735323, 11.93475, 12.496033, -26.075993, 13.270106, 12.690508, -25.548643, 11.995004, 12.470713, -25.735323, 11.93475, 12.496033, -26.206875, 13.210678, 12.70623, -26.075993, 13.270106, 12.690508, -25.463963, 12.079072, 12.129919, -26.127062, 13.325804, 12.349884, -25.613142, 12.056503, 12.001019, -25.463963, 12.079072, 12.129919, -26.021097, 13.349201, 12.445444, -26.127062, 13.325804, 12.349884, -25.430141, 12.056503, 12.32415, -26.021097, 13.349201, 12.445444, -25.463963, 12.079072, 12.129919, -25.430141, 12.056503, 12.32415, -25.993643, 13.325804, 12.585468, -26.021097, 13.349201, 12.445444, -25.79978, 11.995004, 12.027269, -26.340294, 13.210678, 12.470644, -25.917505, 11.93475, 12.174345, -25.79978, 11.995004, 12.027269, -26.259499, 13.270106, 12.366484, -26.340294, 13.210678, 12.470644, -25.613142, 12.056503, 12.001019, -26.259499, 13.270106, 12.366484, -25.79978, 11.995004, 12.027269, -25.613142, 12.056503, 12.001019, -26.127062, 13.325804, 12.349884, -26.259499, 13.270106, 12.366484, -24.715683, -0.21037531, 12.288706, -24.709448, 3.4888213, 11.70261, -24.350702, 3.512219, 11.995026, -24.715683, -0.21037531, 12.288706, -25.129576, -0.2087202, 11.940542, -24.709448, 3.4888213, 11.70261, -25.917505, 11.93475, 12.174345, -26.31439, 13.191008, 12.611546, -25.883152, 11.911559, 12.367321, -25.917505, 11.93475, 12.174345, -26.340294, 13.210678, 12.470644, -26.31439, 13.191008, 12.611546, -24.350702, 3.512219, 11.995026, -24.819984, 6.963768, 11.765211, -24.514824, 6.9884076, 12.019112, -24.350702, 3.512219, 11.995026, -24.709448, 3.4888213, 11.70261, -24.819984, 6.963768, 11.765211, -25.129576, -0.2087202, 11.940542, -24.77573, 3.5122192, 11.244535, -24.709448, 3.4888213, 11.70261, -25.129576, -0.2087202, 11.940542, -25.215294, -0.21037531, 11.406523, -24.77573, 3.5122192, 11.244535, -24.336596, -0.21907139, 10.908884, -23.637373, 3.6615102, 11.095457, -24.003609, 3.6379066, 10.807255, -24.336596, -0.21907139, 10.908884, -23.924746, -0.2207303, 11.258205, -23.637373, 3.6615102, 11.095457, -24.181253, -0.21472502, 12.204487, -24.350702, 3.512219, 11.995026, -23.888453, 3.5751674, 11.919102, -24.181253, -0.21472502, 12.204487, -24.715683, -0.21037531, 12.288706, -24.350702, 3.512219, 11.995026, -25.215294, -0.21037531, 11.406523, -24.472868, 3.5751677, 10.8871765, -24.77573, 3.5122192, 11.244535, -25.215294, -0.21037531, 11.406523, -24.868216, -0.21472502, 10.9914875, -24.472868, 3.5751677, 10.8871765, -23.924746, -0.2207303, 11.258205, -23.578579, 3.6379063, 11.557745, -23.637373, 3.6615102, 11.095457, -23.924746, -0.2207303, 11.258205, -23.836985, -0.21907139, 11.791069, -23.578579, 3.6379063, 11.557745, -24.514824, 6.9884076, 12.019112, -25.442476, 10.210943, 12.117752, -25.241776, 10.232269, 12.288855, -24.514824, 6.9884076, 12.019112, -24.819984, 6.963768, 11.765211, -25.442476, 10.210943, 12.117752, -25.241776, 10.232269, 12.288855, -25.883152, 11.911559, 12.367321, -25.735323, 11.93475, 12.496033, -25.241776, 10.232269, 12.288855, -25.442476, 10.210943, 12.117752, -25.883152, 11.911559, 12.367321, -25.442476, 10.210943, 12.117752, -25.917505, 11.93475, 12.174345, -25.883152, 11.911559, 12.367321, -25.442476, 10.210943, 12.117752, -25.485994, 10.232269, 11.85763, -25.917505, 11.93475, 12.174345, -24.984426, 10.2888, 12.251429, -25.735323, 11.93475, 12.496033, -25.548643, 11.995004, 12.470713, -24.984426, 10.2888, 12.251429, -25.241776, 10.232269, 12.288855, -25.735323, 11.93475, 12.496033, -25.062378, 10.342636, 11.615177, -25.463963, 12.079072, 12.129919, -25.613142, 12.056503, 12.001019, -25.062378, 10.342636, 11.615177, -24.857891, 10.362101, 11.78668, -25.463963, 12.079072, 12.129919, -24.857891, 10.362101, 11.78668, -25.430141, 12.056503, 12.32415, -25.463963, 12.079072, 12.129919, -24.857891, 10.362101, 11.78668, -24.815989, 10.342636, 12.050236, -25.430141, 12.056503, 12.32415, -25.485994, 10.232269, 11.85763, -25.79978, 11.995004, 12.027269, -25.917505, 11.93475, 12.174345, -25.485994, 10.232269, 11.85763, -25.321539, 10.2888, 11.656172, -25.79978, 11.995004, 12.027269, 14.960796, 7.3177958, 10.284792, 14.197514, 7.0888658, 10.165964, 14.230383, 7.219601, 10.105017, 14.960796, 7.3177958, 10.284792, 14.899889, 6.6811314, 10.556076, 14.197514, 7.0888658, 10.165964, 15.035656, 7.2923393, 9.619492, 14.762205, 7.297971, 9.966335, 14.763325, 7.2744055, 9.734959, 15.035656, 7.2923393, 9.619492, 14.960796, 7.3177958, 10.284792, 14.762205, 7.297971, 9.966335, 17.810453, 5.5428567, 9.76613, 17.232166, 6.147483, 10.085447, 17.132032, 6.2065306, 9.564142, 17.810453, 5.5428567, 9.76613, 17.822802, 5.5103865, 9.856148, 17.232166, 6.147483, 10.085447, 17.232166, 6.147483, 10.085447, 16.95009, 6.3580484, 9.530783, 17.132032, 6.2065306, 9.564142, 17.232166, 6.147483, 10.085447, 16.89884, 6.4360313, 9.857285, 16.95009, 6.3580484, 9.530783, 16.89884, 6.4360313, 9.857285, 17.232166, 6.147483, 10.085447, 16.58012, 6.736306, 10.276844, 16.89884, 6.4360313, 9.857285, 16.58012, 6.736306, 10.276844, 16.462008, 6.7533646, 9.4380245, 16.89884, 6.4360313, 9.857285, 16.462008, 6.7533646, 9.4380245, 16.786558, 6.492572, 9.500252, 16.462008, 6.7533646, 9.4380245, 16.302326, 6.86697, 9.66189, 16.365639, 6.7913795, 9.442841, 16.462008, 6.7533646, 9.4380245, 16.58012, 6.736306, 10.276844, 16.302326, 6.86697, 9.66189, 15.768839, 7.134306, 9.500018, 15.418615, 7.241414, 9.825178, 15.579935, 7.1703434, 9.529699, 15.768839, 7.134306, 9.500018, 15.7336235, 7.169642, 10.347719, 15.418615, 7.241414, 9.825178, 17.788603, 5.4442396, 9.916714, 17.232166, 6.147483, 10.085447, 17.822802, 5.5103865, 9.856148, 17.232166, 6.147483, 10.085447, 17.788603, 5.4442396, 9.916714, 17.429657, 5.7386765, 10.057089, 17.429657, 5.7386765, 10.057089, 17.788603, 5.4442396, 9.916714, 17.469614, 5.541645, 10.084452, 17.232166, 6.147483, 10.085447, 16.729776, 6.127803, 10.365282, 16.58012, 6.736306, 10.276844, 17.232166, 6.147483, 10.085447, 16.926506, 5.9454803, 10.319639, 16.729776, 6.127803, 10.365282, 16.288668, 6.0046787, 10.627327, 15.7336235, 7.169642, 10.347719, 16.58012, 6.736306, 10.276844, 15.7336235, 7.169642, 10.347719, 16.288668, 6.0046787, 10.627327, 15.925083, 6.171483, 10.651344, 15.7336235, 7.169642, 10.347719, 15.925083, 6.171483, 10.651344, 15.8492565, 6.533848, 10.554647, 15.306034, 6.9726505, 10.442774, 14.960796, 7.3177958, 10.284792, 15.7336235, 7.169642, 10.347719, 14.960796, 7.3177958, 10.284792, 15.306034, 6.9726505, 10.442774, 15.061283, 6.615505, 10.587776, 14.960796, 7.3177958, 10.284792, 15.061283, 6.615505, 10.587776, 14.899889, 6.6811314, 10.556076, 15.7336235, 7.169642, 10.347719, 16.302326, 6.86697, 9.66189, 16.58012, 6.736306, 10.276844, 15.95689, 7.068595, 9.972179, 16.302326, 6.86697, 9.66189, 15.7336235, 7.169642, 10.347719, 16.302326, 6.86697, 9.66189, 15.95689, 7.068595, 9.972179, 16.037476, 6.9235826, 9.459768, 16.302326, 6.86697, 9.66189, 16.037476, 6.9235826, 9.459768, 16.200966, 6.8668146, 9.453747, 15.7336235, 7.169642, 10.347719, 15.948803, 7.0493326, 9.487534, 15.95689, 7.068595, 9.972179, 15.7336235, 7.169642, 10.347719, 15.768839, 7.134306, 9.500018, 15.948803, 7.0493326, 9.487534, 15.8492565, 6.533848, 10.554647, 15.598484, 6.34639, 10.67927, 15.7336235, 7.169642, 10.347719, 15.8492565, 6.533848, 10.554647, 15.754543, 6.2731757, 10.668556, 15.598484, 6.34639, 10.67927, 14.960796, 7.3177958, 10.284792, 15.418615, 7.241414, 9.825178, 15.7336235, 7.169642, 10.347719, 15.418615, 7.241414, 9.825178, 14.960796, 7.3177958, 10.284792, 15.035656, 7.2923393, 9.619492, 15.418615, 7.241414, 9.825178, 15.035656, 7.2923393, 9.619492, 15.302166, 7.2475796, 9.57913, 15.306034, 6.9726505, 10.442774, 15.598484, 6.34639, 10.67927, 15.17808, 6.500619, 10.592104, 15.306034, 6.9726505, 10.442774, 15.7336235, 7.169642, 10.347719, 15.598484, 6.34639, 10.67927, 14.230383, 7.219601, 10.105017, 14.762205, 7.297971, 9.966335, 14.960796, 7.3177958, 10.284792, 14.762205, 7.297971, 9.966335, 14.230383, 7.219601, 10.105017, 14.228041, 7.218266, 9.957092, 14.762205, 7.297971, 9.966335, 14.228041, 7.218266, 9.957092, 14.580687, 7.2687683, 9.813696, 16.729776, 6.127803, 10.365282, 16.288668, 6.0046787, 10.627327, 16.58012, 6.736306, 10.276844, 16.729776, 6.127803, 10.365282, 16.561163, 5.9042377, 10.517782, 16.288668, 6.0046787, 10.627327, 16.926506, 5.9454803, 10.319639, 16.737123, 5.796604, 10.437109, 16.729776, 6.127803, 10.365282, 16.926506, 5.9454803, 10.319639, 16.830635, 5.779464, 10.403534, 16.737123, 5.796604, 10.437109, 16.926506, 5.9454803, 10.319639, 17.232166, 6.147483, 10.085447, 17.020973, 5.7145977, 10.328281, 17.429657, 5.7386765, 10.057089, 17.020973, 5.7145977, 10.328281, 17.232166, 6.147483, 10.085447, 17.429657, 5.7386765, 10.057089, 17.308277, 5.615484, 10.174715, 17.020973, 5.7145977, 10.328281, 13.748751, 7.053542, 10.572222, 14.344303, 7.2258663, 9.903076, 14.400131, 7.268545, 10.054003, 13.748751, 7.053542, 10.572222, 13.42976, 6.790598, 9.931854, 14.344303, 7.2258663, 9.903076, 14.244236, 6.5294213, 10.857023, 14.149033, 6.936182, 10.532454, 14.338385, 6.748352, 10.605932, 14.244236, 6.5294213, 10.857023, 13.748751, 7.053542, 10.572222, 14.149033, 6.936182, 10.532454, 11.830196, 3.7078786, 11.580435, 12.08853, 4.698938, 11.459175, 12.606657, 4.4480114, 11.634403, 11.830196, 3.7078786, 11.580435, 11.739759, 3.7365186, 11.530159, 12.08853, 4.698938, 11.459175, 12.08853, 4.698938, 11.459175, 12.792095, 4.643725, 11.622538, 12.606657, 4.4480114, 11.634403, 12.08853, 4.698938, 11.459175, 12.569534, 4.9534965, 11.509512, 12.792095, 4.643725, 11.622538, 12.569534, 4.9534965, 11.509512, 12.08853, 4.698938, 11.459175, 12.50172, 5.6512947, 11.328012, 12.569534, 4.9534965, 11.509512, 12.50172, 5.6512947, 11.328012, 13.291006, 5.162043, 11.5888405, 12.569534, 4.9534965, 11.509512, 13.291006, 5.162043, 11.5888405, 12.958977, 4.8188252, 11.61166, 13.291006, 5.162043, 11.5888405, 13.2354355, 5.49573, 11.458206, 13.363539, 5.246913, 11.546379, 13.291006, 5.162043, 11.5888405, 12.50172, 5.6512947, 11.328012, 13.2354355, 5.49573, 11.458206, 13.796944, 5.897662, 11.320793, 13.790836, 6.4103017, 11.012831, 13.913025, 6.053091, 11.199114, 13.796944, 5.897662, 11.320793, 13.121664, 6.529729, 10.9958515, 13.790836, 6.4103017, 11.012831, 11.699358, 3.746626, 11.430775, 12.08853, 4.698938, 11.459175, 11.739759, 3.7365186, 11.530159, 12.08853, 4.698938, 11.459175, 11.699358, 3.746626, 11.430775, 11.891642, 4.2572117, 11.316582, 11.891642, 4.2572117, 11.316582, 11.699358, 3.746626, 11.430775, 11.803057, 4.0996614, 11.194469, 12.08853, 4.698938, 11.459175, 12.198441, 5.1560144, 10.946365, 12.50172, 5.6512947, 11.328012, 12.08853, 4.698938, 11.459175, 12.062822, 4.8732367, 10.978052, 12.198441, 5.1560144, 10.946365, 12.262251, 5.4878073, 10.418972, 13.121664, 6.529729, 10.9958515, 12.50172, 5.6512947, 11.328012, 13.121664, 6.529729, 10.9958515, 12.262251, 5.4878073, 10.418972, 12.532429, 5.8353195, 10.266994, 13.121664, 6.529729, 10.9958515, 12.532429, 5.8353195, 10.266994, 12.735952, 6.1089916, 10.515257, 13.298405, 6.7030754, 10.491749, 13.748751, 7.053542, 10.572222, 13.121664, 6.529729, 10.9958515, 13.748751, 7.053542, 10.572222, 13.298405, 6.7030754, 10.491749, 13.275257, 6.6692533, 9.985384, 13.748751, 7.053542, 10.572222, 13.275257, 6.6692533, 9.985384, 13.42976, 6.790598, 9.931854, 13.121664, 6.529729, 10.9958515, 13.2354355, 5.49573, 11.458206, 12.50172, 5.6512947, 11.328012, 13.256226, 6.064356, 11.224297, 13.2354355, 5.49573, 11.458206, 13.121664, 6.529729, 10.9958515, 13.2354355, 5.49573, 11.458206, 13.256226, 6.064356, 11.224297, 13.609962, 5.5398574, 11.403032, 13.2354355, 5.49573, 11.458206, 13.609962, 5.5398574, 11.403032, 13.485888, 5.4047327, 11.477678, 13.121664, 6.529729, 10.9958515, 13.663889, 5.719082, 11.394192, 13.256226, 6.064356, 11.224297, 13.121664, 6.529729, 10.9958515, 13.796944, 5.897662, 11.320793, 13.663889, 5.719082, 11.394192, 12.735952, 6.1089916, 10.515257, 12.770527, 6.18994, 10.142353, 13.121664, 6.529729, 10.9958515, 12.735952, 6.1089916, 10.515257, 12.654997, 6.03539, 10.206213, 12.770527, 6.18994, 10.142353, 13.748751, 7.053542, 10.572222, 13.790836, 6.4103017, 11.012831, 13.121664, 6.529729, 10.9958515, 13.790836, 6.4103017, 11.012831, 13.748751, 7.053542, 10.572222, 14.244236, 6.5294213, 10.857023, 13.790836, 6.4103017, 11.012831, 14.244236, 6.5294213, 10.857023, 14.080233, 6.311716, 11.029364, 13.298405, 6.7030754, 10.491749, 12.770527, 6.18994, 10.142353, 13.176046, 6.4788733, 9.995405, 13.298405, 6.7030754, 10.491749, 13.121664, 6.529729, 10.9958515, 12.770527, 6.18994, 10.142353, 14.400131, 7.268545, 10.054003, 14.149033, 6.936182, 10.532454, 13.748751, 7.053542, 10.572222, 14.149033, 6.936182, 10.532454, 14.400131, 7.268545, 10.054003, 14.524361, 7.1721907, 10.108967, 14.149033, 6.936182, 10.532454, 14.524361, 7.1721907, 10.108967, 14.399626, 6.918585, 10.443947, 12.198441, 5.1560144, 10.946365, 12.262251, 5.4878073, 10.418972, 12.50172, 5.6512947, 11.328012, 12.198441, 5.1560144, 10.946365, 12.143154, 5.1808786, 10.591608, 12.262251, 5.4878073, 10.418972, 12.062822, 4.8732367, 10.978052, 12.071648, 4.931636, 10.687195, 12.198441, 5.1560144, 10.946365, 12.062822, 4.8732367, 10.978052, 12.028627, 4.8476563, 10.753109, 12.071648, 4.931636, 10.687195, 12.062822, 4.8732367, 10.978052, 12.08853, 4.698938, 11.459175, 11.94441, 4.6445174, 10.876879, 11.891642, 4.2572117, 11.316582, 11.94441, 4.6445174, 10.876879, 12.08853, 4.698938, 11.459175, 11.891642, 4.2572117, 11.316582, 11.852747, 4.307365, 11.084038, 11.94441, 4.6445174, 10.876879, 13.7075405, 7.556304, 10.0746155, 14.456242, 7.1163726, 9.9533615, 14.450766, 7.1982546, 10.098274, 13.7075405, 7.556304, 10.0746155, 13.637535, 7.179911, 9.4115, 14.456242, 7.1163726, 9.9533615, 13.580511, 7.079011, 10.661566, 13.885704, 7.279489, 10.325115, 13.870678, 7.088043, 10.517448, 13.580511, 7.079011, 10.661566, 13.7075405, 7.556304, 10.0746155, 13.885704, 7.279489, 10.325115, 10.434713, 6.2257376, 9.758102, 11.151068, 6.834375, 9.774982, 11.238207, 6.5067883, 10.272303, 10.434713, 6.2257376, 9.758102, 10.420666, 6.2614727, 9.657367, 11.151068, 6.834375, 9.774982, 11.151068, 6.834375, 9.774982, 11.449902, 6.5769014, 10.375746, 11.238207, 6.5067883, 10.272303, 11.151068, 6.834375, 9.774982, 11.530296, 6.857931, 10.121874, 11.449902, 6.5769014, 10.375746, 11.530296, 6.857931, 10.121874, 11.151068, 6.834375, 9.774982, 11.933365, 7.3444357, 9.894124, 11.530296, 6.857931, 10.121874, 11.933365, 7.3444357, 9.894124, 12.01959, 6.757763, 10.651842, 11.530296, 6.857931, 10.121874, 12.01959, 6.757763, 10.651842, 11.640572, 6.6390653, 10.468557, 12.01959, 6.757763, 10.651842, 12.206385, 6.9807854, 10.499392, 12.129288, 6.772664, 10.661032, 12.01959, 6.757763, 10.651842, 11.933365, 7.3444357, 9.894124, 12.206385, 6.9807854, 10.499392, 12.789576, 6.995577, 10.750685, 13.181564, 7.251497, 10.484621, 12.994299, 7.0094805, 10.72579, 12.789576, 6.995577, 10.750685, 12.882765, 7.613677, 10.007544, 13.181564, 7.251497, 10.484621, 10.444181, 6.238669, 9.556094, 11.151068, 6.834375, 9.774982, 10.420666, 6.2614727, 9.657367, 11.151068, 6.834375, 9.774982, 10.444181, 6.238669, 9.556094, 10.868927, 6.502743, 9.566353, 10.868927, 6.502743, 9.566353, 10.444181, 6.238669, 9.556094, 10.796675, 6.356696, 9.423105, 11.151068, 6.834375, 9.774982, 11.658583, 6.90143, 9.442226, 11.933365, 7.3444357, 9.894124, 11.151068, 6.834375, 9.774982, 11.422882, 6.7517605, 9.392457, 11.658583, 6.90143, 9.442226, 12.092066, 6.8811474, 9.071436, 12.882765, 7.613677, 10.007544, 11.933365, 7.3444357, 9.894124, 12.882765, 7.613677, 10.007544, 12.092066, 6.8811474, 9.071436, 12.501753, 6.965708, 9.113264, 12.882765, 7.613677, 10.007544, 12.501753, 6.965708, 9.113264, 12.637543, 7.2165165, 9.423414, 13.274715, 7.4356117, 9.746176, 13.7075405, 7.556304, 10.0746155, 12.882765, 7.613677, 10.007544, 13.7075405, 7.556304, 10.0746155, 13.274715, 7.4356117, 9.746176, 13.45668, 7.17616, 9.358056, 13.7075405, 7.556304, 10.0746155, 13.45668, 7.17616, 9.358056, 13.637535, 7.179911, 9.4115, 12.882765, 7.613677, 10.007544, 12.206385, 6.9807854, 10.499392, 11.933365, 7.3444357, 9.894124, 12.606947, 7.305357, 10.3043785, 12.206385, 6.9807854, 10.499392, 12.882765, 7.613677, 10.007544, 12.206385, 6.9807854, 10.499392, 12.606947, 7.305357, 10.3043785, 12.502178, 6.827238, 10.693289, 12.206385, 6.9807854, 10.499392, 12.502178, 6.827238, 10.693289, 12.314716, 6.8113565, 10.680117, 12.882765, 7.613677, 10.007544, 12.587612, 6.947036, 10.728325, 12.606947, 7.305357, 10.3043785, 12.882765, 7.613677, 10.007544, 12.789576, 6.995577, 10.750685, 12.587612, 6.947036, 10.728325, 12.637543, 7.2165165, 9.423414, 12.864445, 7.0854006, 9.161785, 12.882765, 7.613677, 10.007544, 12.637543, 7.2165165, 9.423414, 12.688946, 7.04373, 9.142518, 12.864445, 7.0854006, 9.161785, 13.7075405, 7.556304, 10.0746155, 13.181564, 7.251497, 10.484621, 12.882765, 7.613677, 10.007544, 13.181564, 7.251497, 10.484621, 13.7075405, 7.556304, 10.0746155, 13.580511, 7.079011, 10.661566, 13.181564, 7.251497, 10.484621, 13.580511, 7.079011, 10.661566, 13.291115, 7.061289, 10.697266, 13.274715, 7.4356117, 9.746176, 12.864445, 7.0854006, 9.161785, 13.339142, 7.0672264, 9.294153, 13.274715, 7.4356117, 9.746176, 12.882765, 7.613677, 10.007544, 12.864445, 7.0854006, 9.161785, 14.450766, 7.1982546, 10.098274, 13.885704, 7.279489, 10.325115, 13.7075405, 7.556304, 10.0746155, 13.885704, 7.279489, 10.325115, 14.450766, 7.1982546, 10.098274, 14.443308, 7.0981884, 10.231224, 13.885704, 7.279489, 10.325115, 14.443308, 7.0981884, 10.231224, 14.063122, 7.117878, 10.426937, 11.658583, 6.90143, 9.442226, 12.092066, 6.8811474, 9.071436, 11.933365, 7.3444357, 9.894124, 11.658583, 6.90143, 9.442226, 11.79088, 6.773697, 9.139975, 12.092066, 6.8811474, 9.071436, 11.422882, 6.7517605, 9.392457, 11.603992, 6.6508856, 9.16963, 11.658583, 6.90143, 9.442226, 11.422882, 6.7517605, 9.392457, 11.497446, 6.636342, 9.199318, 11.603992, 6.6508856, 9.16963, 11.422882, 6.7517605, 9.392457, 11.151068, 6.834375, 9.774982, 11.28582, 6.5728126, 9.250239, 10.868927, 6.502743, 9.566353, 11.28582, 6.5728126, 9.250239, 11.151068, 6.834375, 9.774982, 10.868927, 6.502743, 9.566353, 10.970734, 6.4467087, 9.364567, 11.28582, 6.5728126, 9.250239, 14.070913, 7.495411, 9.618036, 14.482357, 7.125392, 10.12579, 14.3754425, 7.195709, 10.181591, 14.070913, 7.495411, 9.618036, 14.516771, 7.173098, 9.291218, 14.482357, 7.125392, 10.12579, 13.583624, 7.1059093, 9.775603, 13.968065, 7.2646875, 9.861715, 13.816387, 7.1105375, 9.930347, 13.583624, 7.1059093, 9.775603, 14.070913, 7.495411, 9.618036, 13.968065, 7.2646875, 9.861715, 12.772589, 6.376586, 6.9820247, 13.099979, 6.904664, 7.5420585, 12.775024, 6.637413, 7.820493, 12.772589, 6.376586, 6.9820247, 12.839212, 6.4047265, 6.9280143, 13.099979, 6.904664, 7.5420585, 13.099979, 6.904664, 7.5420585, 12.79912, 6.699265, 8.027189, 12.775024, 6.637413, 7.820493, 13.099979, 6.904664, 7.5420585, 13.025673, 6.931345, 7.982105, 12.79912, 6.699265, 8.027189, 13.025673, 6.931345, 7.982105, 13.099979, 6.904664, 7.5420585, 13.384867, 7.3345337, 8.193618, 13.025673, 6.931345, 7.982105, 13.384867, 7.3345337, 8.193618, 12.864683, 6.8550787, 8.580061, 13.025673, 6.931345, 7.982105, 12.864683, 6.8550787, 8.580061, 12.820887, 6.753347, 8.212795, 12.864683, 6.8550787, 8.580061, 13.068455, 7.0369205, 8.661718, 12.906773, 6.8680534, 8.665814, 12.864683, 6.8550787, 8.580061, 13.384867, 7.3345337, 8.193618, 13.068455, 7.0369205, 8.661718, 13.15687, 7.046695, 9.214457, 13.535355, 7.2501936, 9.400614, 13.26737, 7.0566998, 9.358015, 13.15687, 7.046695, 9.214457, 13.745743, 7.551609, 8.966543, 13.535355, 7.2501936, 9.400614, 12.922939, 6.384966, 6.9034257, 13.099979, 6.904664, 7.5420585, 12.839212, 6.4047265, 6.9280143, 13.099979, 6.904664, 7.5420585, 12.922939, 6.384966, 6.9034257, 13.11478, 6.619231, 7.236095, 13.11478, 6.619231, 7.236095, 12.922939, 6.384966, 6.9034257, 13.179651, 6.491927, 7.1159973, 13.099979, 6.904664, 7.5420585, 13.577553, 6.959513, 7.7937083, 13.384867, 7.3345337, 8.193618, 13.099979, 6.904664, 7.5420585, 13.501598, 6.832964, 7.5911536, 13.577553, 6.959513, 7.7937083, 14.043669, 6.938242, 7.9677033, 13.745743, 7.551609, 8.966543, 13.384867, 7.3345337, 8.193618, 13.745743, 7.551609, 8.966543, 14.043669, 6.938242, 7.9677033, 14.200254, 7.008704, 8.294954, 13.745743, 7.551609, 8.966543, 14.200254, 7.008704, 8.294954, 14.049522, 7.2166758, 8.535611, 14.115025, 7.3930063, 9.158257, 14.070913, 7.495411, 9.618036, 13.745743, 7.551609, 8.966543, 14.070913, 7.495411, 9.618036, 14.115025, 7.3930063, 9.158257, 14.474133, 7.170848, 9.13312, 14.070913, 7.495411, 9.618036, 14.474133, 7.170848, 9.13312, 14.516771, 7.173098, 9.291218, 13.745743, 7.551609, 8.966543, 13.068455, 7.0369205, 8.661718, 13.384867, 7.3345337, 8.193618, 13.402321, 7.300085, 8.886555, 13.068455, 7.0369205, 8.661718, 13.745743, 7.551609, 8.966543, 13.068455, 7.0369205, 8.661718, 13.402321, 7.300085, 8.886555, 13.049887, 6.9149427, 8.958126, 13.068455, 7.0369205, 8.661718, 13.049887, 6.9149427, 8.958126, 12.977623, 6.9004726, 8.814155, 13.745743, 7.551609, 8.966543, 13.079823, 7.007822, 9.05171, 13.402321, 7.300085, 8.886555, 13.745743, 7.551609, 8.966543, 13.15687, 7.046695, 9.214457, 13.079823, 7.007822, 9.05171, 14.049522, 7.2166758, 8.535611, 14.337751, 7.1039696, 8.595517, 13.745743, 7.551609, 8.966543, 14.049522, 7.2166758, 8.535611, 14.270794, 7.0704823, 8.454195, 14.337751, 7.1039696, 8.595517, 14.070913, 7.495411, 9.618036, 13.535355, 7.2501936, 9.400614, 13.745743, 7.551609, 8.966543, 13.535355, 7.2501936, 9.400614, 14.070913, 7.495411, 9.618036, 13.583624, 7.1059093, 9.775603, 13.535355, 7.2501936, 9.400614, 13.583624, 7.1059093, 9.775603, 13.427256, 7.094145, 9.573523, 14.115025, 7.3930063, 9.158257, 14.337751, 7.1039696, 8.595517, 14.450401, 7.090761, 9.003662, 14.115025, 7.3930063, 9.158257, 13.745743, 7.551609, 8.966543, 14.337751, 7.1039696, 8.595517, 14.3754425, 7.195709, 10.181591, 13.968065, 7.2646875, 9.861715, 14.070913, 7.495411, 9.618036, 13.968065, 7.2646875, 9.861715, 14.3754425, 7.195709, 10.181591, 14.275515, 7.113496, 10.233852, 13.968065, 7.2646875, 9.861715, 14.275515, 7.113496, 10.233852, 13.9707985, 7.1304455, 10.03817, 13.577553, 6.959513, 7.7937083, 14.043669, 6.938242, 7.9677033, 13.384867, 7.3345337, 8.193618, 13.577553, 6.959513, 7.7937083, 13.853798, 6.849599, 7.7665267, 14.043669, 6.938242, 7.9677033, 13.501598, 6.832964, 7.5911536, 13.736696, 6.747884, 7.6274853, 13.577553, 6.959513, 7.7937083, 13.501598, 6.832964, 7.5911536, 13.669174, 6.7349615, 7.561953, 13.736696, 6.747884, 7.6274853, 13.501598, 6.832964, 7.5911536, 13.099979, 6.904664, 7.5420585, 13.535788, 6.6803236, 7.4230866, 13.11478, 6.619231, 7.236095, 13.535788, 6.6803236, 7.4230866, 13.099979, 6.904664, 7.5420585, 13.11478, 6.619231, 7.236095, 13.306187, 6.5714235, 7.228906, 13.535788, 6.6803236, 7.4230866, 14.818359, 7.5795794, 9.704287, 14.319729, 7.1040306, 10.273739, 14.231741, 7.193877, 10.164581, 14.818359, 7.5795794, 9.704287, 15.293608, 7.170624, 10.134708, 14.319729, 7.1040306, 10.273739, 14.53705, 7.1410728, 9.124798, 14.520617, 7.3097606, 9.621042, 14.407236, 7.130357, 9.437237, 14.53705, 7.1410728, 9.124798, 14.818359, 7.5795794, 9.704287, 14.520617, 7.3097606, 9.621042, 17.50299, 6.374856, 7.3705115, 16.95148, 6.951913, 7.9566584, 16.564781, 6.648938, 7.610077, 17.50299, 6.374856, 7.3705115, 17.578213, 6.4056153, 7.4395566, 16.95148, 6.951913, 7.9566584, 16.95148, 6.951913, 7.9566584, 16.337984, 6.7154865, 7.697535, 16.564781, 6.648938, 7.610077, 16.95148, 6.951913, 7.9566584, 16.44146, 6.978112, 7.98315, 16.337984, 6.7154865, 7.697535, 16.44146, 6.978112, 7.98315, 16.95148, 6.951913, 7.9566584, 16.283978, 7.4333143, 8.50886, 16.44146, 6.978112, 7.98315, 16.283978, 7.4333143, 8.50886, 15.729202, 6.886676, 7.930798, 16.44146, 6.978112, 7.98315, 15.729202, 6.886676, 7.930798, 16.134073, 6.774377, 7.7760997, 15.729202, 6.886676, 7.930798, 15.686707, 7.0922894, 8.219696, 15.639549, 6.8975234, 8.001675, 15.729202, 6.886676, 7.930798, 16.283978, 7.4333143, 8.50886, 15.686707, 7.0922894, 8.219696, 15.082333, 7.0959883, 8.468272, 14.956093, 7.31973, 8.992256, 14.942156, 7.0999613, 8.635822, 15.082333, 7.0959883, 8.468272, 15.490726, 7.667551, 9.160905, 14.956093, 7.31973, 8.992256, 17.624905, 6.3763094, 7.5322666, 16.95148, 6.951913, 7.9566584, 17.578213, 6.4056153, 7.4395566, 16.95148, 6.951913, 7.9566584, 17.624905, 6.3763094, 7.5322666, 17.296997, 6.6220546, 7.8690057, 17.296997, 6.6220546, 7.8690057, 17.624905, 6.3763094, 7.5322666, 17.441767, 6.4720078, 7.9004264, 16.95148, 6.951913, 7.9566584, 16.778732, 6.9787436, 8.60397, 16.283978, 7.4333143, 8.50886, 16.95148, 6.951913, 7.9566584, 16.988663, 6.836954, 8.447882, 16.778732, 6.9787436, 8.60397, 16.685303, 6.91991, 9.205566, 15.490726, 7.667551, 9.160905, 16.283978, 7.4333143, 8.50886, 15.490726, 7.667551, 9.160905, 16.685303, 6.91991, 9.205566, 16.34667, 6.989422, 9.478991, 15.490726, 7.667551, 9.160905, 16.34667, 6.989422, 9.478991, 16.0481, 7.250002, 9.387381, 15.358458, 7.458866, 9.642784, 14.818359, 7.5795794, 9.704287, 15.490726, 7.667551, 9.160905, 14.818359, 7.5795794, 9.704287, 15.358458, 7.458866, 9.642784, 15.46587, 7.1714168, 10.046328, 14.818359, 7.5795794, 9.704287, 15.46587, 7.1714168, 10.046328, 15.293608, 7.170624, 10.134708, 15.490726, 7.667551, 9.160905, 15.686707, 7.0922894, 8.219696, 16.283978, 7.4333143, 8.50886, 15.509426, 7.387882, 8.707602, 15.686707, 7.0922894, 8.219696, 15.490726, 7.667551, 9.160905, 15.686707, 7.0922894, 8.219696, 15.509426, 7.387882, 8.707602, 15.334177, 6.938472, 8.243979, 15.686707, 7.0922894, 8.219696, 15.334177, 6.938472, 8.243979, 15.486206, 6.9294643, 8.125624, 15.490726, 7.667551, 9.160905, 15.250263, 7.0548754, 8.33129, 15.509426, 7.387882, 8.707602, 15.490726, 7.667551, 9.160905, 15.082333, 7.0959883, 8.468272, 15.250263, 7.0548754, 8.33129, 16.0481, 7.250002, 9.387381, 16.040924, 7.0956764, 9.734488, 15.490726, 7.667551, 9.160905, 16.0481, 7.250002, 9.387381, 16.186634, 7.0604343, 9.615782, 16.040924, 7.0956764, 9.734488, 14.818359, 7.5795794, 9.704287, 14.956093, 7.31973, 8.992256, 15.490726, 7.667551, 9.160905, 14.956093, 7.31973, 8.992256, 14.818359, 7.5795794, 9.704287, 14.53705, 7.1410728, 9.124798, 14.956093, 7.31973, 8.992256, 14.53705, 7.1410728, 9.124798, 14.7350445, 7.1373453, 8.888584, 15.358458, 7.458866, 9.642784, 16.040924, 7.0956764, 9.734488, 15.592907, 7.0656147, 9.958109, 15.358458, 7.458866, 9.642784, 15.490726, 7.667551, 9.160905, 16.040924, 7.0956764, 9.734488, 14.231741, 7.193877, 10.164581, 14.520617, 7.3097606, 9.621042, 14.818359, 7.5795794, 9.704287, 14.520617, 7.3097606, 9.621042, 14.231741, 7.193877, 10.164581, 14.1518955, 7.1016655, 10.051222, 14.520617, 7.3097606, 9.621042, 14.1518955, 7.1016655, 10.051222, 14.318668, 7.147036, 9.652245, 16.778732, 6.9787436, 8.60397, 16.685303, 6.91991, 9.205566, 16.283978, 7.4333143, 8.50886, 16.778732, 6.9787436, 8.60397, 16.869965, 6.8293467, 8.917667, 16.685303, 6.91991, 9.205566, 16.988663, 6.836954, 8.447882, 16.991056, 6.717228, 8.721294, 16.778732, 6.9787436, 8.60397, 16.988663, 6.836954, 8.447882, 17.05367, 6.7085714, 8.62688, 16.991056, 6.717228, 8.721294, 16.988663, 6.836954, 8.447882, 16.95148, 6.951913, 7.9566584, 17.18201, 6.656856, 8.4283905, 17.296997, 6.6220546, 7.8690057, 17.18201, 6.656856, 8.4283905, 16.95148, 6.951913, 7.9566584, 17.296997, 6.6220546, 7.8690057, 17.347916, 6.550868, 8.092527, 17.18201, 6.656856, 8.4283905, 14.640917, 7.231346, 10.77033, 14.15225, 7.201992, 10.013128, 14.311281, 7.246917, 9.992706, 14.640917, 7.231346, 10.77033, 13.950329, 6.9789553, 10.945974, 14.15225, 7.201992, 10.013128, 15.086668, 6.645689, 10.496582, 14.715862, 7.027137, 10.425049, 14.856575, 6.812086, 10.301319, 15.086668, 6.645689, 10.496582, 14.640917, 7.231346, 10.77033, 14.715862, 7.027137, 10.425049, 15.405359, 4.506928, 13.294855, 15.268087, 5.398923, 12.871037, 15.5953045, 5.062126, 12.496258, 15.405359, 4.506928, 13.294855, 15.330811, 4.5490294, 13.357082, 15.268087, 5.398923, 12.871037, 15.268087, 5.398923, 12.871037, 15.614843, 5.2105064, 12.296331, 15.5953045, 5.062126, 12.496258, 15.268087, 5.398923, 12.871037, 15.418043, 5.546952, 12.416988, 15.614843, 5.2105064, 12.296331, 15.418043, 5.546952, 12.416988, 15.268087, 5.398923, 12.871037, 15.162661, 6.218977, 12.31654, 15.418043, 5.546952, 12.416988, 15.162661, 6.218977, 12.31654, 15.6678505, 5.60172, 11.757086, 15.418043, 5.546952, 12.416988, 15.6678505, 5.60172, 11.757086, 15.632406, 5.343074, 12.11624, 15.6678505, 5.60172, 11.757086, 15.4920025, 5.9232817, 11.72563, 15.641216, 5.6641035, 11.663549, 15.6678505, 5.60172, 11.757086, 15.162661, 6.218977, 12.31654, 15.4920025, 5.9232817, 11.72563, 15.469013, 6.1774178, 11.125845, 15.1226845, 6.643654, 10.969555, 15.370789, 6.2906885, 10.961456, 15.469013, 6.1774178, 11.125845, 14.925304, 6.9021482, 11.535374, 15.1226845, 6.643654, 10.969555, 15.222748, 4.557292, 13.366293, 15.268087, 5.398923, 12.871037, 15.330811, 4.5490294, 13.357082, 15.268087, 5.398923, 12.871037, 15.222748, 4.557292, 13.366293, 15.117676, 4.9987955, 13.081551, 15.117676, 4.9987955, 13.081551, 15.222748, 4.557292, 13.366293, 14.994282, 4.8528996, 13.149015, 15.268087, 5.398923, 12.871037, 14.755228, 5.765085, 12.572195, 15.162661, 6.218977, 12.31654, 15.268087, 5.398923, 12.871037, 14.77644, 5.523675, 12.745871, 14.755228, 5.765085, 12.572195, 14.232555, 6.018609, 12.3237705, 14.925304, 6.9021482, 11.535374, 15.162661, 6.218977, 12.31654, 14.925304, 6.9021482, 11.535374, 14.232555, 6.018609, 12.3237705, 14.130428, 6.281682, 11.9799385, 14.925304, 6.9021482, 11.535374, 14.130428, 6.281682, 11.9799385, 14.391569, 6.5280485, 11.829561, 14.462694, 6.9798803, 11.226421, 14.640917, 7.231346, 10.77033, 14.925304, 6.9021482, 11.535374, 14.640917, 7.231346, 10.77033, 14.462694, 6.9798803, 11.226421, 13.968893, 6.899996, 11.121994, 14.640917, 7.231346, 10.77033, 13.968893, 6.899996, 11.121994, 13.950329, 6.9789553, 10.945974, 14.925304, 6.9021482, 11.535374, 15.4920025, 5.9232817, 11.72563, 15.162661, 6.218977, 12.31654, 15.217165, 6.445463, 11.55835, 15.4920025, 5.9232817, 11.72563, 14.925304, 6.9021482, 11.535374, 15.4920025, 5.9232817, 11.72563, 15.217165, 6.445463, 11.55835, 15.550241, 5.8804913, 11.346338, 15.4920025, 5.9232817, 11.72563, 15.550241, 5.8804913, 11.346338, 15.594999, 5.783677, 11.508028, 14.925304, 6.9021482, 11.535374, 15.519932, 6.0406504, 11.294071, 15.217165, 6.445463, 11.55835, 14.925304, 6.9021482, 11.535374, 15.469013, 6.1774178, 11.125845, 15.519932, 6.0406504, 11.294071, 14.391569, 6.5280485, 11.829561, 14.036055, 6.5608177, 11.683962, 14.925304, 6.9021482, 11.535374, 14.391569, 6.5280485, 11.829561, 14.080282, 6.442515, 11.830221, 14.036055, 6.5608177, 11.683962, 14.640917, 7.231346, 10.77033, 15.1226845, 6.643654, 10.969555, 14.925304, 6.9021482, 11.535374, 15.1226845, 6.643654, 10.969555, 14.640917, 7.231346, 10.77033, 15.086668, 6.645689, 10.496582, 15.1226845, 6.643654, 10.969555, 15.086668, 6.645689, 10.496582, 15.225153, 6.48761, 10.729311, 14.462694, 6.9798803, 11.226421, 14.036055, 6.5608177, 11.683962, 13.989519, 6.7390223, 11.216955, 14.462694, 6.9798803, 11.226421, 14.925304, 6.9021482, 11.535374, 14.036055, 6.5608177, 11.683962, 14.311281, 7.246917, 9.992706, 14.715862, 7.027137, 10.425049, 14.640917, 7.231346, 10.77033, 14.715862, 7.027137, 10.425049, 14.311281, 7.246917, 9.992706, 14.403456, 7.132376, 9.914658, 14.715862, 7.027137, 10.425049, 14.403456, 7.132376, 9.914658, 14.700848, 6.947154, 10.176794, 14.755228, 5.765085, 12.572195, 14.232555, 6.018609, 12.3237705, 15.162661, 6.218977, 12.31654, 14.755228, 5.765085, 12.572195, 14.395441, 5.764677, 12.524948, 14.232555, 6.018609, 12.3237705, 14.77644, 5.523675, 12.745871, 14.502789, 5.5489907, 12.638502, 14.755228, 5.765085, 12.572195, 14.77644, 5.523675, 12.745871, 14.557829, 5.4834146, 12.714375, 14.502789, 5.5489907, 12.638502, 14.77644, 5.523675, 12.745871, 15.268087, 5.398923, 12.871037, 14.671074, 5.3173504, 12.858131, 15.117676, 4.9987955, 13.081551, 14.671074, 5.3173504, 12.858131, 15.268087, 5.398923, 12.871037, 15.117676, 4.9987955, 13.081551, 14.877726, 5.0318, 13.048248, 14.671074, 5.3173504, 12.858131, 15.855707, 1.5785854, 8.303576, 15.537302, 3.513335, 8.969594, 15.675556, 3.59141, 8.79463, 15.855707, 1.5785854, 8.303576, 15.684317, 1.4956186, 8.515871, 15.537302, 3.513335, 8.969594, 15.718592, -0.6945374, 7.979791, 15.684317, 1.4956186, 8.515871, 15.855707, 1.5785854, 8.303576, 15.718592, -0.6945374, 7.979791, 15.528423, -0.7451041, 8.231567, 15.684317, 1.4956186, 8.515871, 15.190344, 1.4642165, 8.406557, 15.070126, 3.5373333, 8.645098, 15.119511, 3.4761071, 8.8678665, 15.190344, 1.4642165, 8.406557, 15.135492, 1.5326246, 8.145638, 15.070126, 3.5373333, 8.645098, 15.578283, 1.6655294, 7.8817935, 15.624922, 3.6523986, 8.571777, 15.435907, 3.6665154, 8.430279, 15.578283, 1.6655294, 7.8817935, 15.805153, 1.6476903, 8.039993, 15.624922, 3.6523986, 8.571777, 15.119511, 3.4761071, 8.8678665, 14.720741, 5.3593645, 9.339607, 14.75539, 5.3158965, 9.486606, 15.119511, 3.4761071, 8.8678665, 15.070126, 3.5373333, 8.645098, 14.720741, 5.3593645, 9.339607, 15.675556, 3.59141, 8.79463, 15.031363, 5.349116, 9.558678, 15.124321, 5.4062643, 9.4429035, 15.675556, 3.59141, 8.79463, 15.537302, 3.513335, 8.969594, 15.031363, 5.349116, 9.558678, 15.124321, 5.4062643, 9.4429035, 15.031363, 5.349116, 9.558678, 14.700575, 6.30957, 9.911303, 15.124321, 5.4062643, 9.4429035, 14.700575, 6.30957, 9.911303, 14.765755, 6.3641186, 9.829805, 15.684317, 1.4956186, 8.515871, 15.309, 3.4624698, 9.008275, 15.537302, 3.513335, 8.969594, 15.684317, 1.4956186, 8.515871, 15.412914, 1.4456806, 8.567421, 15.309, 3.4624698, 9.008275, 15.537302, 3.513335, 8.969594, 15.309, 3.4624698, 9.008275, 14.880146, 5.309407, 9.581961, 15.537302, 3.513335, 8.969594, 14.880146, 5.309407, 9.581961, 15.031363, 5.349116, 9.558678, 15.135492, 1.5326246, 8.145638, 15.208366, 3.6164234, 8.469492, 15.070126, 3.5373333, 8.645098, 15.135492, 1.5326246, 8.145638, 15.30286, 1.6151665, 7.9359193, 15.208366, 3.6164234, 8.469492, 15.070126, 3.5373333, 8.645098, 15.208366, 3.6164234, 8.469492, 14.811323, 5.4180756, 9.224138, 15.070126, 3.5373333, 8.645098, 14.811323, 5.4180756, 9.224138, 14.720741, 5.3593645, 9.339607, 15.435907, 3.6665154, 8.430279, 15.090517, 5.4490795, 9.293634, 14.963499, 5.456666, 9.198397, 15.435907, 3.6665154, 8.430279, 15.624922, 3.6523986, 8.571777, 15.090517, 5.4490795, 9.293634, 15.805153, 1.6476903, 8.039993, 15.675556, 3.59141, 8.79463, 15.624922, 3.6523986, 8.571777, 15.805153, 1.6476903, 8.039993, 15.855707, 1.5785854, 8.303576, 15.675556, 3.59141, 8.79463, 15.624922, 3.6523986, 8.571777, 15.124321, 5.4062643, 9.4429035, 15.090517, 5.4490795, 9.293634, 15.624922, 3.6523986, 8.571777, 15.675556, 3.59141, 8.79463, 15.124321, 5.4062643, 9.4429035, 15.30286, 1.6151665, 7.9359193, 15.435907, 3.6665154, 8.430279, 15.208366, 3.6164234, 8.469492, 15.30286, 1.6151665, 7.9359193, 15.578283, 1.6655294, 7.8817935, 15.435907, 3.6665154, 8.430279, 15.080032, -0.60457873, 7.549851, 15.578283, 1.6655294, 7.8817935, 15.30286, 1.6151665, 7.9359193, 15.080032, -0.60457873, 7.549851, 15.392487, -0.5923369, 7.483996, 15.578283, 1.6655294, 7.8817935, 15.208366, 3.6164234, 8.469492, 14.963499, 5.456666, 9.198397, 14.811323, 5.4180756, 9.224138, 15.208366, 3.6164234, 8.469492, 15.435907, 3.6665154, 8.430279, 14.963499, 5.456666, 9.198397, 14.811323, 5.4180756, 9.224138, 14.963499, 5.456666, 9.198397, 14.646309, 6.401553, 9.648203, 14.811323, 5.4180756, 9.224138, 14.646309, 6.401553, 9.648203, 14.5366535, 6.3609424, 9.662085, 14.498898, 6.2705493, 9.8520975, 14.315634, 6.982005, 10.216946, 14.590864, 6.2697954, 9.924797, 14.498898, 6.2705493, 9.8520975, 14.248718, 6.9810524, 10.163109, 14.315634, 6.982005, 10.216946, 14.700575, 6.30957, 9.911303, 14.437746, 7.065465, 10.1538315, 14.765755, 6.3641186, 9.829805, 14.700575, 6.30957, 9.911303, 14.392586, 7.019636, 10.210747, 14.437746, 7.065465, 10.1538315, 14.590864, 6.2697954, 9.924797, 14.392586, 7.019636, 10.210747, 14.700575, 6.30957, 9.911303, 14.590864, 6.2697954, 9.924797, 14.315634, 6.982005, 10.216946, 14.392586, 7.019636, 10.210747, 14.73908, 6.400427, 9.720892, 14.35066, 7.092757, 10.021431, 14.646309, 6.401553, 9.648203, 14.73908, 6.400427, 9.720892, 14.416679, 7.0957565, 10.076281, 14.35066, 7.092757, 10.021431, 14.765755, 6.3641186, 9.829805, 14.416679, 7.0957565, 10.076281, 14.73908, 6.400427, 9.720892, 14.765755, 6.3641186, 9.829805, 14.437746, 7.065465, 10.1538315, 14.416679, 7.0957565, 10.076281, 14.5366535, 6.3609424, 9.662085, 14.22855, 7.0092974, 10.084545, 14.471951, 6.307063, 9.744005, 14.5366535, 6.3609424, 9.662085, 14.27281, 7.057174, 10.028643, 14.22855, 7.0092974, 10.084545, 14.646309, 6.401553, 9.648203, 14.27281, 7.057174, 10.028643, 14.5366535, 6.3609424, 9.662085, 14.646309, 6.401553, 9.648203, 14.35066, 7.092757, 10.021431, 14.27281, 7.057174, 10.028643, 15.214357, -0.7575648, 8.298452, 15.190344, 1.4642165, 8.406557, 15.412914, 1.4456806, 8.567421, 15.214357, -0.7575648, 8.298452, 14.957146, -0.7182157, 8.110065, 15.190344, 1.4642165, 8.406557, 14.471951, 6.307063, 9.744005, 14.248718, 6.9810524, 10.163109, 14.498898, 6.2705493, 9.8520975, 14.471951, 6.307063, 9.744005, 14.22855, 7.0092974, 10.084545, 14.248718, 6.9810524, 10.163109, 15.412914, 1.4456806, 8.567421, 15.119511, 3.4761071, 8.8678665, 15.309, 3.4624698, 9.008275, 15.412914, 1.4456806, 8.567421, 15.190344, 1.4642165, 8.406557, 15.119511, 3.4761071, 8.8678665, 14.957146, -0.7182157, 8.110065, 15.135492, 1.5326246, 8.145638, 15.190344, 1.4642165, 8.406557, 14.957146, -0.7182157, 8.110065, 14.888254, -0.6553638, 7.8026576, 15.135492, 1.5326246, 8.145638, 15.392487, -0.5923369, 7.483996, 15.805153, 1.6476903, 8.039993, 15.578283, 1.6655294, 7.8817935, 15.392487, -0.5923369, 7.483996, 15.648527, -0.6318462, 7.673121, 15.805153, 1.6476903, 8.039993, 15.528423, -0.7451041, 8.231567, 15.412914, 1.4456806, 8.567421, 15.684317, 1.4956186, 8.515871, 15.528423, -0.7451041, 8.231567, 15.214357, -0.7575648, 8.298452, 15.412914, 1.4456806, 8.567421, 14.888254, -0.6553638, 7.8026576, 15.30286, 1.6151665, 7.9359193, 15.135492, 1.5326246, 8.145638, 14.888254, -0.6553638, 7.8026576, 15.080032, -0.60457873, 7.549851, 15.30286, 1.6151665, 7.9359193, 15.648527, -0.6318462, 7.673121, 15.855707, 1.5785854, 8.303576, 15.805153, 1.6476903, 8.039993, 15.648527, -0.6318462, 7.673121, 15.718592, -0.6945374, 7.979791, 15.855707, 1.5785854, 8.303576, 15.309, 3.4624698, 9.008275, 14.75539, 5.3158965, 9.486606, 14.880146, 5.309407, 9.581961, 15.309, 3.4624698, 9.008275, 15.119511, 3.4761071, 8.8678665, 14.75539, 5.3158965, 9.486606, 14.880146, 5.309407, 9.581961, 14.498898, 6.2705493, 9.8520975, 14.590864, 6.2697954, 9.924797, 14.880146, 5.309407, 9.581961, 14.75539, 5.3158965, 9.486606, 14.498898, 6.2705493, 9.8520975, 14.75539, 5.3158965, 9.486606, 14.471951, 6.307063, 9.744005, 14.498898, 6.2705493, 9.8520975, 14.75539, 5.3158965, 9.486606, 14.720741, 5.3593645, 9.339607, 14.471951, 6.307063, 9.744005, 15.031363, 5.349116, 9.558678, 14.590864, 6.2697954, 9.924797, 14.700575, 6.30957, 9.911303, 15.031363, 5.349116, 9.558678, 14.880146, 5.309407, 9.581961, 14.590864, 6.2697954, 9.924797, 14.963499, 5.456666, 9.198397, 14.73908, 6.400427, 9.720892, 14.646309, 6.401553, 9.648203, 14.963499, 5.456666, 9.198397, 15.090517, 5.4490795, 9.293634, 14.73908, 6.400427, 9.720892, 15.090517, 5.4490795, 9.293634, 14.765755, 6.3641186, 9.829805, 14.73908, 6.400427, 9.720892, 15.090517, 5.4490795, 9.293634, 15.124321, 5.4062643, 9.4429035, 14.765755, 6.3641186, 9.829805, 14.720741, 5.3593645, 9.339607, 14.5366535, 6.3609424, 9.662085, 14.471951, 6.307063, 9.744005, 14.720741, 5.3593645, 9.339607, 14.811323, 5.4180756, 9.224138, 14.5366535, 6.3609424, 9.662085, -18.8297, 3.3895998, -9.473499, -19.616299, 3.2075999, -9.711899, -19.1775, 3.1662998, -9.7628, -18.8297, 3.3895998, -9.473499, -19.3743, 3.391, -9.417299, -19.616299, 3.2075999, -9.711899, -19.3743, 3.391, -9.417299, -19.611, 3.187, -9.246899, -19.616299, 3.2075999, -9.711899, 10.0335, 3.3913999, -10.0343, 13.378099, 3.3913999, -13.378599, 13.378099, 3.3913999, -10.0343, 13.378099, 3.3913999, -13.378599, 16.722599, 3.3913999, -10.0343, 13.378099, 3.3913999, -10.0343, 13.378099, 3.3913999, -6.6894, 13.378099, 3.3913999, -10.0343, 16.722599, 3.3913999, -10.0343, 13.378099, 3.3913999, -6.6894, 16.722599, 3.3913999, -10.0343, 16.722599, 3.3913999, -6.6894, 10.0335, 3.3913999, -6.6894, 13.378099, 3.3913999, -10.0343, 13.378099, 3.3913999, -6.6894, 10.0335, 3.3913999, -6.6894, 10.0335, 3.3913999, -10.0343, 13.378099, 3.3913999, -10.0343, 16.722599, 3.3913999, -10.0343, 16.4746, 3.3913999, -13.3993, 16.722599, 3.3913999, -13.109999, 16.722599, 3.3913999, -10.0343, 13.378099, 3.3913999, -13.378599, 16.4746, 3.3913999, -13.3993, 16.4746, 3.3913999, -13.3993, 15.5536995, 3.3913999, -16.3177, 16.4952, 3.3913999, -15.5392, 16.4746, 3.3913999, -13.3993, 12.7383995, 3.3913999, -15.8953, 15.5536995, 3.3913999, -16.3177, 12.7383995, 3.3913999, -15.8953, 16.4746, 3.3913999, -13.3993, 13.378099, 3.3913999, -13.378599, 13.378099, 3.3913999, -13.378599, 12.460499, 3.3913999, -16.1674, 12.7383995, 3.3913999, -15.8953, 13.378099, 3.3913999, -13.378599, 10.0335, 3.3913999, -16.7235, 12.460499, 3.3913999, -16.1674, 10.0335, 3.3913999, -16.7235, 13.378099, 3.3913999, -13.378599, 10.0335, 3.3913999, -13.378599, 10.0335, 3.3913999, -10.0343, 10.0335, 3.3913999, -13.378599, 13.378099, 3.3913999, -13.378599, 6.6889997, 3.3913999, -13.378599, 10.0335, 3.3913999, -16.7235, 10.0335, 3.3913999, -13.378599, 6.6889997, 3.3913999, -13.378599, 6.6889997, 3.3913999, -16.7235, 10.0335, 3.3913999, -16.7235, 6.6889997, 3.3913999, -10.0343, 10.0335, 3.3913999, -13.378599, 10.0335, 3.3913999, -10.0343, 6.6889997, 3.3913999, -10.0343, 6.6889997, 3.3913999, -13.378599, 10.0335, 3.3913999, -13.378599, 4.6816, 3.3913999, -13.378599, 6.6889997, 3.3913999, -16.7235, 6.6889997, 3.3913999, -13.378599, 4.6816, 3.3913999, -13.378599, 3.8384998, 3.3913999, -16.7235, 6.6889997, 3.3913999, -16.7235, 4.5101, 3.3913999, -8.955799, 4.6816, 3.3913999, -13.378599, 6.6889997, 3.3913999, -13.378599, 4.5101, 3.3913999, -8.955799, 6.6889997, 3.3913999, -13.378599, 6.6889997, 3.3913999, -10.0343, 4.6816, 3.3913999, -13.378599, 4.5101, 3.3913999, -8.955799, 4.1105, 3.3913999, -9.3386, 6.6889997, 3.3913999, -6.6894, 6.6889997, 3.3913999, -10.0343, 10.0335, 3.3913999, -10.0343, 6.6889997, 3.3913999, -6.6894, 4.5101, 3.3913999, -8.955799, 6.6889997, 3.3913999, -10.0343, 6.6889997, 3.3913999, -6.6894, 10.0335, 3.3913999, -10.0343, 10.0335, 3.3913999, -6.6894, 4.1105, 3.3913999, -9.3386, 4.5101, 3.3913999, -8.955799, 3.8492, 3.3913999, -8.198, 6.6889997, 3.3913999, -6.6894, 3.8492, 3.3913999, -8.198, 4.5101, 3.3913999, -8.955799, 4.1105, 3.3913999, -9.3386, 3.8492, 3.3913999, -8.198, 3.4176, 3.3913999, -8.714399, 3.3444998, 3.3913999, -6.6894, 3.4176, 3.3913999, -8.714399, 3.8492, 3.3913999, -8.198, 3.8492, 3.3913999, -8.198, 6.6889997, 3.3913999, -6.6894, 3.3444998, 3.3913999, -6.6894, 3.3444998, 3.3913999, -6.6894, 0, 3.3913999, -8.714399, 3.4176, 3.3913999, -8.714399, 6.6889997, 3.3913999, -3.3451, 6.6889997, 3.3913999, -6.6894, 10.0335, 3.3913999, -6.6894, 6.6889997, 3.3913999, -3.3451, 10.0335, 3.3913999, -6.6894, 10.0335, 3.3913999, -3.3451, 3.3444998, 3.3913999, -3.3451, 3.3444998, 3.3913999, -6.6894, 6.6889997, 3.3913999, -6.6894, 3.3444998, 3.3913999, -3.3451, 6.6889997, 3.3913999, -6.6894, 6.6889997, 3.3913999, -3.3451, 0, 3.3913999, -8.714399, 3.3444998, 3.3913999, -6.6894, 0, 3.3913999, -6.6894, 0, 3.3913999, -6.6894, -3.5373998, 3.3913999, -9.750299, 0, 3.3913999, -8.714399, 0, 3.3913999, -3.3451, 3.3444998, 3.3913999, -6.6894, 3.3444998, 3.3913999, -3.3451, 0, 3.3913999, -3.3451, 0, 3.3913999, -6.6894, 3.3444998, 3.3913999, -6.6894, 3.3444998, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, -3.3451, 6.6889997, 3.3913999, -3.3451, 3.3444998, 3.3913999, -0.000100016594, 6.6889997, 3.3913999, -3.3451, 6.6889997, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, 3.3442, 3.3444998, 3.3913999, -0.000100016594, 6.6889997, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, 3.3442, 6.6889997, 3.3913999, -0.000100016594, 6.6889997, 3.3913999, 3.3442, 0, 3.3913999, 3.3442, 3.3444998, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, 3.3442, 3.3444998, 3.3913999, 6.6891, 3.3444998, 3.3913999, 3.3442, 6.6889997, 3.3913999, 3.3442, 0, 3.3913999, 3.3442, 0, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, -0.000100016594, 0, 3.3913999, -0.000100016594, 3.3444998, 3.3913999, -3.3451, 3.3444998, 3.3913999, -0.000100016594, 0, 3.3913999, -0.000100016594, 0, 3.3913999, -3.3451, 3.3444998, 3.3913999, -3.3451, -2.9569001, 3.3913999, 3.3442, 0, 3.3913999, -0.000100016594, 0, 3.3913999, 3.3442, -2.9569001, 3.3913999, 3.3442, -2.9569001, 3.3913999, -0.000100016594, 0, 3.3913999, -0.000100016594, -2.9569001, 3.3913999, -0.000100016594, 0, 3.3913999, -3.3451, 0, 3.3913999, -0.000100016594, -2.9569001, 3.3913999, -0.000100016594, -3.6383996, 3.3913999, -2.0795999, 0, 3.3913999, -3.3451, -3.6383996, 3.3913999, -2.0795999, 0, 3.3913999, -6.6894, 0, 3.3913999, -3.3451, -3.6383996, 3.3913999, -2.0795999, -3.3452, 3.3913999, -6.6894, 0, 3.3913999, -6.6894, -6.6896996, 3.3913999, -3.7331, -3.3452, 3.3913999, -6.6894, -3.6383996, 3.3913999, -2.0795999, -3.8484998, 3.3913999, -9.5107, 0, 3.3913999, -6.6894, -3.3452, 3.3913999, -6.6894, 0, 3.3913999, -6.6894, -3.8484998, 3.3913999, -9.5107, -3.5373998, 3.3913999, -9.750299, -3.5373998, 3.3913999, -9.750299, -3.8484998, 3.3913999, -9.5107, -4.2641, 3.3913999, -9.881699, -3.3452, 3.3913999, -6.6894, -4.2641, 3.3913999, -9.881699, -3.8484998, 3.3913999, -9.5107, -3.5373998, 3.3913999, -9.750299, -4.2641, 3.3913999, -9.881699, -3.9104, 3.3913999, -10.240799, -4.2641, 3.3913999, -9.881699, -3.9104, 3.3913999, -12.1610985, -3.9104, 3.3913999, -10.240799, -6.6896996, 3.3913999, -3.7331, -6.6896996, 3.3913999, -6.6894, -3.3452, 3.3913999, -6.6894, -10.034201, 3.3913999, -3.7331, -6.6896996, 3.3913999, -6.6894, -6.6896996, 3.3913999, -3.7331, -3.3452, 3.3913999, -6.6894, -6.6896996, 3.3913999, -10.0343, -4.2641, 3.3913999, -9.881699, -6.6896996, 3.3913999, -10.0343, -3.3452, 3.3913999, -6.6894, -6.6896996, 3.3913999, -6.6894, -4.2641, 3.3913999, -9.881699, -6.6896996, 3.3913999, -12.5385, -3.9104, 3.3913999, -12.1610985, -6.6896996, 3.3913999, -12.5385, -4.2641, 3.3913999, -9.881699, -6.6896996, 3.3913999, -10.0343, -3.9104, 3.3913999, -12.1610985, -6.6896996, 3.3913999, -12.5385, -4.2794, 3.3913999, -12.5385, -10.034201, 3.3913999, -3.7331, -10.034201, 3.3913999, -6.6894, -6.6896996, 3.3913999, -6.6894, -10.034201, 3.3913999, -6.6894, -6.6896996, 3.3913999, -10.0343, -6.6896996, 3.3913999, -6.6894, -13.378799, 3.3913999, -3.7331, -10.034201, 3.3913999, -6.6894, -10.034201, 3.3913999, -3.7331, -10.034201, 3.3913999, -10.0343, -6.6896996, 3.3913999, -12.5385, -6.6896996, 3.3913999, -10.0343, -10.034201, 3.3913999, -6.6894, -10.034201, 3.3913999, -10.0343, -6.6896996, 3.3913999, -10.0343, -10.034201, 3.3913999, -10.0343, -10.6998005, 3.3913999, -13.1763, -6.6896996, 3.3913999, -12.5385, -13.378799, 3.3913999, -3.7331, -13.378799, 3.3913999, -6.6894, -10.034201, 3.3913999, -6.6894, -13.378799, 3.3913999, -6.6894, -10.034201, 3.3913999, -10.0343, -10.034201, 3.3913999, -6.6894, -16.192, 3.3913999, -3.0972, -13.378799, 3.3913999, -6.6894, -13.378799, 3.3913999, -3.7331, -13.378799, 3.3913999, -10.0343, -10.6998005, 3.3913999, -13.1763, -10.034201, 3.3913999, -10.0343, -13.378799, 3.3913999, -6.6894, -13.378799, 3.3913999, -10.0343, -10.034201, 3.3913999, -10.0343, -13.378799, 3.3913999, -10.0343, -13.378799, 3.3913999, -13.378599, -10.6998005, 3.3913999, -13.1763, -16.192, 3.3913999, -3.0972, -16.723299, 3.3913999, -6.6894, -13.378799, 3.3913999, -6.6894, -19.754599, 3.3913999, -2.7854, -16.723299, 3.3913999, -6.6894, -16.192, 3.3913999, -3.0972, -19.754599, 3.3913999, -2.7854, -19.2812, 3.3913999, -6.6894, -16.723299, 3.3913999, -6.6894, -17.111599, 3.3913999, -0.000100016594, -19.754599, 3.3913999, -2.7854, -16.192, 3.3913999, -3.0972, -17.111599, 3.3913999, -0.000100016594, -19.9515, 3.3913999, -2.5836997, -19.754599, 3.3913999, -2.7854, -19.9515, 3.3913999, -2.5836997, -17.111599, 3.3913999, -0.000100016594, -20.068499, 3.3913999, -0.000100016594, -20.068499, 3.3913999, 3.3442, -20.068499, 3.3913999, -0.000100016594, -17.111599, 3.3913999, -0.000100016594, -20.068499, 3.3913999, 3.3442, -17.111599, 3.3913999, -0.000100016594, -17.111599, 3.3913999, 3.304, -20.068499, 3.3913999, 6.6891, -20.068499, 3.3913999, 3.3442, -17.111599, 3.3913999, 3.304, -22.332499, 3.3913999, 8.990399, -22.315199, 3.3913999, 6.6891, -20.068499, 3.3913999, 6.6891, -22.332499, 3.3913999, 8.990399, -20.068499, 3.3913999, 6.6891, -20.068499, 3.3913999, 9.1673, -20.068499, 3.3913999, 9.1673, -20.068499, 3.3913999, 6.6891, -16.723299, 3.3913999, 6.6891, -20.068499, 3.3913999, 6.6891, -17.111599, 3.3913999, 3.304, -16.723299, 3.3913999, 6.6891, -20.068499, 3.3913999, 9.1673, -16.723299, 3.3913999, 6.6891, -16.285099, 3.3913999, 9.5862, -16.723299, 3.3913999, 6.6891, -16.0544, 3.3913999, 9.808, -16.285099, 3.3913999, 9.5862, -16.0544, 3.3913999, 9.808, -16.723299, 3.3913999, 6.6891, -13.136101, 3.3913999, 6.7548, -17.111599, 3.3913999, 3.304, -13.136101, 3.3913999, 6.7548, -16.723299, 3.3913999, 6.6891, -16.0544, 3.3913999, 9.808, -13.136101, 3.3913999, 6.7548, -13.378799, 3.3913999, 10.0334, -13.378799, 3.3913999, 10.0334, -13.136101, 3.3913999, 6.7548, -10.034201, 3.3913999, 7.0772, -13.378799, 3.3913999, 10.0334, -10.034201, 3.3913999, 7.0772, -10.034201, 3.3913999, 10.0334, -13.136101, 3.3913999, 6.7548, -17.111599, 3.3913999, 3.304, -14.877501, 3.3913999, 4.6651998, -14.877501, 3.3913999, 4.6651998, -17.111599, 3.3913999, 3.304, -15.5823, 3.3913999, 4.0364, -13.136101, 3.3913999, 6.7548, -14.877501, 3.3913999, 4.6651998, -14.0949, 3.3913999, 5.5070996, 3.3444998, 3.3913999, 10.0334, 6.6889997, 3.3913999, 6.6891, 6.6889997, 3.3913999, 10.0334, 0, 3.3913999, 13.3783, 0, 3.3913999, 10.0334, 3.3444998, 3.3913999, 10.0334, 0, 3.3913999, 13.3783, 3.3444998, 3.3913999, 10.0334, 3.3444998, 3.3913999, 13.3783, 3.3444998, 3.3913999, 13.3783, 3.3444998, 3.3913999, 10.0334, 6.6889997, 3.3913999, 10.0334, 3.3444998, 3.3913999, 10.0334, 3.3444998, 3.3913999, 6.6891, 6.6889997, 3.3913999, 6.6891, 3.3444998, 3.3913999, 6.6891, 6.6889997, 3.3913999, 3.3442, 6.6889997, 3.3913999, 6.6891, 6.6889997, 3.3913999, 6.6891, 6.6889997, 3.3913999, 3.3442, 10.0335, 3.3913999, 4.2546997, 6.6889997, 3.3913999, 6.6891, 10.0335, 3.3913999, 4.2546997, 10.0335, 3.3913999, 6.6891, 6.6889997, 3.3913999, 10.0334, 6.6889997, 3.3913999, 6.6891, 10.0335, 3.3913999, 6.6891, 6.6889997, 3.3913999, 10.0334, 10.0335, 3.3913999, 6.6891, 10.0335, 3.3913999, 10.0334, 3.3444998, 3.3913999, 13.3783, 6.6889997, 3.3913999, 10.0334, 6.6889997, 3.3913999, 13.3783, 3.9143, 3.3913999, 16.5144, 3.3444998, 3.3913999, 13.3783, 6.6889997, 3.3913999, 13.3783, 3.3444998, 3.3913999, 13.3783, 3.9143, 3.3913999, 16.5144, 3.6397, 3.3913999, 16.2405, 3.9143, 3.3913999, 16.5144, 6.6889997, 3.3913999, 13.3783, 6.6889997, 3.3913999, 16.7227, -3.3452, 3.3913999, 13.3783, 0, 3.3913999, 10.0334, 0, 3.3913999, 13.3783, -3.3452, 3.3913999, 13.3783, -3.3452, 3.4796999, 10.0334, 0, 3.3913999, 10.0334, 0, 3.3913999, 10.0334, 0, 3.4796999, 6.6891, 3.3444998, 3.3913999, 6.6891, 0, 3.3913999, 10.0334, 3.3444998, 3.3913999, 6.6891, 3.3444998, 3.3913999, 10.0334, 0, 3.4796999, 6.6891, 3.3444998, 3.3913999, 3.3442, 3.3444998, 3.3913999, 6.6891, 0, 3.4796999, 6.6891, 0, 3.3913999, 3.3442, 3.3444998, 3.3913999, 3.3442, 6.6889997, 3.3913999, -0.000100016594, 10.0335, 3.3913999, -3.3451, 10.0335, 3.2212, -2.2310996, 6.6889997, 3.3913999, -0.000100016594, 6.6889997, 3.3913999, -3.3451, 10.0335, 3.3913999, -3.3451, -10.034201, 3.0033998, 6.6891, -13.136101, 3.3913999, 6.7548, -12.747801, 3.0033998, 6.3666997, -10.034201, 3.0033998, 6.6891, -10.034201, 3.3913999, 7.0772, -13.136101, 3.3913999, 6.7548, -2.5679002, 2.9782999, 7.6208997, -6.6896996, 3.4796999, 7.0772, -6.6896996, 3.0033998, 6.6891, -2.5679002, 2.9782999, 7.6208997, -2.1796002, 3.3107998, 8.009, -6.6896996, 3.4796999, 7.0772, -12.747801, 3.0033998, 6.3666997, -14.0949, 3.3913999, 5.5070996, -13.694601, 3.0033998, 5.1793, -12.747801, 3.0033998, 6.3666997, -13.136101, 3.3913999, 6.7548, -14.0949, 3.3913999, 5.5070996, -6.6896996, 3.0033998, 6.6891, -10.034201, 3.3913999, 7.0772, -10.034201, 3.0033998, 6.6891, -6.6896996, 3.0033998, 6.6891, -6.6896996, 3.4796999, 7.0772, -10.034201, 3.3913999, 7.0772, -16.723299, 3.0033998, -0.000100016594, -16.192, 3.3913999, -3.0972, -15.8036995, 3.0033998, -2.7097, -16.723299, 3.0033998, -0.000100016594, -17.111599, 3.3913999, -0.000100016594, -16.192, 3.3913999, -3.0972, -13.378799, 3.3913999, -3.7331, -15.8036995, 3.0033998, -2.7097, -16.192, 3.3913999, -3.0972, -13.378799, 3.3913999, -3.7331, -13.378799, 3.0033998, -3.3451, -15.8036995, 3.0033998, -2.7097, -2.9569001, 3.3913999, -0.000100016594, -4.0260997, 3.0033998, -1.6915, -3.6383996, 3.3913999, -2.0795999, -2.9569001, 3.3913999, -0.000100016594, -3.3452, 3.0033998, -0.000100016594, -4.0260997, 3.0033998, -1.6915, -3.6383996, 3.3913999, -2.0795999, -6.6896996, 3.0033998, -3.3451, -6.6896996, 3.3913999, -3.7331, -3.6383996, 3.3913999, -2.0795999, -4.0260997, 3.0033998, -1.6915, -6.6896996, 3.0033998, -3.3451, -10.034201, 3.3913999, -3.7331, -13.378799, 3.0033998, -3.3451, -13.378799, 3.3913999, -3.7331, -10.034201, 3.3913999, -3.7331, -10.034201, 3.0033998, -3.3451, -13.378799, 3.0033998, -3.3451, -6.6896996, 3.3913999, -3.7331, -10.034201, 3.0033998, -3.3451, -10.034201, 3.3913999, -3.7331, -6.6896996, 3.3913999, -3.7331, -6.6896996, 3.0033998, -3.3451, -10.034201, 3.0033998, -3.3451, -16.723299, 3.0033998, 2.9164999, -17.111599, 3.3913999, -0.000100016594, -16.723299, 3.0033998, -0.000100016594, -16.723299, 3.0033998, 2.9164999, -17.111599, 3.3913999, 3.304, -17.111599, 3.3913999, -0.000100016594, -14.4897995, 3.0033998, 4.2777, -15.5823, 3.3913999, 4.0364, -15.3722, 3.0033998, 3.6128, -14.4897995, 3.0033998, 4.2777, -14.877501, 3.3913999, 4.6651998, -15.5823, 3.3913999, 4.0364, -2.9569001, 3.3913999, 3.3442, -3.3452, 3.0033998, -0.000100016594, -2.9569001, 3.3913999, -0.000100016594, -2.9569001, 3.3913999, 3.3442, -3.3452, 3.0033998, 3.3442, -3.3452, 3.0033998, -0.000100016594, -2.1796002, 3.3107998, 8.009, -2.1397, 3.0033998, 5.1793, -1.7839999, 3.3913999, 5.216, -2.1796002, 3.3107998, 8.009, -2.5679002, 2.9782999, 7.6208997, -2.1397, 3.0033998, 5.1793, -6.6896996, 3.3913999, 10.0334, -2.1796002, 3.3107998, 8.009, -3.3452, 3.4796999, 10.0334, -6.6896996, 3.3913999, 10.0334, -6.6896996, 3.4796999, 7.0772, -2.1796002, 3.3107998, 8.009, -10.034201, 3.3913999, 10.0334, -6.6896996, 3.4796999, 7.0772, -6.6896996, 3.3913999, 10.0334, -10.034201, 3.3913999, 10.0334, -10.034201, 3.3913999, 7.0772, -6.6896996, 3.4796999, 7.0772, -1.7839999, 3.3913999, 5.216, 0, 3.4796999, 6.6891, -2.1796002, 3.3107998, 8.009, 0, 3.4796999, 6.6891, -1.7839999, 3.3913999, 5.216, -2.9569001, 3.3913999, 3.3442, 0, 3.4796999, 6.6891, -2.9569001, 3.3913999, 3.3442, 0, 3.3913999, 3.3442, -3.3452, 3.4796999, 10.0334, 0, 3.4796999, 6.6891, 0, 3.3913999, 10.0334, -3.3452, 3.4796999, 10.0334, -2.1796002, 3.3107998, 8.009, 0, 3.4796999, 6.6891, -2.1397, 3.0033998, 5.1793, -2.9569001, 3.3913999, 3.3442, -1.7839999, 3.3913999, 5.216, -2.1397, 3.0033998, 5.1793, -3.3452, 3.0033998, 3.3442, -2.9569001, 3.3913999, 3.3442, -14.0949, 3.3913999, 5.5070996, -14.4897995, 3.0033998, 4.2777, -13.694601, 3.0033998, 5.1793, -14.0949, 3.3913999, 5.5070996, -14.877501, 3.3913999, 4.6651998, -14.4897995, 3.0033998, 4.2777, -15.5823, 3.3913999, 4.0364, -16.723299, 3.0033998, 2.9164999, -15.3722, 3.0033998, 3.6128, -15.5823, 3.3913999, 4.0364, -17.111599, 3.3913999, 3.304, -16.723299, 3.0033998, 2.9164999, 16.722599, 3.3913999, -13.109999, 16.4746, 3.3913999, -13.3993, 16.8123, 3.1578999, -13.4637985, 10.0335, 3.0523999, -19.0296, 6.6797, 3.2777998, -18.734999, 6.6763997, 3.0570998, -19.0278, 10.0335, 3.0523999, -19.0296, 10.0335, 3.2784998, -18.7001, 6.6797, 3.2777998, -18.734999, 6.6889997, 3.3913999, -16.7235, 10.0335, 3.2784998, -18.7001, 10.0335, 3.3913999, -16.7235, 6.6889997, 3.3913999, -16.7235, 6.6797, 3.2777998, -18.734999, 10.0335, 3.2784998, -18.7001, 12.7383995, 3.3913999, -15.8953, 12.460499, 3.3913999, -16.1674, 12.747099, 3.1769, -16.1994, 4.6816, 3.3913999, -13.378599, 3.5892, 3.2033, -16.7235, 3.8384998, 3.3913999, -16.7235, 4.6816, 3.3913999, -13.378599, 4.413, 3.2091, -13.357899, 3.5892, 3.2033, -16.7235, -10.6998005, 3.3913999, -13.1763, -6.6896996, 3.175, -12.867498, -6.6896996, 3.3913999, -12.5385, -10.6998005, 3.3913999, -13.1763, -10.4046, 3.1608999, -13.429499, -6.6896996, 3.175, -12.867498, -22.8711, 3.4937, 3.3673, -23.3678, 3.4459999, 0.13709998, -23.171, 3.6251, 0.12290001, -22.8711, 3.4937, 3.3673, -23.079899, 3.314, 3.3673, -23.3678, 3.4459999, 0.13709998, -22.8711, 3.4937, 3.3673, -20.068499, 3.3913999, -0.000100016594, -20.068499, 3.3913999, 3.3442, -22.8711, 3.4937, 3.3673, -23.171, 3.6251, 0.12290001, -20.068499, 3.3913999, -0.000100016594, -23.079899, 3.314, 3.3673, -22.315199, 3.3913999, 6.6891, -22.5639, 3.2219, 6.6891, -23.079899, 3.314, 3.3673, -22.8711, 3.4937, 3.3673, -22.315199, 3.3913999, 6.6891, -22.315199, 3.3913999, 6.6891, -20.068499, 3.3913999, 3.3442, -20.068499, 3.3913999, 6.6891, -22.315199, 3.3913999, 6.6891, -22.8711, 3.4937, 3.3673, -20.068499, 3.3913999, 3.3442, -15.739201, 3.2087, 12.341301, -13.378799, 3.3913999, 10.0334, -13.378799, 3.3922, 12.5714, -15.739201, 3.2087, 12.341301, -16.0544, 3.3913999, 9.808, -13.378799, 3.3913999, 10.0334, -10.034201, 3.2142, 12.105801, -13.378799, 3.1938999, 12.808599, -13.378799, 3.3922, 12.5714, -10.034201, 3.2142, 12.105801, -10.034201, 2.9384, 12.453701, -13.378799, 3.1938999, 12.808599, -13.378799, 3.3922, 12.5714, -10.034201, 3.3913999, 10.0334, -10.034201, 3.2142, 12.105801, -13.378799, 3.3922, 12.5714, -13.378799, 3.3913999, 10.0334, -10.034201, 3.3913999, 10.0334, 0, 3.2243998, 15.7092, -3.3452, 3.1497998, 15.914499, -3.3452, 3.3913999, 15.601, 0, 3.2243998, 15.7092, 0, 2.9636998, 16.0175, -3.3452, 3.1497998, 15.914499, -3.3452, 3.3913999, 15.601, 0, 3.3913999, 13.3783, 0, 3.2243998, 15.7092, -3.3452, 3.3913999, 15.601, -3.3452, 3.3913999, 13.3783, 0, 3.3913999, 13.3783, 0, 3.2243998, 15.7092, 3.3444998, 3.3913999, 13.3783, 3.6397, 3.3913999, 16.2405, 0, 3.2243998, 15.7092, 0, 3.3913999, 13.3783, 3.3444998, 3.3913999, 13.3783, 3.6397, 3.3913999, 16.2405, 3.9143, 3.3913999, 16.5144, 3.6729999, 3.1532, 16.5718, 13.2491, 2.9931, -3.474, 16.722599, 3.3913999, -6.6894, 16.722599, 3.1513, -3.6023998, 13.2491, 2.9931, -3.474, 13.378099, 3.3913999, -6.6894, 16.722599, 3.3913999, -6.6894, 10.0335, 3.3913999, -3.3451, 13.378099, 3.3913999, -6.6894, 13.2491, 2.9931, -3.474, 10.0335, 3.3913999, -3.3451, 10.0335, 3.3913999, -6.6894, 13.378099, 3.3913999, -6.6894, 19.8151, 3.3908, -10.0177, 20.1469, 3.0588999, -6.6894, 19.8317, 3.2891998, -6.6894, 19.8151, 3.3908, -10.0177, 20.188799, 3.1655998, -10.0154, 20.1469, 3.0588999, -6.6894, 19.8317, 3.2891998, -6.6894, 20.139599, 2.779, -3.3616, 19.8317, 3.0491, -3.6023998, 19.8317, 3.2891998, -6.6894, 20.1469, 3.0588999, -6.6894, 20.139599, 2.779, -3.3616, 16.722599, 3.1513, -3.6023998, 19.8317, 3.2891998, -6.6894, 19.8317, 3.0491, -3.6023998, 16.722599, 3.1513, -3.6023998, 16.722599, 3.3913999, -6.6894, 19.8317, 3.2891998, -6.6894, 16.722599, 3.3913999, -6.6894, 19.8151, 3.3908, -10.0177, 19.8317, 3.2891998, -6.6894, 16.722599, 3.3913999, -6.6894, 16.722599, 3.3913999, -10.0343, 19.8151, 3.3908, -10.0177, 20.139599, 2.779, -3.3616, 16.722599, 3.1513, -3.6023998, 19.8317, 3.0491, -3.6023998, 20.139599, 2.779, -3.3616, 16.712599, 2.8734, -3.3451, 16.722599, 3.1513, -3.6023998, 19.767899, 3.1308, -13.4058, 19.7985, 3.3913999, -12.747999, 19.4075, 3.3913999, -13.109999, 19.767899, 3.1308, -13.4058, 20.1582, 3.1318998, -13.041399, 19.7985, 3.3913999, -12.747999, 19.767899, 3.1308, -13.4058, 16.722599, 3.3913999, -13.109999, 16.8123, 3.1578999, -13.4637985, 19.767899, 3.1308, -13.4058, 19.4075, 3.3913999, -13.109999, 16.722599, 3.3913999, -13.109999, 20.188799, 3.1655998, -10.0154, 19.7985, 3.3913999, -12.747999, 20.1582, 3.1318998, -13.041399, 20.188799, 3.1655998, -10.0154, 19.8151, 3.3908, -10.0177, 19.7985, 3.3913999, -12.747999, 16.722599, 3.3913999, -13.109999, 19.8151, 3.3908, -10.0177, 16.722599, 3.3913999, -10.0343, 19.8151, 3.3908, -10.0177, 16.722599, 3.3913999, -13.109999, 19.4075, 3.3913999, -13.109999, 19.8151, 3.3908, -10.0177, 19.4075, 3.3913999, -13.109999, 19.7985, 3.3913999, -12.747999, 16.4952, 3.3913999, -15.5392, 15.828299, 3.1678, -16.6064, 16.7698, 3.1685998, -15.8202, 16.4952, 3.3913999, -15.5392, 15.5536995, 3.3913999, -16.3177, 15.828299, 3.1678, -16.6064, 16.8123, 3.1578999, -13.4637985, 16.4952, 3.3913999, -15.5392, 16.7698, 3.1685998, -15.8202, 16.8123, 3.1578999, -13.4637985, 16.4746, 3.3913999, -13.3993, 16.4952, 3.3913999, -15.5392, 15.828299, 3.1678, -16.6064, 12.7383995, 3.3913999, -15.8953, 12.747099, 3.1769, -16.1994, 15.828299, 3.1678, -16.6064, 15.5536995, 3.3913999, -16.3177, 12.7383995, 3.3913999, -15.8953, 12.4485, 3.2073998, -18.4711, 12.299599, 2.942, -19.2491, 12.726398, 2.9599, -18.824299, 12.4485, 3.2073998, -18.4711, 12.0203, 3.1891, -18.8983, 12.299599, 2.942, -19.2491, 12.4485, 3.2073998, -18.4711, 12.747099, 3.1769, -16.1994, 12.460499, 3.3913999, -16.1674, 12.4485, 3.2073998, -18.4711, 12.726398, 2.9599, -18.824299, 12.747099, 3.1769, -16.1994, 12.299599, 2.942, -19.2491, 10.0335, 3.2784998, -18.7001, 10.0335, 3.0523999, -19.0296, 12.299599, 2.942, -19.2491, 12.0203, 3.1891, -18.8983, 10.0335, 3.2784998, -18.7001, 10.0335, 3.2784998, -18.7001, 12.460499, 3.3913999, -16.1674, 10.0335, 3.3913999, -16.7235, 12.460499, 3.3913999, -16.1674, 10.0335, 3.2784998, -18.7001, 12.0203, 3.1891, -18.8983, 12.460499, 3.3913999, -16.1674, 12.0203, 3.1891, -18.8983, 12.4485, 3.2073998, -18.4711, 5.6212, 3.2835999, -18.3475, 3.9036999, 3.1690998, -17.2696, 5.4681997, 3.0900998, -18.607199, 5.6212, 3.2835999, -18.3475, 4.0333, 3.3667998, -17.0276, 3.9036999, 3.1690998, -17.2696, 4.0333, 3.3667998, -17.0276, 6.6889997, 3.3913999, -16.7235, 3.8384998, 3.3913999, -16.7235, 6.6889997, 3.3913999, -16.7235, 4.0333, 3.3667998, -17.0276, 5.6212, 3.2835999, -18.3475, 6.6889997, 3.3913999, -16.7235, 5.6212, 3.2835999, -18.3475, 6.6797, 3.2777998, -18.734999, 3.8384998, 3.3913999, -16.7235, 3.9036999, 3.1690998, -17.2696, 4.0333, 3.3667998, -17.0276, 3.8384998, 3.3913999, -16.7235, 3.5892, 3.2033, -16.7235, 3.9036999, 3.1690998, -17.2696, 6.6763997, 3.0570998, -19.0278, 5.6212, 3.2835999, -18.3475, 5.4681997, 3.0900998, -18.607199, 6.6763997, 3.0570998, -19.0278, 6.6797, 3.2777998, -18.734999, 5.6212, 3.2835999, -18.3475, -15.2073, 3.5182998, -15.4569, -16.124199, 3.3711998, -15.150499, -15.441299, 3.3151, -15.7533, -15.2073, 3.5182998, -15.4569, -15.9035, 3.5797, -14.867699, -16.124199, 3.3711998, -15.150499, -15.9035, 3.5797, -14.867699, -13.378799, 3.3913999, -13.378599, -16.1309, 3.6227, -13.6241, -13.378799, 3.3913999, -13.378599, -15.9035, 3.5797, -14.867699, -15.2073, 3.5182998, -15.4569, -13.378799, 3.3913999, -13.378599, -15.2073, 3.5182998, -15.4569, -13.3874, 3.3918998, -15.424398, -16.1309, 3.6227, -13.6241, -16.124199, 3.3711998, -15.150499, -15.9035, 3.5797, -14.867699, -16.1309, 3.6227, -13.6241, -16.3755, 3.4225, -13.6283, -16.124199, 3.3711998, -15.150499, -13.385401, 3.1832, -15.7598, -15.2073, 3.5182998, -15.4569, -15.441299, 3.3151, -15.7533, -13.385401, 3.1832, -15.7598, -13.3874, 3.3918998, -15.424398, -15.2073, 3.5182998, -15.4569, -10.749701, 3.1581, -16.1136, -10.6998005, 3.3913999, -15.507799, -11.021601, 3.3913999, -15.7846985, -10.749701, 3.1581, -16.1136, -10.429201, 3.1564, -15.8326, -10.6998005, 3.3913999, -15.507799, -10.749701, 3.1581, -16.1136, -13.3874, 3.3918998, -15.424398, -13.385401, 3.1832, -15.7598, -10.749701, 3.1581, -16.1136, -11.021601, 3.3913999, -15.7846985, -13.3874, 3.3918998, -15.424398, -10.4046, 3.1608999, -13.429499, -10.6998005, 3.3913999, -15.507799, -10.429201, 3.1564, -15.8326, -10.4046, 3.1608999, -13.429499, -10.6998005, 3.3913999, -13.1763, -10.6998005, 3.3913999, -15.507799, -13.3874, 3.3918998, -15.424398, -10.6998005, 3.3913999, -13.1763, -13.378799, 3.3913999, -13.378599, -10.6998005, 3.3913999, -13.1763, -13.3874, 3.3918998, -15.424398, -11.021601, 3.3913999, -15.7846985, -10.6998005, 3.3913999, -13.1763, -11.021601, 3.3913999, -15.7846985, -10.6998005, 3.3913999, -15.507799, -3.9104, 3.3913999, -12.1610985, -4.0188, 3.1604998, -12.820099, -3.6476998, 3.1597998, -12.4415, -3.9104, 3.3913999, -12.1610985, -4.2794, 3.3913999, -12.5385, -4.0188, 3.1604998, -12.820099, -4.0188, 3.1604998, -12.820099, -6.6896996, 3.3913999, -12.5385, -6.6896996, 3.175, -12.867498, -4.0188, 3.1604998, -12.820099, -4.2794, 3.3913999, -12.5385, -6.6896996, 3.3913999, -12.5385, -3.5373998, 3.3913999, -9.750299, -3.6144996, 3.1664, -10.4478, -3.2335, 3.1696, -9.965099, -3.5373998, 3.3913999, -9.750299, -3.9104, 3.3913999, -10.240799, -3.6144996, 3.1664, -10.4478, -3.6144996, 3.1664, -10.4478, -3.9104, 3.3913999, -12.1610985, -3.6476998, 3.1597998, -12.4415, -3.6144996, 3.1664, -10.4478, -3.9104, 3.3913999, -10.240799, -3.9104, 3.3913999, -12.1610985, -0.0046999454, 3.1827998, -9.064699, -3.5373998, 3.3913999, -9.750299, -3.2335, 3.1696, -9.965099, -0.0046999454, 3.1827998, -9.064699, 0, 3.3913999, -8.714399, -3.5373998, 3.3913999, -9.750299, 4.1105, 3.3913999, -9.3386, 3.149, 3.1724, -9.052198, 3.8465, 3.1766, -9.664, 4.1105, 3.3913999, -9.3386, 3.4176, 3.3913999, -8.714399, 3.149, 3.1724, -9.052198, 4.1105, 3.3913999, -9.3386, 4.413, 3.2091, -13.357899, 4.6816, 3.3913999, -13.378599, 4.1105, 3.3913999, -9.3386, 3.8465, 3.1766, -9.664, 4.413, 3.2091, -13.357899, 3.149, 3.1724, -9.052198, 0, 3.3913999, -8.714399, -0.0046999454, 3.1827998, -9.064699, 3.149, 3.1724, -9.052198, 3.4176, 3.3913999, -8.714399, 0, 3.3913999, -8.714399, -19.2812, 3.3913999, -6.6894, -19.611, 3.187, -9.246899, -19.3743, 3.391, -9.417299, -19.2812, 3.3913999, -6.6894, -19.515299, 3.2122, -6.6894, -19.611, 3.187, -9.246899, -16.1255, 3.4196, -10.133099, -16.240599, 3.3848999, -8.961699, -16.7605, 3.3848, -9.501299, -16.1255, 3.4196, -10.133099, -15.5737, 3.3848999, -9.614899, -16.240599, 3.3848999, -8.961699, -16.1255, 3.4196, -10.133099, -17.049099, 3.1696, -9.7829, -16.4075, 3.2108998, -10.402899, -16.1255, 3.4196, -10.133099, -16.7605, 3.3848, -9.501299, -17.049099, 3.1696, -9.7829, -16.7605, 3.3848, -9.501299, -19.1775, 3.1662998, -9.7628, -17.049099, 3.1696, -9.7829, -16.7605, 3.3848, -9.501299, -18.8297, 3.3895998, -9.473499, -19.1775, 3.1662998, -9.7628, -16.3755, 3.4225, -13.6283, -16.1255, 3.4196, -10.133099, -16.4075, 3.2108998, -10.402899, -16.3755, 3.4225, -13.6283, -16.1309, 3.6227, -13.6241, -16.1255, 3.4196, -10.133099, -16.240599, 3.3848999, -8.961699, -13.378799, 3.3913999, -6.6894, -16.723299, 3.3913999, -6.6894, -13.378799, 3.3913999, -6.6894, -16.240599, 3.3848999, -8.961699, -15.5737, 3.3848999, -9.614899, -13.378799, 3.3913999, -6.6894, -15.5737, 3.3848999, -9.614899, -13.378799, 3.3913999, -10.0343, -16.1309, 3.6227, -13.6241, -15.5737, 3.3848999, -9.614899, -16.1255, 3.4196, -10.133099, -15.5737, 3.3848999, -9.614899, -16.1309, 3.6227, -13.6241, -13.378799, 3.3913999, -13.378599, -15.5737, 3.3848999, -9.614899, -13.378799, 3.3913999, -13.378599, -13.378799, 3.3913999, -10.0343, -19.3743, 3.391, -9.417299, -16.723299, 3.3913999, -6.6894, -19.2812, 3.3913999, -6.6894, -16.723299, 3.3913999, -6.6894, -19.3743, 3.391, -9.417299, -16.7605, 3.3848, -9.501299, -16.7605, 3.3848, -9.501299, -19.3743, 3.391, -9.417299, -18.8297, 3.3895998, -9.473499, -16.723299, 3.3913999, -6.6894, -16.7605, 3.3848, -9.501299, -16.240599, 3.3848999, -8.961699, -19.754599, 3.3913999, -2.7854, -19.9515, 3.3913999, -2.5836997, -19.9495, 3.2063, -2.8084998, -19.754599, 3.3913999, -2.7854, -19.515299, 3.2122, -6.6894, -19.2812, 3.3913999, -6.6894, -19.754599, 3.3913999, -2.7854, -19.8424, 3.2077, -3.7668996, -19.515299, 3.2122, -6.6894, -22.7335, 3.5105, -2.4837003, -23.3864, 3.3542, -2.205, -22.931599, 3.3177998, -2.7097, -22.7335, 3.5105, -2.4837003, -23.1883, 3.5481, -1.9755001, -23.3864, 3.3542, -2.205, -23.1883, 3.5481, -1.9755001, -20.068499, 3.3913999, -0.000100016594, -23.171, 3.6251, 0.12290001, -20.068499, 3.3913999, -0.000100016594, -23.1883, 3.5481, -1.9755001, -22.7335, 3.5105, -2.4837003, -20.068499, 3.3913999, -0.000100016594, -22.7335, 3.5105, -2.4837003, -19.9515, 3.3913999, -2.5836997, -23.171, 3.6251, 0.12290001, -23.3864, 3.3542, -2.205, -23.1883, 3.5481, -1.9755001, -23.171, 3.6251, 0.12290001, -23.3678, 3.4459999, 0.13709998, -23.3864, 3.3542, -2.205, -22.7335, 3.5105, -2.4837003, -19.9495, 3.2063, -2.8084998, -19.9515, 3.3913999, -2.5836997, -22.7335, 3.5105, -2.4837003, -22.931599, 3.3177998, -2.7097, -19.9495, 3.2063, -2.8084998, -22.332499, 3.3913999, 8.990399, -22.5912, 3.2112, 9.44, -22.7647, 3.2136, 9.1158, -22.7647, 3.2136, 9.1158, -22.315199, 3.3913999, 6.6891, -22.332499, 3.3913999, 8.990399, -22.7647, 3.2136, 9.1158, -22.5639, 3.2219, 6.6891, -22.315199, 3.3913999, 6.6891, -22.5912, 3.2112, 9.44, -20.068499, 3.3913999, 9.1673, -20.068499, 3.1943, 9.406899, -22.5912, 3.2112, 9.44, -22.332499, 3.3913999, 8.990399, -20.068499, 3.3913999, 9.1673, -6.2755, 3.126, 16.1251, -5.9743, 3.3983, 13.383699, -5.9743, 3.393, 15.6513, -6.2755, 3.126, 16.1251, -6.2755, 3.126, 13.6215, -5.9743, 3.3983, 13.383699, -17.1362, 3.192, 9.7157, -16.285099, 3.3913999, 9.5862, -16.2818, 3.1913998, 9.8050995, -16.285099, 3.3913999, 9.5862, -16.0544, 3.3913999, 9.808, -16.2818, 3.1913998, 9.8050995, -16.285099, 3.3913999, 9.5862, -20.068499, 3.1943, 9.406899, -20.068499, 3.3913999, 9.1673, -16.285099, 3.3913999, 9.5862, -17.1362, 3.192, 9.7157, -20.068499, 3.1943, 9.406899, -16.1122, 3.066, 12.232401, -15.739201, 3.2087, 12.341301, -15.571699, 3.0688, 12.748899, -15.739201, 3.2087, 12.341301, -16.2818, 3.1913998, 9.8050995, -16.0544, 3.3913999, 9.808, -15.739201, 3.2087, 12.341301, -16.1122, 3.066, 12.232401, -16.2818, 3.1913998, 9.8050995, -13.378799, 3.3922, 12.5714, -15.571699, 3.0688, 12.748899, -15.739201, 3.2087, 12.341301, -13.378799, 3.3922, 12.5714, -13.378799, 3.1938999, 12.808599, -15.571699, 3.0688, 12.748899, -6.4743, 3.3766, 12.7861, -5.5162, 3.398, 12.9678, -5.9743, 3.3983, 13.383699, -6.4743, 3.3766, 12.7861, -6.088, 3.3981, 12.428801, -5.5162, 3.398, 12.9678, -6.4743, 3.3766, 12.7861, -6.2755, 3.126, 13.6215, -6.7781997, 3.1009, 13.0322, -6.4743, 3.3766, 12.7861, -5.9743, 3.3983, 13.383699, -6.2755, 3.126, 13.6215, -6.4743, 3.3766, 12.7861, -10.034201, 2.9384, 12.453701, -10.034201, 3.2142, 12.105801, -6.4743, 3.3766, 12.7861, -6.7781997, 3.1009, 13.0322, -10.034201, 2.9384, 12.453701, -10.034201, 3.3913999, 10.0334, -6.4743, 3.3766, 12.7861, -10.034201, 3.2142, 12.105801, -6.4743, 3.3766, 12.7861, -10.034201, 3.3913999, 10.0334, -6.6896996, 3.3913999, 10.0334, -6.4743, 3.3766, 12.7861, -6.6896996, 3.3913999, 10.0334, -6.088, 3.3981, 12.428801, -6.6896996, 3.3913999, 10.0334, -5.5162, 3.398, 12.9678, -6.088, 3.3981, 12.428801, -5.5162, 3.398, 12.9678, -6.6896996, 3.3913999, 10.0334, -3.3452, 3.4796999, 10.0334, -5.5162, 3.398, 12.9678, -3.3452, 3.4796999, 10.0334, -3.3452, 3.3913999, 13.3783, -5.9743, 3.393, 15.6513, -6.0454, 3.135, 16.5322, -6.2755, 3.126, 16.1251, -5.9743, 3.393, 15.6513, -5.5313997, 3.3918, 16.0056, -6.0454, 3.135, 16.5322, -6.0454, 3.135, 16.5322, -3.3452, 3.3913999, 15.601, -3.3452, 3.1497998, 15.914499, -6.0454, 3.135, 16.5322, -5.5313997, 3.3918, 16.0056, -3.3452, 3.3913999, 15.601, -5.9743, 3.3983, 13.383699, -5.5313997, 3.3918, 16.0056, -5.9743, 3.393, 15.6513, -5.5313997, 3.3918, 16.0056, -5.9743, 3.3983, 13.383699, -3.3452, 3.3913999, 13.3783, -3.3452, 3.3913999, 13.3783, -5.9743, 3.3983, 13.383699, -5.5162, 3.398, 12.9678, -5.5313997, 3.3918, 16.0056, -3.3452, 3.3913999, 13.3783, -3.3452, 3.3913999, 15.601, 2.7767, 3.0992, 16.3949, 3.6397, 3.3913999, 16.2405, 3.6729999, 3.1532, 16.5718, 3.6397, 3.3913999, 16.2405, 0, 2.9636998, 16.0175, 0, 3.2243998, 15.7092, 3.6397, 3.3913999, 16.2405, 2.7767, 3.0992, 16.3949, 0, 2.9636998, 16.0175, 3.9987998, 3.4764, 18.6069, 3.9143, 3.3913999, 16.5144, 6.6889997, 3.3913999, 16.7227, 3.8212, 3.3128, 18.7347, 4.941, 3.4643, 19.3458, 4.8006997, 3.3019998, 19.5215, 3.8212, 3.3128, 18.7347, 3.9987998, 3.4764, 18.6069, 4.941, 3.4643, 19.3458, 6.6923, 3.3525, 19.0394, 4.8006997, 3.3019998, 19.5215, 4.941, 3.4643, 19.3458, 6.6923, 3.3525, 19.0394, 6.7794, 3.1271, 19.2435, 4.8006997, 3.3019998, 19.5215, 3.6729999, 3.1532, 16.5718, 3.9987998, 3.4764, 18.6069, 3.8212, 3.3128, 18.7347, 3.6729999, 3.1532, 16.5718, 3.9143, 3.3913999, 16.5144, 3.9987998, 3.4764, 18.6069, 6.6889997, 3.3913999, 16.7227, 4.941, 3.4643, 19.3458, 3.9987998, 3.4764, 18.6069, 6.6923, 3.3525, 19.0394, 4.941, 3.4643, 19.3458, 6.6889997, 3.3913999, 16.7227, 8.6452, 3.3837, 18.872, 9.5275, 3.2163, 18.6602, 8.8241, 3.2010999, 19.0991, 8.6452, 3.3837, 18.872, 9.3605995, 3.3913, 18.4371, 9.5275, 3.2163, 18.6602, 8.6452, 3.3837, 18.872, 6.7794, 3.1271, 19.2435, 6.6923, 3.3525, 19.0394, 8.6452, 3.3837, 18.872, 8.8241, 3.2010999, 19.0991, 6.7794, 3.1271, 19.2435, 9.5275, 3.2163, 18.6602, 10.388599, 3.3911998, 16.7085, 10.590099, 3.2050998, 16.7167, 9.5275, 3.2163, 18.6602, 9.3605995, 3.3913, 18.4371, 10.388599, 3.3911998, 16.7085, 6.6889997, 3.3913999, 16.7227, 8.6452, 3.3837, 18.872, 6.6923, 3.3525, 19.0394, 8.6452, 3.3837, 18.872, 6.6889997, 3.3913999, 16.7227, 10.388599, 3.3911998, 16.7085, 8.6452, 3.3837, 18.872, 10.388599, 3.3911998, 16.7085, 9.3605995, 3.3913, 18.4371, 9.8819, 3.359, 13.619101, 9.838699, 3.359, 12.8258, 10.225699, 3.399, 13.197901, 9.8819, 3.359, 13.619101, 9.4411, 3.359, 13.2192, 9.838699, 3.359, 12.8258, 9.8819, 3.359, 13.619101, 10.462399, 3.2359, 13.4067, 10.122, 3.1906, 13.8256, 9.8819, 3.359, 13.619101, 10.225699, 3.399, 13.197901, 10.462399, 3.2359, 13.4067, 12.575499, 3.4812999, 13.4044, 10.225699, 3.399, 13.197901, 12.125999, 3.6032, 13.197901, 12.575499, 3.4812999, 13.4044, 10.462399, 3.2359, 13.4067, 10.225699, 3.399, 13.197901, 6.6889997, 3.3913999, 13.3783, 10.388599, 3.3911998, 16.7085, 6.6889997, 3.3913999, 16.7227, 10.388599, 3.3911998, 16.7085, 6.6889997, 3.3913999, 13.3783, 9.4411, 3.359, 13.2192, 10.388599, 3.3911998, 16.7085, 9.4411, 3.359, 13.2192, 9.8819, 3.359, 13.619101, 6.6889997, 3.3913999, 10.0334, 9.4411, 3.359, 13.2192, 6.6889997, 3.3913999, 13.3783, 9.4411, 3.359, 13.2192, 6.6889997, 3.3913999, 10.0334, 10.0335, 3.3913999, 10.0334, 9.4411, 3.359, 13.2192, 10.0335, 3.3913999, 10.0334, 9.838699, 3.359, 12.8258, 9.8819, 3.359, 13.619101, 10.590099, 3.2050998, 16.7167, 10.388599, 3.3911998, 16.7085, 9.8819, 3.359, 13.619101, 10.122, 3.1906, 13.8256, 10.590099, 3.2050998, 16.7167, 12.125999, 3.6032, 13.197901, 13.189199, 3.2312999, 12.5394, 13.262999, 3.3165998, 13.403801, 12.125999, 3.6032, 13.197901, 12.9445, 3.6148, 12.325901, 13.189199, 3.2312999, 12.5394, 13.262999, 3.3165998, 13.403801, 12.575499, 3.4812999, 13.4044, 12.125999, 3.6032, 13.197901, 13.189199, 3.2312999, 12.5394, 12.732399, 3.3913999, 10.0334, 12.977798, 3.2031, 10.0163, 13.189199, 3.2312999, 12.5394, 12.9445, 3.6148, 12.325901, 12.732399, 3.3913999, 10.0334, 10.0335, 3.3913999, 10.0334, 10.225699, 3.399, 13.197901, 9.838699, 3.359, 12.8258, 10.225699, 3.399, 13.197901, 10.0335, 3.3913999, 10.0334, 12.9445, 3.6148, 12.325901, 12.9445, 3.6148, 12.325901, 10.0335, 3.3913999, 10.0334, 12.732399, 3.3913999, 10.0334, 10.225699, 3.399, 13.197901, 12.9445, 3.6148, 12.325901, 12.125999, 3.6032, 13.197901, 12.8249, 2.8544, 7.9231997, 12.9499, 3.3256998, 8.668, 11.173199, 3.3332, 6.6548, 10.0335, 3.3913999, 6.6891, 10.0335, 3.3913999, 4.2546997, 11.173199, 3.3332, 6.6548, 12.732399, 3.3913999, 10.0334, 13.175299, 2.4743, 8.0415, 12.977798, 3.2031, 10.0163, 13.175299, 2.4743, 8.0415, 12.732399, 3.3913999, 10.0334, 12.9499, 3.3256998, 8.668, 13.175299, 2.4743, 8.0415, 12.9499, 3.3256998, 8.668, 12.8249, 2.8544, 7.9231997, 10.0335, 3.3913999, 6.6891, 12.732399, 3.3913999, 10.0334, 10.0335, 3.3913999, 10.0334, 12.732399, 3.3913999, 10.0334, 10.0335, 3.3913999, 6.6891, 11.173199, 3.3332, 6.6548, 12.732399, 3.3913999, 10.0334, 11.173199, 3.3332, 6.6548, 12.9499, 3.3256998, 8.668, 16.722599, 3.1513, -3.6023998, 15.810999, 2.9368, -3.3060002, 13.2491, 2.9931, -3.474, 16.722599, 3.1513, -3.6023998, 16.712599, 2.8734, -3.3451, 15.810999, 2.9368, -3.3060002, 10.0335, 3.2212, -2.2310996, 10.0335, 3.3913999, -3.3451, 13.2491, 2.9931, -3.474, -16.7232, 0.6137, 0, -15.754801, 0.6137, 3.5372, -16.7232, 0.6137, 2.9164, -15.754801, 0.6137, 3.5372, -16.7232, 0.6137, 0, -13.378601, 0.6137, 0, -16.7232, 0.6137, 0, -15.803801, 0.6137, -2.7093, -13.378601, 0.6137, -3.3446002, -16.7232, 0.6137, 0, -13.378601, 0.6137, -3.3446002, -13.378601, 0.6137, 0, -13.378601, 0.6137, 0, -13.378601, 0.6137, -3.3446002, -10.033899, 0.6137, -3.3446002, -15.754801, 0.6137, 3.5372, -13.378601, 0.6137, 0, -14.489201, 0.6137, 4.2777, -13.378601, 0.6137, 0, -10.033899, 0.6137, -3.3446002, -10.033899, 0.6137, 0, -14.489201, 0.6137, 4.2777, -13.378601, 0.6137, 0, -10.033899, 0.6137, 0, -10.033899, 0.6137, 0, -10.033899, 0.6137, -3.3446002, -6.6893, 0.6137, -3.3446002, -10.033899, 0.6137, 0, -6.6893, 0.6137, -3.3446002, -6.6893, 0.6137, 0, -6.6893, 0.6137, 0, -6.6893, 0.6137, -3.3446002, -4.0259, 0.6137, -1.6911998, -6.6893, 0.6137, 0, -4.0259, 0.6137, -1.6911998, -3.3446999, 0.6137, 0, -10.033899, 0.6137, 3.3446, -10.033899, 0.6137, 0, -6.6893, 0.6137, 0, -14.489201, 0.6137, 4.2777, -10.033899, 0.6137, 0, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 0, -3.3446999, 0.6137, 0, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 0, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -3.3446999, 0.6137, 0, -3.3446999, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -14.489201, 0.6137, 4.2777, -10.033899, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 6.6893, -10.033899, 0.6137, 6.6893, -13.6772, 0.6137, 5.2616, -14.489201, 0.6137, 4.2777, -13.6772, 0.6137, 5.2616, -10.033899, 0.6137, 6.6893, -12.7477, 0.6137, 6.3669996, -6.6893, 0.6137, 3.3446, -2.5675998, 0.0266, 7.6215, -6.6893, 0.6137, 6.6893, -2.5675998, 0.0266, 7.6215, -6.6893, 0.6137, 3.3446, -3.3446999, 0.6137, 3.3446, -2.5675998, 0.0266, 7.6215, -3.3446999, 0.6137, 3.3446, -2.1193, 0.6137, 5.2736, 10.033899, 0, -20.467, 6.6766996, 3.0570998, -19.0275, 6.6893, 0, -20.1318, 10.033899, 0, -20.467, 10.033899, 3.0523999, -19.0294, 6.6766996, 3.0570998, -19.0275, 3.0140998, 0, -16.7232, 4.4131, 3.2091, -13.357698, 3.3446, -0.3989, -12.9443, 3.0140998, 0, -16.7232, 3.5895, 3.2033, -16.7232, 4.4131, 3.2091, -13.357698, -6.6893, 0, -14.263699, -10.404301, 3.1608999, -13.429499, -9.6168995, 0, -14.127899, -6.6893, 0, -14.263699, -6.6893, 3.175, -12.866999, -10.404301, 3.1608999, -13.429499, -23.412498, -0.2913, 0.26119995, -23.0793, 3.314, 3.3674998, -23.412498, 0, 3.3446, -23.412498, -0.2913, 0.26119995, -23.3676, 3.4459999, 0.1372, -23.0793, 3.314, 3.3674998, -23.412498, 0, 3.3446, -22.563799, 3.2219, 6.6893, -23.8078, 0, 6.6893, -23.412498, 0, 3.3446, -23.0793, 3.314, 3.3674998, -22.563799, 3.2219, 6.6893, -13.378601, 0, 13.378601, -10.033899, 2.9384, 12.453701, -10.033899, 0, 13.378601, -13.378601, 0, 13.378601, -13.378601, 3.194, 12.808901, -10.033899, 2.9384, 12.453701, -3.3446002, 0, 16.7232, 0, 2.9636998, 16.0179, 0, 0, 16.7232, -3.3446002, 0, 16.7232, -3.3446002, 3.1497998, 15.9146, 0, 2.9636998, 16.0179, 21.2349, 0, -6.6893, 20.188799, 3.1655998, -10.014999, 21.8888, 0, -10.033899, 21.2349, 0, -6.6893, 20.147, 3.0588999, -6.6893, 20.188799, 3.1655998, -10.014999, 20.1586, 3.1318998, -13.0413, 20.809599, 0, -13.7309, 21.251299, 0, -13.3043995, 20.1586, 3.1318998, -13.0413, 19.7684, 3.1308, -13.405399, 20.809599, 0, -13.7309, 20.809599, 0, -13.7309, 16.8128, 3.1578999, -13.463299, 18.0241, 0, -14.301899, 20.809599, 0, -13.7309, 19.7684, 3.1308, -13.405399, 16.8128, 3.1578999, -13.463299, 21.8888, 0, -10.033899, 20.1586, 3.1318998, -13.0413, 21.251299, 0, -13.3043995, 21.8888, 0, -10.033899, 20.188799, 3.1655998, -10.014999, 20.1586, 3.1318998, -13.0413, 16.7704, 3.1685998, -15.819698, 16.3113, 0, -16.9629, 17.503, 0, -15.940498, 16.7704, 3.1685998, -15.819698, 15.8286, 3.1678, -16.6059, 16.3113, 0, -16.9629, 16.3113, 0, -16.9629, 12.747099, 3.1769, -16.199, 13.701399, 0, -17.416399, 16.3113, 0, -16.9629, 15.8286, 3.1678, -16.6059, 12.747099, 3.1769, -16.199, 18.0241, 0, -14.301899, 16.7704, 3.1685998, -15.819698, 17.503, 0, -15.940498, 18.0241, 0, -14.301899, 16.8128, 3.1578999, -13.463299, 16.7704, 3.1685998, -15.819698, 12.961399, 0, -20.5828, 12.727098, 2.9599, -18.8239, 12.2999, 2.942, -19.2491, 12.961399, 0, -20.5828, 13.423399, 0, -20.1574, 12.727098, 2.9599, -18.8239, 12.961399, 0, -20.5828, 10.033899, 3.0523999, -19.0294, 10.033899, 0, -20.467, 12.961399, 0, -20.5828, 12.2999, 2.942, -19.2491, 10.033899, 3.0523999, -19.0294, 13.701399, 0, -17.416399, 12.727098, 2.9599, -18.8239, 13.423399, 0, -20.1574, 13.701399, 0, -17.416399, 12.747099, 3.1769, -16.199, 12.727098, 2.9599, -18.8239, 3.2372, 0, -19.3395, 5.4684, 3.0900998, -18.6069, 3.9039, 3.1690998, -17.2691, 3.2372, 0, -19.3395, 4.4523, 0, -20.444399, 5.4684, 3.0900998, -18.6069, 6.6893, 0, -20.1318, 5.4684, 3.0900998, -18.6069, 4.4523, 0, -20.444399, 6.6893, 0, -20.1318, 6.6766996, 3.0570998, -19.0275, 5.4684, 3.0900998, -18.6069, 3.2372, 0, -19.3395, 3.5895, 3.2033, -16.7232, 3.0140998, 0, -16.7232, 3.2372, 0, -19.3395, 3.9039, 3.1690998, -17.2691, 3.5895, 3.2033, -16.7232, -15.441, 3.3151, -15.753099, -16.7232, 0, -16.113699, -16.1493, 0, -16.8284, -15.441, 3.3151, -15.753099, -16.1238, 3.3711998, -15.15, -16.7232, 0, -16.113699, -16.7232, 0, -16.113699, -16.3753, 3.4225, -13.627699, -16.7232, 0, -13.378599, -16.7232, 0, -16.113699, -16.1238, 3.3711998, -15.15, -16.3753, 3.4225, -13.627699, -13.378601, 0, -17.3364, -15.441, 3.3151, -15.753099, -16.1493, 0, -16.8284, -13.378601, 0, -17.3364, -13.3848, 3.1832, -15.7598, -15.441, 3.3151, -15.753099, -10.3452, 0, -16.7803, -10.4286995, 3.1564, -15.832399, -10.7493, 3.1581, -16.1132, -10.3452, 0, -16.7803, -9.983101, 0, -16.4067, -10.4286995, 3.1564, -15.832399, -10.3452, 0, -16.7803, -13.3848, 3.1832, -15.7598, -13.378601, 0, -17.3364, -10.3452, 0, -16.7803, -10.7493, 3.1581, -16.1132, -13.3848, 3.1832, -15.7598, -9.6168995, 0, -14.127899, -10.4286995, 3.1564, -15.832399, -9.983101, 0, -16.4067, -9.6168995, 0, -14.127899, -10.404301, 3.1608999, -13.429499, -10.4286995, 3.1564, -15.832399, -3.6946998, 0, -13.471199, -3.6475997, 3.1597998, -12.441198, -4.0183997, 3.1606, -12.819899, -3.6946998, 0, -13.471199, -3.2535, 0, -13.020899, -3.6475997, 3.1597998, -12.441198, -3.6946998, 0, -13.471199, -6.6893, 3.175, -12.866999, -6.6893, 0, -14.263699, -3.6946998, 0, -13.471199, -4.0183997, 3.1606, -12.819899, -6.6893, 3.175, -12.866999, -3.2331, 3.1696, -9.964899, -2.7220998, 0, -10.936998, -2.2352996, 0, -10.6031, -3.2331, 3.1696, -9.964899, -3.6138997, 3.1664, -10.447599, -2.7220998, 0, -10.936998, 0, 0, -10.7654, -3.2331, 3.1696, -9.964899, -2.2352996, 0, -10.6031, 0, 0, -10.7654, -0.0039999485, 3.1827998, -9.0644, -3.2331, 3.1696, -9.964899, -2.7220998, 0, -10.936998, -3.6475997, 3.1597998, -12.441198, -3.2535, 0, -13.020899, -2.7220998, 0, -10.936998, -3.6138997, 3.1664, -10.447599, -3.6475997, 3.1597998, -12.441198, 3.847, 3.1766, -9.663599, 2.2182999, 0, -10.525, 2.9573, -0.1021, -11.0952, 3.847, 3.1766, -9.663599, 3.1496, 3.1724, -9.052, 2.2182999, 0, -10.525, 3.3446, -0.3989, -12.9443, 3.847, 3.1766, -9.663599, 2.9573, -0.1021, -11.0952, 3.3446, -0.3989, -12.9443, 4.4131, 3.2091, -13.357698, 3.847, 3.1766, -9.663599, 2.2182999, 0, -10.525, -0.0039999485, 3.1827998, -9.0644, 0, 0, -10.7654, 2.2182999, 0, -10.525, 3.1496, 3.1724, -9.052, -0.0039999485, 3.1827998, -9.0644, -20.108599, 0, -9.592199, -19.176899, 3.1662998, -9.762199, -19.6161, 3.2075999, -9.711699, -20.108599, 0, -9.592199, -19.6286, 0, -10.1098995, -19.176899, 3.1662998, -9.762199, -19.6161, 3.2075999, -9.711699, -20.3764, 0, -6.6893, -20.108599, 0, -9.592199, -20.3764, 0, -6.6893, -19.6161, 3.2075999, -9.711699, -19.610699, 3.187, -9.246599, -20.3764, 0, -6.6893, -19.610699, 3.187, -9.246599, -19.515, 3.2122, -6.6893, -16.407099, 3.2108998, -10.4028, -17.8929, 0, -10.41, -17.1586, 0, -11.120298, -16.407099, 3.2108998, -10.4028, -17.0486, 3.1696, -9.782799, -17.8929, 0, -10.41, -16.7232, 0, -13.378599, -16.407099, 3.2108998, -10.4028, -17.1586, 0, -11.120298, -16.7232, 0, -13.378599, -16.3753, 3.4225, -13.627699, -16.407099, 3.2108998, -10.4028, -17.8929, 0, -10.41, -19.176899, 3.1662998, -9.762199, -19.6286, 0, -10.1098995, -17.8929, 0, -10.41, -17.0486, 3.1696, -9.782799, -19.176899, 3.1662998, -9.762199, -19.841799, 3.2077, -3.7668, -19.7545, 3.3913999, -2.7851996, -19.9489, 3.2063, -2.8082, -19.841799, 3.2077, -3.7668, -21.0086, -0.2504, -3.5043998, -20.1607, -0.2436, -4.5060997, -19.841799, 3.2077, -3.7668, -19.9489, 3.2063, -2.8082, -21.0086, -0.2504, -3.5043998, -20.3764, 0, -6.6893, -19.841799, 3.2077, -3.7668, -20.1607, -0.2436, -4.5060997, -20.3764, 0, -6.6893, -19.515, 3.2122, -6.6893, -19.841799, 3.2077, -3.7668, -22.9314, 3.3177998, -2.7092, -23.412498, -0.0385, -2.8684, -22.9552, -0.047599997, -3.375, -22.9314, 3.3177998, -2.7092, -23.3864, 3.3542, -2.2045999, -23.412498, -0.0385, -2.8684, -23.412498, -0.0385, -2.8684, -23.3676, 3.4459999, 0.1372, -23.412498, -0.2913, 0.26119995, -23.412498, -0.0385, -2.8684, -23.3864, 3.3542, -2.2045999, -23.3676, 3.4459999, 0.1372, -21.0086, -0.2504, -3.5043998, -22.9314, 3.3177998, -2.7092, -22.9552, -0.047599997, -3.375, -21.0086, -0.2504, -3.5043998, -19.9489, 3.2063, -2.8082, -22.9314, 3.3177998, -2.7092, -22.756899, 0, 10.033899, -22.7643, 3.2136, 9.1159, -22.5907, 3.2112, 9.440499, -22.756899, 0, 10.033899, -23.489, 0, 9.386499, -22.7643, 3.2136, 9.1159, -23.8078, 0, 6.6893, -22.7643, 3.2136, 9.1159, -23.489, 0, 9.386499, -23.8078, 0, 6.6893, -22.563799, 3.2219, 6.6893, -22.7643, 3.2136, 9.1159, -16.7232, 0, 10.8878, -17.1359, 3.192, 9.715799, -16.2818, 3.1913998, 9.8056, -16.7232, 0, 10.8878, -17.583, 0, 10.033899, -17.1359, 3.192, 9.715799, -20.0679, 0, 10.033899, -17.1359, 3.192, 9.715799, -17.583, 0, 10.033899, -20.0679, 0, 10.033899, -20.0679, 3.1943, 9.407499, -17.1359, 3.192, 9.715799, -16.111599, 3.066, 12.2328, -16.223, 0, 13.378601, -16.7232, 0, 12.878401, -16.111599, 3.066, 12.2328, -15.5713005, 3.0688999, 12.748899, -16.223, 0, 13.378601, -16.223, 0, 13.378601, -13.378601, 3.194, 12.808901, -13.378601, 0, 13.378601, -16.223, 0, 13.378601, -15.5713005, 3.0688999, 12.748899, -13.378601, 3.194, 12.808901, -16.7232, 0, 10.8878, -16.111599, 3.066, 12.2328, -16.7232, 0, 12.878401, -16.7232, 0, 10.8878, -16.2818, 3.1913998, 9.8056, -16.111599, 3.066, 12.2328, -6.6893, 0, 13.8773, -6.7777, 3.1009, 13.0326, -6.2748, 3.126, 13.622, -6.6893, 0, 13.8773, -7.1966996, 0, 13.378601, -6.7777, 3.1009, 13.0326, -10.033899, 0, 13.378601, -6.7777, 3.1009, 13.0326, -7.1966996, 0, 13.378601, -10.033899, 0, 13.378601, -10.033899, 2.9384, 12.453701, -6.7777, 3.1009, 13.0326, -6.1093993, 0, 16.7232, -6.2748, 3.1260998, 16.1257, -6.0452, 3.135, 16.5325, -6.1093993, 0, 16.7232, -6.6893, 0, 16.1455, -6.2748, 3.1260998, 16.1257, -6.1093993, 0, 16.7232, -3.3446002, 3.1497998, 15.9146, -3.3446002, 0, 16.7232, -6.1093993, 0, 16.7232, -6.0452, 3.135, 16.5325, -3.3446002, 3.1497998, 15.9146, -6.6893, 0, 13.8773, -6.2748, 3.1260998, 16.1257, -6.6893, 0, 16.1455, -6.6893, 0, 13.8773, -6.2748, 3.126, 13.622, -6.2748, 3.1260998, 16.1257, 3.3446, 0, 17.592, 2.777, 3.0992, 16.3951, 3.6736, 3.1532, 16.5721, 3.3446, 0, 17.592, 2.4738998, 0, 16.7232, 2.777, 3.0992, 16.3951, 0, 0, 16.7232, 2.777, 3.0992, 16.3951, 2.4738998, 0, 16.7232, 0, 0, 16.7232, 0, 2.9636998, 16.0179, 2.777, 3.0992, 16.3951, 3.3446, 0, 17.592, 3.8212998, 3.3128, 18.735199, 3.3446, 0, 19.1425, 3.3446, 0, 17.592, 3.6736, 3.1532, 16.5721, 3.8212998, 3.3128, 18.735199, 4.275, 0, 20.0679, 6.7795997, 3.1271, 19.243599, 6.6893, 0, 20.0679, 4.275, 0, 20.0679, 4.8012, 3.3019998, 19.5215, 6.7795997, 3.1271, 19.243599, 3.8212998, 3.3128, 18.735199, 4.275, 0, 20.0679, 3.3446, 0, 19.1425, 3.8212998, 3.3128, 18.735199, 4.8012, 3.3019998, 19.5215, 4.275, 0, 20.0679, -22.756899, 0, 10.033899, -20.0679, 3.1943, 9.407499, -20.0679, 0, 10.033899, -22.756899, 0, 10.033899, -22.5907, 3.2112, 9.440499, -20.0679, 3.1943, 9.407499, 10.572599, 0, 19.5895, 8.8245, 3.2012, 19.0993, 9.5278, 3.2163, 18.6607, 10.572599, 0, 19.5895, 10.080299, 0, 20.0679, 8.8245, 3.2012, 19.0993, 6.6893, 0, 20.0679, 8.8245, 3.2012, 19.0993, 10.080299, 0, 20.0679, 6.6893, 0, 20.0679, 6.7795997, 3.1271, 19.243599, 8.8245, 3.2012, 19.0993, 10.572599, 0, 19.5895, 10.5903, 3.2052, 16.7169, 10.572599, 0, 16.7232, 10.572599, 0, 19.5895, 9.5278, 3.2163, 18.6607, 10.5903, 3.2052, 16.7169, 10.986898, 0, 13.9188, 10.122399, 3.1906, 13.826099, 10.462799, 3.2359, 13.406799, 10.986898, 0, 13.9188, 10.572599, 0, 14.3402, 10.122399, 3.1906, 13.826099, 10.572599, 0, 16.7232, 10.122399, 3.1906, 13.826099, 10.572599, 0, 14.3402, 10.572599, 0, 16.7232, 10.5903, 3.2052, 16.7169, 10.122399, 3.1906, 13.826099, 13.8046, 0, 13.2202, 12.5756, 3.4812999, 13.4049, 13.2631, 3.3165998, 13.404301, 13.8046, 0, 13.2202, 13.105099, 0, 13.9188, 12.5756, 3.4812999, 13.4049, 13.2631, 3.3165998, 13.404301, 13.8046, 0, 10.033899, 13.8046, 0, 13.2202, 13.8046, 0, 10.033899, 13.2631, 3.3165998, 13.404301, 13.1894, 3.2312999, 12.539801, 13.8046, 0, 10.033899, 13.1894, 3.2312999, 12.539801, 12.9783, 3.2031, 10.0168, 10.986898, 0, 13.9188, 12.5756, 3.4812999, 13.4049, 13.105099, 0, 13.9188, 10.986898, 0, 13.9188, 10.462799, 3.2359, 13.406799, 12.5756, 3.4812999, 13.4049, 13.8046, 0, 10.033899, 13.175798, 2.4743, 8.042, 14.0257, 0.0442, 7.3252997, 13.8046, 0, 10.033899, 12.9783, 3.2031, 10.0168, 13.175798, 2.4743, 8.042, 20.1399, 2.779, -3.3615003, 21.09, -0.0218, -4.9179, 20.613499, 1.0832, -3.1922002, 21.09, -0.0218, -4.9179, 20.1399, 2.779, -3.3615003, 20.147, 3.0588999, -6.6893, 21.09, -0.0218, -4.9179, 20.147, 3.0588999, -6.6893, 21.2349, 0, -6.6893, 15.6619, 2.2603, -2.7998996, 20.1399, 2.779, -3.3615003, 20.613499, 1.0832, -3.1922002, 20.1399, 2.779, -3.3615003, 15.6619, 2.2603, -2.7998996, 16.7127, 2.8734, -3.3446002, 16.7127, 2.8734, -3.3446002, 15.6619, 2.2603, -2.7998996, 15.810999, 2.9368, -3.3059, 13.249599, 2.9931998, -3.4737, 15.810999, 2.9368, -3.3059, 14.217899, 2.8779, -3.3838, 14.217899, 2.8779, -3.3838, 15.810999, 2.9368, -3.3059, 15.6619, 2.2603, -2.7998996, -16.7232, 3.0033998, 2.9164, -15.754801, 0.6137, 3.5372, -15.372101, 3.0033998, 3.6132, -16.7232, 3.0033998, 2.9164, -16.7232, 0.6137, 2.9164, -15.754801, 0.6137, 3.5372, -14.489201, 3.0033998, 4.2777, -13.6772, 0.6137, 5.2616, -13.694401, 3.0033998, 5.1798, -14.489201, 3.0033998, 4.2777, -14.489201, 0.6137, 4.2777, -13.6772, 0.6137, 5.2616, -15.803801, 3.0033998, -2.7093, -16.7232, 0.6137, 0, -16.7232, 3.0033998, 0, -15.803801, 3.0033998, -2.7093, -15.803801, 0.6137, -2.7093, -16.7232, 0.6137, 0, -16.7232, 3.0033998, 0, -16.7232, 0.6137, 2.9164, -16.7232, 3.0033998, 2.9164, -16.7232, 3.0033998, 0, -16.7232, 0.6137, 0, -16.7232, 0.6137, 2.9164, -3.3446999, 3.0033998, 0, -4.0259, 0.6137, -1.6911998, -4.0259, 3.0033998, -1.6911998, -3.3446999, 3.0033998, 0, -3.3446999, 0.6137, 0, -4.0259, 0.6137, -1.6911998, -3.3446999, 3.0033998, 3.3446, -3.3446999, 0.6137, 0, -3.3446999, 3.0033998, 0, -3.3446999, 3.0033998, 3.3446, -3.3446999, 0.6137, 3.3446, -3.3446999, 0.6137, 0, -12.7477, 3.0033998, 6.3669996, -10.033899, 0.6137, 6.6893, -10.033899, 3.0033998, 6.6893, -12.7477, 3.0033998, 6.3669996, -12.7477, 0.6137, 6.3669996, -10.033899, 0.6137, 6.6893, -10.033899, 3.0033998, -3.3446002, -13.378601, 0.6137, -3.3446002, -13.378601, 3.0033998, -3.3446002, -10.033899, 3.0033998, -3.3446002, -10.033899, 0.6137, -3.3446002, -13.378601, 0.6137, -3.3446002, -6.6893, 3.0033998, -3.3446002, -10.033899, 0.6137, -3.3446002, -10.033899, 3.0033998, -3.3446002, -6.6893, 3.0033998, -3.3446002, -6.6893, 0.6137, -3.3446002, -10.033899, 0.6137, -3.3446002, -13.378601, 3.0033998, -3.3446002, -15.803801, 0.6137, -2.7093, -15.803801, 3.0033998, -2.7093, -13.378601, 3.0033998, -3.3446002, -13.378601, 0.6137, -3.3446002, -15.803801, 0.6137, -2.7093, -4.0259, 3.0033998, -1.6911998, -6.6893, 0.6137, -3.3446002, -6.6893, 3.0033998, -3.3446002, -4.0259, 3.0033998, -1.6911998, -4.0259, 0.6137, -1.6911998, -6.6893, 0.6137, -3.3446002, -6.6893, 3.0033998, 6.6893, -2.5675998, 0.0266, 7.6215, -2.5675998, 2.9782, 7.6215, -6.6893, 3.0033998, 6.6893, -6.6893, 0.6137, 6.6893, -2.5675998, 0.0266, 7.6215, -10.033899, 3.0033998, 6.6893, -6.6893, 0.6137, 6.6893, -6.6893, 3.0033998, 6.6893, -10.033899, 3.0033998, 6.6893, -10.033899, 0.6137, 6.6893, -6.6893, 0.6137, 6.6893, -2.5675998, 2.9782, 7.6215, -2.1193, 0.6137, 5.2736, -2.1397996, 3.0033998, 5.1794, -2.5675998, 2.9782, 7.6215, -2.5675998, 0.0266, 7.6215, -2.1193, 0.6137, 5.2736, -2.1193, 0.6137, 5.2736, -3.3446999, 3.0033998, 3.3446, -2.1397996, 3.0033998, 5.1794, -2.1193, 0.6137, 5.2736, -3.3446999, 0.6137, 3.3446, -3.3446999, 3.0033998, 3.3446, -13.6772, 0.6137, 5.2616, -12.7477, 3.0033998, 6.3669996, -13.694401, 3.0033998, 5.1798, -13.6772, 0.6137, 5.2616, -12.7477, 0.6137, 6.3669996, -12.7477, 3.0033998, 6.3669996, -15.754801, 0.6137, 3.5372, -14.489201, 3.0033998, 4.2777, -15.372101, 3.0033998, 3.6132, -15.754801, 0.6137, 3.5372, -14.489201, 0.6137, 4.2777, -14.489201, 3.0033998, 4.2777, -3.3446002, -1.4008, -23.412498, 0, -1.0608, -26.7572, 0, -0.9271, -23.412498, -3.3446002, -1.4008, -23.412498, -3.3446002, -1.458, -26.7572, 0, -1.0608, -26.7572, -16.7232, -1.7572, -23.412498, -13.378601, -2.7663999, -26.7572, -13.378601, -1.3177999, -23.412498, -16.7232, -1.7572, -23.412498, -16.7232, -3.0929, -26.7572, -13.378601, -2.7663999, -26.7572, 10.033899, 0, -23.412498, 13.378599, -0.8401, -26.7572, 13.378599, 0, -23.412498, 10.033899, 0, -23.412498, 10.033899, -0.8648, -26.7572, 13.378599, -0.8401, -26.7572, 3.3446, -0.3434, -23.412498, 6.6893, -1.0129, -26.7572, 6.6893, 0, -23.412498, 3.3446, -0.3434, -23.412498, 3.3446, -0.98829997, -26.7572, 6.6893, -1.0129, -26.7572, -23.412498, -2.7663999, -23.412498, -20.0679, -3.0929, -26.7572, -20.0679, -2.7663999, -23.412498, -23.412498, -2.7663999, -23.412498, -23.412498, -3.0929, -26.7572, -20.0679, -3.0929, -26.7572, -26.7572, -2.7663999, -23.412498, -23.412498, -3.0929, -26.7572, -23.412498, -2.7663999, -23.412498, -26.7572, -2.7663999, -23.412498, -26.7572, -3.0929, -26.7572, -23.412498, -3.0929, -26.7572, -23.412498, -0.7606, -16.7232, -20.0679, -1.7572, -20.0679, -20.0679, -0.43429998, -16.7232, -23.412498, -0.7606, -16.7232, -23.412498, -2.7663999, -20.0679, -20.0679, -1.7572, -20.0679, -10.033899, -0.2814, 23.412498, -6.6893, 0, 20.0679, -6.6893, -0.2814, 23.412498, -6.6893, -0.2814, 23.412498, -6.6893, 0, 20.0679, -3.3446002, 0, 20.0679, -10.033899, -0.2814, 23.412498, -10.033899, 0, 20.0679, -6.6893, 0, 20.0679, -6.6893, -0.2814, 23.412498, -3.3446002, 0, 20.0679, -3.3446002, -0.2814, 23.412498, -3.3446002, -0.2814, 23.412498, -3.3446002, 0, 20.0679, 0, 0, 20.0679, -3.3446002, -0.2814, 23.412498, 0, 0, 20.0679, 0, -0.2814, 23.412498, -13.378601, 0, 20.0679, -10.033899, 0, 20.0679, -10.033899, -0.2814, 23.412498, -13.378601, 0, 20.0679, -10.033899, -0.2814, 23.412498, -12.357901, -0.2814, 23.412498, -13.378601, -0.2814, 23.412498, -13.378601, 0, 20.0679, -12.357901, -0.2814, 23.412498, -23.412498, -0.36479998, 16.7232, -23.412498, 0, 13.378601, -20.0679, -0.36479998, 16.7232, -23.412498, 0, 13.378601, -20.0679, 0, 13.378601, -20.0679, -0.36479998, 16.7232, -23.412498, -0.7373, 23.412498, -23.412498, -0.692, 20.0679, -20.0679, -0.5589, 23.412498, -16.7232, -0.36479998, 23.412498, -16.7232, -0.36479998, 20.0679, -13.378601, -0.2814, 23.412498, 16.7232, -1.0746, 16.7232, 20.0679, -1.0746, 13.378601, 20.0679, -1.8294, 16.7232, 20.0679, -1.8294, 16.7232, 20.0679, -1.0746, 13.378601, 23.412498, -1.8294, 13.378601, 16.7232, -1.8294, 20.0679, 16.7232, -1.0746, 16.7232, 20.0679, -1.8294, 16.7232, 16.7232, -2.2719998, 23.3902, 20.0679, -1.8294, 20.0679, 20.0679, -2.2719998, 23.3902, 16.7232, -2.2719998, 23.3902, 16.7232, -1.8294, 20.0679, 20.0679, -1.8294, 20.0679, 16.7232, -1.8294, 20.0679, 16.7232, -2.2719998, 23.3902, 13.378599, -2.2719998, 23.3902, 20.0679, -2.2719998, 23.3902, 20.0679, -1.8294, 20.0679, 23.412498, -1.8294, 20.0679, 20.0679, -2.2719998, 23.3902, 23.412498, -1.8294, 20.0679, 23.412498, -2.2719998, 23.3902, 23.412498, -1.8294, 20.0679, 26.7582, -2.2719998, 23.3902, 23.412498, -2.2719998, 23.3902, 23.412498, -1.8294, 20.0679, 26.7582, -1.8294, 20.0679, 26.7582, -2.2719998, 23.3902, -10.033899, -0.9271, -23.412498, -6.6893, -1.458, -26.7572, -6.6893, -1.3241999, -23.412498, -10.033899, -0.9271, -23.412498, -10.033899, -1.8786, -26.7572, -6.6893, -1.458, -26.7572, -3.3446002, -0.9271, -16.7232, 0, -0.9271, -20.0679, 0, -0.9271, -16.7232, -3.3446002, -0.9271, -16.7232, -3.3446002, -0.9271, -20.0679, 0, -0.9271, -20.0679, -6.6893, -0.9271, -20.0679, -3.3446002, -0.9271, -20.0679, -3.3446002, -0.9271, -16.7232, 16.7232, -0.3105, -23.412498, 16.7232, -1.3382, -26.7572, 20.0679, -0.8222, -23.412498, 20.0679, 0, -16.7232, 20.0679, -0.2837, -20.0679, 23.412498, -0.456, -16.7232, 13.378599, 0, -23.412498, 13.378599, -0.8401, -26.7572, 16.7232, -0.3105, -23.412498, 16.7232, 0, -20.0679, 16.7232, -0.3105, -23.412498, 20.0679, -0.2837, -20.0679, -6.6893, 0, -16.7232, -6.6893, -0.9271, -20.0679, -3.3446002, -0.9271, -16.7232, -13.378601, -1.3177999, -23.412498, -10.033899, -1.8786, -26.7572, -10.033899, -0.9271, -23.412498, -13.378601, -1.3177999, -23.412498, -13.378601, -2.7663999, -26.7572, -10.033899, -1.8786, -26.7572, -13.210501, -0.3964, -20.032099, -10.033899, -0.9271, -23.412498, -9.318001, -0.3969, -19.413, -13.210501, -0.3964, -20.032099, -13.378601, -1.3177999, -23.412498, -10.033899, -0.9271, -23.412498, -9.318001, -0.3969, -19.413, -10.033899, -0.9271, -23.412498, -6.6893, -0.9271, -20.0679, 20.0679, -1.0746, 13.378601, 20.0679, 0, 10.033899, 23.412498, -0.35529998, 10.033899, 13.378599, -2.2719998, 23.3902, 16.7232, -2.2194998, 26.781, 13.378599, -2.2194998, 26.781, 13.378599, -2.2719998, 23.3902, 16.7232, -2.2719998, 23.3902, 16.7232, -2.2194998, 26.781, 16.7232, -2.2194998, 26.781, 16.7232, -2.2719998, 23.3902, 20.0679, -2.2719998, 23.3902, 16.7232, -2.2194998, 26.781, 20.0679, -2.2719998, 23.3902, 20.0679, -2.2194998, 26.781, 20.0679, -2.2194998, 26.781, 20.0679, -2.2719998, 23.3902, 23.412498, -2.2719998, 23.3902, 20.0679, -2.2194998, 26.781, 23.412498, -2.2719998, 23.3902, 23.412498, -2.2194998, 26.781, 13.378599, -1.0746, 20.0679, 15.0508995, -0.40039998, 16.7232, 16.7232, -1.0746, 16.7232, 16.7232, -1.0746, 13.378601, 16.7232, 0, 10.033899, 20.0679, 0, 10.033899, 20.0679, 0, 10.033899, 20.0679, -1.0746, 13.378601, 16.7232, -1.0746, 13.378601, 6.6893, -1.1209999, 26.7572, 10.033899, -0.501, 23.412498, 10.033899, -1.1209999, 26.7572, 6.6893, -1.1209999, 26.7572, 6.6893, -0.2814, 23.412498, 10.033899, -0.501, 23.412498, 10.033899, -1.1209999, 26.7572, 13.378599, -2.2719998, 23.3902, 13.378599, -2.2194998, 26.781, 10.033899, -1.1209999, 26.7572, 10.033899, -0.501, 23.412498, 13.378599, -2.2719998, 23.3902, 0, -1.1209999, 26.7572, 3.3446, -0.2814, 23.412498, 3.3446, -1.1209999, 26.7572, 3.3446, -1.1209999, 26.7572, 3.3446, -0.2814, 23.412498, 6.6893, -0.2814, 23.412498, 3.3446, -1.1209999, 26.7572, 6.6893, -0.2814, 23.412498, 6.6893, -1.1209999, 26.7572, 0, -1.1209999, 26.7572, 0, -0.2814, 23.412498, 3.3446, -0.2814, 23.412498, -3.3446002, -1.1209999, 26.7572, 0, -0.2814, 23.412498, 0, -1.1209999, 26.7572, -3.3446002, -1.1209999, 26.7572, -3.3446002, -0.2814, 23.412498, 0, -0.2814, 23.412498, -6.6893, -1.1209999, 26.7572, -3.3446002, -0.2814, 23.412498, -3.3446002, -1.1209999, 26.7572, -6.6893, -1.1209999, 26.7572, -6.6893, -0.2814, 23.412498, -3.3446002, -0.2814, 23.412498, -10.033899, -1.1209999, 26.7572, -6.6893, -0.2814, 23.412498, -6.6893, -1.1209999, 26.7572, -10.033899, -1.1209999, 26.7572, -10.033899, -0.2814, 23.412498, -6.6893, -0.2814, 23.412498, -10.033899, -1.1209999, 26.7572, -12.357901, -0.2814, 23.412498, -10.033899, -0.2814, 23.412498, -10.033899, -1.1209999, 26.7572, -13.378601, -0.2814, 23.412498, -12.357901, -0.2814, 23.412498, -13.378601, -0.2814, 23.412498, -10.033899, -1.1209999, 26.7572, -13.378601, -1.1209999, 26.7572, 16.7232, -1.0746, 13.378601, 15.0508995, -0.6288, 13.378601, 16.7232, 0, 10.033899, -29.294899, -0.6617, 3.3446, -25.479, -0.4588, 0.143, -25.869999, -0.2764, 3.3446, -29.294899, -0.6617, 3.3446, -27.9812, -0.6617, 0, -25.479, -0.4588, 0.143, -29.294899, -0.6617, 6.6893, -25.869999, -0.2764, 3.3446, -25.945799, -0.25779998, 6.6893, -29.294899, -0.6617, 6.6893, -29.294899, -0.6617, 3.3446, -25.869999, -0.2764, 3.3446, -20.0679, -0.5589, 23.412498, -20.0679, -0.36479998, 20.0679, -16.7232, -0.36479998, 23.412498, -20.0679, -1.1374999, 26.7572, -20.0679, -0.5589, 23.412498, -16.7232, -1.1374999, 26.7572, -16.7232, -1.1374999, 26.7572, -16.7232, -0.36479998, 23.412498, -13.378601, -1.1209999, 26.7572, -26.7572, -1.0756, 23.412498, -25.174, -0.7391, 20.0679, -23.412498, -0.7373, 23.412498, -26.7572, -1.0756, 23.412498, -26.7572, -1.0756, 20.0679, -25.174, -0.7391, 20.0679, -26.7572, -1.2701, 26.7572, -23.412498, -0.7373, 23.412498, -23.412498, -1.1374999, 26.7572, -26.7572, -1.2701, 26.7572, -26.7572, -1.0756, 23.412498, -23.412498, -0.7373, 23.412498, -23.412498, -1.1374999, 26.7572, -23.412498, -0.7373, 23.412498, -20.0679, -1.1374999, 26.7572, -29.294899, -1.0265, 16.7232, -25.9681, -0.2875, 13.378601, -25.4212, -0.5907, 16.7232, -29.294899, -1.0265, 16.7232, -29.294899, -0.6617, 13.378601, -25.9681, -0.2875, 13.378601, -25.9681, -0.2875, 13.378601, -23.412498, -0.36479998, 16.7232, -25.4212, -0.5907, 16.7232, -23.412498, -0.36479998, 16.7232, -25.9681, -0.2875, 13.378601, -23.412498, 0, 13.378601, -26.7572, -1.0756, 20.0679, -25.4212, -0.5907, 16.7232, -25.174, -0.7391, 20.0679, -26.7572, -1.0756, 20.0679, -29.294899, -1.0265, 16.7232, -25.4212, -0.5907, 16.7232, -23.412498, -0.692, 20.0679, -23.412498, -0.36479998, 16.7232, -20.0679, -0.36479998, 20.0679, -13.378601, 0, 16.7232, -10.033899, 0, 13.378601, -10.033899, 0, 16.7232, -13.378601, 0, 16.7232, -13.378601, 0, 13.378601, -10.033899, 0, 13.378601, -13.378601, 0, 20.0679, -13.378601, 0, 16.7232, -10.033899, 0, 16.7232, -13.378601, 0, 20.0679, -10.033899, 0, 16.7232, -10.033899, 0, 20.0679, -10.033899, 0, 16.7232, -6.6893, 0, 20.0679, -10.033899, 0, 20.0679, -10.033899, 0, 13.378601, -7.2641997, 0, 16.7232, -10.033899, 0, 16.7232, -6.6893, 0, 20.0679, -10.033899, 0, 16.7232, -7.2641997, 0, 16.7232, -6.6893, 0, 13.8773, -10.033899, 0, 13.378601, -7.1966996, 0, 13.378601, -7.2641997, 0, 16.7232, -10.033899, 0, 13.378601, -6.6893, 0, 13.8773, -7.2641997, 0, 16.7232, -6.6893, 0, 13.8773, -6.6893, 0, 16.1455, -6.1093993, 0, 16.7232, -7.2641997, 0, 16.7232, -6.6893, 0, 16.1455, -6.6893, 0, 20.0679, -7.2641997, 0, 16.7232, -6.6893, 0, 17.298199, -6.1093993, 0, 16.7232, -6.6893, 0, 17.298199, -7.2641997, 0, 16.7232, -6.6893, 0, 17.298199, -3.3446002, 0, 20.0679, -6.6893, 0, 20.0679, -3.3446002, 0, 20.0679, -6.6893, 0, 17.298199, -6.1093993, 0, 16.7232, -3.3446002, 0, 20.0679, -6.1093993, 0, 16.7232, -3.3446002, 0, 16.7232, -3.3446002, 0, 20.0679, -3.3446002, 0, 16.7232, 0, 0, 16.7232, -3.3446002, 0, 20.0679, 0, 0, 16.7232, 0, 0, 20.0679, 0, 0, 16.7232, 2.4261, 0, 20.0679, 0, 0, 20.0679, 2.4261, 0, 20.0679, 0, 0, 16.7232, 3.3446, 0, 17.592, 3.3446, 0, 17.592, 0, 0, 16.7232, 2.4738998, 0, 16.7232, 2.4261, 0, 20.0679, 3.3446, 0, 17.592, 3.3446, 0, 19.1425, 4.275, 0, 20.0679, 2.4261, 0, 20.0679, 3.3446, 0, 19.1425, 4.275, 0, 20.0679, 3.3446, 0, 20.986399, 2.4261, 0, 20.0679, -26.7572, -1.6710999, -17.1511, -23.412498, -2.7663999, -20.0679, -23.412498, -0.7606, -16.7232, -26.7572, -1.6710999, -17.1511, -26.7572, -1.6710999, -20.4958, -23.412498, -2.7663999, -20.0679, -29.294899, -0.6617, -13.378599, -23.412498, -0.7606, -16.7232, -23.412498, 0, -13.378599, -29.294899, -0.6617, -13.378599, -26.7572, -1.6710999, -17.1511, -23.412498, -0.7606, -16.7232, -23.412498, 0, -13.378599, -23.412498, -0.7606, -16.7232, -20.0679, -0.43429998, -16.7232, -26.7572, -1.6710999, -20.4958, -23.412498, -2.7663999, -23.412498, -23.412498, -2.7663999, -20.0679, -26.7572, -1.6710999, -20.4958, -26.7572, -2.7663999, -23.412498, -23.412498, -2.7663999, -23.412498, -23.412498, -2.7663999, -20.0679, -20.0679, -2.7663999, -23.412498, -20.0679, -1.7572, -20.0679, -23.412498, -2.7663999, -20.0679, -23.412498, -2.7663999, -23.412498, -20.0679, -2.7663999, -23.412498, -29.294899, -0.6617, -10.033899, -23.412498, 0, -13.378599, -23.412498, 0, -10.033899, -29.294899, -0.6617, -10.033899, -29.294899, -0.6617, -13.378599, -23.412498, 0, -13.378599, -29.294899, -0.6617, -6.6893, -29.294899, -0.6617, -10.033899, -23.412498, 0, -10.033899, -29.294899, -0.6617, -6.6893, -23.412498, 0, -10.033899, -23.412498, 0, -6.6893, 0, 0, -13.378599, 0, -0.9271, -16.7232, 3.0140998, 0, -16.7232, 0, -0.9271, -23.412498, 3.3446, -0.98829997, -26.7572, 3.3446, -0.3434, -23.412498, 0, -0.9271, -23.412498, 0, -1.0608, -26.7572, 3.3446, -0.98829997, -26.7572, 21.2349, 0, -6.6893, 23.412498, 0, -10.033899, 23.412498, 0, -6.6893, 21.2349, 0, -6.6893, 21.8888, 0, -10.033899, 23.412498, 0, -10.033899, 21.8888, 0, -10.033899, 21.5122, 0, -13.6136, 23.412498, 0, -10.033899, 21.8888, 0, -10.033899, 21.251299, 0, -13.3043995, 21.5122, 0, -13.6136, 21.5122, 0, -13.6136, 23.412498, 0, -13.378599, 23.412498, 0, -10.033899, 20.809599, 0, -13.7309, 21.5122, 0, -13.6136, 21.251299, 0, -13.3043995, 21.0698, 0, -13.966099, 23.412498, 0, -13.378599, 21.5122, 0, -13.6136, 20.809599, 0, -13.7309, 21.0698, 0, -13.966099, 21.5122, 0, -13.6136, 21.0698, 0, -13.966099, 20.0679, 0, -16.7232, 23.412498, 0, -13.378599, 20.809599, 0, -13.7309, 18.053999, 0, -16.7802, 21.0698, 0, -13.966099, 18.053999, 0, -16.7802, 20.0679, 0, -16.7232, 21.0698, 0, -13.966099, 20.809599, 0, -13.7309, 17.503, 0, -15.940498, 18.053999, 0, -16.7802, 17.503, 0, -15.940498, 20.809599, 0, -13.7309, 18.0241, 0, -14.301899, 16.3113, 0, -16.9629, 18.053999, 0, -16.7802, 17.503, 0, -15.940498, 17.1022, 0, -17.6197, 20.0679, 0, -16.7232, 18.053999, 0, -16.7802, 16.3113, 0, -16.9629, 17.1022, 0, -17.6197, 18.053999, 0, -16.7802, 17.1022, 0, -17.6197, 16.7232, 0, -20.0679, 20.0679, 0, -16.7232, 16.3113, 0, -16.9629, 13.748098, 0, -20.540499, 17.1022, 0, -17.6197, 13.748098, 0, -20.540499, 16.7232, 0, -20.0679, 17.1022, 0, -17.6197, 16.3113, 0, -16.9629, 13.423399, 0, -20.1574, 13.748098, 0, -20.540499, 13.423399, 0, -20.1574, 16.3113, 0, -16.9629, 13.701399, 0, -17.416399, 12.961399, 0, -20.5828, 13.748098, 0, -20.540499, 13.423399, 0, -20.1574, 13.378599, 0, -20.9734, 16.7232, 0, -20.0679, 13.748098, 0, -20.540499, 12.961399, 0, -20.5828, 13.378599, 0, -20.9734, 13.748098, 0, -20.540499, 13.378599, 0, -20.9734, 13.378599, 0, -23.412498, 16.7232, 0, -20.0679, 10.033899, 0, -20.467, 13.378599, 0, -20.9734, 12.961399, 0, -20.5828, 10.033899, 0, -23.412498, 13.378599, 0, -23.412498, 13.378599, 0, -20.9734, 10.033899, 0, -20.467, 10.033899, 0, -23.412498, 13.378599, 0, -20.9734, 6.6893, 0, -20.1318, 10.033899, 0, -23.412498, 10.033899, 0, -20.467, 6.6893, 0, -20.1318, 6.6893, 0, -23.412498, 10.033899, 0, -23.412498, 6.6893, 0, -23.412498, 6.6893, 0, -20.1318, 4.4523, 0, -20.444399, 6.6893, 0, -23.412498, 4.4523, 0, -20.444399, 3.3446, 0, -21.6384, 3.2372, 0, -19.3395, 3.3446, 0, -21.6384, 4.4523, 0, -20.444399, 3.2372, 0, -19.3395, 2.3184, 0, -20.4362, 3.3446, 0, -21.6384, 6.6893, 0, -23.412498, 10.033899, -0.8648, -26.7572, 10.033899, 0, -23.412498, 6.6893, 0, -23.412498, 6.6893, -1.0129, -26.7572, 10.033899, -0.8648, -26.7572, -20.0679, -2.7663999, -23.412498, -16.7232, -3.0929, -26.7572, -16.7232, -1.7572, -23.412498, -20.0679, -2.7663999, -23.412498, -20.0679, -3.0929, -26.7572, -16.7232, -3.0929, -26.7572, -20.0679, -1.7572, -20.0679, -16.7232, -1.7572, -23.412498, -17.2383, -0.66719997, -19.6364, -20.0679, -1.7572, -20.0679, -20.0679, -2.7663999, -23.412498, -16.7232, -1.7572, -23.412498, -17.2383, -0.66719997, -19.6364, -13.378601, -1.3177999, -23.412498, -13.210501, -0.3964, -20.032099, -17.2383, -0.66719997, -19.6364, -16.7232, -1.7572, -23.412498, -13.378601, -1.3177999, -23.412498, -20.0679, -0.36479998, 20.0679, -20.0679, -0.36479998, 16.7232, -16.7232, -0.36479998, 20.0679, -23.412498, -0.36479998, 16.7232, -20.0679, -0.36479998, 16.7232, -20.0679, -0.36479998, 20.0679, -20.0679, -0.36479998, 20.0679, -16.7232, -0.36479998, 20.0679, -16.7232, -0.36479998, 23.412498, -16.7232, -0.36479998, 20.0679, -16.7232, -0.26209998, 16.7232, -13.378601, 0, 20.0679, 20.0679, -1.8294, 20.0679, 23.412498, -1.8294, 16.7232, 23.412498, -1.8294, 20.0679, 23.412498, -1.8294, 16.7232, 26.7582, -1.8294, 20.0679, 23.412498, -1.8294, 20.0679, 23.412498, -1.8294, 16.7232, 26.7582, -1.8294, 16.7232, 26.7582, -1.8294, 20.0679, 20.0679, -1.8294, 20.0679, 20.0679, -1.8294, 16.7232, 23.412498, -1.8294, 16.7232, 20.0679, -1.8294, 16.7232, 20.0679, -1.8294, 20.0679, 16.7232, -1.8294, 20.0679, 23.412498, -1.8294, 13.378601, 23.412498, -1.8294, 16.7232, 20.0679, -1.8294, 16.7232, 23.412498, -1.8294, 13.378601, 26.7582, -1.8294, 16.7232, 23.412498, -1.8294, 16.7232, 23.412498, -1.8294, 13.378601, 26.7582, -1.8294, 13.378601, 26.7582, -1.8294, 16.7232, -6.6893, -1.3241999, -23.412498, -3.3446002, -1.458, -26.7572, -3.3446002, -1.4008, -23.412498, -6.6893, -1.3241999, -23.412498, -6.6893, -1.458, -26.7572, -3.3446002, -1.458, -26.7572, -6.6893, -0.9271, -20.0679, -3.3446002, -1.4008, -23.412498, -3.3446002, -0.9271, -20.0679, -6.6893, -0.9271, -20.0679, -6.6893, -1.3241999, -23.412498, -3.3446002, -1.4008, -23.412498, -3.3446002, -0.9271, -20.0679, 0, -0.9271, -23.412498, 0, -0.9271, -20.0679, -3.3446002, -0.9271, -20.0679, -3.3446002, -1.4008, -23.412498, 0, -0.9271, -23.412498, 20.0679, -0.8222, -23.412498, 23.412498, -1.1158999, -26.7572, 23.412498, -1.0924, -23.412498, 20.0679, -0.8222, -23.412498, 20.0679, -1.1922, -26.7572, 23.412498, -1.1158999, -26.7572, 20.0679, -0.2837, -20.0679, 20.0679, -0.8222, -23.412498, 23.412498, -1.0924, -20.0679, 26.7573, -1.3222, -26.7572, 29.564798, -1.6410999, -23.412498, 26.7582, -1.0924, -23.412498, 26.7573, -1.3222, -26.7572, 29.3928, -1.796, -26.7572, 29.564798, -1.6410999, -23.412498, 13.378599, -1.0746, 20.0679, 16.7232, -1.8294, 20.0679, 13.378599, -2.2719998, 23.3902, 13.378599, -1.0746, 20.0679, 15.0508995, -1.0746, 20.0679, 16.7232, -1.8294, 20.0679, 0, -0.9271, -20.0679, 3.3446, 0, -21.6384, 2.3184, 0, -20.4362, 0, -0.9271, -20.0679, 3.3446, -0.3434, -23.412498, 3.3446, 0, -21.6384, 0, -0.9271, -16.7232, 3.2372, 0, -19.3395, 3.0140998, 0, -16.7232, 0, -0.9271, -16.7232, 2.3184, 0, -20.4362, 3.2372, 0, -19.3395, 3.3446, 0, -21.6384, 3.3446, -0.3434, -23.412498, 6.6893, 0, -23.412498, -16.7232, 0, -16.113699, -16.7232, 0, -17.2664, -16.1493, 0, -16.8284, -16.7232, 0, -16.113699, -17.2664, 0, -16.7232, -16.7232, 0, -17.2664, -20.0679, -0.43429998, -16.7232, -16.7232, 0, -17.2664, -17.2664, 0, -16.7232, -20.0679, -0.43429998, -16.7232, -17.2383, -0.66719997, -19.6364, -16.7232, 0, -17.2664, -20.0679, -0.43429998, -16.7232, -16.7232, 0, -13.378599, -20.0679, 0, -13.378599, -16.7232, 0, -13.378599, -20.0679, -0.43429998, -16.7232, -17.2664, 0, -16.7232, -16.7232, 0, -13.378599, -17.2664, 0, -16.7232, -16.7232, 0, -16.113699, -17.2383, -0.66719997, -19.6364, -16.1493, 0, -16.8284, -16.7232, 0, -17.2664, -16.1493, 0, -16.8284, -17.2383, -0.66719997, -19.6364, -13.210501, -0.3964, -20.032099, -16.1493, 0, -16.8284, -13.210501, -0.3964, -20.032099, -13.378601, 0, -17.3364, -10.3452, 0, -16.7803, -9.7488, 0, -16.7232, -9.983101, 0, -16.4067, -10.3452, 0, -16.7803, -10.033899, 0, -17.008299, -9.7488, 0, -16.7232, -6.6893, 0, -14.263699, -9.983101, 0, -16.4067, -9.7488, 0, -16.7232, -9.983101, 0, -16.4067, -6.6893, 0, -14.263699, -9.6168995, 0, -14.127899, -6.6893, 0, -14.263699, -9.7488, 0, -16.7232, -6.6893, 0, -16.7232, -6.6893, 0, -14.263699, -6.6893, 0, -16.7232, -3.3446002, 0, -13.7127, -6.6893, 0, -14.263699, -3.3446002, 0, -13.7127, -3.6946998, 0, -13.471199, -3.6946998, 0, -13.471199, -3.3446002, 0, -13.7127, -3.0105996, 0, -13.378599, 0, 0, -13.378599, -3.0105996, 0, -13.378599, -3.3446002, 0, -13.7127, -3.6946998, 0, -13.471199, -3.0105996, 0, -13.378599, -3.2535, 0, -13.020899, 0, 0, -13.378599, -3.2535, 0, -13.020899, -3.0105996, 0, -13.378599, -2.2352996, 0, -10.6031, -3.2535, 0, -13.020899, 0, 0, -13.378599, -3.2535, 0, -13.020899, -2.2352996, 0, -10.6031, -2.7220998, 0, -10.936998, -2.2352996, 0, -10.6031, 0, 0, -13.378599, 0, 0, -10.7654, -13.210501, -0.3964, -20.032099, -10.3452, 0, -16.7803, -13.378601, 0, -17.3364, -10.3452, 0, -16.7803, -13.210501, -0.3964, -20.032099, -9.318001, -0.3969, -19.413, -10.3452, 0, -16.7803, -9.318001, -0.3969, -19.413, -10.033899, 0, -17.008299, -10.033899, 0, -17.008299, -6.6893, 0, -16.7232, -9.7488, 0, -16.7232, -10.033899, 0, -17.008299, -9.318001, -0.3969, -19.413, -6.6893, 0, -16.7232, -3.3446002, 0, -13.7127, 0, -0.9271, -16.7232, 0, 0, -13.378599, -3.3446002, 0, -13.7127, -3.3446002, -0.9271, -16.7232, 0, -0.9271, -16.7232, 0, 0, -13.378599, 2.2182999, 0, -10.525, 0, 0, -10.7654, 2.2182999, 0, -10.525, 0, 0, -13.378599, 3.3446, -0.3989, -12.9443, 2.2182999, 0, -10.525, 3.3446, -0.3989, -12.9443, 2.9573, -0.1021, -11.0952, -20.108599, 0, -9.592199, -20.0679, 0, -10.476398, -19.6286, 0, -10.1098995, -20.108599, 0, -9.592199, -20.5103, 0, -10.033899, -20.0679, 0, -10.476398, -20.3764, 0, -6.6893, -20.5103, 0, -10.033899, -20.108599, 0, -9.592199, -20.0679, 0, -13.378599, -19.6286, 0, -10.1098995, -20.0679, 0, -10.476398, -20.5103, 0, -10.033899, -20.0679, 0, -13.378599, -20.0679, 0, -10.476398, -19.6286, 0, -10.1098995, -20.0679, 0, -13.378599, -17.1586, 0, -11.120298, -19.6286, 0, -10.1098995, -17.1586, 0, -11.120298, -17.8929, 0, -10.41, -17.1586, 0, -11.120298, -20.0679, 0, -13.378599, -16.7232, 0, -13.378599, -20.5103, 0, -10.033899, -23.412498, 0, -13.378599, -20.0679, 0, -13.378599, -23.412498, 0, -13.378599, -20.5103, 0, -10.033899, -23.412498, 0, -10.033899, -20.3764, 0, -6.6893, -23.412498, 0, -10.033899, -20.5103, 0, -10.033899, -23.412498, 0, -10.033899, -20.3764, 0, -6.6893, -23.412498, 0, -6.6893, -23.412498, -0.0385, -2.8684, -23.412498, 0, -3.7743, -22.9552, -0.047599997, -3.375, -23.412498, -0.0385, -2.8684, -23.8421, 0, -3.3446002, -23.412498, 0, -3.7743, -23.412498, 0, -6.6893, -22.9552, -0.047599997, -3.375, -23.412498, 0, -3.7743, -22.9552, -0.047599997, -3.375, -23.412498, 0, -6.6893, -20.1607, -0.2436, -4.5060997, -20.1607, -0.2436, -4.5060997, -23.412498, 0, -6.6893, -20.3764, 0, -6.6893, -22.9552, -0.047599997, -3.375, -20.1607, -0.2436, -4.5060997, -21.0086, -0.2504, -3.5043998, -29.294899, -0.6617, -6.6893, -23.8421, 0, -3.3446002, -27.9812, -0.6617, -3.3446002, -23.8421, 0, -3.3446002, -29.294899, -0.6617, -6.6893, -23.412498, 0, -6.6893, -23.8421, 0, -3.3446002, -23.412498, 0, -6.6893, -23.412498, 0, -3.7743, -27.9812, -0.6617, -3.3446002, -25.479, -0.4588, 0.143, -27.9812, -0.6617, 0, -25.479, -0.4588, 0.143, -27.9812, -0.6617, -3.3446002, -23.412498, -0.0385, -2.8684, -23.412498, -0.0385, -2.8684, -27.9812, -0.6617, -3.3446002, -23.8421, 0, -3.3446002, -25.479, -0.4588, 0.143, -23.412498, -0.0385, -2.8684, -23.412498, -0.2913, 0.26119995, -22.756899, 0, 10.033899, -24.056599, 0, 10.033899, -23.489, 0, 9.386499, -22.756899, 0, 10.033899, -23.412498, 0, 10.6779995, -24.056599, 0, 10.033899, -20.0679, 0, 13.378601, -23.412498, 0, 10.6779995, -22.756899, 0, 10.033899, -23.412498, 0, 10.6779995, -20.0679, 0, 13.378601, -23.412498, 0, 13.378601, -20.0679, 0, 13.378601, -22.756899, 0, 10.033899, -20.0679, 0, 10.033899, -20.0679, 0, 10.033899, -17.213, 0, 13.378601, -20.0679, 0, 13.378601, -17.213, 0, 13.378601, -20.0679, 0, 10.033899, -16.7232, 0, 10.8878, -16.7232, 0, 10.8878, -20.0679, 0, 10.033899, -17.583, 0, 10.033899, -17.213, 0, 13.378601, -16.7232, 0, 10.8878, -16.7232, 0, 12.878401, -16.223, 0, 13.378601, -17.213, 0, 13.378601, -16.7232, 0, 12.878401, -16.223, 0, 13.378601, -16.7232, 0, 13.868401, -17.213, 0, 13.378601, -29.294899, -0.6617, 10.033899, -25.945799, -0.25779998, 6.6893, -26.0077, -0.2465, 10.033899, -29.294899, -0.6617, 10.033899, -29.294899, -0.6617, 6.6893, -25.945799, -0.25779998, 6.6893, -29.294899, -0.6617, 13.378601, -26.0077, -0.2465, 10.033899, -25.9681, -0.2875, 13.378601, -29.294899, -0.6617, 13.378601, -29.294899, -0.6617, 10.033899, -26.0077, -0.2465, 10.033899, -20.0679, -0.36479998, 16.7232, -20.0679, 0, 13.378601, -16.7232, -0.26209998, 16.7232, -16.7232, 0, 13.868401, -13.378601, 0, 16.7232, -16.7232, -0.26209998, 16.7232, -13.378601, 0, 16.7232, -16.7232, 0, 13.868401, -16.223, 0, 13.378601, -13.378601, 0, 16.7232, -16.223, 0, 13.378601, -13.378601, 0, 13.378601, 0, 0, 20.0679, 3.3446, -0.2814, 23.412498, 0, -0.2814, 23.412498, 3.3446, -0.2814, 23.412498, 0, 0, 20.0679, 2.4261, 0, 20.0679, 3.3446, -0.2814, 23.412498, 2.4261, 0, 20.0679, 3.3446, 0, 20.986399, 3.3446, 0, 20.986399, 6.6893, -0.2814, 23.412498, 3.3446, -0.2814, 23.412498, 6.6893, -0.2814, 23.412498, 3.3446, 0, 20.986399, 4.275, 0, 20.0679, 6.6893, -0.2814, 23.412498, 4.275, 0, 20.0679, 6.6893, 0, 20.0679, 10.572599, 0, 19.5895, 10.501598, 0, 20.5087, 10.080299, 0, 20.0679, 10.572599, 0, 19.5895, 11.0191, 0, 20.0679, 10.501598, 0, 20.5087, 10.572599, 0, 19.5895, 13.378599, 0, 16.7232, 11.0191, 0, 20.0679, 10.572599, 0, 19.5895, 10.572599, 0, 16.7232, 13.378599, 0, 16.7232, 10.572599, 0, 14.3402, 13.378599, 0, 16.7232, 10.572599, 0, 16.7232, 13.378599, 0, 16.7232, 10.572599, 0, 14.3402, 13.105099, 0, 13.9188, 13.105099, 0, 13.9188, 10.572599, 0, 14.3402, 10.986898, 0, 13.9188, 13.378599, 0, 16.7232, 13.105099, 0, 13.9188, 13.700699, 0, 14.602699, 13.8046, 0, 13.2202, 13.700699, 0, 14.602699, 13.105099, 0, 13.9188, 13.8046, 0, 13.2202, 14.439199, 0, 13.6437, 13.700699, 0, 14.602699, 6.6893, -0.2814, 23.412498, 10.501598, 0, 20.5087, 10.033899, -0.501, 23.412498, 10.033899, -0.501, 23.412498, 11.0191, 0, 20.0679, 13.378599, -1.0746, 20.0679, 10.033899, -0.501, 23.412498, 10.501598, 0, 20.5087, 11.0191, 0, 20.0679, 17.4912, 0.0034999999, 7.4080997, 13.8046, 0, 10.033899, 14.0257, 0.0442, 7.3252997, 13.8046, 0, 10.033899, 17.4912, 0.0034999999, 7.4080997, 16.7232, 0, 10.033899, 13.8046, 0, 10.033899, 16.7232, 0, 10.033899, 15.0508995, 0, 10.033899, 16.7232, -1.0746, 13.378601, 15.0508995, -0.40039998, 16.7232, 15.0508995, -0.6288, 13.378601, -16.7232, -1.1374999, 26.7572, -20.0679, -1.9081, 30.3625, -20.0679, -1.1374999, 26.7572, -16.7232, -1.1374999, 26.7572, -16.7232, -1.9068999, 30.3568, -20.0679, -1.9081, 30.3625, -23.412498, -1.9093, 30.3681, -20.0679, -1.1374999, 26.7572, -20.0679, -1.9081, 30.3625, -23.412498, -1.9093, 30.3681, -23.412498, -1.1374999, 26.7572, -20.0679, -1.1374999, 26.7572, -23.412498, -2.6287, 33.7341, -23.412498, -1.9093, 30.3681, -20.0679, -1.9081, 30.3625, -16.7232, -1.9068999, 30.3568, -20.0679, -2.628, 33.7306, -20.0679, -1.9081, 30.3625, -23.412498, -2.6287, 33.7341, -20.0679, -1.9081, 30.3625, -20.0679, -2.628, 33.7306, -16.7232, -1.9068999, 30.3568, -16.7232, -2.6272, 33.726997, -20.0679, -2.628, 33.7306, -23.412498, -3.2477999, 36.6305, -23.412498, -2.6287, 33.7341, -20.0679, -2.628, 33.7306, -16.7232, -2.6272, 33.726997, -20.0679, -3.2473998, 36.6287, -20.0679, -2.628, 33.7306, -23.412498, -3.2477999, 36.6305, -20.0679, -2.628, 33.7306, -20.0679, -3.2473998, 36.6287, -16.7232, -2.6272, 33.726997, -16.7232, -3.247, 36.6269, -20.0679, -3.2473998, 36.6287, -20.0679, -3.8518999, 39.456898, -23.412498, -3.2477999, 36.6305, -20.0679, -3.2473998, 36.6287, -16.7232, -3.247, 36.6269, -20.0679, -3.8518999, 39.456898, -20.0679, -3.2473998, 36.6287, -20.0679, -3.8518999, 39.456898, -23.412498, -3.8518999, 39.456898, -23.412498, -3.2477999, 36.6305, -16.7232, -3.247, 36.6269, -16.7232, -3.8518999, 39.456898, -20.0679, -3.8518999, 39.456898, -27.9812, -0.6617, 0, -30.315699, -0.9931, 3.3446, -30.300001, -1.3205999, 0, -27.9812, -0.6617, 0, -29.294899, -0.6617, 3.3446, -30.315699, -0.9931, 3.3446, -50.290497, -8.1437, 10.033899, -53.117798, -8.6939, 6.6893, -50.290497, -8.1437, 6.6893, -50.290497, -8.1437, 10.033899, -50.290497, -8.1437, 13.378601, -53.117798, -8.6939, 6.6893, -53.117798, -8.6939, 3.3446, -50.290497, -8.1437, 6.6893, -53.117798, -8.6939, 6.6893, -53.117798, -8.6939, 3.3446, -50.290497, -8.1437, 3.3446, -50.290497, -8.1437, 6.6893, -53.117798, -8.6939, 6.6893, -50.290497, -8.1437, 13.378601, -53.117798, -8.6939, 13.378601, -53.117798, -8.6939, 0, -50.290497, -8.1437, 3.3446, -53.117798, -8.6939, 3.3446, -53.117798, -8.6939, 0, -50.290497, -8.1437, 0, -50.290497, -8.1437, 3.3446, -55.5951, -9.176, 3.3446, -53.117798, -8.6939, 3.3446, -53.117798, -8.6939, 6.6893, -53.117798, -8.6939, -3.3446002, -50.290497, -8.1437, 0, -53.117798, -8.6939, 0, -53.117798, -8.6939, -3.3446002, -50.290497, -8.1437, -3.3446002, -50.290497, -8.1437, 0, -55.5951, -9.176, 0, -53.117798, -8.6939, 0, -53.117798, -8.6939, 3.3446, -55.5951, -9.176, 0, -53.117798, -8.6939, 3.3446, -55.5951, -9.176, 3.3446, -55.5951, -9.176, -3.3446002, -53.117798, -8.6939, -3.3446002, -53.117798, -8.6939, 0, -55.5951, -9.176, -3.3446002, -53.117798, -8.6939, 0, -55.5951, -9.176, 0, -53.117798, -8.6939, -6.6893, -50.290497, -8.1437, -3.3446002, -53.117798, -8.6939, -3.3446002, -53.117798, -8.6939, -6.6893, -50.290497, -8.1437, -6.6893, -50.290497, -8.1437, -3.3446002, -55.5951, -9.176, -6.6893, -53.117798, -8.6939, -3.3446002, -55.5951, -9.176, -3.3446002, -55.5951, -9.176, -6.6893, -53.117798, -8.6939, -6.6893, -53.117798, -8.6939, -3.3446002, -53.117798, -8.6939, -10.033899, -50.290497, -8.1437, -6.6893, -53.117798, -8.6939, -6.6893, -53.117798, -8.6939, -10.033899, -50.290497, -8.1437, -10.033899, -50.290497, -8.1437, -6.6893, -55.5951, -9.176, -10.033899, -53.117798, -8.6939, -6.6893, -55.5951, -9.176, -6.6893, -55.5951, -9.176, -10.033899, -53.117798, -8.6939, -10.033899, -53.117798, -8.6939, -6.6893, -53.117798, -8.6939, -13.378599, -50.290497, -8.1437, -10.033899, -53.117798, -8.6939, -10.033899, -53.117798, -8.6939, -13.378599, -50.290497, -8.1437, -13.378599, -50.290497, -8.1437, -10.033899, -53.117798, -8.6939, -13.378599, -50.290497, -8.1437, -16.7232, -50.290497, -8.1437, -13.378599, -53.117798, -8.6939, -13.378599, -50.290497, -8.1437, -16.937199, -50.290497, -8.1437, -16.7232, -50.290497, -8.1437, -16.937199, -53.117798, -8.6939, -13.378599, -53.117798, -8.6939, -16.911499, -53.117798, -8.6939, -16.911499, -50.290497, -8.1437, -20.0679, -50.290497, -8.1437, -16.937199, -55.5951, -9.176, -13.378599, -53.117798, -8.6939, -13.378599, -53.117798, -8.6939, -10.033899, -55.5951, -9.176, -13.378599, -53.117798, -8.6939, -10.033899, -55.5951, -9.176, -10.033899, -53.117798, -8.6939, -16.911499, -50.290497, -8.1437, -20.2818, -50.290497, -8.1437, -20.0679, -55.5951, -9.176, -16.888899, -53.117798, -8.6939, -13.378599, -55.5951, -9.176, -13.378599, -55.5951, -9.176, -16.888899, -53.117798, -8.6939, -16.911499, -53.117798, -8.6939, -13.378599, -58.463497, -9.7343, -13.378599, -55.5951, -9.176, -13.378599, -55.5951, -9.176, -10.033899, -58.463497, -9.7343, -16.8629, -55.5951, -9.176, -16.888899, -55.5951, -9.176, -13.378599, -58.463497, -9.7343, -16.8629, -55.5951, -9.176, -13.378599, -58.463497, -9.7343, -13.378599, -55.5951, -9.176, -20.233599, -53.117798, -8.6939, -16.911499, -55.5951, -9.176, -16.888899, -50.290497, -8.1437, -20.2818, -53.117798, -8.6939, -16.911499, -53.117798, -8.6939, -20.2561, -55.5951, -9.176, -20.233599, -53.117798, -8.6939, -20.2561, -53.117798, -8.6939, -16.911499, -53.117798, -8.6939, -23.412498, -50.290497, -8.1437, -20.2818, -53.117798, -8.6939, -20.2561, -53.117798, -8.6939, -23.412498, -50.290497, -8.1437, -23.412498, -50.290497, -8.1437, -20.2818, -53.117798, -8.6939, -26.7572, -50.290497, -8.1437, -23.412498, -53.117798, -8.6939, -23.412498, -53.117798, -8.6939, -26.7572, -50.290497, -8.1437, -26.7572, -50.290497, -8.1437, -23.412498, -55.5951, -9.176, -26.7572, -53.117798, -8.6939, -26.7572, -53.117798, -8.6939, -23.412498, -55.5951, -9.176, -23.412498, -53.117798, -8.6939, -23.412498, -53.117798, -8.6939, -20.2561, -55.5951, -9.176, -26.7572, -53.117798, -8.6939, -23.412498, -55.5951, -9.176, -23.412498, -55.5951, -9.176, -23.412498, -53.117798, -8.6939, -20.2561, -55.5951, -9.176, -20.233599, -58.463497, -9.7343, -26.7572, -55.5951, -9.176, -26.7572, -55.5951, -9.176, -23.412498, -58.463497, -9.7343, -23.412498, -55.5951, -9.176, -23.412498, -55.5951, -9.176, -20.233599, -58.463497, -9.7343, -26.7572, -55.5951, -9.176, -23.412498, -58.463497, -9.7343, -23.412498, -62.057194, -10.4337, -23.412498, -58.463497, -9.7343, -26.7572, -58.463497, -9.7343, -23.412498, -62.057194, -10.4337, -23.412498, -62.057194, -10.4337, -26.7572, -58.463497, -9.7343, -26.7572, -62.057194, -10.4337, -20.174799, -62.057194, -10.4337, -23.412498, -58.463497, -9.7343, -23.412498, -58.463497, -9.7343, -23.412498, -55.5951, -9.176, -20.233599, -58.463497, -9.7343, -20.207499, -62.057194, -10.4337, -20.174799, -58.463497, -9.7343, -23.412498, -58.463497, -9.7343, -20.207499, -58.463497, -9.7343, -20.207499, -55.5951, -9.176, -20.233599, -55.5951, -9.176, -16.888899, -58.463497, -9.7343, -20.207499, -55.5951, -9.176, -16.888899, -58.463497, -9.7343, -16.8629, -58.463497, -9.7343, -16.8629, -62.057194, -10.4337, -20.174799, -58.463497, -9.7343, -20.207499, -58.463497, -9.7343, -16.8629, -62.057194, -10.4337, -20.0679, -62.057194, -10.4337, -20.174799, -62.057194, -10.4337, -20.0679, -58.463497, -9.7343, -16.8629, -62.057194, -10.4337, -16.8302, -58.463497, -9.7343, -13.378599, -62.057194, -10.4337, -16.8302, -58.463497, -9.7343, -16.8629, -58.463497, -9.7343, -13.378599, -62.057194, -10.4337, -16.7232, -62.057194, -10.4337, -16.8302, -62.057194, -10.4337, -16.7232, -58.463497, -9.7343, -13.378599, -62.057194, -10.4337, -13.378599, -62.057194, -10.4337, -10.033899, -62.057194, -10.4337, -13.378599, -58.463497, -9.7343, -13.378599, -62.057194, -10.4337, -10.033899, -58.463497, -9.7343, -13.378599, -58.463497, -9.7343, -10.033899, -58.463497, -9.7343, -13.378599, -55.5951, -9.176, -10.033899, -58.463497, -9.7343, -10.033899, -62.057194, -10.4337, -6.6893, -62.057194, -10.4337, -10.033899, -58.463497, -9.7343, -10.033899, -58.463497, -9.7343, -10.033899, -55.5951, -9.176, -10.033899, -55.5951, -9.176, -6.6893, -62.057194, -10.4337, -6.6893, -58.463497, -9.7343, -10.033899, -58.463497, -9.7343, -6.6893, -58.463497, -9.7343, -10.033899, -55.5951, -9.176, -6.6893, -58.463497, -9.7343, -6.6893, -62.057194, -10.4337, -3.3446002, -62.057194, -10.4337, -6.6893, -58.463497, -9.7343, -6.6893, -58.463497, -9.7343, -6.6893, -55.5951, -9.176, -6.6893, -55.5951, -9.176, -3.3446002, -62.057194, -10.4337, -3.3446002, -58.463497, -9.7343, -6.6893, -58.463497, -9.7343, -3.3446002, -58.463497, -9.7343, -6.6893, -55.5951, -9.176, -3.3446002, -58.463497, -9.7343, -3.3446002, -62.057194, -10.4337, 0, -62.057194, -10.4337, -3.3446002, -58.463497, -9.7343, -3.3446002, -58.463497, -9.7343, -3.3446002, -55.5951, -9.176, -3.3446002, -55.5951, -9.176, 0, -62.057194, -10.4337, 0, -58.463497, -9.7343, -3.3446002, -58.463497, -9.7343, 0, -58.463497, -9.7343, -3.3446002, -55.5951, -9.176, 0, -58.463497, -9.7343, 0, -62.057194, -10.4337, 3.3446, -62.057194, -10.4337, 0, -58.463497, -9.7343, 0, -58.463497, -9.7343, 0, -55.5951, -9.176, 0, -55.5951, -9.176, 3.3446, -62.057194, -10.4337, 3.3446, -58.463497, -9.7343, 0, -58.463497, -9.7343, 3.3446, -58.463497, -9.7343, 0, -55.5951, -9.176, 3.3446, -58.463497, -9.7343, 3.3446, -62.057194, -10.4337, 6.6893, -62.057194, -10.4337, 3.3446, -58.463497, -9.7343, 3.3446, -62.057194, -10.4337, 6.6893, -58.463497, -9.7343, 3.3446, -58.463497, -9.7343, 6.6893, -58.463497, -9.7343, 6.6893, -62.057194, -10.4337, 10.033899, -62.057194, -10.4337, 6.6893, -58.463497, -9.7343, 3.3446, -55.5951, -9.176, 3.3446, -55.5951, -9.176, 6.6893, -58.463497, -9.7343, 3.3446, -55.5951, -9.176, 6.6893, -58.463497, -9.7343, 6.6893, -55.5951, -9.176, 3.3446, -53.117798, -8.6939, 6.6893, -55.5951, -9.176, 6.6893, -58.463497, -9.7343, 6.6893, -62.057194, -10.4337, 13.378601, -62.057194, -10.4337, 10.033899, -53.117798, -8.6939, 13.378601, -55.5951, -9.176, 6.6893, -53.117798, -8.6939, 6.6893, -55.5951, -9.176, 13.378601, -58.463497, -9.7343, 6.6893, -55.5951, -9.176, 6.6893, -53.117798, -8.6939, 13.378601, -55.5951, -9.176, 13.378601, -55.5951, -9.176, 6.6893, -55.5951, -9.176, 13.378601, -58.463497, -9.7343, 13.378601, -58.463497, -9.7343, 6.6893, -62.057194, -10.4337, 13.378601, -58.463497, -9.7343, 6.6893, -58.463497, -9.7343, 13.378601, -53.117798, -8.6939, 16.7232, -55.5951, -9.176, 13.378601, -53.117798, -8.6939, 13.378601, -50.290497, -8.1437, 13.378601, -53.117798, -8.6939, 16.7232, -53.117798, -8.6939, 13.378601, -50.290497, -8.1437, 13.378601, -50.290497, -8.1437, 16.7232, -53.117798, -8.6939, 16.7232, -53.117798, -8.6939, 16.7232, -55.5951, -9.176, 16.7232, -55.5951, -9.176, 13.378601, -55.5951, -9.176, 16.7232, -58.463497, -9.7343, 13.378601, -55.5951, -9.176, 13.378601, -50.290497, -8.1437, 16.7232, -53.117798, -8.6939, 20.0679, -53.117798, -8.6939, 16.7232, -53.117798, -8.6939, 20.0679, -55.5951, -9.176, 16.7232, -53.117798, -8.6939, 16.7232, -50.290497, -8.1437, 16.7232, -50.290497, -8.1437, 20.0679, -53.117798, -8.6939, 20.0679, -58.463497, -9.7343, 16.7232, -62.057194, -10.4337, 13.378601, -58.463497, -9.7343, 13.378601, -55.5951, -9.176, 16.7232, -58.463497, -9.7343, 16.7232, -58.463497, -9.7343, 13.378601, -58.463497, -9.7343, 16.7232, -62.057194, -10.4337, 16.7232, -62.057194, -10.4337, 13.378601, -53.117798, -8.6939, 20.0679, -55.5951, -9.176, 20.0679, -55.5951, -9.176, 16.7232, -55.5951, -9.176, 20.0679, -58.463497, -9.7343, 16.7232, -55.5951, -9.176, 16.7232, -50.290497, -8.1437, 20.0679, -53.117798, -8.6939, 23.412498, -53.117798, -8.6939, 20.0679, -53.117798, -8.6939, 23.412498, -55.5951, -9.176, 20.0679, -53.117798, -8.6939, 20.0679, -50.290497, -8.1437, 20.0679, -50.290497, -8.1437, 23.412498, -53.117798, -8.6939, 23.412498, -50.290497, -8.1437, 23.412498, -53.117798, -8.6939, 26.7572, -53.117798, -8.6939, 23.412498, -50.290497, -8.1437, 23.412498, -50.290497, -8.1437, 26.7572, -53.117798, -8.6939, 26.7572, -53.117798, -8.6939, 26.7572, -55.5951, -9.176, 23.412498, -53.117798, -8.6939, 23.412498, -53.117798, -8.6939, 23.412498, -55.5951, -9.176, 23.412498, -55.5951, -9.176, 20.0679, -53.117798, -8.6939, 26.7572, -55.5951, -9.176, 26.7572, -55.5951, -9.176, 23.412498, -55.5951, -9.176, 20.0679, -58.463497, -9.7343, 20.0679, -58.463497, -9.7343, 16.7232, -58.463497, -9.7343, 20.0679, -62.057194, -10.4337, 16.7232, -58.463497, -9.7343, 16.7232, -55.5951, -9.176, 23.412498, -58.463497, -9.7343, 20.0679, -55.5951, -9.176, 20.0679, -58.463497, -9.7343, 20.0679, -62.057194, -10.4337, 20.0679, -62.057194, -10.4337, 16.7232, -55.5951, -9.176, 26.7572, -58.463497, -9.7343, 23.412498, -55.5951, -9.176, 23.412498, -55.5951, -9.176, 23.412498, -58.463497, -9.7343, 23.412498, -58.463497, -9.7343, 20.0679, -58.463497, -9.7343, 23.412498, -62.057194, -10.4337, 20.0679, -58.463497, -9.7343, 20.0679, -55.5951, -9.176, 26.7572, -58.463497, -9.7343, 26.7572, -58.463497, -9.7343, 23.412498, -58.463497, -9.7343, 23.412498, -62.057194, -10.4337, 23.412498, -62.057194, -10.4337, 20.0679, -58.463497, -9.7343, 26.7572, -62.057194, -10.4337, 23.412498, -58.463497, -9.7343, 23.412498, -58.463497, -9.7343, 26.7572, -62.057194, -10.4337, 26.7572, -62.057194, -10.4337, 23.412498, -62.057194, -10.4337, 0, -64.963196, -10.4337, -3.3446002, -62.057194, -10.4337, -3.3446002, -64.963196, -10.4337, -6.6893, -62.057194, -10.4337, -3.3446002, -64.963196, -10.4337, -3.3446002, -64.963196, -10.4337, -6.6893, -62.057194, -10.4337, -6.6893, -62.057194, -10.4337, -3.3446002, -62.057194, -10.4337, 0, -64.963196, -10.4337, 0, -64.963196, -10.4337, -3.3446002, -64.963196, -10.4337, 0, -62.057194, -10.4337, 0, -62.057194, -10.4337, 3.3446, -68.2489, -10.4337, -6.6893, -64.963196, -10.4337, -6.6893, -64.963196, -10.4337, -3.3446002, -64.963196, -10.4337, 0, -68.2489, -10.4337, -3.3446002, -64.963196, -10.4337, -3.3446002, -68.2489, -10.4337, -6.6893, -64.963196, -10.4337, -3.3446002, -68.2489, -10.4337, -3.3446002, -64.963196, -10.4337, -10.033899, -62.057194, -10.4337, -6.6893, -64.963196, -10.4337, -6.6893, -64.963196, -10.4337, -10.033899, -62.057194, -10.4337, -10.033899, -62.057194, -10.4337, -6.6893, -68.2489, -10.4337, -10.033899, -64.963196, -10.4337, -6.6893, -68.2489, -10.4337, -6.6893, -68.2489, -10.4337, -10.033899, -64.963196, -10.4337, -10.033899, -64.963196, -10.4337, -6.6893, -64.963196, -10.4337, -13.378599, -62.057194, -10.4337, -10.033899, -64.963196, -10.4337, -10.033899, -64.963196, -10.4337, -13.378599, -62.057194, -10.4337, -13.378599, -62.057194, -10.4337, -10.033899, -64.963196, -10.4337, -13.378599, -62.057194, -10.4337, -16.7232, -62.057194, -10.4337, -13.378599, -64.963196, -10.4337, -13.378599, -62.057194, -10.4337, -16.8302, -62.057194, -10.4337, -16.7232, -62.057194, -10.4337, -16.8302, -64.963196, -10.4337, -13.378599, -64.963196, -10.4337, -16.803799, -64.963196, -10.4337, -16.803799, -62.057194, -10.4337, -20.0679, -62.057194, -10.4337, -16.8302, -68.2489, -10.4337, -13.378599, -64.963196, -10.4337, -13.378599, -64.963196, -10.4337, -10.033899, -68.2489, -10.4337, -13.378599, -64.963196, -10.4337, -10.033899, -68.2489, -10.4337, -10.033899, -64.963196, -10.4337, -16.803799, -62.057194, -10.4337, -20.174799, -62.057194, -10.4337, -20.0679, -68.2489, -10.4337, -16.7739, -64.963196, -10.4337, -13.378599, -68.2489, -10.4337, -13.378599, -68.2489, -10.4337, -16.7739, -64.963196, -10.4337, -16.803799, -64.963196, -10.4337, -13.378599, -71.2999, -10.4337, -13.378599, -68.2489, -10.4337, -13.378599, -68.2489, -10.4337, -10.033899, -71.2999, -10.4337, -16.746199, -68.2489, -10.4337, -16.7739, -68.2489, -10.4337, -13.378599, -71.2999, -10.4337, -16.746199, -68.2489, -10.4337, -13.378599, -71.2999, -10.4337, -13.378599, -73.8239, -10.4337, -13.378599, -71.2999, -10.4337, -16.746199, -71.2999, -10.4337, -13.378599, -73.8239, -10.4337, -13.378599, -73.8239, -10.4337, -16.7232, -71.2999, -10.4337, -16.746199, -73.8239, -10.4337, -10.033899, -73.8239, -10.4337, -13.378599, -71.2999, -10.4337, -13.378599, -73.8239, -10.4337, -16.7232, -71.2999, -10.4337, -20.0908, -71.2999, -10.4337, -16.746199, -71.2999, -10.4337, -20.0908, -68.2489, -10.4337, -16.7739, -71.2999, -10.4337, -16.746199, -73.8239, -10.4337, -16.7232, -73.8239, -10.4337, -20.0679, -71.2999, -10.4337, -20.0908, -71.2999, -10.4337, -13.378599, -68.2489, -10.4337, -10.033899, -71.2999, -10.4337, -10.033899, -73.8239, -10.4337, -10.033899, -71.2999, -10.4337, -13.378599, -71.2999, -10.4337, -10.033899, -71.2999, -10.4337, -10.033899, -68.2489, -10.4337, -10.033899, -68.2489, -10.4337, -6.6893, -73.8239, -10.4337, -6.6893, -73.8239, -10.4337, -10.033899, -71.2999, -10.4337, -10.033899, -71.2999, -10.4337, -10.033899, -68.2489, -10.4337, -6.6893, -71.2999, -10.4337, -6.6893, -73.8239, -10.4337, -6.6893, -71.2999, -10.4337, -10.033899, -71.2999, -10.4337, -6.6893, -71.2999, -10.4337, -6.6893, -68.2489, -10.4337, -6.6893, -68.2489, -10.4337, -3.3446002, -73.8239, -10.4337, -3.3446002, -73.8239, -10.4337, -6.6893, -71.2999, -10.4337, -6.6893, -71.2999, -10.4337, -6.6893, -68.2489, -10.4337, -3.3446002, -71.2999, -10.4337, -3.3446002, -73.8239, -10.4337, -3.3446002, -71.2999, -10.4337, -6.6893, -71.2999, -10.4337, -3.3446002, -68.2489, -10.4337, 0, -71.2999, -10.4337, -3.3446002, -68.2489, -10.4337, -3.3446002, -71.2999, -10.4337, 0, -73.8239, -10.4337, -3.3446002, -71.2999, -10.4337, -3.3446002, -68.2489, -10.4337, 0, -71.2999, -10.4337, 0, -71.2999, -10.4337, -3.3446002, -71.2999, -10.4337, 0, -73.8239, -10.4337, 0, -73.8239, -10.4337, -3.3446002, -64.963196, -10.4337, 0, -68.2489, -10.4337, 0, -68.2489, -10.4337, -3.3446002, -73.8239, -10.4337, 0, -71.2999, -10.4337, 0, -71.2999, -10.4337, 3.3446, -73.8239, -10.4337, 0, -71.2999, -10.4337, 3.3446, -73.8239, -10.4337, 3.3446, -71.2999, -10.4337, 0, -68.2489, -10.4337, 0, -68.2489, -10.4337, 3.3446, -71.2999, -10.4337, 0, -68.2489, -10.4337, 3.3446, -71.2999, -10.4337, 3.3446, -68.2489, -10.4337, 0, -64.963196, -10.4337, 0, -64.963196, -10.4337, 3.3446, -68.2489, -10.4337, 0, -64.963196, -10.4337, 3.3446, -68.2489, -10.4337, 3.3446, -64.963196, -10.4337, 0, -62.057194, -10.4337, 3.3446, -64.963196, -10.4337, 3.3446, -62.057194, -10.4337, 3.3446, -64.963196, -10.4337, 6.6893, -64.963196, -10.4337, 3.3446, -64.963196, -10.4337, 6.6893, -68.2489, -10.4337, 3.3446, -64.963196, -10.4337, 3.3446, -62.057194, -10.4337, 3.3446, -62.057194, -10.4337, 6.6893, -64.963196, -10.4337, 6.6893, -62.057194, -10.4337, 10.033899, -64.963196, -10.4337, 6.6893, -62.057194, -10.4337, 6.6893, -64.963196, -10.4337, 6.6893, -62.057194, -10.4337, 10.033899, -62.057194, -10.4337, 13.378601, -64.963196, -10.4337, 6.6893, -68.2489, -10.4337, 6.6893, -68.2489, -10.4337, 3.3446, -68.2489, -10.4337, 6.6893, -71.2999, -10.4337, 3.3446, -68.2489, -10.4337, 3.3446, -64.963196, -10.4337, 6.6893, -62.057194, -10.4337, 13.378601, -64.963196, -10.4337, 13.378601, -64.963196, -10.4337, 13.378601, -68.2489, -10.4337, 6.6893, -64.963196, -10.4337, 6.6893, -62.057194, -10.4337, 13.378601, -64.963196, -10.4337, 16.7232, -64.963196, -10.4337, 13.378601, -62.057194, -10.4337, 13.378601, -62.057194, -10.4337, 16.7232, -64.963196, -10.4337, 16.7232, -64.963196, -10.4337, 13.378601, -68.2489, -10.4337, 13.378601, -68.2489, -10.4337, 6.6893, -64.963196, -10.4337, 16.7232, -68.2489, -10.4337, 13.378601, -64.963196, -10.4337, 13.378601, -68.2489, -10.4337, 6.6893, -71.2999, -10.4337, 6.6893, -71.2999, -10.4337, 3.3446, -68.2489, -10.4337, 13.378601, -71.2999, -10.4337, 6.6893, -68.2489, -10.4337, 6.6893, -71.2999, -10.4337, 6.6893, -73.8239, -10.4337, 3.3446, -71.2999, -10.4337, 3.3446, -71.2999, -10.4337, 6.6893, -73.8239, -10.4337, 6.6893, -73.8239, -10.4337, 3.3446, -71.2999, -10.4337, 6.6893, -73.8239, -10.4337, 10.033899, -73.8239, -10.4337, 6.6893, -71.2999, -10.4337, 6.6893, -73.8239, -10.4337, 13.378601, -73.8239, -10.4337, 10.033899, -68.2489, -10.4337, 13.378601, -71.2999, -10.4337, 13.378601, -71.2999, -10.4337, 6.6893, -73.8239, -10.4337, 13.378601, -71.2999, -10.4337, 6.6893, -71.2999, -10.4337, 13.378601, -64.963196, -10.4337, 16.7232, -68.2489, -10.4337, 16.7232, -68.2489, -10.4337, 13.378601, -68.2489, -10.4337, 16.7232, -71.2999, -10.4337, 13.378601, -68.2489, -10.4337, 13.378601, -71.2999, -10.4337, 16.7232, -73.8239, -10.4337, 13.378601, -71.2999, -10.4337, 13.378601, -68.2489, -10.4337, 16.7232, -71.2999, -10.4337, 16.7232, -71.2999, -10.4337, 13.378601, -71.2999, -10.4337, 16.7232, -73.8239, -10.4337, 16.7232, -73.8239, -10.4337, 13.378601, -64.963196, -10.4337, 20.0679, -68.2489, -10.4337, 16.7232, -64.963196, -10.4337, 16.7232, -62.057194, -10.4337, 16.7232, -64.963196, -10.4337, 20.0679, -64.963196, -10.4337, 16.7232, -62.057194, -10.4337, 16.7232, -62.057194, -10.4337, 20.0679, -64.963196, -10.4337, 20.0679, -64.963196, -10.4337, 20.0679, -68.2489, -10.4337, 20.0679, -68.2489, -10.4337, 16.7232, -68.2489, -10.4337, 20.0679, -71.2999, -10.4337, 16.7232, -68.2489, -10.4337, 16.7232, -62.057194, -10.4337, 20.0679, -64.963196, -10.4337, 23.412498, -64.963196, -10.4337, 20.0679, -64.963196, -10.4337, 23.412498, -68.2489, -10.4337, 20.0679, -64.963196, -10.4337, 20.0679, -62.057194, -10.4337, 20.0679, -62.057194, -10.4337, 23.412498, -64.963196, -10.4337, 23.412498, -71.2999, -10.4337, 20.0679, -73.8239, -10.4337, 16.7232, -71.2999, -10.4337, 16.7232, -68.2489, -10.4337, 20.0679, -71.2999, -10.4337, 20.0679, -71.2999, -10.4337, 16.7232, -71.2999, -10.4337, 20.0679, -73.8239, -10.4337, 20.0679, -73.8239, -10.4337, 16.7232, -64.963196, -10.4337, 23.412498, -68.2489, -10.4337, 23.412498, -68.2489, -10.4337, 20.0679, -68.2489, -10.4337, 23.412498, -71.2999, -10.4337, 20.0679, -68.2489, -10.4337, 20.0679, -62.057194, -10.4337, 23.412498, -64.963196, -10.4337, 26.7572, -64.963196, -10.4337, 23.412498, -64.963196, -10.4337, 26.7572, -68.2489, -10.4337, 23.412498, -64.963196, -10.4337, 23.412498, -62.057194, -10.4337, 23.412498, -62.057194, -10.4337, 26.7572, -64.963196, -10.4337, 26.7572, -71.2999, -10.4337, 23.412498, -73.8239, -10.4337, 20.0679, -71.2999, -10.4337, 20.0679, -68.2489, -10.4337, 23.412498, -71.2999, -10.4337, 23.412498, -71.2999, -10.4337, 20.0679, -71.2999, -10.4337, 23.412498, -73.8239, -10.4337, 23.412498, -73.8239, -10.4337, 20.0679, -68.2489, -10.4337, 26.7572, -71.2999, -10.4337, 23.412498, -68.2489, -10.4337, 23.412498, -64.963196, -10.4337, 26.7572, -68.2489, -10.4337, 26.7572, -68.2489, -10.4337, 23.412498, -71.2999, -10.4337, 26.7572, -73.8239, -10.4337, 23.412498, -71.2999, -10.4337, 23.412498, -68.2489, -10.4337, 26.7572, -71.2999, -10.4337, 26.7572, -71.2999, -10.4337, 23.412498, -71.2999, -10.4337, 26.7572, -73.8239, -10.4337, 26.7572, -73.8239, -10.4337, 23.412498, -73.8239, -10.4337, 26.7572, -71.2999, -10.4337, 26.7572, -72.9579, -10.4337, 27.7057, -71.2999, -10.4337, 26.7572, -71.694496, -10.4337, 29.089499, -72.9579, -10.4337, 27.7057, -71.2999, -10.4337, 26.7572, -70.1271, -10.4337, 28.0285, -71.694496, -10.4337, 29.089499, -71.2999, -10.4337, 26.7572, -68.2489, -10.4337, 26.7572, -70.1271, -10.4337, 28.0285, -70.1271, -10.4337, 28.0285, -70.3329, -10.4337, 30.580898, -71.694496, -10.4337, 29.089499, -70.1271, -10.4337, 28.0285, -68.7877, -10.4337, 29.480598, -70.3329, -10.4337, 30.580898, -68.2489, -10.4337, 26.7572, -68.7877, -10.4337, 29.480598, -70.1271, -10.4337, 28.0285, -68.7877, -10.4337, 29.480598, -69.0569, -10.4337, 31.9786, -70.3329, -10.4337, 30.580898, -68.2489, -10.4337, 26.7572, -66.948, -10.4337, 28.1705, -68.7877, -10.4337, 29.480598, -68.2489, -10.4337, 26.7572, -64.963196, -10.4337, 26.7572, -66.948, -10.4337, 28.1705, -68.7877, -10.4337, 29.480598, -67.5324, -10.4337, 30.8414, -69.0569, -10.4337, 31.9786, -66.948, -10.4337, 28.1705, -67.5324, -10.4337, 30.8414, -68.7877, -10.4337, 29.480598, -67.5324, -10.4337, 30.8414, -67.618996, -10.4337, 33.553497, -69.0569, -10.4337, 31.9786, -64.963196, -10.4337, 26.7572, -65.7283, -10.4337, 29.495699, -66.948, -10.4337, 28.1705, -66.948, -10.4337, 28.1705, -65.7283, -10.4337, 29.495699, -67.5324, -10.4337, 30.8414, -67.5324, -10.4337, 30.8414, -66.0847, -10.4337, 32.410698, -67.618996, -10.4337, 33.553497, -65.7283, -10.4337, 29.495699, -66.0847, -10.4337, 32.410698, -67.5324, -10.4337, 30.8414, -66.0847, -10.4337, 32.410698, -66.2484, -10.4337, 35.0548, -67.618996, -10.4337, 33.553497, -64.963196, -10.4337, 26.7572, -63.779697, -10.4337, 28.042099, -65.7283, -10.4337, 29.495699, -64.963196, -10.4337, 26.7572, -62.057194, -10.4337, 26.7572, -63.779697, -10.4337, 28.042099, -65.7283, -10.4337, 29.495699, -64.2815, -10.4337, 31.0675, -66.0847, -10.4337, 32.410698, -63.779697, -10.4337, 28.042099, -64.2815, -10.4337, 31.0675, -65.7283, -10.4337, 29.495699, -66.0847, -10.4337, 32.410698, -64.736496, -10.4337, 33.8722, -66.2484, -10.4337, 35.0548, -64.2815, -10.4337, 31.0675, -64.736496, -10.4337, 33.8722, -66.0847, -10.4337, 32.410698, -64.736496, -10.4337, 33.8722, -65.1522, -10.4337, 36.255398, -66.2484, -10.4337, 35.0548, -62.057194, -10.4337, 26.7572, -62.331196, -10.4337, 29.6148, -63.779697, -10.4337, 28.042099, -63.779697, -10.4337, 28.042099, -62.331196, -10.4337, 29.6148, -64.2815, -10.4337, 31.0675, -62.057194, -10.4337, 26.7572, -60.611, -10.4337, 28.3335, -62.331196, -10.4337, 29.6148, -64.2815, -10.4337, 31.0675, -62.971096, -10.4337, 32.4913, -64.736496, -10.4337, 33.8722, -62.331196, -10.4337, 29.6148, -62.971096, -10.4337, 32.4913, -64.2815, -10.4337, 31.0675, -64.736496, -10.4337, 33.8722, -63.642498, -10.4337, 35.0582, -65.1522, -10.4337, 36.255398, -62.971096, -10.4337, 32.4913, -63.642498, -10.4337, 35.0582, -64.736496, -10.4337, 33.8722, -63.642498, -10.4337, 35.0582, -63.8252, -10.4337, 37.7089, -65.1522, -10.4337, 36.255398, -60.611, -10.4337, 28.3335, -61.059097, -10.4337, 30.9959, -62.331196, -10.4337, 29.6148, -62.331196, -10.4337, 29.6148, -61.059097, -10.4337, 30.9959, -62.971096, -10.4337, 32.4913, -60.611, -10.4337, 28.3335, -59.3761, -10.4337, 29.679499, -61.059097, -10.4337, 30.9959, -62.971096, -10.4337, 32.4913, -61.8887, -10.4337, 33.667297, -63.642498, -10.4337, 35.0582, -61.059097, -10.4337, 30.9959, -61.8887, -10.4337, 33.667297, -62.971096, -10.4337, 32.4913, -63.642498, -10.4337, 35.0582, -62.323597, -10.4337, 36.4879, -63.8252, -10.4337, 37.7089, -61.8887, -10.4337, 33.667297, -62.323597, -10.4337, 36.4879, -63.642498, -10.4337, 35.0582, -62.323597, -10.4337, 36.4879, -62.558193, -10.4337, 39.0967, -63.8252, -10.4337, 37.7089, -59.3761, -10.4337, 29.679499, -59.9874, -10.4337, 32.1594, -61.059097, -10.4337, 30.9959, -61.059097, -10.4337, 30.9959, -59.9874, -10.4337, 32.1594, -61.8887, -10.4337, 33.667297, -59.3761, -10.4337, 29.679499, -58.316597, -10.4337, 30.834398, -59.9874, -10.4337, 32.1594, -61.8887, -10.4337, 33.667297, -60.59, -10.4337, 35.078197, -62.323597, -10.4337, 36.4879, -59.9874, -10.4337, 32.1594, -60.59, -10.4337, 35.078197, -61.8887, -10.4337, 33.667297, -62.323597, -10.4337, 36.4879, -61.055798, -10.4337, 37.8623, -62.558193, -10.4337, 39.0967, -60.59, -10.4337, 35.078197, -61.055798, -10.4337, 37.8623, -62.323597, -10.4337, 36.4879, -61.055798, -10.4337, 37.8623, -61.1665, -10.4337, 40.621098, -62.558193, -10.4337, 39.0967, -58.316597, -10.4337, 30.834398, -58.708298, -10.4337, 33.5481, -59.9874, -10.4337, 32.1594, -59.9874, -10.4337, 32.1594, -58.708298, -10.4337, 33.5481, -60.59, -10.4337, 35.078197, -58.316597, -10.4337, 30.834398, -57.058, -10.4337, 32.2062, -58.708298, -10.4337, 33.5481, -60.59, -10.4337, 35.078197, -59.331398, -10.4337, 36.4456, -61.055798, -10.4337, 37.8623, -58.708298, -10.4337, 33.5481, -59.331398, -10.4337, 36.4456, -60.59, -10.4337, 35.078197, -61.055798, -10.4337, 37.8623, -59.6695, -10.4337, 39.3651, -61.1665, -10.4337, 40.621098, -59.331398, -10.4337, 36.4456, -59.6695, -10.4337, 39.3651, -61.055798, -10.4337, 37.8623, -59.6695, -10.4337, 39.3651, -59.815098, -10.4337, 42.1012, -61.1665, -10.4337, 40.621098, -57.058, -10.4337, 32.2062, -57.457497, -10.4337, 34.906097, -58.708298, -10.4337, 33.5481, -58.708298, -10.4337, 33.5481, -57.457497, -10.4337, 34.906097, -59.331398, -10.4337, 36.4456, -57.058, -10.4337, 32.2062, -55.8173, -10.4337, 33.5585, -57.457497, -10.4337, 34.906097, -59.331398, -10.4337, 36.4456, -57.962597, -10.4337, 37.9328, -59.6695, -10.4337, 39.3651, -57.457497, -10.4337, 34.906097, -57.962597, -10.4337, 37.9328, -59.331398, -10.4337, 36.4456, -59.6695, -10.4337, 39.3651, -58.3182, -10.4337, 40.8299, -59.815098, -10.4337, 42.1012, -57.962597, -10.4337, 37.9328, -58.3182, -10.4337, 40.8299, -59.6695, -10.4337, 39.3651, -58.3182, -10.4337, 40.8299, -58.397198, -10.4337, 43.6543, -59.815098, -10.4337, 42.1012, -55.8173, -10.4337, 33.5585, -56.105198, -10.4337, 36.374397, -57.457497, -10.4337, 34.906097, -57.457497, -10.4337, 34.906097, -56.105198, -10.4337, 36.374397, -57.962597, -10.4337, 37.9328, -55.8173, -10.4337, 33.5585, -54.4828, -10.4337, 35.0131, -56.105198, -10.4337, 36.374397, -57.962597, -10.4337, 37.9328, -56.621998, -10.4337, 39.389297, -58.3182, -10.4337, 40.8299, -56.105198, -10.4337, 36.374397, -56.621998, -10.4337, 39.389297, -57.962597, -10.4337, 37.9328, -58.3182, -10.4337, 40.8299, -56.8974, -10.4337, 42.370197, -58.397198, -10.4337, 43.6543, -56.621998, -10.4337, 39.389297, -56.8974, -10.4337, 42.370197, -58.3182, -10.4337, 40.8299, -56.8974, -10.4337, 42.370197, -57.1702, -10.4337, 44.9982, -58.397198, -10.4337, 43.6543, -54.4828, -10.4337, 35.0131, -54.7739, -10.4337, 37.819798, -56.105198, -10.4337, 36.374397, -56.105198, -10.4337, 36.374397, -54.7739, -10.4337, 37.819798, -56.621998, -10.4337, 39.389297, -54.4828, -10.4337, 35.0131, -53.163, -10.4337, 36.4517, -54.7739, -10.4337, 37.819798, -56.621998, -10.4337, 39.389297, -55.2089, -10.4337, 40.9246, -56.8974, -10.4337, 42.370197, -54.7739, -10.4337, 37.819798, -55.2089, -10.4337, 40.9246, -56.621998, -10.4337, 39.389297, -56.8974, -10.4337, 42.370197, -55.676598, -10.4337, 43.6936, -57.1702, -10.4337, 44.9982, -55.2089, -10.4337, 40.9246, -55.676598, -10.4337, 43.6936, -56.8974, -10.4337, 42.370197, -55.676598, -10.4337, 43.6936, -55.7286, -10.4337, 46.577297, -57.1702, -10.4337, 44.9982, -53.163, -10.4337, 36.4517, -53.3668, -10.4337, 39.3474, -54.7739, -10.4337, 37.819798, -54.7739, -10.4337, 37.819798, -53.3668, -10.4337, 39.3474, -55.2089, -10.4337, 40.9246, -53.163, -10.4337, 36.4517, -51.764698, -10.4337, 37.9757, -53.3668, -10.4337, 39.3474, -55.2089, -10.4337, 40.9246, -54.004498, -10.4337, 42.233097, -55.676598, -10.4337, 43.6936, -53.3668, -10.4337, 39.3474, -54.004498, -10.4337, 42.233097, -55.2089, -10.4337, 40.9246, -55.676598, -10.4337, 43.6936, -54.2416, -10.4337, 45.2492, -55.7286, -10.4337, 46.577297, -54.004498, -10.4337, 42.233097, -54.2416, -10.4337, 45.2492, -55.676598, -10.4337, 43.6936, -54.2416, -10.4337, 45.2492, -54.056297, -10.4337, 48.408897, -55.7286, -10.4337, 46.577297, -51.764698, -10.4337, 37.9757, -52.1782, -10.4337, 40.637897, -53.3668, -10.4337, 39.3474, -53.3668, -10.4337, 39.3474, -52.1782, -10.4337, 40.637897, -54.004498, -10.4337, 42.233097, -51.764698, -10.4337, 37.9757, -50.5928, -10.4337, 39.2532, -52.1782, -10.4337, 40.637897, -54.004498, -10.4337, 42.233097, -52.5879, -10.4337, 43.772198, -54.2416, -10.4337, 45.2492, -52.1782, -10.4337, 40.637897, -52.5879, -10.4337, 43.772198, -54.004498, -10.4337, 42.233097, -54.2416, -10.4337, 45.2492, -52.5793, -10.4337, 47.051098, -54.056297, -10.4337, 48.408897, -52.5879, -10.4337, 43.772198, -52.5793, -10.4337, 47.051098, -54.2416, -10.4337, 45.2492, -52.5793, -10.4337, 47.051098, -52.2215, -10.4337, 50.418697, -54.056297, -10.4337, 48.408897, -50.5928, -10.4337, 39.2532, -50.779198, -10.4337, 42.1568, -52.1782, -10.4337, 40.637897, -52.1782, -10.4337, 40.637897, -50.779198, -10.4337, 42.1568, -52.5879, -10.4337, 43.772198, -50.5928, -10.4337, 39.2532, -49.212498, -10.4337, 40.7576, -50.779198, -10.4337, 42.1568, -52.5879, -10.4337, 43.772198, -50.9492, -10.4337, 45.552597, -52.5793, -10.4337, 47.051098, -50.779198, -10.4337, 42.1568, -50.9492, -10.4337, 45.552597, -52.5879, -10.4337, 43.772198, -52.5793, -10.4337, 47.051098, -50.741398, -10.4337, 49.0436, -52.2215, -10.4337, 50.418697, -50.9492, -10.4337, 45.552597, -50.741398, -10.4337, 49.0436, -52.5793, -10.4337, 47.051098, -50.741398, -10.4337, 49.0436, -50.267597, -10.4337, 52.5587, -52.2215, -10.4337, 50.418697, -49.212498, -10.4337, 40.7576, -49.163498, -10.4337, 43.911, -50.779198, -10.4337, 42.1568, -50.779198, -10.4337, 42.1568, -49.163498, -10.4337, 43.911, -50.9492, -10.4337, 45.552597, -49.212498, -10.4337, 40.7576, -47.620697, -10.4337, 42.4927, -49.163498, -10.4337, 43.911, -50.9492, -10.4337, 45.552597, -49.1213, -10.4337, 47.5384, -50.741398, -10.4337, 49.0436, -49.163498, -10.4337, 43.911, -49.1213, -10.4337, 47.5384, -50.9492, -10.4337, 45.552597, -50.741398, -10.4337, 49.0436, -48.787197, -10.4337, 51.162, -50.267597, -10.4337, 52.5587, -49.1213, -10.4337, 47.5384, -48.787197, -10.4337, 51.162, -50.741398, -10.4337, 49.0436, -48.787197, -10.4337, 51.162, -48.3197, -10.4337, 54.6923, -50.267597, -10.4337, 52.5587, -47.620697, -10.4337, 42.4927, -47.343597, -10.4337, 45.8868, -49.163498, -10.4337, 43.911, -49.163498, -10.4337, 43.911, -47.343597, -10.4337, 45.8868, -49.1213, -10.4337, 47.5384, -47.620697, -10.4337, 42.4927, -45.8121, -10.4337, 44.463898, -47.343597, -10.4337, 45.8868, -49.1213, -10.4337, 47.5384, -47.181, -10.4337, 49.6466, -48.787197, -10.4337, 51.162, -47.343597, -10.4337, 45.8868, -47.181, -10.4337, 49.6466, -49.1213, -10.4337, 47.5384, -48.787197, -10.4337, 51.162, -46.8489, -10.4337, 53.263298, -48.3197, -10.4337, 54.6923, -47.181, -10.4337, 49.6466, -46.8489, -10.4337, 53.263298, -48.787197, -10.4337, 51.162, -46.8489, -10.4337, 53.263298, -46.839, -10.4337, 56.314198, -48.3197, -10.4337, 54.6923, -45.8121, -10.4337, 44.463898, -45.4151, -10.4337, 47.9805, -47.343597, -10.4337, 45.8868, -47.343597, -10.4337, 45.8868, -45.4151, -10.4337, 47.9805, -47.181, -10.4337, 49.6466, -45.8121, -10.4337, 44.463898, -43.8985, -10.4337, 46.549698, -45.4151, -10.4337, 47.9805, -47.181, -10.4337, 49.6466, -45.2669, -10.4337, 51.7262, -46.8489, -10.4337, 53.263298, -45.4151, -10.4337, 47.9805, -45.2669, -10.4337, 51.7262, -47.181, -10.4337, 49.6466, -46.8489, -10.4337, 53.263298, -45.3659, -10.4337, 54.8708, -46.839, -10.4337, 56.314198, -45.2669, -10.4337, 51.7262, -45.3659, -10.4337, 54.8708, -46.8489, -10.4337, 53.263298, -45.3659, -10.4337, 54.8708, -45.411, -10.4337, 57.8783, -46.839, -10.4337, 56.314198, -43.8985, -10.4337, 46.549698, -43.524498, -10.4337, 50.0333, -45.4151, -10.4337, 47.9805, -45.4151, -10.4337, 47.9805, -43.524498, -10.4337, 50.0333, -45.2669, -10.4337, 51.7262, -43.8985, -10.4337, 46.549698, -42.032497, -10.4337, 48.5836, -43.524498, -10.4337, 50.0333, -45.2669, -10.4337, 51.7262, -43.792, -10.4337, 53.328598, -45.3659, -10.4337, 54.8708, -43.524498, -10.4337, 50.0333, -43.792, -10.4337, 53.328598, -45.2669, -10.4337, 51.7262, -45.3659, -10.4337, 54.8708, -43.935497, -10.4337, 56.421497, -45.411, -10.4337, 57.8783, -43.792, -10.4337, 53.328598, -43.935497, -10.4337, 56.421497, -45.3659, -10.4337, 54.8708, -43.935497, -10.4337, 56.421497, -43.670998, -10.4337, 59.7842, -45.411, -10.4337, 57.8783, -42.032497, -10.4337, 48.5836, -42.056, -10.4337, 51.6275, -43.524498, -10.4337, 50.0333, -43.524498, -10.4337, 50.0333, -42.056, -10.4337, 51.6275, -43.792, -10.4337, 53.328598, -42.032497, -10.4337, 48.5836, -40.572998, -10.4337, 50.1744, -42.056, -10.4337, 51.6275, -43.792, -10.4337, 53.328598, -42.368797, -10.4337, 54.874798, -43.935497, -10.4337, 56.421497, -42.056, -10.4337, 51.6275, -42.368797, -10.4337, 54.874798, -43.792, -10.4337, 53.328598, -43.935497, -10.4337, 56.421497, -42.2006, -10.4337, 58.3022, -43.670998, -10.4337, 59.7842, -42.368797, -10.4337, 54.874798, -42.2006, -10.4337, 58.3022, -43.935497, -10.4337, 56.421497, -42.2006, -10.4337, 58.3022, -41.9354, -10.4337, 61.685097, -43.670998, -10.4337, 59.7842, -40.572998, -10.4337, 50.1744, -40.6386, -10.4337, 53.1665, -42.056, -10.4337, 51.6275, -42.056, -10.4337, 51.6275, -40.6386, -10.4337, 53.1665, -42.368797, -10.4337, 54.874798, -40.572998, -10.4337, 50.1744, -39.1638, -10.4337, 51.7104, -40.6386, -10.4337, 53.1665, -42.368797, -10.4337, 54.874798, -40.6512, -10.4337, 56.7408, -42.2006, -10.4337, 58.3022, -40.6386, -10.4337, 53.1665, -40.6512, -10.4337, 56.7408, -42.368797, -10.4337, 54.874798, -42.2006, -10.4337, 58.3022, -40.4544, -10.4337, 60.1951, -41.9354, -10.4337, 61.685097, -40.6512, -10.4337, 56.7408, -40.4544, -10.4337, 60.1951, -42.2006, -10.4337, 58.3022, -40.4544, -10.4337, 60.1951, -40.3009, -10.4337, 63.4754, -41.9354, -10.4337, 61.685097, -39.1638, -10.4337, 51.7104, -38.937298, -10.4337, 55.0135, -40.6386, -10.4337, 53.1665, -40.6386, -10.4337, 53.1665, -38.937298, -10.4337, 55.0135, -40.6512, -10.4337, 56.7408, -39.1638, -10.4337, 51.7104, -37.4804, -10.4337, 53.5453, -38.937298, -10.4337, 55.0135, -40.6512, -10.4337, 56.7408, -38.9059, -10.4337, 58.6371, -40.4544, -10.4337, 60.1951, -38.937298, -10.4337, 55.0135, -38.9059, -10.4337, 58.6371, -40.6512, -10.4337, 56.7408, -40.4544, -10.4337, 60.1951, -38.822998, -10.4337, 61.9637, -40.3009, -10.4337, 63.4754, -38.9059, -10.4337, 58.6371, -38.822998, -10.4337, 61.9637, -40.4544, -10.4337, 60.1951, -38.822998, -10.4337, 61.9637, -38.953697, -10.4337, 64.951, -40.3009, -10.4337, 63.4754, -37.4804, -10.4337, 53.5453, -37.1899, -10.4337, 56.910698, -38.937298, -10.4337, 55.0135, -38.937298, -10.4337, 55.0135, -37.1899, -10.4337, 56.910698, -38.9059, -10.4337, 58.6371, -37.4804, -10.4337, 53.5453, -35.735397, -10.4337, 55.4473, -37.1899, -10.4337, 56.910698, -38.9059, -10.4337, 58.6371, -37.2887, -10.4337, 60.3941, -38.822998, -10.4337, 61.9637, -37.1899, -10.4337, 56.910698, -37.2887, -10.4337, 60.3941, -38.9059, -10.4337, 58.6371, -38.822998, -10.4337, 61.9637, -37.4867, -10.4337, 63.4123, -38.953697, -10.4337, 64.951, -37.2887, -10.4337, 60.3941, -37.4867, -10.4337, 63.4123, -38.822998, -10.4337, 61.9637, -37.4867, -10.4337, 63.4123, -37.4493, -10.4337, 66.5989, -38.953697, -10.4337, 64.951, -35.735397, -10.4337, 55.4473, -35.5858, -10.4337, 58.6522, -37.1899, -10.4337, 56.910698, -37.1899, -10.4337, 56.910698, -35.5858, -10.4337, 58.6522, -37.2887, -10.4337, 60.3941, -35.735397, -10.4337, 55.4473, -34.1461, -10.4337, 57.1796, -35.5858, -10.4337, 58.6522, -37.2887, -10.4337, 60.3941, -35.9725, -10.4337, 61.824097, -37.4867, -10.4337, 63.4123, -35.5858, -10.4337, 58.6522, -35.9725, -10.4337, 61.824097, -37.2887, -10.4337, 60.3941, -37.4867, -10.4337, 63.4123, -35.9927, -10.4337, 65.0319, -37.4493, -10.4337, 66.5989, -35.9725, -10.4337, 61.824097, -35.9927, -10.4337, 65.0319, -37.4867, -10.4337, 63.4123, -35.9927, -10.4337, 65.0319, -36.0228, -10.4337, 68.1614, -37.4493, -10.4337, 66.5989, -34.1461, -10.4337, 57.1796, -34.2898, -10.4337, 60.0593, -35.5858, -10.4337, 58.6522, -35.5858, -10.4337, 58.6522, -34.2898, -10.4337, 60.0593, -35.9725, -10.4337, 61.824097, -34.1461, -10.4337, 57.1796, -32.870197, -10.4337, 58.570297, -34.2898, -10.4337, 60.0593, -35.9725, -10.4337, 61.824097, -34.499, -10.4337, 63.425, -35.9927, -10.4337, 65.0319, -34.2898, -10.4337, 60.0593, -34.499, -10.4337, 63.425, -35.9725, -10.4337, 61.824097, -35.9927, -10.4337, 65.0319, -34.5678, -10.4337, 66.5766, -36.0228, -10.4337, 68.1614, -34.499, -10.4337, 63.425, -34.5678, -10.4337, 66.5766, -35.9927, -10.4337, 65.0319, -34.5678, -10.4337, 66.5766, -34.1187, -10.4337, 70.246895, -36.0228, -10.4337, 68.1614, -32.870197, -10.4337, 58.570297, -32.8368, -10.4337, 61.636898, -34.2898, -10.4337, 60.0593, -34.2898, -10.4337, 60.0593, -32.8368, -10.4337, 61.636898, -34.499, -10.4337, 63.425, -32.870197, -10.4337, 58.570297, -31.437601, -10.4337, 60.131798, -32.8368, -10.4337, 61.636898, -34.499, -10.4337, 63.425, -33.0849, -10.4337, 64.961395, -34.5678, -10.4337, 66.5766, -32.8368, -10.4337, 61.636898, -33.0849, -10.4337, 64.961395, -34.499, -10.4337, 63.425, -34.5678, -10.4337, 66.5766, -32.69, -10.4337, 68.6121, -34.1187, -10.4337, 70.246895, -33.0849, -10.4337, 64.961395, -32.69, -10.4337, 68.6121, -34.5678, -10.4337, 66.5766, -32.69, -10.4337, 68.6121, -32.6527, -10.4337, 71.8527, -34.1187, -10.4337, 70.246895, -31.437601, -10.4337, 60.131798, -31.4325, -10.4337, 63.1615, -32.8368, -10.4337, 61.636898, -32.8368, -10.4337, 61.636898, -31.4325, -10.4337, 63.1615, -33.0849, -10.4337, 64.961395, -31.437601, -10.4337, 60.131798, -30.044802, -10.4337, 61.649998, -31.4325, -10.4337, 63.1615, -33.0849, -10.4337, 64.961395, -31.245802, -10.4337, 66.959496, -32.69, -10.4337, 68.6121, -31.4325, -10.4337, 63.1615, -31.245802, -10.4337, 66.959496, -33.0849, -10.4337, 64.961395, -32.69, -10.4337, 68.6121, -31.2026, -10.4337, 70.2246, -32.6527, -10.4337, 71.8527, -31.245802, -10.4337, 66.959496, -31.2026, -10.4337, 70.2246, -32.69, -10.4337, 68.6121, -31.2026, -10.4337, 70.2246, -31.218801, -10.4337, 73.423195, -32.6527, -10.4337, 71.8527, -30.044802, -10.4337, 61.649998, -29.633501, -10.4337, 65.1147, -31.4325, -10.4337, 63.1615, -31.4325, -10.4337, 63.1615, -29.633501, -10.4337, 65.1147, -31.245802, -10.4337, 66.959496, -30.044802, -10.4337, 61.649998, -28.2834, -10.4337, 63.569798, -29.633501, -10.4337, 65.1147, -31.245802, -10.4337, 66.959496, -29.745901, -10.4337, 68.589, -31.2026, -10.4337, 70.2246, -29.633501, -10.4337, 65.1147, -29.745901, -10.4337, 68.589, -31.245802, -10.4337, 66.959496, -31.2026, -10.4337, 70.2246, -29.787, -10.4337, 71.7591, -31.218801, -10.4337, 73.423195, -29.745901, -10.4337, 68.589, -29.787, -10.4337, 71.7591, -31.2026, -10.4337, 70.2246, -29.787, -10.4337, 71.7591, -29.6429, -10.4337, 75.1494, -31.218801, -10.4337, 73.423195, -28.2834, -10.4337, 63.569798, -28.117498, -10.4337, 66.7606, -29.633501, -10.4337, 65.1147, -29.633501, -10.4337, 65.1147, -28.117498, -10.4337, 66.7606, -29.745901, -10.4337, 68.589, -28.2834, -10.4337, 63.569798, -26.7572, -10.4337, 65.2334, -28.117498, -10.4337, 66.7606, -29.745901, -10.4337, 68.589, -28.357399, -10.4337, 70.097496, -29.787, -10.4337, 71.7591, -28.117498, -10.4337, 66.7606, -28.357399, -10.4337, 70.097496, -29.745901, -10.4337, 68.589, -29.787, -10.4337, 71.7591, -28.1941, -10.4337, 73.4859, -29.6429, -10.4337, 75.1494, -28.357399, -10.4337, 70.097496, -28.1941, -10.4337, 73.4859, -29.787, -10.4337, 71.7591, -28.1941, -10.4337, 73.4859, -28.2134, -10.4337, 76.715096, -29.6429, -10.4337, 75.1494, -26.7572, -10.4337, 65.2334, -26.7572, -10.4337, 68.237495, -28.117498, -10.4337, 66.7606, -28.117498, -10.4337, 66.7606, -26.7572, -10.4337, 68.237495, -28.357399, -10.4337, 70.097496, -26.7572, -10.4337, 68.237495, -26.7572, -10.4337, 65.2334, -23.412498, -10.4337, 65.2334, -28.1941, -10.4337, 73.4859, -26.7572, -10.4337, 75.043594, -28.2134, -10.4337, 76.715096, -26.7572, -10.4337, 75.043594, -26.7572, -10.4337, 78.3101, -28.2134, -10.4337, 76.715096, -28.357399, -10.4337, 70.097496, -26.7572, -10.4337, 71.8361, -28.1941, -10.4337, 73.4859, -26.7572, -10.4337, 68.237495, -26.7572, -10.4337, 71.8361, -28.357399, -10.4337, 70.097496, -26.7572, -10.4337, 71.8361, -26.7572, -10.4337, 75.043594, -28.1941, -10.4337, 73.4859, -23.412498, -10.4337, 78.3101, -26.7572, -10.4337, 78.3101, -26.7572, -10.4337, 75.043594, -26.7572, -10.4337, 71.8361, -26.7572, -10.4337, 68.237495, -23.412498, -10.4337, 68.237495, -26.7572, -10.4337, 68.237495, -23.412498, -10.4337, 65.2334, -23.412498, -10.4337, 68.237495, -23.412498, -10.4337, 68.237495, -23.412498, -10.4337, 65.2334, -20.0679, -10.4337, 65.2334, -26.7572, -10.4337, 71.8361, -23.412498, -10.4337, 68.237495, -23.412498, -10.4337, 71.8361, -26.7572, -10.4337, 75.043594, -26.7572, -10.4337, 71.8361, -23.412498, -10.4337, 71.8361, -23.412498, -10.4337, 68.237495, -20.0679, -10.4337, 65.2334, -20.0679, -10.4337, 68.237495, -23.412498, -10.4337, 71.8361, -23.412498, -10.4337, 68.237495, -20.0679, -10.4337, 68.237495, -16.7232, -10.4337, 65.2334, -20.0679, -10.4337, 68.237495, -20.0679, -10.4337, 65.2334, -23.412498, -10.4337, 78.3101, -26.7572, -10.4337, 75.043594, -23.412498, -10.4337, 75.043594, -26.7572, -10.4337, 75.043594, -23.412498, -10.4337, 71.8361, -23.412498, -10.4337, 75.043594, -20.0679, -10.4337, 78.3101, -23.412498, -10.4337, 78.3101, -23.412498, -10.4337, 75.043594, -23.412498, -10.4337, 71.8361, -20.0679, -10.4337, 68.237495, -20.0679, -10.4337, 71.8361, -23.412498, -10.4337, 75.043594, -23.412498, -10.4337, 71.8361, -20.0679, -10.4337, 71.8361, -16.7232, -10.4337, 65.2334, -16.7232, -10.4337, 68.237495, -20.0679, -10.4337, 68.237495, -16.7232, -10.4337, 68.237495, -20.0679, -10.4337, 71.8361, -20.0679, -10.4337, 68.237495, -16.7232, -10.4337, 68.237495, -16.7232, -10.4337, 65.2334, -13.378601, -10.4337, 65.2334, -23.412498, -10.4337, 75.043594, -20.0679, -10.4337, 71.8361, -20.0679, -10.4337, 75.043594, -20.0679, -10.4337, 78.3101, -23.412498, -10.4337, 75.043594, -20.0679, -10.4337, 75.043594, -16.7232, -10.4337, 68.237495, -16.7232, -10.4337, 71.8361, -20.0679, -10.4337, 71.8361, -16.7232, -10.4337, 71.8361, -20.0679, -10.4337, 75.043594, -20.0679, -10.4337, 71.8361, -16.7232, -10.4337, 75.043594, -20.0679, -10.4337, 78.3101, -20.0679, -10.4337, 75.043594, -16.7232, -10.4337, 71.8361, -16.7232, -10.4337, 75.043594, -20.0679, -10.4337, 75.043594, -16.7232, -10.4337, 75.043594, -16.7232, -10.4337, 78.3101, -20.0679, -10.4337, 78.3101, -16.7232, -10.4337, 71.8361, -16.7232, -10.4337, 68.237495, -13.378601, -10.4337, 68.237495, -16.7232, -10.4337, 68.237495, -13.378601, -10.4337, 65.2334, -13.378601, -10.4337, 68.237495, -16.7232, -10.4337, 75.043594, -16.7232, -10.4337, 71.8361, -13.378601, -10.4337, 71.8361, -16.7232, -10.4337, 71.8361, -13.378601, -10.4337, 68.237495, -13.378601, -10.4337, 71.8361, -16.7232, -10.4337, 78.3101, -16.7232, -10.4337, 75.043594, -13.378601, -10.4337, 75.043594, -16.7232, -10.4337, 75.043594, -13.378601, -10.4337, 71.8361, -13.378601, -10.4337, 75.043594, -16.7232, -10.4337, 78.3101, -13.378601, -10.4337, 75.043594, -13.378601, -10.4337, 78.3101, -13.378601, -10.4337, 65.2334, -10.033899, -10.4337, 68.237495, -13.378601, -10.4337, 68.237495, -10.033899, -10.4337, 68.237495, -13.378601, -10.4337, 71.8361, -13.378601, -10.4337, 68.237495, -13.378601, -10.4337, 65.2334, -10.033899, -10.4337, 65.2334, -10.033899, -10.4337, 68.237495, -10.033899, -10.4337, 71.8361, -13.378601, -10.4337, 75.043594, -13.378601, -10.4337, 71.8361, -10.033899, -10.4337, 68.237495, -10.033899, -10.4337, 71.8361, -13.378601, -10.4337, 71.8361, -10.033899, -10.4337, 75.043594, -13.378601, -10.4337, 78.3101, -13.378601, -10.4337, 75.043594, -10.033899, -10.4337, 71.8361, -10.033899, -10.4337, 75.043594, -13.378601, -10.4337, 75.043594, -10.033899, -10.4337, 75.043594, -10.033899, -10.4337, 78.3101, -13.378601, -10.4337, 78.3101, -10.033899, -10.4337, 65.2334, -6.6893, -10.4337, 68.237495, -10.033899, -10.4337, 68.237495, -6.6893, -10.4337, 68.237495, -10.033899, -10.4337, 71.8361, -10.033899, -10.4337, 68.237495, -10.033899, -10.4337, 65.2334, -6.6893, -10.4337, 65.2334, -6.6893, -10.4337, 68.237495, -6.6893, -10.4337, 71.8361, -10.033899, -10.4337, 75.043594, -10.033899, -10.4337, 71.8361, -6.6893, -10.4337, 68.237495, -6.6893, -10.4337, 71.8361, -10.033899, -10.4337, 71.8361, -6.6893, -10.4337, 75.043594, -10.033899, -10.4337, 78.3101, -10.033899, -10.4337, 75.043594, -6.6893, -10.4337, 71.8361, -6.6893, -10.4337, 75.043594, -10.033899, -10.4337, 75.043594, -6.6893, -10.4337, 75.043594, -6.6893, -10.4337, 78.3101, -10.033899, -10.4337, 78.3101, -6.6893, -10.4337, 65.2334, -3.3446002, -10.4337, 68.237495, -6.6893, -10.4337, 68.237495, -3.3446002, -10.4337, 68.237495, -6.6893, -10.4337, 71.8361, -6.6893, -10.4337, 68.237495, -6.6893, -10.4337, 65.2334, -3.3446002, -10.4337, 65.2334, -3.3446002, -10.4337, 68.237495, -3.3446002, -10.4337, 71.8361, -6.6893, -10.4337, 75.043594, -6.6893, -10.4337, 71.8361, -3.3446002, -10.4337, 68.237495, -3.3446002, -10.4337, 71.8361, -6.6893, -10.4337, 71.8361, -3.3446002, -10.4337, 75.043594, -6.6893, -10.4337, 78.3101, -6.6893, -10.4337, 75.043594, -3.3446002, -10.4337, 71.8361, -3.3446002, -10.4337, 75.043594, -6.6893, -10.4337, 75.043594, -3.3446002, -10.4337, 75.043594, -3.3446002, -10.4337, 78.3101, -6.6893, -10.4337, 78.3101, -3.3446002, -10.4337, 65.2334, 0, -10.4337, 68.237495, -3.3446002, -10.4337, 68.237495, 0, -10.4337, 68.237495, -3.3446002, -10.4337, 71.8361, -3.3446002, -10.4337, 68.237495, -3.3446002, -10.4337, 65.2334, 0, -10.4337, 65.2334, 0, -10.4337, 68.237495, 0, -10.4337, 71.8361, -3.3446002, -10.4337, 75.043594, -3.3446002, -10.4337, 71.8361, 0, -10.4337, 68.237495, 0, -10.4337, 71.8361, -3.3446002, -10.4337, 71.8361, 0, -10.4337, 75.043594, -3.3446002, -10.4337, 78.3101, -3.3446002, -10.4337, 75.043594, 0, -10.4337, 71.8361, 0, -10.4337, 75.043594, -3.3446002, -10.4337, 75.043594, 0, -10.4337, 75.043594, 0, -10.4337, 78.3101, -3.3446002, -10.4337, 78.3101, 0, -10.4337, 65.2334, 3.3446, -10.4337, 68.237495, 0, -10.4337, 68.237495, 3.3446, -10.4337, 68.237495, 0, -10.4337, 71.8361, 0, -10.4337, 68.237495, 0, -10.4337, 65.2334, 3.3446, -10.4337, 65.2334, 3.3446, -10.4337, 68.237495, 3.3446, -10.4337, 71.8361, 0, -10.4337, 75.043594, 0, -10.4337, 71.8361, 3.3446, -10.4337, 68.237495, 3.3446, -10.4337, 71.8361, 0, -10.4337, 71.8361, 3.3446, -10.4337, 75.043594, 0, -10.4337, 78.3101, 0, -10.4337, 75.043594, 3.3446, -10.4337, 71.8361, 3.3446, -10.4337, 75.043594, 0, -10.4337, 75.043594, 3.3446, -10.4337, 75.043594, 3.3446, -10.4337, 78.3101, 0, -10.4337, 78.3101, 3.3446, -10.4337, 65.2334, 6.6893, -10.4337, 68.237495, 3.3446, -10.4337, 68.237495, 6.6893, -10.4337, 68.237495, 3.3446, -10.4337, 71.8361, 3.3446, -10.4337, 68.237495, 3.3446, -10.4337, 65.2334, 6.6893, -10.4337, 65.2334, 6.6893, -10.4337, 68.237495, 6.6893, -10.4337, 71.8361, 3.3446, -10.4337, 75.043594, 3.3446, -10.4337, 71.8361, 6.6893, -10.4337, 68.237495, 6.6893, -10.4337, 71.8361, 3.3446, -10.4337, 71.8361, 6.6893, -10.4337, 75.043594, 3.3446, -10.4337, 78.3101, 3.3446, -10.4337, 75.043594, 6.6893, -10.4337, 71.8361, 6.6893, -10.4337, 75.043594, 3.3446, -10.4337, 75.043594, 6.6893, -10.4337, 75.043594, 6.6893, -10.4337, 78.3101, 3.3446, -10.4337, 78.3101, 6.6893, -10.4337, 65.2334, 10.033899, -10.4337, 68.237495, 6.6893, -10.4337, 68.237495, 10.033899, -10.4337, 68.237495, 6.6893, -10.4337, 71.8361, 6.6893, -10.4337, 68.237495, 6.6893, -10.4337, 65.2334, 10.033899, -10.4337, 65.2334, 10.033899, -10.4337, 68.237495, 10.033899, -10.4337, 71.8361, 6.6893, -10.4337, 75.043594, 6.6893, -10.4337, 71.8361, 10.033899, -10.4337, 68.237495, 10.033899, -10.4337, 71.8361, 6.6893, -10.4337, 71.8361, 10.033899, -10.4337, 75.043594, 6.6893, -10.4337, 78.3101, 6.6893, -10.4337, 75.043594, 10.033899, -10.4337, 71.8361, 10.033899, -10.4337, 75.043594, 6.6893, -10.4337, 75.043594, 10.033899, -10.4337, 75.043594, 10.033899, -10.4337, 78.3101, 6.6893, -10.4337, 78.3101, 10.033899, -10.4337, 65.2334, 13.378599, -10.4337, 68.237495, 10.033899, -10.4337, 68.237495, 13.378599, -10.4337, 68.237495, 10.033899, -10.4337, 71.8361, 10.033899, -10.4337, 68.237495, 10.033899, -10.4337, 65.2334, 13.378599, -10.4337, 65.2334, 13.378599, -10.4337, 68.237495, 13.378599, -10.4337, 71.8361, 10.033899, -10.4337, 75.043594, 10.033899, -10.4337, 71.8361, 13.378599, -10.4337, 68.237495, 13.378599, -10.4337, 71.8361, 10.033899, -10.4337, 71.8361, 13.378599, -10.4337, 75.043594, 10.033899, -10.4337, 78.3101, 10.033899, -10.4337, 75.043594, 13.378599, -10.4337, 71.8361, 13.378599, -10.4337, 75.043594, 10.033899, -10.4337, 75.043594, 13.378599, -10.4337, 75.043594, 13.378599, -10.4337, 78.3101, 10.033899, -10.4337, 78.3101, 13.378599, -10.4337, 65.2334, 16.7232, -10.4337, 68.237495, 13.378599, -10.4337, 68.237495, 16.7232, -10.4337, 68.237495, 13.378599, -10.4337, 71.8361, 13.378599, -10.4337, 68.237495, 13.378599, -10.4337, 65.2334, 16.7232, -10.4337, 65.2334, 16.7232, -10.4337, 68.237495, 16.7232, -10.4337, 71.8361, 13.378599, -10.4337, 75.043594, 13.378599, -10.4337, 71.8361, 16.7232, -10.4337, 68.237495, 16.7232, -10.4337, 71.8361, 13.378599, -10.4337, 71.8361, 16.7232, -10.4337, 75.043594, 13.378599, -10.4337, 78.3101, 13.378599, -10.4337, 75.043594, 16.7232, -10.4337, 71.8361, 16.7232, -10.4337, 75.043594, 13.378599, -10.4337, 75.043594, 16.7232, -10.4337, 75.043594, 16.7232, -10.4337, 78.3101, 13.378599, -10.4337, 78.3101, 16.7232, -10.4337, 65.2334, 20.0679, -10.4337, 68.237495, 16.7232, -10.4337, 68.237495, 20.0679, -10.4337, 68.237495, 16.7232, -10.4337, 71.8361, 16.7232, -10.4337, 68.237495, 16.7232, -10.4337, 65.2334, 20.0679, -10.4337, 65.2334, 20.0679, -10.4337, 68.237495, 20.0679, -10.4337, 71.8361, 16.7232, -10.4337, 75.043594, 16.7232, -10.4337, 71.8361, 20.0679, -10.4337, 68.237495, 20.0679, -10.4337, 71.8361, 16.7232, -10.4337, 71.8361, 20.0679, -10.4337, 75.043594, 16.7232, -10.4337, 78.3101, 16.7232, -10.4337, 75.043594, 20.0679, -10.4337, 71.8361, 20.0679, -10.4337, 75.043594, 16.7232, -10.4337, 75.043594, 20.0679, -10.4337, 75.043594, 20.0679, -10.4337, 78.3101, 16.7232, -10.4337, 78.3101, 20.0679, -10.4337, 65.2334, 23.412498, -10.4337, 68.237495, 20.0679, -10.4337, 68.237495, 23.412498, -10.4337, 68.237495, 20.0679, -10.4337, 71.8361, 20.0679, -10.4337, 68.237495, 20.0679, -10.4337, 65.2334, 23.412498, -10.4337, 65.2334, 23.412498, -10.4337, 68.237495, 23.412498, -10.4337, 71.8361, 20.0679, -10.4337, 75.043594, 20.0679, -10.4337, 71.8361, 23.412498, -10.4337, 68.237495, 23.412498, -10.4337, 71.8361, 20.0679, -10.4337, 71.8361, 23.412498, -10.4337, 75.043594, 20.0679, -10.4337, 78.3101, 20.0679, -10.4337, 75.043594, 23.412498, -10.4337, 71.8361, 23.412498, -10.4337, 75.043594, 20.0679, -10.4337, 75.043594, 23.412498, -10.4337, 75.043594, 23.412498, -10.4337, 78.3101, 20.0679, -10.4337, 78.3101, 23.412498, -10.4337, 65.2334, 26.7582, -10.4337, 68.237495, 23.412498, -10.4337, 68.237495, 26.7582, -10.4337, 68.237495, 23.412498, -10.4337, 71.8361, 23.412498, -10.4337, 68.237495, 23.412498, -10.4337, 65.2334, 26.7582, -10.4337, 65.2334, 26.7582, -10.4337, 68.237495, 26.7582, -10.4337, 71.8361, 23.412498, -10.4337, 75.043594, 23.412498, -10.4337, 71.8361, 26.7582, -10.4337, 68.237495, 26.7582, -10.4337, 71.8361, 23.412498, -10.4337, 71.8361, 26.7582, -10.4337, 75.043594, 23.412498, -10.4337, 78.3101, 23.412498, -10.4337, 75.043594, 26.7582, -10.4337, 71.8361, 26.7582, -10.4337, 75.043594, 23.412498, -10.4337, 75.043594, 26.7582, -10.4337, 75.043594, 26.7582, -10.4337, 78.3101, 23.412498, -10.4337, 78.3101, 26.7582, -10.4337, 75.043594, 75.8818, -10.4337, 26.7572, 26.7582, -10.4337, 78.3101, 26.7582, -10.4337, 71.8361, 75.8818, -10.4337, 26.7572, 26.7582, -10.4337, 75.043594, 26.7582, -10.4337, 78.3101, 75.8818, -10.4337, 26.7572, 79.236, -10.4337, 26.7572, 79.236, -10.4337, 23.412498, 79.236, -10.4337, 26.7572, 75.8818, -10.4337, 26.7572, 71.9379, -10.4337, 26.7572, 26.7582, -10.4337, 71.8361, 26.7582, -10.4337, 68.237495, 75.8818, -10.4337, 26.7572, 26.7582, -10.4337, 71.8361, 71.9379, -10.4337, 26.7572, 68.9355, -10.4337, 26.7572, 26.7582, -10.4337, 68.237495, 26.7582, -10.4337, 65.2334, 71.9379, -10.4337, 26.7572, 26.7582, -10.4337, 68.237495, 68.9355, -10.4337, 26.7572, 68.9355, -10.4337, 26.7572, 26.7582, -10.4337, 65.2334, 66.1166, -10.4337, 26.7572, 68.9355, -10.4337, 26.7572, 66.1166, -10.4337, 26.7572, 66.1166, -10.4337, 23.412498, 68.9355, -10.4337, 26.7572, 66.1166, -10.4337, 23.412498, 68.937, -10.4337, 23.412498, 71.9379, -10.4337, 26.7572, 68.9355, -10.4337, 26.7572, 68.937, -10.4337, 23.412498, 68.937, -10.4337, 23.412498, 66.1166, -10.4337, 23.412498, 66.1166, -10.4337, 20.0679, 75.8818, -10.4337, 26.7572, 71.9379, -10.4337, 26.7572, 71.9555, -10.4337, 23.412498, 71.9379, -10.4337, 26.7572, 68.937, -10.4337, 23.412498, 71.9555, -10.4337, 23.412498, 79.236, -10.4337, 23.412498, 75.8818, -10.4337, 26.7572, 75.8708, -10.4337, 23.412498, 75.8818, -10.4337, 26.7572, 71.9555, -10.4337, 23.412498, 75.8708, -10.4337, 23.412498, 79.236, -10.4337, 20.0679, 79.236, -10.4337, 23.412498, 75.8708, -10.4337, 23.412498, 68.937, -10.4337, 23.412498, 66.1166, -10.4337, 20.0679, 68.9385, -10.4337, 20.0679, 71.9555, -10.4337, 23.412498, 68.937, -10.4337, 23.412498, 68.9385, -10.4337, 20.0679, 68.9385, -10.4337, 20.0679, 66.1166, -10.4337, 20.0679, 66.1166, -10.4337, 16.7232, 75.8708, -10.4337, 23.412498, 71.9555, -10.4337, 23.412498, 71.9732, -10.4337, 20.0679, 71.9555, -10.4337, 23.412498, 68.9385, -10.4337, 20.0679, 71.9732, -10.4337, 20.0679, 79.236, -10.4337, 20.0679, 75.8708, -10.4337, 23.412498, 75.859795, -10.4337, 20.0679, 75.8708, -10.4337, 23.412498, 71.9732, -10.4337, 20.0679, 75.859795, -10.4337, 20.0679, 79.236, -10.4337, 16.7232, 79.236, -10.4337, 20.0679, 75.859795, -10.4337, 20.0679, 68.9385, -10.4337, 20.0679, 66.1166, -10.4337, 16.7232, 68.9401, -10.4337, 16.7232, 71.9732, -10.4337, 20.0679, 68.9385, -10.4337, 20.0679, 68.9401, -10.4337, 16.7232, 68.9401, -10.4337, 16.7232, 66.1166, -10.4337, 16.7232, 66.1166, -10.4337, 13.378601, 75.859795, -10.4337, 20.0679, 71.9732, -10.4337, 20.0679, 71.9908, -10.4337, 16.7232, 71.9732, -10.4337, 20.0679, 68.9401, -10.4337, 16.7232, 71.9908, -10.4337, 16.7232, 79.236, -10.4337, 16.7232, 75.859795, -10.4337, 20.0679, 75.8488, -10.4337, 16.7232, 75.859795, -10.4337, 20.0679, 71.9908, -10.4337, 16.7232, 75.8488, -10.4337, 16.7232, 79.236, -10.4337, 13.378601, 79.236, -10.4337, 16.7232, 75.8488, -10.4337, 16.7232, 68.9401, -10.4337, 16.7232, 66.1166, -10.4337, 13.378601, 68.9416, -10.4337, 13.378601, 71.9908, -10.4337, 16.7232, 68.9401, -10.4337, 16.7232, 68.9416, -10.4337, 13.378601, 68.9416, -10.4337, 13.378601, 66.1166, -10.4337, 13.378601, 66.1166, -10.4337, 10.033899, 75.8488, -10.4337, 16.7232, 71.9908, -10.4337, 16.7232, 72.0085, -10.4337, 13.378601, 71.9908, -10.4337, 16.7232, 68.9416, -10.4337, 13.378601, 72.0085, -10.4337, 13.378601, 79.236, -10.4337, 13.378601, 75.8488, -10.4337, 16.7232, 75.8377, -10.4337, 13.378601, 75.8488, -10.4337, 16.7232, 72.0085, -10.4337, 13.378601, 75.8377, -10.4337, 13.378601, 79.236, -10.4337, 10.033899, 79.236, -10.4337, 13.378601, 75.8377, -10.4337, 13.378601, 68.9416, -10.4337, 13.378601, 66.1166, -10.4337, 10.033899, 68.9432, -10.4337, 10.033899, 72.0085, -10.4337, 13.378601, 68.9416, -10.4337, 13.378601, 68.9432, -10.4337, 10.033899, 68.9432, -10.4337, 10.033899, 66.1166, -10.4337, 10.033899, 66.1166, -10.4337, 6.6893, 75.8377, -10.4337, 13.378601, 72.0085, -10.4337, 13.378601, 72.0261, -10.4337, 10.033899, 72.0085, -10.4337, 13.378601, 68.9432, -10.4337, 10.033899, 72.0261, -10.4337, 10.033899, 79.236, -10.4337, 10.033899, 75.8377, -10.4337, 13.378601, 75.8267, -10.4337, 10.033899, 75.8377, -10.4337, 13.378601, 72.0261, -10.4337, 10.033899, 75.8267, -10.4337, 10.033899, 79.236, -10.4337, 6.6893, 79.236, -10.4337, 10.033899, 75.8267, -10.4337, 10.033899, 68.9432, -10.4337, 10.033899, 66.1166, -10.4337, 6.6893, 68.944695, -10.4337, 6.6893, 72.0261, -10.4337, 10.033899, 68.9432, -10.4337, 10.033899, 68.944695, -10.4337, 6.6893, 68.944695, -10.4337, 6.6893, 66.1166, -10.4337, 6.6893, 66.1166, -10.4337, 3.3446, 75.8267, -10.4337, 10.033899, 72.0261, -10.4337, 10.033899, 72.0437, -10.4337, 6.6893, 72.0261, -10.4337, 10.033899, 68.944695, -10.4337, 6.6893, 72.0437, -10.4337, 6.6893, 79.236, -10.4337, 6.6893, 75.8267, -10.4337, 10.033899, 75.8157, -10.4337, 6.6893, 75.8267, -10.4337, 10.033899, 72.0437, -10.4337, 6.6893, 75.8157, -10.4337, 6.6893, 79.236, -10.4337, 3.3446, 79.236, -10.4337, 6.6893, 75.8157, -10.4337, 6.6893, 68.944695, -10.4337, 6.6893, 66.1166, -10.4337, 3.3446, 68.9463, -10.4337, 3.3446, 72.0437, -10.4337, 6.6893, 68.944695, -10.4337, 6.6893, 68.9463, -10.4337, 3.3446, 68.9463, -10.4337, 3.3446, 66.1166, -10.4337, 3.3446, 66.1166, -10.4337, 0, 75.8157, -10.4337, 6.6893, 72.0437, -10.4337, 6.6893, 72.0614, -10.4337, 3.3446, 72.0437, -10.4337, 6.6893, 68.9463, -10.4337, 3.3446, 72.0614, -10.4337, 3.3446, 79.236, -10.4337, 3.3446, 75.8157, -10.4337, 6.6893, 75.804695, -10.4337, 3.3446, 75.8157, -10.4337, 6.6893, 72.0614, -10.4337, 3.3446, 75.804695, -10.4337, 3.3446, 79.236, -10.4337, 0, 79.236, -10.4337, 3.3446, 75.804695, -10.4337, 3.3446, 68.9463, -10.4337, 3.3446, 66.1166, -10.4337, 0, 68.9478, -10.4337, 0, 72.0614, -10.4337, 3.3446, 68.9463, -10.4337, 3.3446, 68.9478, -10.4337, 0, 68.9478, -10.4337, 0, 66.1166, -10.4337, 0, 66.1166, -10.4337, -3.3446002, 75.804695, -10.4337, 3.3446, 72.0614, -10.4337, 3.3446, 72.078995, -10.4337, 0, 72.0614, -10.4337, 3.3446, 68.9478, -10.4337, 0, 72.078995, -10.4337, 0, 79.236, -10.4337, 0, 75.804695, -10.4337, 3.3446, 75.793594, -10.4337, 0, 75.804695, -10.4337, 3.3446, 72.078995, -10.4337, 0, 75.793594, -10.4337, 0, 79.236, -10.4337, -3.3446002, 79.236, -10.4337, 0, 75.793594, -10.4337, 0, 68.9478, -10.4337, 0, 66.1166, -10.4337, -3.3446002, 68.9494, -10.4337, -3.3446002, 72.078995, -10.4337, 0, 68.9478, -10.4337, 0, 68.9494, -10.4337, -3.3446002, 68.9494, -10.4337, -3.3446002, 66.1166, -10.4337, -3.3446002, 66.1166, -10.4337, -6.6893, 75.793594, -10.4337, 0, 72.078995, -10.4337, 0, 72.096695, -10.4337, -3.3446002, 72.078995, -10.4337, 0, 68.9494, -10.4337, -3.3446002, 72.096695, -10.4337, -3.3446002, 79.236, -10.4337, -3.3446002, 75.793594, -10.4337, 0, 75.7826, -10.4337, -3.3446002, 75.793594, -10.4337, 0, 72.096695, -10.4337, -3.3446002, 75.7826, -10.4337, -3.3446002, 79.236, -10.4337, -6.6893, 79.236, -10.4337, -3.3446002, 75.7826, -10.4337, -3.3446002, 68.9494, -10.4337, -3.3446002, 66.1166, -10.4337, -6.6893, 68.9509, -10.4337, -6.6893, 72.096695, -10.4337, -3.3446002, 68.9494, -10.4337, -3.3446002, 68.9509, -10.4337, -6.6893, 68.9509, -10.4337, -6.6893, 66.1166, -10.4337, -6.6893, 66.1166, -10.4337, -10.033899, 75.7826, -10.4337, -3.3446002, 72.096695, -10.4337, -3.3446002, 72.114296, -10.4337, -6.6893, 72.096695, -10.4337, -3.3446002, 68.9509, -10.4337, -6.6893, 72.114296, -10.4337, -6.6893, 79.236, -10.4337, -6.6893, 75.7826, -10.4337, -3.3446002, 75.7716, -10.4337, -6.6893, 75.7826, -10.4337, -3.3446002, 72.114296, -10.4337, -6.6893, 75.7716, -10.4337, -6.6893, 79.236, -10.4337, -10.033899, 79.236, -10.4337, -6.6893, 75.7716, -10.4337, -6.6893, 68.9509, -10.4337, -6.6893, 66.1166, -10.4337, -10.033899, 68.9524, -10.4337, -10.033899, 72.114296, -10.4337, -6.6893, 68.9509, -10.4337, -6.6893, 68.9524, -10.4337, -10.033899, 68.9524, -10.4337, -10.033899, 66.1166, -10.4337, -10.033899, 66.1166, -10.4337, -13.378599, 75.7716, -10.4337, -6.6893, 72.114296, -10.4337, -6.6893, 72.1319, -10.4337, -10.033899, 72.114296, -10.4337, -6.6893, 68.9524, -10.4337, -10.033899, 72.1319, -10.4337, -10.033899, 79.236, -10.4337, -10.033899, 75.7716, -10.4337, -6.6893, 75.7606, -10.4337, -10.033899, 75.7716, -10.4337, -6.6893, 72.1319, -10.4337, -10.033899, 75.7606, -10.4337, -10.033899, 79.236, -10.4337, -13.378599, 79.236, -10.4337, -10.033899, 75.7606, -10.4337, -10.033899, 68.9524, -10.4337, -10.033899, 66.1166, -10.4337, -13.378599, 68.953995, -10.4337, -13.378599, 72.1319, -10.4337, -10.033899, 68.9524, -10.4337, -10.033899, 68.953995, -10.4337, -13.378599, 68.953995, -10.4337, -13.378599, 66.1166, -10.4337, -13.378599, 66.1166, -10.4337, -16.7232, 75.7606, -10.4337, -10.033899, 72.1319, -10.4337, -10.033899, 72.1496, -10.4337, -13.378599, 72.1319, -10.4337, -10.033899, 68.953995, -10.4337, -13.378599, 72.1496, -10.4337, -13.378599, 79.236, -10.4337, -13.378599, 75.7606, -10.4337, -10.033899, 75.749596, -10.4337, -13.378599, 75.7606, -10.4337, -10.033899, 72.1496, -10.4337, -13.378599, 75.749596, -10.4337, -13.378599, 79.236, -10.4337, -16.7232, 79.236, -10.4337, -13.378599, 75.749596, -10.4337, -13.378599, 68.953995, -10.4337, -13.378599, 66.1166, -10.4337, -16.7232, 68.9555, -10.4337, -16.7232, 72.1496, -10.4337, -13.378599, 68.953995, -10.4337, -13.378599, 68.9555, -10.4337, -16.7232, 68.9555, -10.4337, -16.7232, 66.1166, -10.4337, -16.7232, 66.1166, -10.4337, -20.0679, 75.749596, -10.4337, -13.378599, 72.1496, -10.4337, -13.378599, 72.1672, -10.4337, -16.7232, 72.1496, -10.4337, -13.378599, 68.9555, -10.4337, -16.7232, 72.1672, -10.4337, -16.7232, 79.236, -10.4337, -16.7232, 75.749596, -10.4337, -13.378599, 75.738495, -10.4337, -16.7232, 75.749596, -10.4337, -13.378599, 72.1672, -10.4337, -16.7232, 75.738495, -10.4337, -16.7232, 79.236, -10.4337, -20.0679, 79.236, -10.4337, -16.7232, 75.738495, -10.4337, -16.7232, 68.9555, -10.4337, -16.7232, 66.1166, -10.4337, -20.0679, 68.9571, -10.4337, -20.0679, 72.1672, -10.4337, -16.7232, 68.9555, -10.4337, -16.7232, 68.9571, -10.4337, -20.0679, 68.9571, -10.4337, -20.0679, 66.1166, -10.4337, -20.0679, 66.1166, -10.4337, -23.412498, 68.9571, -10.4337, -20.0679, 66.1166, -10.4337, -23.412498, 68.958595, -10.4337, -23.412498, 72.1672, -10.4337, -16.7232, 68.9571, -10.4337, -20.0679, 72.1849, -10.4337, -20.0679, 72.1849, -10.4337, -20.0679, 68.9571, -10.4337, -20.0679, 68.958595, -10.4337, -23.412498, 75.738495, -10.4337, -16.7232, 72.1672, -10.4337, -16.7232, 72.1849, -10.4337, -20.0679, 72.1849, -10.4337, -20.0679, 68.958595, -10.4337, -23.412498, 72.2025, -10.4337, -23.412498, 79.236, -10.4337, -20.0679, 75.738495, -10.4337, -16.7232, 75.7275, -10.4337, -20.0679, 75.738495, -10.4337, -16.7232, 72.1849, -10.4337, -20.0679, 75.7275, -10.4337, -20.0679, 75.7275, -10.4337, -20.0679, 72.1849, -10.4337, -20.0679, 72.2025, -10.4337, -23.412498, 79.236, -10.4337, -23.412498, 79.236, -10.4337, -20.0679, 75.7275, -10.4337, -20.0679, 75.7275, -10.4337, -20.0679, 72.2025, -10.4337, -23.412498, 75.7165, -10.4337, -23.412498, 79.236, -10.4337, -23.412498, 75.7275, -10.4337, -20.0679, 75.7165, -10.4337, -23.412498, -38.5239, -3.6573, 10.033899, -41.627, -4.8403997, 6.6893, -38.5239, -3.6573, 6.6893, -38.5239, -3.6573, 10.033899, -38.5239, -3.6573, 13.378601, -41.627, -4.8403997, 6.6893, -41.627, -4.8403997, 3.3446, -38.5239, -3.6573, 6.6893, -41.627, -4.8403997, 6.6893, -41.627, -4.8403997, 3.3446, -38.5239, -3.6573, 3.3446, -38.5239, -3.6573, 6.6893, -41.627, -4.8403997, 6.6893, -38.5239, -3.6573, 13.378601, -41.627, -4.8403997, 13.378601, -41.627, -4.8403997, 0, -38.5239, -3.6573, 3.3446, -41.627, -4.8403997, 3.3446, -41.627, -4.8403997, 0, -38.5239, -3.6573, 0, -38.5239, -3.6573, 3.3446, -44.537098, -5.95, 3.3446, -41.627, -4.8403997, 3.3446, -41.627, -4.8403997, 6.6893, -41.627, -4.8403997, -3.3446002, -38.5239, -3.6573, 0, -41.627, -4.8403997, 0, -41.627, -4.8403997, -3.3446002, -38.5239, -3.6573, -3.3446002, -38.5239, -3.6573, 0, -44.537098, -5.95, 0, -41.627, -4.8403997, 0, -41.627, -4.8403997, 3.3446, -44.537098, -5.95, 0, -41.627, -4.8403997, 3.3446, -44.537098, -5.95, 3.3446, -44.537098, -5.95, -3.3446002, -41.627, -4.8403997, -3.3446002, -41.627, -4.8403997, 0, -44.537098, -5.95, -3.3446002, -41.627, -4.8403997, 0, -44.537098, -5.95, 0, -41.627, -4.8403997, -6.6893, -38.5239, -3.6573, -3.3446002, -41.627, -4.8403997, -3.3446002, -41.627, -4.8403997, -6.6893, -38.5239, -3.6573, -6.6893, -38.5239, -3.6573, -3.3446002, -44.537098, -5.95, -6.6893, -41.627, -4.8403997, -3.3446002, -44.537098, -5.95, -3.3446002, -44.537098, -5.95, -6.6893, -41.627, -4.8403997, -6.6893, -41.627, -4.8403997, -3.3446002, -41.627, -4.8403997, -10.033899, -38.5239, -3.6573, -6.6893, -41.627, -4.8403997, -6.6893, -41.627, -4.8403997, -10.033899, -38.5239, -3.6573, -10.033899, -38.5239, -3.6573, -6.6893, -44.537098, -5.95, -10.033899, -41.627, -4.8403997, -6.6893, -44.537098, -5.95, -6.6893, -44.537098, -5.95, -10.033899, -41.627, -4.8403997, -10.033899, -41.627, -4.8403997, -6.6893, -41.627, -4.8403997, -13.378599, -38.5239, -3.6573, -10.033899, -41.627, -4.8403997, -10.033899, -41.627, -4.8403997, -13.378599, -38.5239, -3.6573, -13.378599, -38.5239, -3.6573, -10.033899, -41.627, -4.8403997, -13.378599, -38.5239, -3.6573, -16.7232, -38.5239, -3.6573, -13.378599, -41.627, -4.8403997, -13.378599, -38.5239, -3.6573, -17.0441, -38.5239, -3.6573, -16.7232, -38.5239, -3.6573, -17.0441, -41.627, -4.8403997, -13.378599, -41.627, -4.8403997, -17.0159, -41.627, -4.8403997, -17.0159, -38.5239, -3.6573, -20.0679, -38.5239, -3.6573, -17.0441, -44.537098, -5.95, -13.378599, -41.627, -4.8403997, -13.378599, -41.627, -4.8403997, -10.033899, -44.537098, -5.95, -13.378599, -41.627, -4.8403997, -10.033899, -44.537098, -5.95, -10.033899, -41.627, -4.8403997, -17.0159, -38.5239, -3.6573, -20.3888, -38.5239, -3.6573, -20.0679, -44.537098, -5.95, -16.9895, -41.627, -4.8403997, -13.378599, -44.537098, -5.95, -13.378599, -44.537098, -5.95, -16.9895, -41.627, -4.8403997, -17.0159, -41.627, -4.8403997, -13.378599, -47.4473, -7.0596, -13.378599, -44.537098, -5.95, -13.378599, -44.537098, -5.95, -10.033899, -47.4473, -7.0596, -16.963, -44.537098, -5.95, -16.9895, -44.537098, -5.95, -13.378599, -47.4473, -7.0596, -16.963, -44.537098, -5.95, -13.378599, -47.4473, -7.0596, -13.378599, -44.537098, -5.95, -20.334099, -41.627, -4.8403997, -17.0159, -44.537098, -5.95, -16.9895, -38.5239, -3.6573, -20.3888, -41.627, -4.8403997, -17.0159, -41.627, -4.8403997, -20.3606, -44.537098, -5.95, -20.334099, -41.627, -4.8403997, -20.3606, -41.627, -4.8403997, -17.0159, -41.627, -4.8403997, -23.412498, -38.5239, -3.6573, -20.3888, -41.627, -4.8403997, -20.3606, -41.627, -4.8403997, -23.412498, -38.5239, -3.6573, -23.412498, -38.5239, -3.6573, -20.3888, -41.627, -4.8403997, -26.7572, -38.5239, -3.6573, -23.412498, -41.627, -4.8403997, -23.412498, -41.627, -4.8403997, -26.7572, -38.5239, -3.6573, -26.7572, -38.5239, -3.6573, -23.412498, -44.537098, -5.95, -26.7572, -41.627, -4.8403997, -26.7572, -41.627, -4.8403997, -23.412498, -44.537098, -5.95, -23.412498, -41.627, -4.8403997, -23.412498, -41.627, -4.8403997, -20.3606, -44.537098, -5.95, -26.7572, -41.627, -4.8403997, -23.412498, -44.537098, -5.95, -23.412498, -44.537098, -5.95, -23.412498, -41.627, -4.8403997, -20.3606, -44.537098, -5.95, -20.334099, -47.4473, -7.0596, -26.7572, -44.537098, -5.95, -26.7572, -44.537098, -5.95, -23.412498, -47.4473, -7.0596, -23.412498, -44.537098, -5.95, -23.412498, -44.537098, -5.95, -20.334099, -47.4473, -7.0596, -26.7572, -44.537098, -5.95, -23.412498, -47.4473, -7.0596, -23.412498, -50.290497, -8.1437, -23.412498, -47.4473, -7.0596, -26.7572, -47.4473, -7.0596, -23.412498, -50.290497, -8.1437, -23.412498, -50.290497, -8.1437, -26.7572, -47.4473, -7.0596, -26.7572, -50.290497, -8.1437, -20.2818, -50.290497, -8.1437, -23.412498, -47.4473, -7.0596, -23.412498, -47.4473, -7.0596, -23.412498, -44.537098, -5.95, -20.334099, -47.4473, -7.0596, -20.3077, -50.290497, -8.1437, -20.2818, -47.4473, -7.0596, -23.412498, -47.4473, -7.0596, -20.3077, -47.4473, -7.0596, -20.3077, -44.537098, -5.95, -20.334099, -44.537098, -5.95, -16.9895, -47.4473, -7.0596, -20.3077, -44.537098, -5.95, -16.9895, -47.4473, -7.0596, -16.963, -47.4473, -7.0596, -16.963, -50.290497, -8.1437, -20.2818, -47.4473, -7.0596, -20.3077, -47.4473, -7.0596, -16.963, -50.290497, -8.1437, -20.0679, -50.290497, -8.1437, -20.2818, -50.290497, -8.1437, -20.0679, -47.4473, -7.0596, -16.963, -50.290497, -8.1437, -16.937199, -47.4473, -7.0596, -13.378599, -50.290497, -8.1437, -16.937199, -47.4473, -7.0596, -16.963, -47.4473, -7.0596, -13.378599, -50.290497, -8.1437, -16.7232, -50.290497, -8.1437, -16.937199, -50.290497, -8.1437, -16.7232, -47.4473, -7.0596, -13.378599, -50.290497, -8.1437, -13.378599, -50.290497, -8.1437, -10.033899, -50.290497, -8.1437, -13.378599, -47.4473, -7.0596, -13.378599, -50.290497, -8.1437, -10.033899, -47.4473, -7.0596, -13.378599, -47.4473, -7.0596, -10.033899, -47.4473, -7.0596, -13.378599, -44.537098, -5.95, -10.033899, -47.4473, -7.0596, -10.033899, -50.290497, -8.1437, -6.6893, -50.290497, -8.1437, -10.033899, -47.4473, -7.0596, -10.033899, -47.4473, -7.0596, -10.033899, -44.537098, -5.95, -10.033899, -44.537098, -5.95, -6.6893, -50.290497, -8.1437, -6.6893, -47.4473, -7.0596, -10.033899, -47.4473, -7.0596, -6.6893, -47.4473, -7.0596, -10.033899, -44.537098, -5.95, -6.6893, -47.4473, -7.0596, -6.6893, -50.290497, -8.1437, -3.3446002, -50.290497, -8.1437, -6.6893, -47.4473, -7.0596, -6.6893, -47.4473, -7.0596, -6.6893, -44.537098, -5.95, -6.6893, -44.537098, -5.95, -3.3446002, -50.290497, -8.1437, -3.3446002, -47.4473, -7.0596, -6.6893, -47.4473, -7.0596, -3.3446002, -47.4473, -7.0596, -6.6893, -44.537098, -5.95, -3.3446002, -47.4473, -7.0596, -3.3446002, -50.290497, -8.1437, 0, -50.290497, -8.1437, -3.3446002, -47.4473, -7.0596, -3.3446002, -47.4473, -7.0596, -3.3446002, -44.537098, -5.95, -3.3446002, -44.537098, -5.95, 0, -50.290497, -8.1437, 0, -47.4473, -7.0596, -3.3446002, -47.4473, -7.0596, 0, -47.4473, -7.0596, -3.3446002, -44.537098, -5.95, 0, -47.4473, -7.0596, 0, -50.290497, -8.1437, 3.3446, -50.290497, -8.1437, 0, -47.4473, -7.0596, 0, -47.4473, -7.0596, 0, -44.537098, -5.95, 0, -44.537098, -5.95, 3.3446, -50.290497, -8.1437, 3.3446, -47.4473, -7.0596, 0, -47.4473, -7.0596, 3.3446, -47.4473, -7.0596, 0, -44.537098, -5.95, 3.3446, -47.4473, -7.0596, 3.3446, -50.290497, -8.1437, 6.6893, -50.290497, -8.1437, 3.3446, -47.4473, -7.0596, 3.3446, -50.290497, -8.1437, 6.6893, -47.4473, -7.0596, 3.3446, -47.4473, -7.0596, 6.6893, -47.4473, -7.0596, 6.6893, -50.290497, -8.1437, 10.033899, -50.290497, -8.1437, 6.6893, -47.4473, -7.0596, 3.3446, -44.537098, -5.95, 3.3446, -44.537098, -5.95, 6.6893, -47.4473, -7.0596, 3.3446, -44.537098, -5.95, 6.6893, -47.4473, -7.0596, 6.6893, -44.537098, -5.95, 3.3446, -41.627, -4.8403997, 6.6893, -44.537098, -5.95, 6.6893, -47.4473, -7.0596, 6.6893, -50.290497, -8.1437, 13.378601, -50.290497, -8.1437, 10.033899, -41.627, -4.8403997, 13.378601, -44.537098, -5.95, 6.6893, -41.627, -4.8403997, 6.6893, -44.537098, -5.95, 13.378601, -47.4473, -7.0596, 6.6893, -44.537098, -5.95, 6.6893, -41.627, -4.8403997, 13.378601, -44.537098, -5.95, 13.378601, -44.537098, -5.95, 6.6893, -44.537098, -5.95, 13.378601, -47.4473, -7.0596, 13.378601, -47.4473, -7.0596, 6.6893, -50.290497, -8.1437, 13.378601, -47.4473, -7.0596, 6.6893, -47.4473, -7.0596, 13.378601, -41.627, -4.8403997, 16.7232, -44.537098, -5.95, 13.378601, -41.627, -4.8403997, 13.378601, -38.5239, -3.6573, 13.378601, -41.627, -4.8403997, 16.7232, -41.627, -4.8403997, 13.378601, -38.5239, -3.6573, 13.378601, -38.5239, -3.6573, 16.7232, -41.627, -4.8403997, 16.7232, -41.627, -4.8403997, 16.7232, -44.537098, -5.95, 16.7232, -44.537098, -5.95, 13.378601, -44.537098, -5.95, 16.7232, -47.4473, -7.0596, 13.378601, -44.537098, -5.95, 13.378601, -38.5239, -3.6573, 16.7232, -41.627, -4.8403997, 20.0679, -41.627, -4.8403997, 16.7232, -41.627, -4.8403997, 20.0679, -44.537098, -5.95, 16.7232, -41.627, -4.8403997, 16.7232, -38.5239, -3.6573, 16.7232, -38.5239, -3.6573, 20.0679, -41.627, -4.8403997, 20.0679, -47.4473, -7.0596, 16.7232, -50.290497, -8.1437, 13.378601, -47.4473, -7.0596, 13.378601, -44.537098, -5.95, 16.7232, -47.4473, -7.0596, 16.7232, -47.4473, -7.0596, 13.378601, -47.4473, -7.0596, 16.7232, -50.290497, -8.1437, 16.7232, -50.290497, -8.1437, 13.378601, -41.627, -4.8403997, 20.0679, -44.537098, -5.95, 20.0679, -44.537098, -5.95, 16.7232, -44.537098, -5.95, 20.0679, -47.4473, -7.0596, 16.7232, -44.537098, -5.95, 16.7232, -38.5239, -3.6573, 20.0679, -41.627, -4.8403997, 23.412498, -41.627, -4.8403997, 20.0679, -41.627, -4.8403997, 23.412498, -44.537098, -5.95, 20.0679, -41.627, -4.8403997, 20.0679, -38.5239, -3.6573, 20.0679, -38.5239, -3.6573, 23.412498, -41.627, -4.8403997, 23.412498, -38.5239, -3.6573, 23.412498, -41.627, -4.8403997, 26.7572, -41.627, -4.8403997, 23.412498, -38.5239, -3.6573, 23.412498, -38.5239, -3.6573, 26.7572, -41.627, -4.8403997, 26.7572, -41.627, -4.8403997, 26.7572, -44.537098, -5.95, 23.412498, -41.627, -4.8403997, 23.412498, -41.627, -4.8403997, 23.412498, -44.537098, -5.95, 23.412498, -44.537098, -5.95, 20.0679, -41.627, -4.8403997, 26.7572, -44.537098, -5.95, 26.7572, -44.537098, -5.95, 23.412498, -44.537098, -5.95, 20.0679, -47.4473, -7.0596, 20.0679, -47.4473, -7.0596, 16.7232, -47.4473, -7.0596, 20.0679, -50.290497, -8.1437, 16.7232, -47.4473, -7.0596, 16.7232, -44.537098, -5.95, 23.412498, -47.4473, -7.0596, 20.0679, -44.537098, -5.95, 20.0679, -47.4473, -7.0596, 20.0679, -50.290497, -8.1437, 20.0679, -50.290497, -8.1437, 16.7232, -44.537098, -5.95, 26.7572, -47.4473, -7.0596, 23.412498, -44.537098, -5.95, 23.412498, -44.537098, -5.95, 23.412498, -47.4473, -7.0596, 23.412498, -47.4473, -7.0596, 20.0679, -47.4473, -7.0596, 23.412498, -50.290497, -8.1437, 20.0679, -47.4473, -7.0596, 20.0679, -44.537098, -5.95, 26.7572, -47.4473, -7.0596, 26.7572, -47.4473, -7.0596, 23.412498, -47.4473, -7.0596, 23.412498, -50.290497, -8.1437, 23.412498, -50.290497, -8.1437, 20.0679, -47.4473, -7.0596, 26.7572, -50.290497, -8.1437, 23.412498, -47.4473, -7.0596, 23.412498, -47.4473, -7.0596, 26.7572, -50.290497, -8.1437, 26.7572, -50.290497, -8.1437, 23.412498, -6.6893, -8.1437, -54.500298, -3.4038, -8.6382, -57.495697, -3.4199996, -8.1437, -54.500298, -3.4038, -8.6382, -57.495697, -3.3446002, -8.1437, -54.500298, -3.4199996, -8.1437, -54.500298, -6.6893, -8.1437, -54.500298, -6.7919, -8.1437, -54.500298, -3.4038, -8.6382, -57.495697, -3.4038, -8.6382, -57.495697, -0.048199892, -8.1437, -54.500298, -3.3446002, -8.1437, -54.500298, -3.4038, -8.6382, -57.495697, -6.7919, -8.1437, -54.500298, -6.7697997, -8.6367, -57.4865, -10.033899, -8.1437, -54.500298, -6.7697997, -8.6367, -57.4865, -6.7919, -8.1437, -54.500298, -0.048199892, -8.1437, -54.500298, -3.4038, -8.6382, -57.495697, -0.037699938, -8.6397, -57.504997, -6.7697997, -8.6367, -57.4865, -10.033899, -8.1437, -54.500298, -10.141901, -8.1437, -54.500298, -0.037699938, -8.6397, -57.504997, 0, -8.1437, -54.500298, -0.048199892, -8.1437, -54.500298, -6.7697997, -8.6367, -57.4865, -10.141901, -8.1437, -54.500298, -10.1187, -8.635099, -57.4772, -13.378601, -8.1437, -54.500298, -10.1187, -8.635099, -57.4772, -10.141901, -8.1437, -54.500298, -0.037699938, -8.6397, -57.504997, 3.3446, -8.1437, -54.500298, 0, -8.1437, -54.500298, -10.1187, -8.635099, -57.4772, -13.378601, -8.1437, -54.500298, -13.4286, -8.1437, -54.500298, 3.3446, -8.1437, -54.500298, -0.037699938, -8.6397, -57.504997, 3.3446, -8.6413, -57.514297, -10.1187, -8.635099, -57.4772, -6.749, -9.1004, -60.295498, -6.7697997, -8.6367, -57.4865, 6.6893, -8.642799, -57.5235, 3.3446, -8.1437, -54.500298, 3.3446, -8.6413, -57.514297, 6.6893, -8.642799, -57.5235, 6.6893, -8.1437, -54.500298, 3.3446, -8.1437, -54.500298, 3.3446, -9.0949, -60.262497, 3.3446, -8.6413, -57.514297, -0.037699938, -8.6397, -57.504997, 10.033899, -8.6442995, -57.5327, 6.6893, -8.1437, -54.500298, 6.6893, -8.642799, -57.5235, 10.033899, -8.6442995, -57.5327, 10.033899, -8.1437, -54.500298, 6.6893, -8.1437, -54.500298, 10.033899, -8.6442995, -57.5327, 13.378599, -8.1437, -54.500298, 10.033899, -8.1437, -54.500298, 10.033899, -8.6442995, -57.5327, 13.444599, -8.1437, -54.500298, 13.378599, -8.1437, -54.500298, 13.444599, -8.1437, -54.500298, 10.033899, -8.6442995, -57.5327, 13.4300995, -8.6458, -57.5421, 13.4300995, -8.6458, -57.5421, 16.7232, -8.1437, -54.500298, 13.444599, -8.1437, -54.500298, 13.4300995, -8.6458, -57.5421, 16.8188, -8.1437, -54.500298, 16.7232, -8.1437, -54.500298, 16.8188, -8.1437, -54.500298, 13.4300995, -8.6458, -57.5421, 16.7978, -8.6474, -57.5514, 16.7978, -8.6474, -57.5514, 20.0679, -8.1437, -54.500298, 16.8188, -8.1437, -54.500298, 16.7978, -8.6474, -57.5514, 20.1975, -8.1437, -54.500298, 20.0679, -8.1437, -54.500298, 20.1975, -8.1437, -54.500298, 16.7978, -8.6474, -57.5514, 20.1689, -8.6489, -57.5607, 20.1442, -9.085899, -60.207497, 20.1689, -8.6489, -57.5607, 16.7978, -8.6474, -57.5514, 20.1442, -9.085899, -60.207497, 16.7978, -8.6474, -57.5514, 16.7794, -9.0877, -60.2185, 16.7794, -9.0877, -60.2185, 16.7978, -8.6474, -57.5514, 13.4300995, -8.6458, -57.5421, 20.112099, -9.6529, -63.642, 20.1442, -9.085899, -60.207497, 16.7794, -9.0877, -60.2185, 16.7794, -9.0877, -60.2185, 13.4300995, -8.6458, -57.5421, 13.417299, -9.089499, -60.2295, 13.417299, -9.089499, -60.2295, 13.4300995, -8.6458, -57.5421, 10.033899, -8.6442995, -57.5327, 20.112099, -9.6529, -63.642, 16.7794, -9.0877, -60.2185, 16.7557, -9.6571, -63.6679, 16.7557, -9.6571, -63.6679, 16.7794, -9.0877, -60.2185, 13.417299, -9.089499, -60.2295, 16.7232, -10.4337, -68.371895, 20.112099, -9.6529, -63.642, 16.7557, -9.6571, -63.6679, 16.7232, -10.4337, -68.371895, 20.0679, -10.4337, -68.371895, 20.112099, -9.6529, -63.642, 13.378599, -10.4337, -68.371895, 16.7232, -10.4337, -68.371895, 16.7557, -9.6571, -63.6679, 13.378599, -10.4337, -68.371895, 16.7557, -9.6571, -63.6679, 13.400799, -9.6614, -63.693794, 16.7557, -9.6571, -63.6679, 13.417299, -9.089499, -60.2295, 13.400799, -9.6614, -63.693794, 10.033899, -10.4337, -68.371895, 13.378599, -10.4337, -68.371895, 13.400799, -9.6614, -63.693794, 13.417299, -9.089499, -60.2295, 10.033899, -8.6442995, -57.5327, 10.033899, -9.0913, -60.240597, 13.400799, -9.6614, -63.693794, 13.417299, -9.089499, -60.2295, 10.033899, -9.0913, -60.240597, 10.033899, -9.0913, -60.240597, 10.033899, -8.6442995, -57.5327, 6.6893, -8.642799, -57.5235, 10.033899, -10.4337, -68.371895, 13.400799, -9.6614, -63.693794, 10.033899, -9.6657, -63.719696, 13.400799, -9.6614, -63.693794, 10.033899, -9.0913, -60.240597, 10.033899, -9.6657, -63.719696, 6.6893, -10.4337, -68.371895, 10.033899, -10.4337, -68.371895, 10.033899, -9.6657, -63.719696, 10.033899, -9.0913, -60.240597, 6.6893, -8.642799, -57.5235, 6.6893, -9.0931, -60.2515, 10.033899, -9.6657, -63.719696, 10.033899, -9.0913, -60.240597, 6.6893, -9.0931, -60.2515, 6.6893, -9.0931, -60.2515, 6.6893, -8.642799, -57.5235, 3.3446, -8.6413, -57.514297, 6.6893, -10.4337, -68.371895, 10.033899, -9.6657, -63.719696, 6.6893, -9.6699, -63.7455, 10.033899, -9.6657, -63.719696, 6.6893, -9.0931, -60.2515, 6.6893, -9.6699, -63.7455, 3.3446, -10.4337, -68.371895, 6.6893, -10.4337, -68.371895, 6.6893, -9.6699, -63.7455, 6.6893, -9.0931, -60.2515, 3.3446, -8.6413, -57.514297, 3.3446, -9.0949, -60.262497, 6.6893, -9.6699, -63.7455, 6.6893, -9.0931, -60.2515, 3.3446, -9.0949, -60.262497, 3.3446, -10.4337, -68.371895, 6.6893, -9.6699, -63.7455, 3.3446, -9.6742, -63.771194, 6.6893, -9.6699, -63.7455, 3.3446, -9.0949, -60.262497, 3.3446, -9.6742, -63.771194, 0, -10.4337, -68.371895, 3.3446, -10.4337, -68.371895, 3.3446, -9.6742, -63.771194, 3.3446, -9.6742, -63.771194, 3.3446, -9.0949, -60.262497, -0.028100014, -9.0968, -60.2735, 3.3446, -9.0949, -60.262497, -0.037699938, -8.6397, -57.504997, -0.028100014, -9.0968, -60.2735, -0.028100014, -9.0968, -60.2735, -0.037699938, -8.6397, -57.504997, -3.4038, -8.6382, -57.495697, 0, -10.4337, -68.371895, 3.3446, -9.6742, -63.771194, -0.015899897, -9.6785, -63.797096, 3.3446, -9.6742, -63.771194, -0.028100014, -9.0968, -60.2735, -0.015899897, -9.6785, -63.797096, -3.3446002, -10.4337, -68.371895, 0, -10.4337, -68.371895, -0.015899897, -9.6785, -63.797096, -0.028100014, -9.0968, -60.2735, -3.4038, -8.6382, -57.495697, -3.3885999, -9.098599, -60.2845, -0.015899897, -9.6785, -63.797096, -0.028100014, -9.0968, -60.2735, -3.3885999, -9.098599, -60.2845, -6.7697997, -8.6367, -57.4865, -3.3885999, -9.098599, -60.2845, -3.4038, -8.6382, -57.495697, -6.7697997, -8.6367, -57.4865, -6.749, -9.1004, -60.295498, -3.3885999, -9.098599, -60.2845, -0.015899897, -9.6785, -63.797096, -3.3885999, -9.098599, -60.2845, -3.3694, -9.6827, -63.8229, -3.3446002, -10.4337, -68.371895, -0.015899897, -9.6785, -63.797096, -3.3694, -9.6827, -63.8229, -6.749, -9.1004, -60.295498, -3.3694, -9.6827, -63.8229, -3.3885999, -9.098599, -60.2845, -6.7226996, -9.686999, -63.848793, -3.3446002, -10.4337, -68.371895, -3.3694, -9.6827, -63.8229, -6.749, -9.1004, -60.295498, -6.7226996, -9.686999, -63.848793, -3.3694, -9.6827, -63.8229, -6.7226996, -9.686999, -63.848793, -6.6893, -10.4337, -68.371895, -3.3446002, -10.4337, -68.371895, -10.096701, -9.1022, -60.3065, -6.7226996, -9.686999, -63.848793, -6.749, -9.1004, -60.295498, -10.068901, -9.691199, -63.874596, -6.6893, -10.4337, -68.371895, -6.7226996, -9.686999, -63.848793, -10.096701, -9.1022, -60.3065, -10.068901, -9.691199, -63.874596, -6.7226996, -9.686999, -63.848793, -10.068901, -9.691199, -63.874596, -10.033899, -10.4337, -68.371895, -6.6893, -10.4337, -68.371895, -10.1187, -8.635099, -57.4772, -10.096701, -9.1022, -60.3065, -6.749, -9.1004, -60.295498, -13.394701, -9.695499, -63.9002, -10.033899, -10.4337, -68.371895, -10.068901, -9.691199, -63.874596, -13.394701, -9.695499, -63.9002, -13.378601, -10.4337, -68.371895, -10.033899, -10.4337, -68.371895, -13.4076, -9.104, -60.3173, -10.068901, -9.691199, -63.874596, -10.096701, -9.1022, -60.3065, -13.4076, -9.104, -60.3173, -13.394701, -9.695499, -63.9002, -10.068901, -9.691199, -63.874596, -13.4179, -8.6336, -57.468098, -10.096701, -9.1022, -60.3065, -10.1187, -8.635099, -57.4772, -13.4179, -8.6336, -57.468098, -13.4076, -9.104, -60.3173, -10.096701, -9.1022, -60.3065, -10.1187, -8.635099, -57.4772, -13.4286, -8.1437, -54.500298, -13.4179, -8.6336, -57.468098, -13.4286, -8.1437, -54.500298, -16.7232, -8.6321, -57.459, -13.4179, -8.6336, -57.468098, -16.7232, -8.6321, -57.459, -13.4076, -9.104, -60.3173, -13.4179, -8.6336, -57.468098, -13.4286, -8.1437, -54.500298, -16.7232, -8.1437, -54.500298, -16.7232, -8.6321, -57.459, -16.7232, -9.1058, -60.3281, -13.394701, -9.695499, -63.9002, -13.4076, -9.104, -60.3173, -16.7232, -8.6321, -57.459, -16.7232, -9.1058, -60.3281, -13.4076, -9.104, -60.3173, -16.7232, -9.699699, -63.925797, -13.378601, -10.4337, -68.371895, -13.394701, -9.695499, -63.9002, -16.7232, -9.1058, -60.3281, -16.7232, -9.699699, -63.925797, -13.394701, -9.695499, -63.9002, -16.7232, -9.699699, -63.925797, -16.7232, -10.4337, -68.371895, -13.378601, -10.4337, -68.371895, -16.7232, -8.1437, -54.500298, -20.0679, -8.6306, -57.4498, -16.7232, -8.6321, -57.459, -20.0679, -8.6306, -57.4498, -16.7232, -9.1058, -60.3281, -16.7232, -8.6321, -57.459, -16.7232, -8.1437, -54.500298, -20.0679, -8.1437, -54.500298, -20.0679, -8.6306, -57.4498, -20.0679, -9.1076, -60.3391, -16.7232, -9.699699, -63.925797, -16.7232, -9.1058, -60.3281, -20.0679, -8.6306, -57.4498, -20.0679, -9.1076, -60.3391, -16.7232, -9.1058, -60.3281, -20.0679, -9.7039995, -63.9516, -16.7232, -10.4337, -68.371895, -16.7232, -9.699699, -63.925797, -20.0679, -9.1076, -60.3391, -20.0679, -9.7039995, -63.9516, -16.7232, -9.699699, -63.925797, -20.0679, -9.7039995, -63.9516, -20.0679, -10.4337, -68.371895, -16.7232, -10.4337, -68.371895, -20.0679, -8.1437, -54.500298, -23.412498, -8.6291, -57.440598, -20.0679, -8.6306, -57.4498, -23.412498, -8.6291, -57.440598, -20.0679, -9.1076, -60.3391, -20.0679, -8.6306, -57.4498, -20.0679, -8.1437, -54.500298, -23.412498, -8.1437, -54.500298, -23.412498, -8.6291, -57.440598, -23.412498, -8.1437, -54.500298, -26.7572, -8.6276, -57.4314, -23.412498, -8.6291, -57.440598, -23.412498, -8.1437, -54.500298, -26.7572, -8.1437, -54.500298, -26.7572, -8.6276, -57.4314, -23.412498, -8.6291, -57.440598, -23.412498, -9.1094, -60.35, -20.0679, -9.1076, -60.3391, -26.7572, -8.6276, -57.4314, -23.412498, -9.1094, -60.35, -23.412498, -8.6291, -57.440598, -23.412498, -9.1094, -60.35, -20.0679, -9.7039995, -63.9516, -20.0679, -9.1076, -60.3391, -26.7572, -8.6276, -57.4314, -26.7572, -9.111199, -60.361, -23.412498, -9.1094, -60.35, -23.412498, -9.7081995, -63.977394, -20.0679, -10.4337, -68.371895, -20.0679, -9.7039995, -63.9516, -23.412498, -9.1094, -60.35, -23.412498, -9.7081995, -63.977394, -20.0679, -9.7039995, -63.9516, -26.7572, -9.111199, -60.361, -23.412498, -9.7081995, -63.977394, -23.412498, -9.1094, -60.35, -23.412498, -9.7081995, -63.977394, -23.412498, -10.4337, -68.371895, -20.0679, -10.4337, -68.371895, -26.7572, -9.111199, -60.361, -26.7572, -9.7125, -64.0031, -23.412498, -9.7081995, -63.977394, -26.7572, -9.7125, -64.0031, -23.412498, -10.4337, -68.371895, -23.412498, -9.7081995, -63.977394, -26.7572, -9.7125, -64.0031, -26.7572, -10.4337, -68.371895, -23.412498, -10.4337, -68.371895, -3.3446002, -10.4337, -68.371895, -0.0020999908, -10.5633, -70.6314, 0, -10.4337, -68.371895, -3.3446002, -10.4337, -68.371895, -3.3514, -10.5471, -70.669, -0.0020999908, -10.5633, -70.6314, 23.412498, 0, -3.3446002, 26.7577, -0.6956, 0, 23.412498, 0, 0, 23.412498, 0, -3.3446002, 26.7577, -0.4894, -3.3446002, 26.7577, -0.6956, 0, 23.412498, 0, -6.6893, 26.7577, -0.4894, -3.3446002, 23.412498, 0, -3.3446002, 23.412498, 0, -6.6893, 26.7577, -0.3464, -6.6893, 26.7577, -0.4894, -3.3446002, 23.412498, -1.0924, -23.412498, 26.7582, -1.0924, -20.0679, 23.412498, -1.0924, -20.0679, 23.412498, -1.0924, -23.412498, 26.7582, -1.0924, -23.412498, 26.7582, -1.0924, -20.0679, 23.412498, 0, -10.033899, 26.7577, -0.3464, -6.6893, 23.412498, 0, -6.6893, 23.412498, 0, -10.033899, 26.572199, -0.4003, -10.314899, 26.7577, -0.3464, -6.6893, 23.412498, -0.35529998, 10.033899, 26.7582, -1.7623999, 10.033899, 23.412498, -1.8294, 13.378601, 23.412498, -0.456, -16.7232, 26.7577, -0.8804, -16.7232, 26.572199, -0.95549995, -13.659599, 23.412498, -1.1158999, -26.7572, 26.7582, -1.0924, -23.412498, 23.412498, -1.0924, -23.412498, 23.412498, -1.1158999, -26.7572, 26.7573, -1.3222, -26.7572, 26.7582, -1.0924, -23.412498, 23.412498, -2.2719998, 23.3902, 26.7582, -2.7837, 26.6955, 23.412498, -2.2194998, 26.781, 23.412498, -2.2719998, 23.3902, 26.7582, -2.2719998, 23.3902, 26.7582, -2.7837, 26.6955, 23.412498, 0, -13.378599, 26.572199, -0.4003, -10.314899, 23.412498, 0, -10.033899, 23.412498, 0, -13.378599, 26.572199, -0.95549995, -13.659599, 26.572199, -0.4003, -10.314899, 23.412498, 0, 0, 26.7577, -0.6956, 0, 26.7577, -0.73109996, 3.3446, 23.412498, -1.0924, -20.0679, 26.7582, -1.0924, -20.0679, 26.7577, -0.8804, -16.7232, 52.997097, -8.1437, -6.6893, 56.213997, -8.7052, -3.3446002, 52.997097, -8.1437, -3.3446002, 56.173397, -8.6981, 0, 52.997097, -8.1437, -3.3446002, 56.213997, -8.7052, -3.3446002, 56.173397, -8.6981, 0, 52.997097, -8.1437, 0, 52.997097, -8.1437, -3.3446002, 52.997097, -8.1437, -6.6893, 56.254498, -8.712299, -6.6893, 56.213997, -8.7052, -3.3446002, 56.254498, -8.712299, -6.6893, 52.997097, -8.1437, -6.6893, 52.997097, -8.1437, -10.033899, 59.1829, -9.2234, 0, 56.173397, -8.6981, 0, 56.213997, -8.7052, -3.3446002, 56.254498, -8.712299, -6.6893, 59.216, -9.229199, -3.3446002, 56.213997, -8.7052, -3.3446002, 59.1829, -9.2234, 0, 56.213997, -8.7052, -3.3446002, 59.216, -9.229199, -3.3446002, 56.1329, -8.691, 3.3446, 52.997097, -8.1437, 0, 56.173397, -8.6981, 0, 56.1329, -8.691, 3.3446, 52.997097, -8.1437, 3.3446, 52.997097, -8.1437, 0, 59.1498, -9.2176, 3.3446, 56.173397, -8.6981, 0, 59.1829, -9.2234, 0, 59.1498, -9.2176, 3.3446, 56.1329, -8.691, 3.3446, 56.173397, -8.6981, 0, 56.0924, -8.684, 6.6893, 52.997097, -8.1437, 3.3446, 56.1329, -8.691, 3.3446, 56.0924, -8.684, 6.6893, 52.997097, -8.1437, 6.6893, 52.997097, -8.1437, 3.3446, 59.1167, -9.2119, 6.6893, 56.1329, -8.691, 3.3446, 59.1498, -9.2176, 3.3446, 59.1167, -9.2119, 6.6893, 56.0924, -8.684, 6.6893, 56.1329, -8.691, 3.3446, 56.0518, -8.6769, 10.033899, 52.997097, -8.1437, 6.6893, 56.0924, -8.684, 6.6893, 56.0518, -8.6769, 10.033899, 52.997097, -8.1437, 10.033899, 52.997097, -8.1437, 6.6893, 59.0836, -9.2060995, 10.033899, 56.0924, -8.684, 6.6893, 59.1167, -9.2119, 6.6893, 59.0836, -9.2060995, 10.033899, 56.0518, -8.6769, 10.033899, 56.0924, -8.684, 6.6893, 56.0113, -8.6698, 13.378601, 52.997097, -8.1437, 10.033899, 56.0518, -8.6769, 10.033899, 56.0113, -8.6698, 13.378601, 52.997097, -8.1437, 13.378601, 52.997097, -8.1437, 10.033899, 59.0505, -9.2003, 13.378601, 56.0518, -8.6769, 10.033899, 59.0836, -9.2060995, 10.033899, 59.0505, -9.2003, 13.378601, 56.0113, -8.6698, 13.378601, 56.0518, -8.6769, 10.033899, 55.9708, -8.6627, 16.7232, 52.997097, -8.1437, 13.378601, 56.0113, -8.6698, 13.378601, 55.9708, -8.6627, 16.7232, 52.997097, -8.1437, 16.7232, 52.997097, -8.1437, 13.378601, 59.017498, -9.1945, 16.7232, 56.0113, -8.6698, 13.378601, 59.0505, -9.2003, 13.378601, 59.017498, -9.1945, 16.7232, 55.9708, -8.6627, 16.7232, 56.0113, -8.6698, 13.378601, 55.930298, -8.6557, 20.0679, 52.997097, -8.1437, 16.7232, 55.9708, -8.6627, 16.7232, 55.930298, -8.6557, 20.0679, 52.997097, -8.1437, 20.0679, 52.997097, -8.1437, 16.7232, 58.984398, -9.1888, 20.0679, 55.9708, -8.6627, 16.7232, 59.017498, -9.1945, 16.7232, 58.984398, -9.1888, 20.0679, 55.930298, -8.6557, 20.0679, 55.9708, -8.6627, 16.7232, 55.889698, -8.6486, 23.412498, 52.997097, -8.1437, 20.0679, 55.930298, -8.6557, 20.0679, 55.889698, -8.6486, 23.412498, 52.997097, -8.1437, 23.412498, 52.997097, -8.1437, 20.0679, 55.849197, -8.6414995, 26.7572, 52.997097, -8.1437, 23.412498, 55.889698, -8.6486, 23.412498, 55.849197, -8.6414995, 26.7572, 52.997097, -8.1437, 26.7572, 52.997097, -8.1437, 23.412498, 58.918198, -9.177199, 26.7572, 55.849197, -8.6414995, 26.7572, 55.889698, -8.6486, 23.412498, 58.951298, -9.183, 23.412498, 55.889698, -8.6486, 23.412498, 55.930298, -8.6557, 20.0679, 58.918198, -9.177199, 26.7572, 55.889698, -8.6486, 23.412498, 58.951298, -9.183, 23.412498, 58.951298, -9.183, 23.412498, 55.930298, -8.6557, 20.0679, 58.984398, -9.1888, 20.0679, 62.4636, -9.7961, 26.7572, 58.918198, -9.177199, 26.7572, 58.951298, -9.183, 23.412498, 62.4577, -9.795, 23.412498, 58.951298, -9.183, 23.412498, 58.984398, -9.1888, 20.0679, 62.4636, -9.7961, 26.7572, 58.951298, -9.183, 23.412498, 62.4577, -9.795, 23.412498, 66.1166, -10.4337, 23.412498, 62.4636, -9.7961, 26.7572, 62.4577, -9.795, 23.412498, 66.1166, -10.4337, 23.412498, 66.1166, -10.4337, 26.7572, 62.4636, -9.7961, 26.7572, 66.1166, -10.4337, 20.0679, 66.1166, -10.4337, 23.412498, 62.4577, -9.795, 23.412498, 62.4577, -9.795, 23.412498, 58.984398, -9.1888, 20.0679, 62.451897, -9.794, 20.0679, 66.1166, -10.4337, 20.0679, 62.4577, -9.795, 23.412498, 62.451897, -9.794, 20.0679, 62.451897, -9.794, 20.0679, 58.984398, -9.1888, 20.0679, 59.017498, -9.1945, 16.7232, 66.1166, -10.4337, 16.7232, 66.1166, -10.4337, 20.0679, 62.451897, -9.794, 20.0679, 62.451897, -9.794, 20.0679, 59.017498, -9.1945, 16.7232, 62.446, -9.793, 16.7232, 66.1166, -10.4337, 16.7232, 62.451897, -9.794, 20.0679, 62.446, -9.793, 16.7232, 62.446, -9.793, 16.7232, 59.017498, -9.1945, 16.7232, 59.0505, -9.2003, 13.378601, 66.1166, -10.4337, 13.378601, 66.1166, -10.4337, 16.7232, 62.446, -9.793, 16.7232, 62.446, -9.793, 16.7232, 59.0505, -9.2003, 13.378601, 62.440098, -9.792, 13.378601, 66.1166, -10.4337, 13.378601, 62.446, -9.793, 16.7232, 62.440098, -9.792, 13.378601, 62.440098, -9.792, 13.378601, 59.0505, -9.2003, 13.378601, 59.0836, -9.2060995, 10.033899, 66.1166, -10.4337, 10.033899, 66.1166, -10.4337, 13.378601, 62.440098, -9.792, 13.378601, 62.440098, -9.792, 13.378601, 59.0836, -9.2060995, 10.033899, 62.4343, -9.790899, 10.033899, 66.1166, -10.4337, 10.033899, 62.440098, -9.792, 13.378601, 62.4343, -9.790899, 10.033899, 62.4343, -9.790899, 10.033899, 59.0836, -9.2060995, 10.033899, 59.1167, -9.2119, 6.6893, 66.1166, -10.4337, 6.6893, 66.1166, -10.4337, 10.033899, 62.4343, -9.790899, 10.033899, 62.4343, -9.790899, 10.033899, 59.1167, -9.2119, 6.6893, 62.4284, -9.7899, 6.6893, 66.1166, -10.4337, 6.6893, 62.4343, -9.790899, 10.033899, 62.4284, -9.7899, 6.6893, 62.4284, -9.7899, 6.6893, 59.1167, -9.2119, 6.6893, 59.1498, -9.2176, 3.3446, 66.1166, -10.4337, 3.3446, 66.1166, -10.4337, 6.6893, 62.4284, -9.7899, 6.6893, 62.4284, -9.7899, 6.6893, 59.1498, -9.2176, 3.3446, 62.422497, -9.788899, 3.3446, 66.1166, -10.4337, 3.3446, 62.4284, -9.7899, 6.6893, 62.422497, -9.788899, 3.3446, 62.422497, -9.788899, 3.3446, 59.1498, -9.2176, 3.3446, 59.1829, -9.2234, 0, 66.1166, -10.4337, 0, 66.1166, -10.4337, 3.3446, 62.422497, -9.788899, 3.3446, 62.422497, -9.788899, 3.3446, 59.1829, -9.2234, 0, 62.4167, -9.7879, 0, 66.1166, -10.4337, 0, 62.422497, -9.788899, 3.3446, 62.4167, -9.7879, 0, 62.4167, -9.7879, 0, 59.1829, -9.2234, 0, 59.216, -9.229199, -3.3446002, 66.1166, -10.4337, -3.3446002, 66.1166, -10.4337, 0, 62.4167, -9.7879, 0, 62.4167, -9.7879, 0, 59.216, -9.229199, -3.3446002, 62.410797, -9.786799, -3.3446002, 66.1166, -10.4337, -3.3446002, 62.4167, -9.7879, 0, 62.410797, -9.786799, -3.3446002, 59.248997, -9.235, -6.6893, 62.410797, -9.786799, -3.3446002, 59.216, -9.229199, -3.3446002, 62.4049, -9.7858, -6.6893, 66.1166, -10.4337, -3.3446002, 62.410797, -9.786799, -3.3446002, 59.248997, -9.235, -6.6893, 62.4049, -9.7858, -6.6893, 62.410797, -9.786799, -3.3446002, 62.4049, -9.7858, -6.6893, 66.1166, -10.4337, -6.6893, 66.1166, -10.4337, -3.3446002, 56.254498, -8.712299, -6.6893, 59.248997, -9.235, -6.6893, 59.216, -9.229199, -3.3446002, 66.1166, -10.4337, -6.6893, 62.4049, -9.7858, -6.6893, 62.399, -9.7848, -10.033899, 66.1166, -10.4337, -6.6893, 62.399, -9.7848, -10.033899, 66.1166, -10.4337, -10.033899, 62.4049, -9.7858, -6.6893, 59.248997, -9.235, -6.6893, 59.282097, -9.2407, -10.033899, 62.4049, -9.7858, -6.6893, 59.282097, -9.2407, -10.033899, 62.399, -9.7848, -10.033899, 59.248997, -9.235, -6.6893, 56.254498, -8.712299, -6.6893, 56.295, -8.719299, -10.033899, 59.248997, -9.235, -6.6893, 56.295, -8.719299, -10.033899, 59.282097, -9.2407, -10.033899, 56.254498, -8.712299, -6.6893, 52.997097, -8.1437, -10.033899, 56.295, -8.719299, -10.033899, 52.997097, -8.1437, -10.033899, 56.3355, -8.726399, -13.378599, 56.295, -8.719299, -10.033899, 56.3355, -8.726399, -13.378599, 59.282097, -9.2407, -10.033899, 56.295, -8.719299, -10.033899, 52.997097, -8.1437, -10.033899, 52.997097, -8.1437, -13.378599, 56.3355, -8.726399, -13.378599, 59.315197, -9.2465, -13.378599, 62.399, -9.7848, -10.033899, 59.282097, -9.2407, -10.033899, 56.3355, -8.726399, -13.378599, 59.315197, -9.2465, -13.378599, 59.282097, -9.2407, -10.033899, 52.997097, -8.1437, -13.378599, 56.3761, -8.7335, -16.7232, 56.3355, -8.726399, -13.378599, 56.3761, -8.7335, -16.7232, 59.315197, -9.2465, -13.378599, 56.3355, -8.726399, -13.378599, 52.997097, -8.1437, -13.378599, 52.997097, -8.1437, -16.7232, 56.3761, -8.7335, -16.7232, 59.315197, -9.2465, -13.378599, 62.3932, -9.7838, -13.378599, 62.399, -9.7848, -10.033899, 62.3932, -9.7838, -13.378599, 66.1166, -10.4337, -10.033899, 62.399, -9.7848, -10.033899, 62.3932, -9.7838, -13.378599, 66.1166, -10.4337, -13.378599, 66.1166, -10.4337, -10.033899, 59.348297, -9.252299, -16.7232, 62.3932, -9.7838, -13.378599, 59.315197, -9.2465, -13.378599, 56.3761, -8.7335, -16.7232, 59.348297, -9.252299, -16.7232, 59.315197, -9.2465, -13.378599, 62.3873, -9.7827, -16.7232, 66.1166, -10.4337, -13.378599, 62.3932, -9.7838, -13.378599, 59.348297, -9.252299, -16.7232, 62.3873, -9.7827, -16.7232, 62.3932, -9.7838, -13.378599, 62.3873, -9.7827, -16.7232, 66.1166, -10.4337, -16.7232, 66.1166, -10.4337, -13.378599, 56.4166, -8.7406, -20.0679, 59.348297, -9.252299, -16.7232, 56.3761, -8.7335, -16.7232, 52.997097, -8.1437, -16.7232, 56.4166, -8.7406, -20.0679, 56.3761, -8.7335, -16.7232, 52.997097, -8.1437, -16.7232, 52.997097, -8.1437, -20.0679, 56.4166, -8.7406, -20.0679, 52.997097, -8.1437, -20.0679, 56.4571, -8.7476, -23.412498, 56.4166, -8.7406, -20.0679, 52.997097, -8.1437, -20.0679, 52.997097, -8.1437, -23.412498, 56.4571, -8.7476, -23.412498, 56.4166, -8.7406, -20.0679, 59.381397, -9.2581, -20.0679, 59.348297, -9.252299, -16.7232, 56.4571, -8.7476, -23.412498, 59.381397, -9.2581, -20.0679, 56.4166, -8.7406, -20.0679, 59.381397, -9.2581, -20.0679, 62.3873, -9.7827, -16.7232, 59.348297, -9.252299, -16.7232, 56.4571, -8.7476, -23.412498, 59.414497, -9.2638, -23.412498, 59.381397, -9.2581, -20.0679, 62.381397, -9.7817, -20.0679, 66.1166, -10.4337, -16.7232, 62.3873, -9.7827, -16.7232, 59.381397, -9.2581, -20.0679, 62.381397, -9.7817, -20.0679, 62.3873, -9.7827, -16.7232, 59.414497, -9.2638, -23.412498, 62.381397, -9.7817, -20.0679, 59.381397, -9.2581, -20.0679, 62.381397, -9.7817, -20.0679, 66.1166, -10.4337, -20.0679, 66.1166, -10.4337, -16.7232, 59.414497, -9.2638, -23.412498, 62.3756, -9.7807, -23.412498, 62.381397, -9.7817, -20.0679, 62.3756, -9.7807, -23.412498, 66.1166, -10.4337, -20.0679, 62.381397, -9.7817, -20.0679, 62.3756, -9.7807, -23.412498, 66.1166, -10.4337, -23.412498, 66.1166, -10.4337, -20.0679, 66.1166, -10.4572, -26.7572, 68.958595, -10.4337, -23.412498, 66.1166, -10.4337, -23.412498, 66.1166, -10.4572, -26.7572, 68.9481, -10.4572, -26.7572, 68.958595, -10.4337, -23.412498, 68.9481, -10.4572, -26.7572, 72.2025, -10.4337, -23.412498, 68.958595, -10.4337, -23.412498, 68.9481, -10.4572, -26.7572, 72.2092, -10.4572, -26.7572, 72.2025, -10.4337, -23.412498, 72.2092, -10.4572, -26.7572, 75.7165, -10.4337, -23.412498, 72.2025, -10.4337, -23.412498, 72.2092, -10.4572, -26.7572, 75.6957, -10.4572, -26.7572, 75.7165, -10.4337, -23.412498, 75.6957, -10.4572, -26.7572, 79.236, -10.4337, -23.412498, 75.7165, -10.4337, -23.412498, 75.6957, -10.4572, -26.7572, 79.236, -10.4572, -26.7572, 79.236, -10.4337, -23.412498, 39.877598, -3.6573, -13.378599, 42.9754, -4.7166, -10.033899, 39.877598, -3.6573, -10.033899, 39.877598, -3.6573, -13.378599, 42.951797, -4.7086, -13.378599, 42.9754, -4.7166, -10.033899, 42.951797, -4.7086, -13.378599, 46.3474, -5.8697, -10.033899, 42.9754, -4.7166, -10.033899, 42.951797, -4.7086, -13.378599, 39.877598, -3.6573, -13.378599, 39.877598, -3.6573, -16.7232, 42.951797, -4.7086, -13.378599, 46.326397, -5.8626, -13.378599, 46.3474, -5.8697, -10.033899, 46.326397, -5.8626, -13.378599, 49.4666, -6.9364, -10.033899, 46.3474, -5.8697, -10.033899, 42.951797, -4.7086, -13.378599, 39.877598, -3.6573, -16.7232, 42.9282, -4.7005, -16.7232, 46.326397, -5.8626, -13.378599, 42.951797, -4.7086, -13.378599, 42.9282, -4.7005, -16.7232, 39.877598, -3.6573, -16.7232, 42.9046, -4.6924, -20.0679, 42.9282, -4.7005, -16.7232, 39.877598, -3.6573, -16.7232, 39.877598, -3.6573, -20.0679, 42.9046, -4.6924, -20.0679, 46.326397, -5.8626, -13.378599, 42.9282, -4.7005, -16.7232, 46.3055, -5.8554, -16.7232, 42.9046, -4.6924, -20.0679, 46.3055, -5.8554, -16.7232, 42.9282, -4.7005, -16.7232, 46.326397, -5.8626, -13.378599, 49.4568, -6.9329996, -13.378599, 49.4666, -6.9364, -10.033899, 49.4568, -6.9329996, -13.378599, 46.326397, -5.8626, -13.378599, 46.3055, -5.8554, -16.7232, 49.4568, -6.9329996, -13.378599, 52.997097, -8.1437, -10.033899, 49.4666, -6.9364, -10.033899, 49.4568, -6.9329996, -13.378599, 52.997097, -8.1437, -13.378599, 52.997097, -8.1437, -10.033899, 39.877598, -3.6573, -20.0679, 42.881, -4.6844, -23.412498, 42.9046, -4.6924, -20.0679, 39.877598, -3.6573, -20.0679, 39.877598, -3.6573, -23.412498, 42.881, -4.6844, -23.412498, 42.881, -4.6844, -23.412498, 46.2845, -5.8482, -20.0679, 42.9046, -4.6924, -20.0679, 42.9046, -4.6924, -20.0679, 46.2845, -5.8482, -20.0679, 46.3055, -5.8554, -16.7232, 42.881, -4.6844, -23.412498, 46.2636, -5.8410997, -23.412498, 46.2845, -5.8482, -20.0679, 52.997097, -8.1437, -13.378599, 49.4568, -6.9329996, -13.378599, 49.447, -6.9297, -16.7232, 49.4568, -6.9329996, -13.378599, 46.3055, -5.8554, -16.7232, 49.447, -6.9297, -16.7232, 46.2845, -5.8482, -20.0679, 49.447, -6.9297, -16.7232, 46.3055, -5.8554, -16.7232, 52.997097, -8.1437, -13.378599, 49.447, -6.9297, -16.7232, 52.997097, -8.1437, -16.7232, 46.2636, -5.8410997, -23.412498, 49.4372, -6.9263997, -20.0679, 46.2845, -5.8482, -20.0679, 46.2845, -5.8482, -20.0679, 49.4372, -6.9263997, -20.0679, 49.447, -6.9297, -16.7232, 49.4372, -6.9263997, -20.0679, 52.997097, -8.1437, -16.7232, 49.447, -6.9297, -16.7232, 46.2636, -5.8410997, -23.412498, 49.427498, -6.923, -23.412498, 49.4372, -6.9263997, -20.0679, 49.4372, -6.9263997, -20.0679, 52.997097, -8.1437, -20.0679, 52.997097, -8.1437, -16.7232, 49.427498, -6.923, -23.412498, 52.997097, -8.1437, -20.0679, 49.4372, -6.9263997, -20.0679, 49.427498, -6.923, -23.412498, 52.997097, -8.1437, -23.412498, 52.997097, -8.1437, -20.0679, 20.0679, -8.1437, 52.156597, 16.7232, -8.658199, 55.0947, 16.7232, -8.1437, 52.156597, 13.378599, -8.658199, 55.0947, 16.7232, -8.1437, 52.156597, 16.7232, -8.658199, 55.0947, 13.378599, -8.658199, 55.0947, 13.378599, -8.1437, 52.156597, 16.7232, -8.1437, 52.156597, 20.0679, -8.1437, 52.156597, 20.0679, -8.658199, 55.0947, 16.7232, -8.658199, 55.0947, 20.0679, -8.658199, 55.0947, 20.0679, -8.1437, 52.156597, 23.412498, -8.1437, 52.156597, 13.378599, -9.1788, 58.067497, 13.378599, -8.658199, 55.0947, 16.7232, -8.658199, 55.0947, 20.0679, -8.658199, 55.0947, 16.7232, -9.1788, 58.067497, 16.7232, -8.658199, 55.0947, 13.378599, -9.1788, 58.067497, 16.7232, -8.658199, 55.0947, 16.7232, -9.1788, 58.067497, 10.033899, -8.658199, 55.0947, 13.378599, -8.1437, 52.156597, 13.378599, -8.658199, 55.0947, 10.033899, -8.658199, 55.0947, 10.033899, -8.1437, 52.156597, 13.378599, -8.1437, 52.156597, 10.033899, -9.1788, 58.067497, 13.378599, -8.658199, 55.0947, 13.378599, -9.1788, 58.067497, 10.033899, -9.1788, 58.067497, 10.033899, -8.658199, 55.0947, 13.378599, -8.658199, 55.0947, 6.6893, -8.658199, 55.0947, 10.033899, -8.1437, 52.156597, 10.033899, -8.658199, 55.0947, 6.6893, -8.658199, 55.0947, 6.6893, -8.1437, 52.156597, 10.033899, -8.1437, 52.156597, 6.6893, -9.1788, 58.067497, 10.033899, -8.658199, 55.0947, 10.033899, -9.1788, 58.067497, 6.6893, -9.1788, 58.067497, 6.6893, -8.658199, 55.0947, 10.033899, -8.658199, 55.0947, 3.3446, -8.658199, 55.0947, 6.6893, -8.1437, 52.156597, 6.6893, -8.658199, 55.0947, 3.3446, -8.658199, 55.0947, 3.3446, -8.1437, 52.156597, 6.6893, -8.1437, 52.156597, 3.3446, -9.1788, 58.067497, 6.6893, -8.658199, 55.0947, 6.6893, -9.1788, 58.067497, 3.3446, -9.1788, 58.067497, 3.3446, -8.658199, 55.0947, 6.6893, -8.658199, 55.0947, 0, -8.658199, 55.0947, 3.3446, -8.1437, 52.156597, 3.3446, -8.658199, 55.0947, 0, -8.658199, 55.0947, 0, -8.1437, 52.156597, 3.3446, -8.1437, 52.156597, 0, -9.1788, 58.067497, 3.3446, -8.658199, 55.0947, 3.3446, -9.1788, 58.067497, 0, -9.1788, 58.067497, 0, -8.658199, 55.0947, 3.3446, -8.658199, 55.0947, -3.3446002, -8.658199, 55.0947, 0, -8.1437, 52.156597, 0, -8.658199, 55.0947, -3.3446002, -8.658199, 55.0947, -3.3446002, -8.1437, 52.156597, 0, -8.1437, 52.156597, -3.3446002, -9.1788, 58.067497, 0, -8.658199, 55.0947, 0, -9.1788, 58.067497, -3.3446002, -9.1788, 58.067497, -3.3446002, -8.658199, 55.0947, 0, -8.658199, 55.0947, -6.6893, -8.658199, 55.0947, -3.3446002, -8.1437, 52.156597, -3.3446002, -8.658199, 55.0947, -6.6893, -8.658199, 55.0947, -6.6893, -8.1437, 52.156597, -3.3446002, -8.1437, 52.156597, -6.6893, -9.1788, 58.067497, -3.3446002, -8.658199, 55.0947, -3.3446002, -9.1788, 58.067497, -6.6893, -9.1788, 58.067497, -6.6893, -8.658199, 55.0947, -3.3446002, -8.658199, 55.0947, -10.033899, -8.658199, 55.0947, -6.6893, -8.1437, 52.156597, -6.6893, -8.658199, 55.0947, -10.033899, -8.658199, 55.0947, -10.033899, -8.1437, 52.156597, -6.6893, -8.1437, 52.156597, -10.033899, -9.1788, 58.067497, -6.6893, -8.658199, 55.0947, -6.6893, -9.1788, 58.067497, -10.033899, -9.1788, 58.067497, -10.033899, -8.658199, 55.0947, -6.6893, -8.658199, 55.0947, -13.378601, -8.658199, 55.0947, -10.033899, -8.1437, 52.156597, -10.033899, -8.658199, 55.0947, -13.378601, -8.658199, 55.0947, -13.378601, -8.1437, 52.156597, -10.033899, -8.1437, 52.156597, -13.378601, -9.1788, 58.067497, -10.033899, -8.658199, 55.0947, -10.033899, -9.1788, 58.067497, -13.378601, -9.1788, 58.067497, -13.378601, -8.658199, 55.0947, -10.033899, -8.658199, 55.0947, -16.7232, -8.658199, 55.0947, -13.378601, -8.1437, 52.156597, -13.378601, -8.658199, 55.0947, -16.7232, -8.658199, 55.0947, -16.7232, -8.1437, 52.156597, -13.378601, -8.1437, 52.156597, -16.7232, -9.1788, 58.067497, -13.378601, -8.658199, 55.0947, -13.378601, -9.1788, 58.067497, -16.7232, -9.1788, 58.067497, -16.7232, -8.658199, 55.0947, -13.378601, -8.658199, 55.0947, -20.0679, -8.658199, 55.0947, -16.7232, -8.1437, 52.156597, -16.7232, -8.658199, 55.0947, -20.0679, -8.658199, 55.0947, -20.0679, -8.1437, 52.156597, -16.7232, -8.1437, 52.156597, -20.0679, -9.1788, 58.067497, -16.7232, -8.658199, 55.0947, -16.7232, -9.1788, 58.067497, -20.0679, -9.1788, 58.067497, -20.0679, -8.658199, 55.0947, -16.7232, -8.658199, 55.0947, -23.412498, -8.658199, 55.0947, -20.0679, -8.1437, 52.156597, -20.0679, -8.658199, 55.0947, -23.412498, -8.658199, 55.0947, -23.412498, -8.1437, 52.156597, -20.0679, -8.1437, 52.156597, -26.7572, -8.658199, 55.0947, -23.412498, -8.1437, 52.156597, -23.412498, -8.658199, 55.0947, -26.7572, -8.658199, 55.0947, -26.7572, -8.1437, 52.156597, -23.412498, -8.1437, 52.156597, -26.7572, -9.1788, 58.067497, -26.7572, -8.658199, 55.0947, -23.412498, -8.658199, 55.0947, -23.412498, -9.1788, 58.067497, -23.412498, -8.658199, 55.0947, -20.0679, -8.658199, 55.0947, -26.7572, -9.1788, 58.067497, -23.412498, -8.658199, 55.0947, -23.412498, -9.1788, 58.067497, -23.412498, -9.1788, 58.067497, -20.0679, -8.658199, 55.0947, -20.0679, -9.1788, 58.067497, -26.7572, -9.8364, 61.822598, -26.7572, -9.1788, 58.067497, -23.412498, -9.1788, 58.067497, -23.412498, -9.8364, 61.822598, -23.412498, -9.1788, 58.067497, -20.0679, -9.1788, 58.067497, -26.7572, -9.8364, 61.822598, -23.412498, -9.1788, 58.067497, -23.412498, -9.8364, 61.822598, -23.412498, -10.4337, 65.2334, -26.7572, -9.8364, 61.822598, -23.412498, -9.8364, 61.822598, -23.412498, -10.4337, 65.2334, -26.7572, -10.4337, 65.2334, -26.7572, -9.8364, 61.822598, -20.0679, -10.4337, 65.2334, -23.412498, -10.4337, 65.2334, -23.412498, -9.8364, 61.822598, -23.412498, -9.8364, 61.822598, -20.0679, -9.1788, 58.067497, -20.0679, -9.8364, 61.822598, -20.0679, -10.4337, 65.2334, -23.412498, -9.8364, 61.822598, -20.0679, -9.8364, 61.822598, -20.0679, -9.8364, 61.822598, -20.0679, -9.1788, 58.067497, -16.7232, -9.1788, 58.067497, -16.7232, -10.4337, 65.2334, -20.0679, -10.4337, 65.2334, -20.0679, -9.8364, 61.822598, -20.0679, -9.8364, 61.822598, -16.7232, -9.1788, 58.067497, -16.7232, -9.8364, 61.822598, -16.7232, -10.4337, 65.2334, -20.0679, -9.8364, 61.822598, -16.7232, -9.8364, 61.822598, -16.7232, -9.8364, 61.822598, -16.7232, -9.1788, 58.067497, -13.378601, -9.1788, 58.067497, -13.378601, -10.4337, 65.2334, -16.7232, -10.4337, 65.2334, -16.7232, -9.8364, 61.822598, -16.7232, -9.8364, 61.822598, -13.378601, -9.1788, 58.067497, -13.378601, -9.8364, 61.822598, -13.378601, -10.4337, 65.2334, -16.7232, -9.8364, 61.822598, -13.378601, -9.8364, 61.822598, -13.378601, -9.8364, 61.822598, -13.378601, -9.1788, 58.067497, -10.033899, -9.1788, 58.067497, -10.033899, -10.4337, 65.2334, -13.378601, -10.4337, 65.2334, -13.378601, -9.8364, 61.822598, -13.378601, -9.8364, 61.822598, -10.033899, -9.1788, 58.067497, -10.033899, -9.8364, 61.822598, -10.033899, -10.4337, 65.2334, -13.378601, -9.8364, 61.822598, -10.033899, -9.8364, 61.822598, -10.033899, -9.8364, 61.822598, -10.033899, -9.1788, 58.067497, -6.6893, -9.1788, 58.067497, -6.6893, -10.4337, 65.2334, -10.033899, -10.4337, 65.2334, -10.033899, -9.8364, 61.822598, -10.033899, -9.8364, 61.822598, -6.6893, -9.1788, 58.067497, -6.6893, -9.8364, 61.822598, -6.6893, -10.4337, 65.2334, -10.033899, -9.8364, 61.822598, -6.6893, -9.8364, 61.822598, -6.6893, -9.8364, 61.822598, -6.6893, -9.1788, 58.067497, -3.3446002, -9.1788, 58.067497, -3.3446002, -10.4337, 65.2334, -6.6893, -10.4337, 65.2334, -6.6893, -9.8364, 61.822598, -6.6893, -9.8364, 61.822598, -3.3446002, -9.1788, 58.067497, -3.3446002, -9.8364, 61.822598, -3.3446002, -10.4337, 65.2334, -6.6893, -9.8364, 61.822598, -3.3446002, -9.8364, 61.822598, -3.3446002, -9.8364, 61.822598, -3.3446002, -9.1788, 58.067497, 0, -9.1788, 58.067497, 0, -10.4337, 65.2334, -3.3446002, -10.4337, 65.2334, -3.3446002, -9.8364, 61.822598, -3.3446002, -9.8364, 61.822598, 0, -9.1788, 58.067497, 0, -9.8364, 61.822598, 0, -10.4337, 65.2334, -3.3446002, -9.8364, 61.822598, 0, -9.8364, 61.822598, 0, -9.8364, 61.822598, 0, -9.1788, 58.067497, 3.3446, -9.1788, 58.067497, 3.3446, -10.4337, 65.2334, 0, -10.4337, 65.2334, 0, -9.8364, 61.822598, 0, -9.8364, 61.822598, 3.3446, -9.1788, 58.067497, 3.3446, -9.8364, 61.822598, 3.3446, -10.4337, 65.2334, 0, -9.8364, 61.822598, 3.3446, -9.8364, 61.822598, 3.3446, -9.8364, 61.822598, 3.3446, -9.1788, 58.067497, 6.6893, -9.1788, 58.067497, 6.6893, -10.4337, 65.2334, 3.3446, -10.4337, 65.2334, 3.3446, -9.8364, 61.822598, 3.3446, -9.8364, 61.822598, 6.6893, -9.1788, 58.067497, 6.6893, -9.8364, 61.822598, 6.6893, -10.4337, 65.2334, 3.3446, -9.8364, 61.822598, 6.6893, -9.8364, 61.822598, 6.6893, -9.8364, 61.822598, 6.6893, -9.1788, 58.067497, 10.033899, -9.1788, 58.067497, 10.033899, -10.4337, 65.2334, 6.6893, -10.4337, 65.2334, 6.6893, -9.8364, 61.822598, 6.6893, -9.8364, 61.822598, 10.033899, -9.1788, 58.067497, 10.033899, -9.8364, 61.822598, 10.033899, -10.4337, 65.2334, 6.6893, -9.8364, 61.822598, 10.033899, -9.8364, 61.822598, 10.033899, -9.8364, 61.822598, 10.033899, -9.1788, 58.067497, 13.378599, -9.1788, 58.067497, 13.378599, -10.4337, 65.2334, 10.033899, -10.4337, 65.2334, 10.033899, -9.8364, 61.822598, 10.033899, -9.8364, 61.822598, 13.378599, -9.1788, 58.067497, 13.378599, -9.8364, 61.822598, 13.378599, -10.4337, 65.2334, 10.033899, -9.8364, 61.822598, 13.378599, -9.8364, 61.822598, 13.378599, -9.8364, 61.822598, 13.378599, -9.1788, 58.067497, 16.7232, -9.1788, 58.067497, 16.7232, -10.4337, 65.2334, 13.378599, -10.4337, 65.2334, 13.378599, -9.8364, 61.822598, 13.378599, -9.8364, 61.822598, 16.7232, -9.1788, 58.067497, 16.7232, -9.8364, 61.822598, 16.7232, -10.4337, 65.2334, 13.378599, -9.8364, 61.822598, 16.7232, -9.8364, 61.822598, 20.0679, -9.1788, 58.067497, 16.7232, -9.8364, 61.822598, 16.7232, -9.1788, 58.067497, 20.0679, -9.8364, 61.822598, 16.7232, -10.4337, 65.2334, 16.7232, -9.8364, 61.822598, 20.0679, -9.1788, 58.067497, 20.0679, -9.8364, 61.822598, 16.7232, -9.8364, 61.822598, 20.0679, -9.8364, 61.822598, 20.0679, -10.4337, 65.2334, 16.7232, -10.4337, 65.2334, 20.0679, -8.658199, 55.0947, 20.0679, -9.1788, 58.067497, 16.7232, -9.1788, 58.067497, 20.0679, -10.4337, 65.2334, 20.0679, -9.8364, 61.822598, 23.412498, -9.8364, 61.822598, 20.0679, -10.4337, 65.2334, 23.412498, -9.8364, 61.822598, 23.412498, -10.4337, 65.2334, 26.7582, -9.8364, 61.822598, 23.412498, -10.4337, 65.2334, 23.412498, -9.8364, 61.822598, 26.7582, -9.8364, 61.822598, 26.7582, -10.4337, 65.2334, 23.412498, -10.4337, 65.2334, 26.7582, -9.1788, 58.067497, 26.7582, -9.8364, 61.822598, 23.412498, -9.8364, 61.822598, 20.0679, -9.8364, 61.822598, 23.412498, -9.1788, 58.067497, 23.412498, -9.8364, 61.822598, 26.7582, -9.1788, 58.067497, 23.412498, -9.8364, 61.822598, 23.412498, -9.1788, 58.067497, 20.0679, -9.8364, 61.822598, 20.0679, -9.1788, 58.067497, 23.412498, -9.1788, 58.067497, 26.7582, -8.658199, 55.0947, 26.7582, -9.1788, 58.067497, 23.412498, -9.1788, 58.067497, 20.0679, -9.1788, 58.067497, 20.0679, -8.658199, 55.0947, 23.412498, -8.658199, 55.0947, 20.0679, -9.1788, 58.067497, 23.412498, -8.658199, 55.0947, 23.412498, -9.1788, 58.067497, 26.7582, -8.658199, 55.0947, 23.412498, -9.1788, 58.067497, 23.412498, -8.658199, 55.0947, 20.0679, -8.658199, 55.0947, 23.412498, -8.1437, 52.156597, 23.412498, -8.658199, 55.0947, 23.412498, -8.1437, 52.156597, 26.7582, -8.658199, 55.0947, 23.412498, -8.658199, 55.0947, 23.412498, -8.1437, 52.156597, 26.7582, -8.1437, 52.156597, 26.7582, -8.658199, 55.0947, 20.0679, -3.8518999, 39.456898, 16.7232, -4.9595, 42.7343, 16.7232, -3.8518999, 39.456898, 13.378599, -4.9595, 42.7343, 16.7232, -3.8518999, 39.456898, 16.7232, -4.9595, 42.7343, 13.378599, -4.9595, 42.7343, 13.378599, -3.8518999, 39.456898, 16.7232, -3.8518999, 39.456898, 20.0679, -3.8518999, 39.456898, 20.0679, -4.9595, 42.7343, 16.7232, -4.9595, 42.7343, 20.0679, -4.9595, 42.7343, 20.0679, -3.8518999, 39.456898, 23.412498, -3.8518999, 39.456898, 13.378599, -6.2019997, 46.4111, 13.378599, -4.9595, 42.7343, 16.7232, -4.9595, 42.7343, 20.0679, -4.9595, 42.7343, 16.7232, -6.2019997, 46.4111, 16.7232, -4.9595, 42.7343, 13.378599, -6.2019997, 46.4111, 16.7232, -4.9595, 42.7343, 16.7232, -6.2019997, 46.4111, 10.033899, -4.9595, 42.7343, 13.378599, -3.8518999, 39.456898, 13.378599, -4.9595, 42.7343, 10.033899, -4.9595, 42.7343, 10.033899, -3.8518999, 39.456898, 13.378599, -3.8518999, 39.456898, 10.033899, -6.2019997, 46.4111, 13.378599, -4.9595, 42.7343, 13.378599, -6.2019997, 46.4111, 10.033899, -6.2019997, 46.4111, 10.033899, -4.9595, 42.7343, 13.378599, -4.9595, 42.7343, 6.6893, -4.9595, 42.7343, 10.033899, -3.8518999, 39.456898, 10.033899, -4.9595, 42.7343, 6.6893, -4.9595, 42.7343, 6.6893, -3.8518999, 39.456898, 10.033899, -3.8518999, 39.456898, 6.6893, -6.2019997, 46.4111, 10.033899, -4.9595, 42.7343, 10.033899, -6.2019997, 46.4111, 6.6893, -6.2019997, 46.4111, 6.6893, -4.9595, 42.7343, 10.033899, -4.9595, 42.7343, 3.3446, -4.9595, 42.7343, 6.6893, -3.8518999, 39.456898, 6.6893, -4.9595, 42.7343, 3.3446, -4.9595, 42.7343, 3.3446, -3.8518999, 39.456898, 6.6893, -3.8518999, 39.456898, 3.3446, -6.2019997, 46.4111, 6.6893, -4.9595, 42.7343, 6.6893, -6.2019997, 46.4111, 3.3446, -6.2019997, 46.4111, 3.3446, -4.9595, 42.7343, 6.6893, -4.9595, 42.7343, 0, -4.9595, 42.7343, 3.3446, -3.8518999, 39.456898, 3.3446, -4.9595, 42.7343, 0, -4.9595, 42.7343, 0, -3.8518999, 39.456898, 3.3446, -3.8518999, 39.456898, 0, -6.2019997, 46.4111, 3.3446, -4.9595, 42.7343, 3.3446, -6.2019997, 46.4111, 0, -6.2019997, 46.4111, 0, -4.9595, 42.7343, 3.3446, -4.9595, 42.7343, -3.3446002, -4.9595, 42.7343, 0, -3.8518999, 39.456898, 0, -4.9595, 42.7343, -3.3446002, -4.9595, 42.7343, -3.3446002, -3.8518999, 39.456898, 0, -3.8518999, 39.456898, -3.3446002, -6.2019997, 46.4111, 0, -4.9595, 42.7343, 0, -6.2019997, 46.4111, -3.3446002, -6.2019997, 46.4111, -3.3446002, -4.9595, 42.7343, 0, -4.9595, 42.7343, -6.6893, -4.9595, 42.7343, -3.3446002, -3.8518999, 39.456898, -3.3446002, -4.9595, 42.7343, -6.6893, -4.9595, 42.7343, -6.6893, -3.8518999, 39.456898, -3.3446002, -3.8518999, 39.456898, -6.6893, -6.2019997, 46.4111, -3.3446002, -4.9595, 42.7343, -3.3446002, -6.2019997, 46.4111, -6.6893, -6.2019997, 46.4111, -6.6893, -4.9595, 42.7343, -3.3446002, -4.9595, 42.7343, -10.033899, -4.9595, 42.7343, -6.6893, -3.8518999, 39.456898, -6.6893, -4.9595, 42.7343, -10.033899, -4.9595, 42.7343, -10.033899, -3.8518999, 39.456898, -6.6893, -3.8518999, 39.456898, -10.033899, -6.2019997, 46.4111, -6.6893, -4.9595, 42.7343, -6.6893, -6.2019997, 46.4111, -10.033899, -6.2019997, 46.4111, -10.033899, -4.9595, 42.7343, -6.6893, -4.9595, 42.7343, -13.378601, -4.9595, 42.7343, -10.033899, -3.8518999, 39.456898, -10.033899, -4.9595, 42.7343, -13.378601, -4.9595, 42.7343, -13.378601, -3.8518999, 39.456898, -10.033899, -3.8518999, 39.456898, -13.378601, -6.2019997, 46.4111, -10.033899, -4.9595, 42.7343, -10.033899, -6.2019997, 46.4111, -13.378601, -6.2019997, 46.4111, -13.378601, -4.9595, 42.7343, -10.033899, -4.9595, 42.7343, -16.7232, -4.9595, 42.7343, -13.378601, -3.8518999, 39.456898, -13.378601, -4.9595, 42.7343, -16.7232, -4.9595, 42.7343, -16.7232, -3.8518999, 39.456898, -13.378601, -3.8518999, 39.456898, -16.7232, -6.2019997, 46.4111, -13.378601, -4.9595, 42.7343, -13.378601, -6.2019997, 46.4111, -16.7232, -6.2019997, 46.4111, -16.7232, -4.9595, 42.7343, -13.378601, -4.9595, 42.7343, -20.0679, -4.9595, 42.7343, -16.7232, -3.8518999, 39.456898, -16.7232, -4.9595, 42.7343, -20.0679, -4.9595, 42.7343, -20.0679, -3.8518999, 39.456898, -16.7232, -3.8518999, 39.456898, -20.0679, -6.2019997, 46.4111, -16.7232, -4.9595, 42.7343, -16.7232, -6.2019997, 46.4111, -20.0679, -6.2019997, 46.4111, -20.0679, -4.9595, 42.7343, -16.7232, -4.9595, 42.7343, -23.412498, -4.9595, 42.7343, -20.0679, -3.8518999, 39.456898, -20.0679, -4.9595, 42.7343, -23.412498, -4.9595, 42.7343, -23.412498, -3.8518999, 39.456898, -20.0679, -3.8518999, 39.456898, -26.7572, -4.9595, 42.7343, -23.412498, -3.8518999, 39.456898, -23.412498, -4.9595, 42.7343, -26.7572, -4.9595, 42.7343, -26.7572, -3.8518999, 39.456898, -23.412498, -3.8518999, 39.456898, -26.7572, -6.2019997, 46.4111, -26.7572, -4.9595, 42.7343, -23.412498, -4.9595, 42.7343, -23.412498, -6.2019997, 46.4111, -23.412498, -4.9595, 42.7343, -20.0679, -4.9595, 42.7343, -26.7572, -6.2019997, 46.4111, -23.412498, -4.9595, 42.7343, -23.412498, -6.2019997, 46.4111, -23.412498, -6.2019997, 46.4111, -20.0679, -4.9595, 42.7343, -20.0679, -6.2019997, 46.4111, -26.7572, -7.286, 49.6186, -26.7572, -6.2019997, 46.4111, -23.412498, -6.2019997, 46.4111, -23.412498, -7.286, 49.6186, -23.412498, -6.2019997, 46.4111, -20.0679, -6.2019997, 46.4111, -26.7572, -7.286, 49.6186, -23.412498, -6.2019997, 46.4111, -23.412498, -7.286, 49.6186, -23.412498, -8.1437, 52.156597, -26.7572, -7.286, 49.6186, -23.412498, -7.286, 49.6186, -23.412498, -8.1437, 52.156597, -26.7572, -8.1437, 52.156597, -26.7572, -7.286, 49.6186, -20.0679, -8.1437, 52.156597, -23.412498, -8.1437, 52.156597, -23.412498, -7.286, 49.6186, -23.412498, -7.286, 49.6186, -20.0679, -6.2019997, 46.4111, -20.0679, -7.286, 49.6186, -20.0679, -8.1437, 52.156597, -23.412498, -7.286, 49.6186, -20.0679, -7.286, 49.6186, -20.0679, -7.286, 49.6186, -20.0679, -6.2019997, 46.4111, -16.7232, -6.2019997, 46.4111, -16.7232, -8.1437, 52.156597, -20.0679, -8.1437, 52.156597, -20.0679, -7.286, 49.6186, -20.0679, -7.286, 49.6186, -16.7232, -6.2019997, 46.4111, -16.7232, -7.286, 49.6186, -16.7232, -8.1437, 52.156597, -20.0679, -7.286, 49.6186, -16.7232, -7.286, 49.6186, -16.7232, -7.286, 49.6186, -16.7232, -6.2019997, 46.4111, -13.378601, -6.2019997, 46.4111, -13.378601, -8.1437, 52.156597, -16.7232, -8.1437, 52.156597, -16.7232, -7.286, 49.6186, -16.7232, -7.286, 49.6186, -13.378601, -6.2019997, 46.4111, -13.378601, -7.286, 49.6186, -13.378601, -8.1437, 52.156597, -16.7232, -7.286, 49.6186, -13.378601, -7.286, 49.6186, -13.378601, -7.286, 49.6186, -13.378601, -6.2019997, 46.4111, -10.033899, -6.2019997, 46.4111, -10.033899, -8.1437, 52.156597, -13.378601, -8.1437, 52.156597, -13.378601, -7.286, 49.6186, -13.378601, -7.286, 49.6186, -10.033899, -6.2019997, 46.4111, -10.033899, -7.286, 49.6186, -10.033899, -8.1437, 52.156597, -13.378601, -7.286, 49.6186, -10.033899, -7.286, 49.6186, -10.033899, -7.286, 49.6186, -10.033899, -6.2019997, 46.4111, -6.6893, -6.2019997, 46.4111, -6.6893, -8.1437, 52.156597, -10.033899, -8.1437, 52.156597, -10.033899, -7.286, 49.6186, -10.033899, -7.286, 49.6186, -6.6893, -6.2019997, 46.4111, -6.6893, -7.286, 49.6186, -6.6893, -8.1437, 52.156597, -10.033899, -7.286, 49.6186, -6.6893, -7.286, 49.6186, -6.6893, -7.286, 49.6186, -6.6893, -6.2019997, 46.4111, -3.3446002, -6.2019997, 46.4111, -3.3446002, -8.1437, 52.156597, -6.6893, -8.1437, 52.156597, -6.6893, -7.286, 49.6186, -6.6893, -7.286, 49.6186, -3.3446002, -6.2019997, 46.4111, -3.3446002, -7.286, 49.6186, -3.3446002, -8.1437, 52.156597, -6.6893, -7.286, 49.6186, -3.3446002, -7.286, 49.6186, -3.3446002, -7.286, 49.6186, -3.3446002, -6.2019997, 46.4111, 0, -6.2019997, 46.4111, 0, -8.1437, 52.156597, -3.3446002, -8.1437, 52.156597, -3.3446002, -7.286, 49.6186, -3.3446002, -7.286, 49.6186, 0, -6.2019997, 46.4111, 0, -7.286, 49.6186, 0, -8.1437, 52.156597, -3.3446002, -7.286, 49.6186, 0, -7.286, 49.6186, 0, -7.286, 49.6186, 0, -6.2019997, 46.4111, 3.3446, -6.2019997, 46.4111, 3.3446, -8.1437, 52.156597, 0, -8.1437, 52.156597, 0, -7.286, 49.6186, 0, -7.286, 49.6186, 3.3446, -6.2019997, 46.4111, 3.3446, -7.286, 49.6186, 3.3446, -8.1437, 52.156597, 0, -7.286, 49.6186, 3.3446, -7.286, 49.6186, 3.3446, -7.286, 49.6186, 3.3446, -6.2019997, 46.4111, 6.6893, -6.2019997, 46.4111, 6.6893, -8.1437, 52.156597, 3.3446, -8.1437, 52.156597, 3.3446, -7.286, 49.6186, 3.3446, -7.286, 49.6186, 6.6893, -6.2019997, 46.4111, 6.6893, -7.286, 49.6186, 6.6893, -8.1437, 52.156597, 3.3446, -7.286, 49.6186, 6.6893, -7.286, 49.6186, 6.6893, -7.286, 49.6186, 6.6893, -6.2019997, 46.4111, 10.033899, -6.2019997, 46.4111, 10.033899, -8.1437, 52.156597, 6.6893, -8.1437, 52.156597, 6.6893, -7.286, 49.6186, 6.6893, -7.286, 49.6186, 10.033899, -6.2019997, 46.4111, 10.033899, -7.286, 49.6186, 10.033899, -8.1437, 52.156597, 6.6893, -7.286, 49.6186, 10.033899, -7.286, 49.6186, 10.033899, -7.286, 49.6186, 10.033899, -6.2019997, 46.4111, 13.378599, -6.2019997, 46.4111, 13.378599, -8.1437, 52.156597, 10.033899, -8.1437, 52.156597, 10.033899, -7.286, 49.6186, 10.033899, -7.286, 49.6186, 13.378599, -6.2019997, 46.4111, 13.378599, -7.286, 49.6186, 13.378599, -8.1437, 52.156597, 10.033899, -7.286, 49.6186, 13.378599, -7.286, 49.6186, 13.378599, -7.286, 49.6186, 13.378599, -6.2019997, 46.4111, 16.7232, -6.2019997, 46.4111, 16.7232, -8.1437, 52.156597, 13.378599, -8.1437, 52.156597, 13.378599, -7.286, 49.6186, 13.378599, -7.286, 49.6186, 16.7232, -6.2019997, 46.4111, 16.7232, -7.286, 49.6186, 16.7232, -8.1437, 52.156597, 13.378599, -7.286, 49.6186, 16.7232, -7.286, 49.6186, 20.0679, -6.2019997, 46.4111, 16.7232, -7.286, 49.6186, 16.7232, -6.2019997, 46.4111, 20.0679, -7.286, 49.6186, 16.7232, -8.1437, 52.156597, 16.7232, -7.286, 49.6186, 20.0679, -6.2019997, 46.4111, 20.0679, -7.286, 49.6186, 16.7232, -7.286, 49.6186, 20.0679, -7.286, 49.6186, 20.0679, -8.1437, 52.156597, 16.7232, -8.1437, 52.156597, 20.0679, -4.9595, 42.7343, 20.0679, -6.2019997, 46.4111, 16.7232, -6.2019997, 46.4111, 20.0679, -8.1437, 52.156597, 20.0679, -7.286, 49.6186, 23.412498, -7.286, 49.6186, 20.0679, -8.1437, 52.156597, 23.412498, -7.286, 49.6186, 23.412498, -8.1437, 52.156597, 26.7582, -7.286, 49.6186, 23.412498, -8.1437, 52.156597, 23.412498, -7.286, 49.6186, 26.7582, -7.286, 49.6186, 26.7582, -8.1437, 52.156597, 23.412498, -8.1437, 52.156597, 26.7582, -6.2019997, 46.4111, 26.7582, -7.286, 49.6186, 23.412498, -7.286, 49.6186, 20.0679, -7.286, 49.6186, 23.412498, -6.2019997, 46.4111, 23.412498, -7.286, 49.6186, 26.7582, -6.2019997, 46.4111, 23.412498, -7.286, 49.6186, 23.412498, -6.2019997, 46.4111, 20.0679, -7.286, 49.6186, 20.0679, -6.2019997, 46.4111, 23.412498, -6.2019997, 46.4111, 26.7582, -4.9595, 42.7343, 26.7582, -6.2019997, 46.4111, 23.412498, -6.2019997, 46.4111, 20.0679, -6.2019997, 46.4111, 20.0679, -4.9595, 42.7343, 23.412498, -4.9595, 42.7343, 20.0679, -6.2019997, 46.4111, 23.412498, -4.9595, 42.7343, 23.412498, -6.2019997, 46.4111, 26.7582, -4.9595, 42.7343, 23.412498, -6.2019997, 46.4111, 23.412498, -4.9595, 42.7343, 20.0679, -4.9595, 42.7343, 23.412498, -3.8518999, 39.456898, 23.412498, -4.9595, 42.7343, 23.412498, -3.8518999, 39.456898, 26.7582, -4.9595, 42.7343, 23.412498, -4.9595, 42.7343, 23.412498, -3.8518999, 39.456898, 26.7582, -3.8518999, 39.456898, 26.7582, -4.9595, 42.7343, -26.7572, -1.2701, 26.7572, -26.7572, -2.0054, 30.3737, -28.645699, -2.01, 28.5121, -28.645699, -2.01, 28.5121, -30.426, -2.0144, 26.7572, -26.7572, -1.2701, 26.7572, -28.447899, -2.6727, 31.969099, -28.645699, -2.01, 28.5121, -26.7572, -2.0054, 30.3737, -26.7572, -2.0054, 30.3737, -26.7572, -2.6892, 33.737698, -28.447899, -2.6727, 31.969099, -30.291101, -2.6547, 30.040998, -30.426, -2.0144, 26.7572, -28.645699, -2.01, 28.5121, -28.447899, -2.6727, 31.969099, -30.291101, -2.6547, 30.040998, -28.645699, -2.01, 28.5121, -30.291101, -2.6547, 30.040998, -32.027798, -2.6376998, 28.2244, -30.426, -2.0144, 26.7572, -32.027798, -2.6376998, 28.2244, -33.4304, -2.6239998, 26.7572, -30.426, -2.0144, 26.7572, -29.8963, -3.2444, 33.336, -30.291101, -2.6547, 30.040998, -28.447899, -2.6727, 31.969099, -26.7572, -2.6892, 33.737698, -29.8963, -3.2444, 33.336, -28.447899, -2.6727, 31.969099, -31.7465, -3.2247999, 31.3933, -32.027798, -2.6376998, 28.2244, -30.291101, -2.6547, 30.040998, -29.8963, -3.2444, 33.336, -31.7465, -3.2247999, 31.3933, -30.291101, -2.6547, 30.040998, -26.7572, -2.6892, 33.737698, -28.188799, -3.2624998, 35.128998, -29.8963, -3.2444, 33.336, -28.188799, -3.2624998, 35.128998, -26.7572, -2.6892, 33.737698, -26.7572, -3.2777, 36.6322, -29.5455, -3.8058, 36.4474, -29.8963, -3.2444, 33.336, -28.188799, -3.2624998, 35.128998, -26.7572, -3.2777, 36.6322, -29.5455, -3.8058, 36.4474, -28.188799, -3.2624998, 35.128998, -26.7572, -3.2777, 36.6322, -28.1288, -3.8291998, 37.976498, -29.5455, -3.8058, 36.4474, -28.1288, -3.8291998, 37.976498, -26.7572, -3.2777, 36.6322, -26.7572, -3.8518999, 39.456898, -29.5455, -3.8058, 36.4474, -31.247301, -3.7775998, 34.6107, -29.8963, -3.2444, 33.336, -31.247301, -3.7775998, 34.6107, -31.7465, -3.2247999, 31.3933, -29.8963, -3.2444, 33.336, -31.247301, -3.7775998, 34.6107, -33.0801, -3.7473, 32.6325, -31.7465, -3.2247999, 31.3933, -33.0801, -3.7473, 32.6325, -33.4894, -3.2064, 29.5632, -31.7465, -3.2247999, 31.3933, -31.7465, -3.2247999, 31.3933, -33.4894, -3.2064, 29.5632, -32.027798, -2.6376998, 28.2244, -33.4894, -3.2064, 29.5632, -33.4304, -2.6239998, 26.7572, -32.027798, -2.6376998, 28.2244, -33.0801, -3.7473, 32.6325, -34.806297, -3.7187998, 30.769499, -33.4894, -3.2064, 29.5632, -33.4894, -3.2064, 29.5632, -34.9099, -3.1913, 28.0716, -33.4304, -2.6239998, 26.7572, -34.806297, -3.7187998, 30.769499, -34.9099, -3.1913, 28.0716, -33.4894, -3.2064, 29.5632, -34.9099, -3.1913, 28.0716, -36.161697, -3.1780999, 26.7572, -33.4304, -2.6239998, 26.7572, -34.806297, -3.7187998, 30.769499, -36.2241, -3.6952999, 29.2393, -34.9099, -3.1913, 28.0716, -36.2241, -3.6952999, 29.2393, -36.161697, -3.1780999, 26.7572, -34.9099, -3.1913, 28.0716, -36.2241, -3.6952999, 29.2393, -37.4711, -3.6747, 27.8934, -36.161697, -3.1780999, 26.7572, -37.4711, -3.6747, 27.8934, -38.5239, -3.6573, 26.7572, -36.161697, -3.1780999, 26.7572, -50.290497, -8.1437, 26.7572, -47.4473, -7.0596, 26.7572, -49.074398, -8.1437, 28.0697, -62.057194, -10.4337, 26.7572, -58.463497, -9.7343, 26.7572, -60.611, -10.4337, 28.3335, 26.7582, -9.8364, 61.822598, 66.1166, -10.4337, 26.7572, 26.7582, -10.4337, 65.2334, 26.7582, -9.8364, 61.822598, 62.4636, -9.7961, 26.7572, 66.1166, -10.4337, 26.7572, 26.7582, -9.1788, 58.067497, 62.4636, -9.7961, 26.7572, 26.7582, -9.8364, 61.822598, 26.7582, -9.1788, 58.067497, 58.918198, -9.177199, 26.7572, 62.4636, -9.7961, 26.7572, 26.7582, -9.1788, 58.067497, 55.849197, -8.6414995, 26.7572, 58.918198, -9.177199, 26.7572, 55.849197, -8.6414995, 26.7572, 26.7582, -9.1788, 58.067497, 52.997097, -8.1437, 26.7572, 52.997097, -8.1437, 26.7572, 26.7582, -9.1788, 58.067497, 26.7582, -8.1437, 52.156597, 26.7582, -8.1437, 52.156597, 26.7582, -9.1788, 58.067497, 26.7582, -8.658199, 55.0947, 43.234898, -4.8054, 26.7572, 26.7582, -3.8518999, 39.456898, 39.877598, -3.6573, 26.7572, 46.577698, -5.9484997, 26.7572, 26.7582, -3.8518999, 39.456898, 43.234898, -4.8054, 26.7572, 46.577698, -5.9484997, 26.7572, 26.7582, -6.2019997, 46.4111, 26.7582, -3.8518999, 39.456898, 26.7582, -3.8518999, 39.456898, 26.7582, -6.2019997, 46.4111, 26.7582, -4.9595, 42.7343, 26.7582, -6.2019997, 46.4111, 46.577698, -5.9484997, 26.7572, 26.7582, -8.1437, 52.156597, 26.7582, -6.2019997, 46.4111, 26.7582, -8.1437, 52.156597, 26.7582, -7.286, 49.6186, 26.7582, -8.1437, 52.156597, 46.577698, -5.9484997, 26.7572, 49.5743, -6.9732, 26.7572, 26.7582, -8.1437, 52.156597, 49.5743, -6.9732, 26.7572, 52.997097, -8.1437, 26.7572, 29.1145, -2.5956, 26.7572, 26.7582, -3.0839999, 30.2834, 26.7582, -2.7837, 26.6955, 29.1145, -2.5956, 26.7572, 26.7582, -3.3683999, 33.680798, 26.7582, -3.0839999, 30.2834, 33.146698, -3.214, 26.7572, 26.7582, -3.3683999, 33.680798, 29.1145, -2.5956, 26.7572, 33.146698, -3.214, 26.7572, 26.7582, -3.6130998, 36.6041, 26.7582, -3.3683999, 33.680798, 26.7582, -3.6130998, 36.6041, 33.146698, -3.214, 26.7572, 39.877598, -3.6573, 26.7572, 39.877598, -3.6573, 26.7572, 33.146698, -3.214, 26.7572, 36.078598, -3.0746999, 26.7572, 26.7582, -3.6130998, 36.6041, 39.877598, -3.6573, 26.7572, 26.7582, -3.8518999, 39.456898, 26.7573, -1.7447, -30.111198, 29.3928, -1.796, -26.7572, 26.7573, -1.3222, -26.7572, 26.7572, -2.5274, -33.9013, 29.3928, -1.796, -26.7572, 26.7573, -1.7447, -30.111198, 29.3928, -1.796, -26.7572, 26.7572, -2.5274, -33.9013, 26.7572, -3.9166, -40.6287, 26.7572, -3.9166, -40.6287, 26.7572, -2.5274, -33.9013, 26.7572, -3.2101, -37.2077, 29.3928, -1.796, -26.7572, 26.7572, -3.9166, -40.6287, 36.0678, -2.9959998, -26.7572, 36.0678, -2.9959998, -26.7572, 26.7572, -3.9166, -40.6287, 39.877598, -3.6808999, -26.7572, 29.3928, -1.796, -26.7572, 36.0678, -2.9959998, -26.7572, 32.9589, -2.4371, -26.7572, 49.4036, -6.9384, -26.7572, 26.7572, -8.403, -54.500298, 52.997097, -8.1672, -26.7572, 46.2278, -5.8524, -26.7572, 26.7572, -8.403, -54.500298, 49.4036, -6.9384, -26.7572, 26.7572, -8.403, -54.500298, 46.2278, -5.8524, -26.7572, 26.7572, -3.9166, -40.6287, 26.7572, -3.9166, -40.6287, 46.2278, -5.8524, -26.7572, 42.8416, -4.6944, -26.7572, 26.7572, -3.9166, -40.6287, 42.8416, -4.6944, -26.7572, 39.877598, -3.6808999, -26.7572, 26.7572, -8.403, -54.500298, 26.7572, -3.9166, -40.6287, 26.7572, -6.2504, -47.8447, 26.7572, -6.2504, -47.8447, 26.7572, -3.9166, -40.6287, 26.7572, -5.1514, -44.446598, 26.7572, -8.403, -54.500298, 26.7572, -6.2504, -47.8447, 26.7572, -7.3550997, -51.2602, 62.356697, -9.8008995, -26.7572, 26.7572, -10.693, -68.371895, 66.1166, -10.4572, -26.7572, 59.4335, -9.2907, -26.7572, 26.7572, -10.693, -68.371895, 62.356697, -9.8008995, -26.7572, 26.7572, -10.693, -68.371895, 59.4335, -9.2907, -26.7572, 26.7572, -9.312699, -60.011097, 26.7572, -10.693, -68.371895, 26.7572, -9.312699, -60.011097, 26.7572, -9.876599, -63.426796, 26.7572, -9.312699, -60.011097, 59.4335, -9.2907, -26.7572, 56.4827, -8.7755995, -26.7572, 26.7572, -9.312699, -60.011097, 56.4827, -8.7755995, -26.7572, 26.7572, -8.881, -57.3956, 26.7572, -8.881, -57.3956, 56.4827, -8.7755995, -26.7572, 52.997097, -8.1672, -26.7572, 26.7572, -8.881, -57.3956, 52.997097, -8.1672, -26.7572, 26.7572, -8.403, -54.500298, 26.7572, -10.693, -70.330795, 66.1166, -10.4572, -26.7572, 26.7572, -10.693, -68.371895, 26.7572, -10.693, -70.330795, 68.9481, -10.4572, -26.7572, 66.1166, -10.4572, -26.7572, 26.7572, -10.693, -73.1232, 68.9481, -10.4572, -26.7572, 26.7572, -10.693, -70.330795, 26.7572, -10.693, -73.1232, 72.2092, -10.4572, -26.7572, 68.9481, -10.4572, -26.7572, 26.7572, -10.693, -73.1232, 75.6957, -10.4572, -26.7572, 72.2092, -10.4572, -26.7572, 75.6957, -10.4572, -26.7572, 26.7572, -10.693, -73.1232, 26.7572, -10.693, -82.2434, 75.6957, -10.4572, -26.7572, 26.7572, -10.693, -82.2434, 79.236, -10.4572, -26.7572, 26.7572, -10.693, -82.2434, 26.7572, -10.693, -73.1232, 26.7572, -10.693, -79.5579, 26.7572, -10.693, -79.5579, 26.7572, -10.693, -73.1232, 26.7572, -10.693, -76.193, -30.173899, -3.2568, -26.7572, -26.7572, -3.2445998, -30.4851, -26.7572, -3.0929, -26.7572, -30.173899, -3.2568, -26.7572, -26.7572, -3.3862, -33.9664, -26.7572, -3.2445998, -30.4851, -30.173899, -3.2568, -26.7572, -26.7572, -3.5244, -37.3623, -26.7572, -3.3862, -33.9664, -26.7572, -3.5244, -37.3623, -30.173899, -3.2568, -26.7572, -36.0882, -3.5405, -26.7572, -36.0882, -3.5405, -26.7572, -30.173899, -3.2568, -26.7572, -33.2719, -3.4053998, -26.7572, -26.7572, -3.5244, -37.3623, -36.0882, -3.5405, -26.7572, -26.7572, -3.6573, -40.6287, -26.7572, -3.6573, -40.6287, -36.0882, -3.5405, -26.7572, -38.5239, -3.6573, -26.7572, -41.627, -4.8403997, -26.7572, -26.7572, -3.6573, -40.6287, -38.5239, -3.6573, -26.7572, -41.627, -4.8403997, -26.7572, -26.7572, -5.9270997, -47.646698, -26.7572, -3.6573, -40.6287, -26.7572, -3.6573, -40.6287, -26.7572, -5.9270997, -47.646698, -26.7572, -4.8125997, -44.200798, -44.537098, -5.95, -26.7572, -26.7572, -5.9270997, -47.646698, -41.627, -4.8403997, -26.7572, -26.7572, -5.9270997, -47.646698, -44.537098, -5.95, -26.7572, -50.290497, -8.1437, -26.7572, -50.290497, -8.1437, -26.7572, -44.537098, -5.95, -26.7572, -47.4473, -7.0596, -26.7572, -26.7572, -5.9270997, -47.646698, -50.290497, -8.1437, -26.7572, -26.7572, -7.1011, -51.2768, -26.7572, -7.1011, -51.2768, -50.290497, -8.1437, -26.7572, -26.7572, -8.1437, -54.500298, -53.117798, -8.6939, -26.7572, -26.7572, -8.1437, -54.500298, -50.290497, -8.1437, -26.7572, -55.5951, -9.176, -26.7572, -26.7572, -8.1437, -54.500298, -53.117798, -8.6939, -26.7572, -58.463497, -9.7343, -26.7572, -26.7572, -8.1437, -54.500298, -55.5951, -9.176, -26.7572, -26.7572, -8.1437, -54.500298, -58.463497, -9.7343, -26.7572, -26.7572, -9.7125, -64.0031, -26.7572, -9.7125, -64.0031, -58.463497, -9.7343, -26.7572, -62.057194, -10.4337, -26.7572, -26.7572, -9.7125, -64.0031, -62.057194, -10.4337, -26.7572, -26.7572, -10.4337, -68.371895, -26.7572, -8.1437, -54.500298, -26.7572, -9.7125, -64.0031, -26.7572, -9.111199, -60.361, -26.7572, -8.1437, -54.500298, -26.7572, -9.111199, -60.361, -26.7572, -8.6276, -57.4314, -64.963196, -10.4337, -26.7572, -26.7572, -10.4337, -68.371895, -62.057194, -10.4337, -26.7572, -64.963196, -10.4337, -26.7572, -26.7572, -10.4337, -70.9319, -26.7572, -10.4337, -68.371895, -64.963196, -10.4337, -26.7572, -62.057194, -10.4337, -26.7572, -62.057194, -10.4337, -23.412498, -68.2489, -10.4337, -26.7572, -26.7572, -10.4337, -70.9319, -64.963196, -10.4337, -26.7572, -68.2489, -10.4337, -26.7572, -26.7572, -10.4337, -73.7615, -26.7572, -10.4337, -70.9319, -64.963196, -10.4337, -26.7572, -62.057194, -10.4337, -23.412498, -64.963196, -10.4337, -23.412498, -68.2489, -10.4337, -26.7572, -64.963196, -10.4337, -26.7572, -64.963196, -10.4337, -23.412498, -64.963196, -10.4337, -23.412498, -62.057194, -10.4337, -23.412498, -62.057194, -10.4337, -20.174799, -71.2999, -10.4337, -26.7572, -26.7572, -10.4337, -73.7615, -68.2489, -10.4337, -26.7572, -71.2999, -10.4337, -26.7572, -26.7572, -10.4337, -76.6203, -26.7572, -10.4337, -73.7615, -26.7572, -10.4337, -76.6203, -71.2999, -10.4337, -26.7572, -26.7572, -10.4337, -79.0804, -26.7572, -10.4337, -79.0804, -71.2999, -10.4337, -26.7572, -26.7572, -10.4337, -82.2434, -26.7572, -10.4337, -82.2434, -71.2999, -10.4337, -26.7572, -73.8239, -10.4337, -26.7572, -73.8239, -10.4337, -23.412498, -73.8239, -10.4337, -26.7572, -71.2999, -10.4337, -26.7572, -68.2489, -10.4337, -26.7572, -64.963196, -10.4337, -23.412498, -68.2489, -10.4337, -23.412498, -71.2999, -10.4337, -26.7572, -68.2489, -10.4337, -26.7572, -68.2489, -10.4337, -23.412498, -73.8239, -10.4337, -23.412498, -71.2999, -10.4337, -26.7572, -71.2999, -10.4337, -23.412498, -71.2999, -10.4337, -26.7572, -68.2489, -10.4337, -23.412498, -71.2999, -10.4337, -23.412498, -73.8239, -10.4337, -20.0679, -73.8239, -10.4337, -23.412498, -71.2999, -10.4337, -23.412498, -73.8239, -10.4337, -20.0679, -71.2999, -10.4337, -23.412498, -71.2999, -10.4337, -20.0908, -71.2999, -10.4337, -23.412498, -68.2489, -10.4337, -20.118599, -71.2999, -10.4337, -20.0908, -71.2999, -10.4337, -23.412498, -68.2489, -10.4337, -23.412498, -68.2489, -10.4337, -20.118599, -71.2999, -10.4337, -20.0908, -68.2489, -10.4337, -20.118599, -68.2489, -10.4337, -16.7739, -68.2489, -10.4337, -20.118599, -64.963196, -10.4337, -16.803799, -68.2489, -10.4337, -16.7739, -68.2489, -10.4337, -23.412498, -64.963196, -10.4337, -20.1484, -68.2489, -10.4337, -20.118599, -68.2489, -10.4337, -20.118599, -64.963196, -10.4337, -20.1484, -64.963196, -10.4337, -16.803799, -68.2489, -10.4337, -23.412498, -64.963196, -10.4337, -23.412498, -64.963196, -10.4337, -20.1484, -62.057194, -10.4337, -20.174799, -64.963196, -10.4337, -16.803799, -64.963196, -10.4337, -20.1484, -64.963196, -10.4337, -23.412498, -62.057194, -10.4337, -20.174799, -64.963196, -10.4337, -20.1484, -3.3446002, -1.458, -26.7572, -6.6709, -1.7958, -30.683697, -3.3313003, -1.7853999, -30.628498, -3.3446002, -1.458, -26.7572, -6.6893, -1.458, -26.7572, -6.6709, -1.7958, -30.683697, -6.6893, -3.6573, -40.6287, -6.6689, -4.8491, -44.313698, -6.6243997, -3.6573, -40.6287, -6.6689, -4.8491, -44.313698, -3.3446002, -3.6573, -40.6287, -6.6243997, -3.6573, -40.6287, -6.6893, -3.6573, -40.6287, -9.908199, -3.6573, -40.6287, -6.6689, -4.8491, -44.313698, -6.6689, -4.8491, -44.313698, -3.297, -3.6573, -40.6287, -3.3446002, -3.6573, -40.6287, -6.6689, -4.8491, -44.313698, -9.908199, -3.6573, -40.6287, -9.969999, -4.8431, -44.295097, -10.033899, -3.6573, -40.6287, -9.969999, -4.8431, -44.295097, -9.908199, -3.6573, -40.6287, -9.969999, -4.8431, -44.295097, -10.033899, -3.6573, -40.6287, -13.0655, -3.6573, -40.6287, -9.969999, -4.8431, -44.295097, -13.0655, -3.6573, -40.6287, -13.160999, -4.8373, -44.2772, -13.378601, -3.6573, -40.6287, -13.160999, -4.8373, -44.2772, -13.0655, -3.6573, -40.6287, -13.160999, -4.8373, -44.2772, -13.378601, -3.6573, -40.6287, -16.3079, -3.6573, -40.6287, -13.160999, -4.8373, -44.2772, -16.3079, -3.6573, -40.6287, -16.4166, -4.8314, -44.2589, -16.7232, -3.6573, -40.6287, -16.4166, -4.8314, -44.2589, -16.3079, -3.6573, -40.6287, -16.4166, -4.8314, -44.2589, -16.7232, -3.6573, -40.6287, -19.5913, -3.6573, -40.6287, -16.4166, -4.8314, -44.2589, -19.5913, -3.6573, -40.6287, -19.7153, -4.8254, -44.2403, -20.0679, -3.6573, -40.6287, -19.7153, -4.8254, -44.2403, -19.5913, -3.6573, -40.6287, -19.7153, -4.8254, -44.2403, -20.0679, -3.6573, -40.6287, -22.8746, -3.6573, -40.6287, -19.7153, -4.8254, -44.2403, -22.8746, -3.6573, -40.6287, -23.013899, -4.8194, -44.221798, -23.412498, -3.6573, -40.6287, -23.013899, -4.8194, -44.221798, -22.8746, -3.6573, -40.6287, -23.013899, -4.8194, -44.221798, -23.412498, -3.6573, -40.6287, -26.7572, -3.6573, -40.6287, -23.013899, -4.8194, -44.221798, -26.7572, -3.6573, -40.6287, -26.7572, -4.8125997, -44.200798, -26.7572, -4.8125997, -44.200798, -23.1474, -5.9323997, -47.6632, -23.013899, -4.8194, -44.221798, -26.7572, -4.8125997, -44.200798, -26.7572, -5.9270997, -47.646698, -23.1474, -5.9323997, -47.6632, -23.013899, -4.8194, -44.221798, -19.8335, -5.9372997, -47.6783, -19.7153, -4.8254, -44.2403, -23.013899, -4.8194, -44.221798, -23.1474, -5.9323997, -47.6632, -19.8335, -5.9372997, -47.6783, -19.7153, -4.8254, -44.2403, -19.8335, -5.9372997, -47.6783, -16.5194, -5.9421997, -47.6935, -19.7153, -4.8254, -44.2403, -16.5194, -5.9421997, -47.6935, -16.4166, -4.8314, -44.2589, -26.7572, -5.9270997, -47.646698, -23.2876, -7.1015997, -51.2782, -23.1474, -5.9323997, -47.6632, -26.7572, -5.9270997, -47.646698, -26.7572, -7.1011, -51.2768, -23.2876, -7.1015997, -51.2782, -26.7572, -7.1011, -51.2768, -23.412498, -8.1437, -54.500298, -23.2876, -7.1015997, -51.2782, -26.7572, -7.1011, -51.2768, -26.7572, -8.1437, -54.500298, -23.412498, -8.1437, -54.500298, -23.2876, -7.1015997, -51.2782, -23.412498, -8.1437, -54.500298, -20.0679, -8.1437, -54.500298, -23.1474, -5.9323997, -47.6632, -23.2876, -7.1015997, -51.2782, -19.9572, -7.1019998, -51.2795, -23.2876, -7.1015997, -51.2782, -20.0679, -8.1437, -54.500298, -19.9572, -7.1019998, -51.2795, -23.1474, -5.9323997, -47.6632, -19.9572, -7.1019998, -51.2795, -19.8335, -5.9372997, -47.6783, -19.9572, -7.1019998, -51.2795, -20.0679, -8.1437, -54.500298, -16.7232, -8.1437, -54.500298, -19.8335, -5.9372997, -47.6783, -19.9572, -7.1019998, -51.2795, -16.626799, -7.1024, -51.2808, -19.9572, -7.1019998, -51.2795, -16.7232, -8.1437, -54.500298, -16.626799, -7.1024, -51.2808, -19.8335, -5.9372997, -47.6783, -16.626799, -7.1024, -51.2808, -16.5194, -5.9421997, -47.6935, -16.626799, -7.1024, -51.2808, -16.7232, -8.1437, -54.500298, -13.4286, -8.1437, -54.500298, -16.5194, -5.9421997, -47.6935, -16.626799, -7.1024, -51.2808, -13.344299, -7.1029, -51.282097, -16.626799, -7.1024, -51.2808, -13.4286, -8.1437, -54.500298, -13.344299, -7.1029, -51.282097, -16.5194, -5.9421997, -47.6935, -13.344299, -7.1029, -51.282097, -13.250801, -5.947, -47.708397, -16.4166, -4.8314, -44.2589, -16.5194, -5.9421997, -47.6935, -13.250801, -5.947, -47.708397, -16.4166, -4.8314, -44.2589, -13.250801, -5.947, -47.708397, -13.160999, -4.8373, -44.2772, -13.4286, -8.1437, -54.500298, -10.0877, -7.1032996, -51.283398, -13.344299, -7.1029, -51.282097, -13.250801, -5.947, -47.708397, -13.344299, -7.1029, -51.282097, -10.0877, -7.1032996, -51.283398, -10.0877, -7.1032996, -51.283398, -13.4286, -8.1437, -54.500298, -13.378601, -8.1437, -54.500298, -10.0877, -7.1032996, -51.283398, -13.378601, -8.1437, -54.500298, -10.141901, -8.1437, -54.500298, -13.160999, -4.8373, -44.2772, -13.250801, -5.947, -47.708397, -10.0277, -5.9518, -47.723198, -13.250801, -5.947, -47.708397, -10.0877, -7.1032996, -51.283398, -10.0277, -5.9518, -47.723198, -13.160999, -4.8373, -44.2772, -10.0277, -5.9518, -47.723198, -9.969999, -4.8431, -44.295097, -10.141901, -8.1437, -54.500298, -6.7531, -7.1036997, -51.284798, -10.0877, -7.1032996, -51.283398, -10.0277, -5.9518, -47.723198, -10.0877, -7.1032996, -51.283398, -6.7531, -7.1036997, -51.284798, -6.7531, -7.1036997, -51.284798, -10.141901, -8.1437, -54.500298, -10.033899, -8.1437, -54.500298, -6.7531, -7.1036997, -51.284798, -10.033899, -8.1437, -54.500298, -6.7919, -8.1437, -54.500298, -6.6893, -8.1437, -54.500298, -6.7531, -7.1036997, -51.284798, -6.7919, -8.1437, -54.500298, -6.7531, -7.1036997, -51.284798, -6.6893, -8.1437, -54.500298, -3.4199996, -8.1437, -54.500298, -9.969999, -4.8431, -44.295097, -10.0277, -5.9518, -47.723198, -6.7102, -5.9567, -47.7383, -10.0277, -5.9518, -47.723198, -6.7531, -7.1036997, -51.284798, -6.7102, -5.9567, -47.7383, -9.969999, -4.8431, -44.295097, -6.7102, -5.9567, -47.7383, -6.6689, -4.8491, -44.313698, -6.7531, -7.1036997, -51.284798, -3.4199996, -8.1437, -54.500298, -3.3915, -7.1040998, -51.2861, -3.3915, -7.1040998, -51.2861, -6.7102, -5.9567, -47.7383, -6.7531, -7.1036997, -51.284798, -3.3446002, -8.1437, -54.500298, -3.3915, -7.1040998, -51.2861, -3.4199996, -8.1437, -54.500298, -3.3915, -7.1040998, -51.2861, -3.3446002, -8.1437, -54.500298, -0.048199892, -8.1437, -54.500298, -3.3915, -7.1040998, -51.2861, -3.3602, -5.9617, -47.753597, -6.7102, -5.9567, -47.7383, -3.3602, -5.9617, -47.753597, -6.6689, -4.8491, -44.313698, -6.7102, -5.9567, -47.7383, -3.3915, -7.1040998, -51.2861, -0.048199892, -8.1437, -54.500298, -0.03699994, -7.1046, -51.2874, -0.03699994, -7.1046, -51.2874, -3.3602, -5.9617, -47.753597, -3.3915, -7.1040998, -51.2861, 0, -8.1437, -54.500298, -0.03699994, -7.1046, -51.2874, -0.048199892, -8.1437, -54.500298, -0.03699994, -7.1046, -51.2874, 0, -8.1437, -54.500298, 3.3446, -8.1437, -54.500298, -3.3602, -5.9617, -47.753597, -3.3298001, -4.8552, -44.3325, -6.6689, -4.8491, -44.313698, -3.297, -3.6573, -40.6287, -6.6689, -4.8491, -44.313698, -3.3298001, -4.8552, -44.3325, -0.03699994, -7.1046, -51.2874, -0.024800062, -5.9666, -47.768898, -3.3602, -5.9617, -47.753597, -0.024800062, -5.9666, -47.768898, -3.3298001, -4.8552, -44.3325, -3.3602, -5.9617, -47.753597, -0.012900114, -4.8612, -44.351097, -3.297, -3.6573, -40.6287, -3.3298001, -4.8552, -44.3325, -0.024800062, -5.9666, -47.768898, -0.012900114, -4.8612, -44.351097, -3.3298001, -4.8552, -44.3325, -0.012900114, -4.8612, -44.351097, 0, -3.6573, -40.6287, -3.297, -3.6573, -40.6287, 3.3446, -7.105, -51.2888, -0.024800062, -5.9666, -47.768898, -0.03699994, -7.1046, -51.2874, -0.03699994, -7.1046, -51.2874, 3.3446, -8.1437, -54.500298, 3.3446, -7.105, -51.2888, 3.3446, -5.9716, -47.7842, -0.012900114, -4.8612, -44.351097, -0.024800062, -5.9666, -47.768898, 3.3446, -7.105, -51.2888, 3.3446, -5.9716, -47.7842, -0.024800062, -5.9666, -47.768898, 3.3446, -4.8673, -44.37, 0, -3.6573, -40.6287, -0.012900114, -4.8612, -44.351097, 3.3446, -5.9716, -47.7842, 3.3446, -4.8673, -44.37, -0.012900114, -4.8612, -44.351097, 3.3446, -4.8673, -44.37, 3.3446, -3.6573, -40.6287, 0, -3.6573, -40.6287, 3.3446, -8.1437, -54.500298, 6.6893, -7.1053996, -51.2901, 3.3446, -7.105, -51.2888, 6.6893, -7.1053996, -51.2901, 3.3446, -5.9716, -47.7842, 3.3446, -7.105, -51.2888, 3.3446, -8.1437, -54.500298, 6.6893, -8.1437, -54.500298, 6.6893, -7.1053996, -51.2901, 6.6893, -5.9765, -47.7995, 3.3446, -4.8673, -44.37, 3.3446, -5.9716, -47.7842, 6.6893, -7.1053996, -51.2901, 6.6893, -5.9765, -47.7995, 3.3446, -5.9716, -47.7842, 6.6893, -4.8733997, -44.388798, 3.3446, -3.6573, -40.6287, 3.3446, -4.8673, -44.37, 6.6893, -5.9765, -47.7995, 6.6893, -4.8733997, -44.388798, 3.3446, -4.8673, -44.37, 6.6893, -4.8733997, -44.388798, 6.6893, -3.6573, -40.6287, 3.3446, -3.6573, -40.6287, 6.6893, -8.1437, -54.500298, 10.033899, -7.1059, -51.291397, 6.6893, -7.1053996, -51.2901, 10.033899, -7.1059, -51.291397, 6.6893, -5.9765, -47.7995, 6.6893, -7.1053996, -51.2901, 6.6893, -8.1437, -54.500298, 10.033899, -8.1437, -54.500298, 10.033899, -7.1059, -51.291397, 13.378599, -8.1437, -54.500298, 10.033899, -7.1059, -51.291397, 10.033899, -8.1437, -54.500298, 10.033899, -7.1059, -51.291397, 13.378599, -8.1437, -54.500298, 13.444599, -8.1437, -54.500298, 10.033899, -4.8795, -44.4076, 6.6893, -3.6573, -40.6287, 6.6893, -4.8733997, -44.388798, 10.033899, -5.9814, -47.8148, 6.6893, -4.8733997, -44.388798, 6.6893, -5.9765, -47.7995, 10.033899, -7.1059, -51.291397, 10.033899, -5.9814, -47.8148, 6.6893, -5.9765, -47.7995, 10.033899, -5.9814, -47.8148, 10.033899, -4.8795, -44.4076, 6.6893, -4.8733997, -44.388798, 10.033899, -7.1059, -51.291397, 13.444599, -8.1437, -54.500298, 13.429298, -7.1063, -51.292797, 13.429298, -7.1063, -51.292797, 10.033899, -5.9814, -47.8148, 10.033899, -7.1059, -51.291397, 10.033899, -4.8795, -44.4076, 10.033899, -3.6573, -40.6287, 6.6893, -3.6573, -40.6287, 16.7232, -8.1437, -54.500298, 13.429298, -7.1063, -51.292797, 13.444599, -8.1437, -54.500298, 13.429298, -7.1063, -51.292797, 16.7232, -8.1437, -54.500298, 16.8188, -8.1437, -54.500298, 13.412899, -5.9863997, -47.8302, 10.033899, -4.8795, -44.4076, 10.033899, -5.9814, -47.8148, 13.429298, -7.1063, -51.292797, 13.412899, -5.9863997, -47.8302, 10.033899, -5.9814, -47.8148, 13.3967, -4.8856, -44.4265, 10.033899, -3.6573, -40.6287, 10.033899, -4.8795, -44.4076, 13.412899, -5.9863997, -47.8302, 13.3967, -4.8856, -44.4265, 10.033899, -4.8795, -44.4076, 13.3967, -4.8856, -44.4265, 13.378599, -3.6573, -40.6287, 10.033899, -3.6573, -40.6287, 13.429298, -7.1063, -51.292797, 16.8188, -8.1437, -54.500298, 16.7967, -7.1067, -51.294098, 16.7967, -7.1067, -51.294098, 13.412899, -5.9863997, -47.8302, 13.429298, -7.1063, -51.292797, 20.0679, -8.1437, -54.500298, 16.7967, -7.1067, -51.294098, 16.8188, -8.1437, -54.500298, 16.7967, -7.1067, -51.294098, 20.0679, -8.1437, -54.500298, 20.1975, -8.1437, -54.500298, 16.7967, -7.1067, -51.294098, 20.1975, -8.1437, -54.500298, 20.1675, -7.1071997, -51.295498, 16.7967, -7.1067, -51.294098, 16.772999, -5.9914, -47.8456, 13.412899, -5.9863997, -47.8302, 20.1675, -7.1071997, -51.295498, 16.772999, -5.9914, -47.8456, 16.7967, -7.1067, -51.294098, 16.772999, -5.9914, -47.8456, 13.3967, -4.8856, -44.4265, 13.412899, -5.9863997, -47.8302, 20.1675, -7.1071997, -51.295498, 20.135399, -5.9964, -47.861, 16.772999, -5.9914, -47.8456, 16.7495, -4.8917, -44.445297, 13.378599, -3.6573, -40.6287, 13.3967, -4.8856, -44.4265, 16.772999, -5.9914, -47.8456, 16.7495, -4.8917, -44.445297, 13.3967, -4.8856, -44.4265, 20.135399, -5.9964, -47.861, 16.7495, -4.8917, -44.445297, 16.772999, -5.9914, -47.8456, 16.7495, -4.8917, -44.445297, 16.7232, -3.6573, -40.6287, 13.378599, -3.6573, -40.6287, 20.135399, -5.9964, -47.861, 20.103699, -4.8978, -44.4642, 16.7495, -4.8917, -44.445297, 20.103699, -4.8978, -44.4642, 16.7232, -3.6573, -40.6287, 16.7495, -4.8917, -44.445297, 20.103699, -4.8978, -44.4642, 20.0679, -3.6573, -40.6287, 16.7232, -3.6573, -40.6287, 16.7232, 0, 10.033899, 17.4912, 0.0034999999, 7.4080997, 20.0679, 0, 10.033899, 12.824999, 2.8544, 7.9234, 11.2783985, 2.1174998, 3.3446, 12.705599, 1.0321, 4.0927, 12.824999, 2.8544, 7.9234, 11.173899, 3.3332, 6.6554, 11.2783985, 2.1174998, 3.3446, 10.033899, 3.1929998, 0, 13.249599, 2.9931998, -3.4737, 11.278099, 2.3706, 0, 10.033899, 3.1929998, 0, 10.033899, 3.2212, -2.2307, 13.249599, 2.9931998, -3.4737, 20.613499, 1.0832, -3.1922002, 22.5396, -0.014599999, -3.3446002, 20.5402, -0.0411, -1.7683, 20.613499, 1.0832, -3.1922002, 21.09, -0.0218, -4.9179, 22.5396, -0.014599999, -3.3446002, 15.485399, 1.0792, -1.6708999, 14.217899, 2.8779, -3.3838, 15.6619, 2.2603, -2.7998996, 20.613499, 1.0832, -3.1922002, 15.485399, 1.0792, -1.6708999, 15.6619, 2.2603, -2.7998996, 20.613499, 1.0832, -3.1922002, 20.5402, -0.0411, -1.7683, 15.485399, 1.0792, -1.6708999, 20.5402, -0.0411, -1.7683, 23.412498, 0, 0, 20.2292, 0.030499998, -0.05219996, 23.412498, 0, 0, 20.5402, -0.0411, -1.7683, 22.5396, -0.014599999, -3.3446002, 23.412498, 0, 0, 22.5396, -0.014599999, -3.3446002, 23.412498, 0, -3.3446002, 21.09, -0.0218, -4.9179, 23.412498, 0, -6.6893, 22.5396, -0.014599999, -3.3446002, 21.09, -0.0218, -4.9179, 21.2349, 0, -6.6893, 23.412498, 0, -6.6893, 15.485399, 1.0792, -1.6708999, 20.2292, 0.030499998, -0.05219996, 14.261799, 0.9069, 1.1807, 14.217899, 2.8779, -3.3838, 11.278099, 2.3706, 0, 13.249599, 2.9931998, -3.4737, 11.278099, 2.3706, 0, 14.217899, 2.8779, -3.3838, 15.485399, 1.0792, -1.6708999, 11.278099, 2.3706, 0, 15.485399, 1.0792, -1.6708999, 14.261799, 0.9069, 1.1807, 15.485399, 1.0792, -1.6708999, 20.5402, -0.0411, -1.7683, 20.2292, 0.030499998, -0.05219996, 10.033899, 3.3913999, 4.2546997, 11.2783985, 2.1174998, 3.3446, 11.173899, 3.3332, 6.6554, 10.033899, 3.3913999, 4.2546997, 10.033899, 3.1929998, 3.3446, 11.2783985, 2.1174998, 3.3446, 6.6893, 3.3913999, 3.3446, 10.033899, 3.1929998, 3.3446, 10.033899, 3.3913999, 4.2546997, 10.033899, 3.2212, -2.2307, 10.033899, 3.1929998, 0, 6.6893, 3.3913999, 0, 14.0257, 0.0442, 7.3252997, 12.824999, 2.8544, 7.9234, 12.705599, 1.0321, 4.0927, 14.0257, 0.0442, 7.3252997, 13.175798, 2.4743, 8.042, 12.824999, 2.8544, 7.9234, 26.7582, -0.83089995, 6.6893, 26.7582, -1.7623999, 10.033899, 23.412498, -0.35529998, 10.033899, 23.826399, -8.175799, -54.500298, 26.7572, -7.3550997, -51.2602, 23.7466, -7.1323, -51.2931, 23.826399, -8.175799, -54.500298, 26.7572, -8.403, -54.500298, 26.7572, -7.3550997, -51.2602, 26.7572, -7.3550997, -51.2602, 23.6614, -6.0197997, -47.8736, 23.7466, -7.1323, -51.2931, 26.7572, -7.3550997, -51.2602, 26.7572, -6.2504, -47.8447, 23.6614, -6.0197997, -47.8736, 26.7572, -6.2504, -47.8447, 23.577, -4.916, -44.481, 23.6614, -6.0197997, -47.8736, 26.7572, -6.2504, -47.8447, 26.7572, -5.1514, -44.446598, 23.577, -4.916, -44.481, 26.7572, -5.1514, -44.446598, 23.480999, -3.6625998, -40.6287, 23.577, -4.916, -44.481, 26.7572, -5.1514, -44.446598, 26.7572, -3.9166, -40.6287, 23.480999, -3.6625998, -40.6287, 23.808699, -10.464399, -68.371895, 26.7572, -9.876599, -63.426796, 23.8148, -9.6761, -63.593796, 23.808699, -10.464399, -68.371895, 26.7572, -10.693, -68.371895, 26.7572, -9.876599, -63.426796, 26.7572, -9.876599, -63.426796, 23.819199, -9.111899, -60.1742, 23.8148, -9.6761, -63.593796, 26.7572, -9.876599, -63.426796, 26.7572, -9.312699, -60.011097, 23.819199, -9.111899, -60.1742, 26.7572, -9.312699, -60.011097, 23.8225, -8.6786995, -57.548298, 23.819199, -9.111899, -60.1742, 26.7572, -9.312699, -60.011097, 26.7572, -8.881, -57.3956, 23.8225, -8.6786995, -57.548298, 26.7572, -8.881, -57.3956, 23.826399, -8.175799, -54.500298, 23.8225, -8.6786995, -57.548298, 26.7572, -8.881, -57.3956, 26.7572, -8.403, -54.500298, 23.826399, -8.175799, -54.500298, 23.480999, -3.6625998, -40.6287, 26.7572, -3.2101, -37.2077, 23.4646, -2.985, -37.2919, 23.480999, -3.6625998, -40.6287, 26.7572, -3.9166, -40.6287, 26.7572, -3.2101, -37.2077, 23.412498, -8.1437, -54.500298, 20.1675, -7.1071997, -51.295498, 20.1975, -8.1437, -54.500298, 20.1675, -7.1071997, -51.295498, 23.412498, -8.1437, -54.500298, 23.826399, -8.175799, -54.500298, 20.1675, -7.1071997, -51.295498, 23.826399, -8.175799, -54.500298, 23.7466, -7.1323, -51.2931, 23.412498, -10.4337, -68.371895, 20.112099, -9.6529, -63.642, 20.0679, -10.4337, -68.371895, 20.112099, -9.6529, -63.642, 23.412498, -10.4337, -68.371895, 23.808699, -10.464399, -68.371895, 20.112099, -9.6529, -63.642, 23.808699, -10.464399, -68.371895, 23.8148, -9.6761, -63.593796, 23.412498, -3.6573, -40.6287, 20.0679, -2.9615998, -37.315, 20.0679, -3.6573, -40.6287, 20.0679, -2.9615998, -37.315, 23.412498, -3.6573, -40.6287, 23.480999, -3.6625998, -40.6287, 20.0679, -2.9615998, -37.315, 23.480999, -3.6625998, -40.6287, 23.4646, -2.985, -37.2919, 16.7232, -3.6573, -40.6287, 20.0679, -2.9615998, -37.315, 16.7232, -2.9859998, -37.3232, 16.7232, -3.6573, -40.6287, 20.0679, -3.6573, -40.6287, 20.0679, -2.9615998, -37.315, 13.378599, -3.6573, -40.6287, 16.7232, -2.9859998, -37.3232, 13.378599, -2.9889998, -37.3379, 13.378599, -3.6573, -40.6287, 16.7232, -3.6573, -40.6287, 16.7232, -2.9859998, -37.3232, 16.7232, -2.9859998, -37.3232, 13.378599, -2.3234, -34.0607, 13.378599, -2.9889998, -37.3379, 16.7232, -2.9859998, -37.3232, 16.7232, -2.3191, -34.0398, 13.378599, -2.3234, -34.0607, 16.7232, -2.3191, -34.0398, 13.378599, -1.582, -30.410397, 13.378599, -2.3234, -34.0607, 16.7232, -2.3191, -34.0398, 16.7232, -1.5709, -30.3554, 13.378599, -1.582, -30.410397, 10.033899, -3.6573, -40.6287, 13.378599, -2.9889998, -37.3379, 10.033899, -2.9973998, -37.350998, 10.033899, -3.6573, -40.6287, 13.378599, -3.6573, -40.6287, 13.378599, -2.9889998, -37.3379, 6.6893, -3.6573, -40.6287, 10.033899, -2.9973998, -37.350998, 6.6893, -3.0333998, -37.355698, 6.6893, -3.6573, -40.6287, 10.033899, -3.6573, -40.6287, 10.033899, -2.9973998, -37.350998, 3.3446, -3.6573, -40.6287, 6.6893, -3.0333998, -37.355698, 3.3446, -3.0307, -37.3722, 3.3446, -3.6573, -40.6287, 6.6893, -3.6573, -40.6287, 6.6893, -3.0333998, -37.355698, 0, -3.6573, -40.6287, 3.3446, -3.0307, -37.3722, 0, -3.0496, -37.3821, 0, -3.6573, -40.6287, 3.3446, -3.6573, -40.6287, 3.3446, -3.0307, -37.3722, -3.297, -3.6573, -40.6287, 0, -3.0496, -37.3821, -3.3081002, -3.0523, -37.396698, -3.297, -3.6573, -40.6287, 0, -3.6573, -40.6287, 0, -3.0496, -37.3821, -3.3081002, -3.0523, -37.396698, -3.3446002, -3.6573, -40.6287, -3.297, -3.6573, -40.6287, -3.3081002, -3.0523, -37.396698, -6.6243997, -3.6573, -40.6287, -3.3446002, -3.6573, -40.6287, -6.6243997, -3.6573, -40.6287, -3.3081002, -3.0523, -37.396698, -6.6394, -3.0551, -37.4115, -6.6547, -2.4452, -34.1534, -6.6394, -3.0551, -37.4115, -3.3081002, -3.0523, -37.396698, 0, -3.0496, -37.3821, -3.3193002, -2.4413, -34.1324, -3.3081002, -3.0523, -37.396698, -6.6547, -2.4452, -34.1534, -3.3081002, -3.0523, -37.396698, -3.3193002, -2.4413, -34.1324, -6.6709, -1.7958, -30.683697, -6.6547, -2.4452, -34.1534, -3.3193002, -2.4413, -34.1324, 0, -3.0496, -37.3821, 0, -2.4373999, -34.1115, -3.3193002, -2.4413, -34.1324, -6.6709, -1.7958, -30.683697, -3.3193002, -2.4413, -34.1324, -3.3313003, -1.7853999, -30.628498, 0, -2.4373999, -34.1115, -3.3313003, -1.7853999, -30.628498, -3.3193002, -2.4413, -34.1324, 0, -2.4373999, -34.1115, 0, -1.7751, -30.573498, -3.3313003, -1.7853999, -30.628498, -6.6893, -1.458, -26.7572, -9.9988, -2.089, -30.630497, -6.6709, -1.7958, -30.683697, -6.6893, -1.458, -26.7572, -10.033899, -1.8786, -26.7572, -9.9988, -2.089, -30.630497, -10.033899, -1.8786, -26.7572, -13.297701, -2.9966, -30.341599, -9.9988, -2.089, -30.630497, -10.033899, -1.8786, -26.7572, -13.378601, -2.7663999, -26.7572, -13.297701, -2.9966, -30.341599, -13.378601, -2.7663999, -26.7572, -16.6169, -3.2373998, -30.3083, -13.297701, -2.9966, -30.341599, -13.378601, -2.7663999, -26.7572, -16.7232, -3.0929, -26.7572, -16.6169, -3.2373998, -30.3083, -16.7232, -3.0929, -26.7572, -19.9439, -3.2396998, -30.366299, -16.6169, -3.2373998, -30.3083, -19.9439, -3.2396998, -30.366299, -16.5094, -3.3834999, -33.898598, -16.6169, -3.2373998, -30.3083, -16.7232, -3.0929, -26.7572, -20.0679, -3.0929, -26.7572, -19.9439, -3.2396998, -30.366299, -19.9439, -3.2396998, -30.366299, -19.8217, -3.3844, -33.920498, -16.5094, -3.3834999, -33.898598, -20.0679, -3.0929, -26.7572, -23.2703, -3.2421, -30.424297, -19.9439, -3.2396998, -30.366299, -23.2703, -3.2421, -30.424297, -19.8217, -3.3844, -33.920498, -19.9439, -3.2396998, -30.366299, -20.0679, -3.0929, -26.7572, -23.412498, -3.0929, -26.7572, -23.2703, -3.2421, -30.424297, -19.8217, -3.3844, -33.920498, -16.4072, -3.5224, -37.3144, -16.5094, -3.3834999, -33.898598, -23.412498, -3.0929, -26.7572, -26.7572, -3.2445998, -30.4851, -23.2703, -3.2421, -30.424297, -23.412498, -3.0929, -26.7572, -26.7572, -3.0929, -26.7572, -26.7572, -3.2445998, -30.4851, -26.7572, -3.2445998, -30.4851, -23.1339, -3.3852, -33.942398, -23.2703, -3.2421, -30.424297, -23.2703, -3.2421, -30.424297, -23.1339, -3.3852, -33.942398, -19.8217, -3.3844, -33.920498, -26.7572, -3.2445998, -30.4851, -26.7572, -3.3862, -33.9664, -23.1339, -3.3852, -33.942398, -16.4072, -3.5224, -37.3144, -16.7232, -3.6573, -40.6287, -16.3079, -3.6573, -40.6287, -16.4072, -3.5224, -37.3144, -19.5913, -3.6573, -40.6287, -16.7232, -3.6573, -40.6287, -19.8217, -3.3844, -33.920498, -19.7046, -3.5231, -37.3297, -16.4072, -3.5224, -37.3144, -19.5913, -3.6573, -40.6287, -16.4072, -3.5224, -37.3144, -19.7046, -3.5231, -37.3297, -23.1339, -3.3852, -33.942398, -19.7046, -3.5231, -37.3297, -19.8217, -3.3844, -33.920498, -19.7046, -3.5231, -37.3297, -20.0679, -3.6573, -40.6287, -19.5913, -3.6573, -40.6287, -19.7046, -3.5231, -37.3297, -22.8746, -3.6573, -40.6287, -20.0679, -3.6573, -40.6287, -23.1339, -3.3852, -33.942398, -23.0019, -3.5237, -37.3449, -19.7046, -3.5231, -37.3297, -22.8746, -3.6573, -40.6287, -19.7046, -3.5231, -37.3297, -23.0019, -3.5237, -37.3449, -26.7572, -3.3862, -33.9664, -23.0019, -3.5237, -37.3449, -23.1339, -3.3852, -33.942398, -23.0019, -3.5237, -37.3449, -23.412498, -3.6573, -40.6287, -22.8746, -3.6573, -40.6287, -26.7572, -3.3862, -33.9664, -26.7572, -3.5244, -37.3623, -23.0019, -3.5237, -37.3449, -23.0019, -3.5237, -37.3449, -26.7572, -3.6573, -40.6287, -23.412498, -3.6573, -40.6287, -26.7572, -3.6573, -40.6287, -23.0019, -3.5237, -37.3449, -26.7572, -3.5244, -37.3623, -13.297701, -2.9966, -30.341599, -9.9673, -2.6348999, -34.110798, -9.9988, -2.089, -30.630497, -13.297701, -2.9966, -30.341599, -13.2167, -3.2271, -33.93, -9.9673, -2.6348999, -34.110798, 6.6893, -1.7218, -30.475399, 3.3446, -0.98829997, -26.7572, 3.3446, -1.7156, -30.536999, 6.6893, -1.7218, -30.475399, 6.6893, -1.0129, -26.7572, 3.3446, -0.98829997, -26.7572, 26.7573, -1.7447, -30.111198, 23.412498, -1.1158999, -26.7572, 23.429699, -1.5537, -30.243198, 26.7573, -1.7447, -30.111198, 26.7573, -1.3222, -26.7572, 23.412498, -1.1158999, -26.7572, -9.9988, -2.089, -30.630497, -6.6547, -2.4452, -34.1534, -6.6709, -1.7958, -30.683697, -9.9988, -2.089, -30.630497, -9.9673, -2.6348999, -34.110798, -6.6547, -2.4452, -34.1534, 10.033899, -1.61, -30.458897, 6.6893, -1.0129, -26.7572, 6.6893, -1.7218, -30.475399, 10.033899, -1.61, -30.458897, 10.033899, -0.8648, -26.7572, 6.6893, -1.0129, -26.7572, 3.3446, -1.7156, -30.536999, 0, -1.0608, -26.7572, 0, -1.7751, -30.573498, 3.3446, -1.7156, -30.536999, 3.3446, -0.98829997, -26.7572, 0, -1.0608, -26.7572, 23.429699, -1.5537, -30.243198, 20.0679, -1.1922, -26.7572, 20.0679, -1.4942, -30.325497, 23.429699, -1.5537, -30.243198, 23.412498, -1.1158999, -26.7572, 20.0679, -1.1922, -26.7572, 16.7232, -1.5709, -30.3554, 16.7232, -1.3382, -26.7572, 13.378599, -1.582, -30.410397, 13.378599, -1.582, -30.410397, 10.033899, -0.8648, -26.7572, 10.033899, -1.61, -30.458897, 13.378599, -1.582, -30.410397, 13.378599, -0.8401, -26.7572, 10.033899, -0.8648, -26.7572, 0, -1.7751, -30.573498, -3.3446002, -1.458, -26.7572, -3.3313003, -1.7853999, -30.628498, 0, -1.7751, -30.573498, 0, -1.0608, -26.7572, -3.3446002, -1.458, -26.7572, 20.0679, -1.4942, -30.325497, 16.7232, -1.3382, -26.7572, 16.7232, -1.5709, -30.3554, 20.0679, -1.4942, -30.325497, 20.0679, -1.1922, -26.7572, 16.7232, -1.3382, -26.7572, -16.6169, -3.2373998, -30.3083, -13.2167, -3.2271, -33.93, -13.297701, -2.9966, -30.341599, -16.6169, -3.2373998, -30.3083, -16.5094, -3.3834999, -33.898598, -13.2167, -3.2271, -33.93, 6.6893, -2.4083, -34.0766, 3.3446, -1.7156, -30.536999, 3.3446, -2.4013999, -34.1014, 6.6893, -2.4083, -34.0766, 6.6893, -1.7218, -30.475399, 3.3446, -1.7156, -30.536999, 26.7572, -2.5274, -33.9013, 23.429699, -1.5537, -30.243198, 23.4483, -2.3157, -33.9959, 26.7572, -2.5274, -33.9013, 26.7573, -1.7447, -30.111198, 23.429699, -1.5537, -30.243198, 23.4483, -2.3157, -33.9959, 20.0679, -1.4942, -30.325497, 20.0679, -2.2726, -34.0333, 23.4483, -2.3157, -33.9959, 23.429699, -1.5537, -30.243198, 20.0679, -1.4942, -30.325497, -9.9673, -2.6348999, -34.110798, -6.6394, -3.0551, -37.4115, -6.6547, -2.4452, -34.1534, -9.9673, -2.6348999, -34.110798, -9.9375, -3.1504998, -37.3978, -6.6394, -3.0551, -37.4115, 3.3446, -2.4013999, -34.1014, 0, -1.7751, -30.573498, 0, -2.4373999, -34.1115, 3.3446, -2.4013999, -34.1014, 3.3446, -1.7156, -30.536999, 0, -1.7751, -30.573498, -16.5094, -3.3834999, -33.898598, -13.1401005, -3.445, -37.3228, -13.2167, -3.2271, -33.93, -16.5094, -3.3834999, -33.898598, -16.4072, -3.5224, -37.3144, -13.1401005, -3.445, -37.3228, 10.033899, -2.3385, -34.078, 6.6893, -1.7218, -30.475399, 6.6893, -2.4083, -34.0766, 10.033899, -2.3385, -34.078, 10.033899, -1.61, -30.458897, 6.6893, -1.7218, -30.475399, 13.378599, -2.3234, -34.0607, 10.033899, -1.61, -30.458897, 10.033899, -2.3385, -34.078, 13.378599, -2.3234, -34.0607, 13.378599, -1.582, -30.410397, 10.033899, -1.61, -30.458897, 20.0679, -2.2726, -34.0333, 16.7232, -1.5709, -30.3554, 16.7232, -2.3191, -34.0398, 20.0679, -2.2726, -34.0333, 20.0679, -1.4942, -30.325497, 16.7232, -1.5709, -30.3554, -13.2167, -3.2271, -33.93, -9.9375, -3.1504998, -37.3978, -9.9673, -2.6348999, -34.110798, -13.2167, -3.2271, -33.93, -13.1401005, -3.445, -37.3228, -9.9375, -3.1504998, -37.3978, -16.3079, -3.6573, -40.6287, -13.1401005, -3.445, -37.3228, -16.4072, -3.5224, -37.3144, -13.1401005, -3.445, -37.3228, -16.3079, -3.6573, -40.6287, -13.378601, -3.6573, -40.6287, -13.1401005, -3.445, -37.3228, -13.378601, -3.6573, -40.6287, -13.0655, -3.6573, -40.6287, -13.0655, -3.6573, -40.6287, -9.9375, -3.1504998, -37.3978, -13.1401005, -3.445, -37.3228, -9.9375, -3.1504998, -37.3978, -13.0655, -3.6573, -40.6287, -10.033899, -3.6573, -40.6287, -9.9375, -3.1504998, -37.3978, -10.033899, -3.6573, -40.6287, -9.908199, -3.6573, -40.6287, 6.6893, -3.0333998, -37.355698, 3.3446, -2.4013999, -34.1014, 3.3446, -3.0307, -37.3722, 6.6893, -3.0333998, -37.355698, 6.6893, -2.4083, -34.0766, 3.3446, -2.4013999, -34.1014, 10.033899, -2.9973998, -37.350998, 6.6893, -2.4083, -34.0766, 6.6893, -3.0333998, -37.355698, 10.033899, -2.9973998, -37.350998, 10.033899, -2.3385, -34.078, 6.6893, -2.4083, -34.0766, 3.3446, -3.0307, -37.3722, 0, -2.4373999, -34.1115, 0, -3.0496, -37.3821, 3.3446, -3.0307, -37.3722, 3.3446, -2.4013999, -34.1014, 0, -2.4373999, -34.1115, 23.4646, -2.985, -37.2919, 20.0679, -2.2726, -34.0333, 20.0679, -2.9615998, -37.315, 23.4646, -2.985, -37.2919, 23.4483, -2.3157, -33.9959, 20.0679, -2.2726, -34.0333, 26.7572, -3.2101, -37.2077, 23.4483, -2.3157, -33.9959, 23.4646, -2.985, -37.2919, 26.7572, -3.2101, -37.2077, 26.7572, -2.5274, -33.9013, 23.4483, -2.3157, -33.9959, 13.378599, -2.9889998, -37.3379, 10.033899, -2.3385, -34.078, 10.033899, -2.9973998, -37.350998, 13.378599, -2.9889998, -37.3379, 13.378599, -2.3234, -34.0607, 10.033899, -2.3385, -34.078, 20.0679, -2.9615998, -37.315, 16.7232, -2.3191, -34.0398, 16.7232, -2.9859998, -37.3232, 20.0679, -2.9615998, -37.315, 20.0679, -2.2726, -34.0333, 16.7232, -2.3191, -34.0398, -9.908199, -3.6573, -40.6287, -6.6394, -3.0551, -37.4115, -9.9375, -3.1504998, -37.3978, -6.6394, -3.0551, -37.4115, -9.908199, -3.6573, -40.6287, -6.6893, -3.6573, -40.6287, -6.6394, -3.0551, -37.4115, -6.6893, -3.6573, -40.6287, -6.6243997, -3.6573, -40.6287, 23.480999, -3.6625998, -40.6287, 20.103699, -4.8978, -44.4642, 23.577, -4.916, -44.481, 20.103699, -4.8978, -44.4642, 23.480999, -3.6625998, -40.6287, 23.412498, -3.6573, -40.6287, 20.103699, -4.8978, -44.4642, 23.412498, -3.6573, -40.6287, 20.0679, -3.6573, -40.6287, 23.6614, -6.0197997, -47.8736, 20.103699, -4.8978, -44.4642, 20.135399, -5.9964, -47.861, 23.6614, -6.0197997, -47.8736, 23.577, -4.916, -44.481, 20.103699, -4.8978, -44.4642, 23.7466, -7.1323, -51.2931, 20.135399, -5.9964, -47.861, 20.1675, -7.1071997, -51.295498, 23.7466, -7.1323, -51.2931, 23.6614, -6.0197997, -47.8736, 20.135399, -5.9964, -47.861, 23.826399, -8.175799, -54.500298, 20.1689, -8.6489, -57.5607, 23.8225, -8.6786995, -57.548298, 20.1689, -8.6489, -57.5607, 23.826399, -8.175799, -54.500298, 23.412498, -8.1437, -54.500298, 20.1689, -8.6489, -57.5607, 23.412498, -8.1437, -54.500298, 20.1975, -8.1437, -54.500298, 23.819199, -9.111899, -60.1742, 20.1689, -8.6489, -57.5607, 20.1442, -9.085899, -60.207497, 23.819199, -9.111899, -60.1742, 23.8225, -8.6786995, -57.548298, 20.1689, -8.6489, -57.5607, 23.8148, -9.6761, -63.593796, 20.1442, -9.085899, -60.207497, 20.112099, -9.6529, -63.642, 23.8148, -9.6761, -63.593796, 23.819199, -9.111899, -60.1742, 20.1442, -9.085899, -60.207497, -26.7572, -10.4337, -70.9319, -23.4177, -10.4499, -73.721596, -23.4177, -10.4499, -70.8944, -23.4177, -10.4499, -73.721596, -20.0768, -10.466, -70.856895, -23.4177, -10.4499, -70.8944, -26.7572, -10.4337, -70.9319, -26.7572, -10.4337, -73.7615, -23.4177, -10.4499, -73.721596, -23.4177, -10.4499, -73.721596, -20.0768, -10.466, -73.6818, -20.0768, -10.466, -70.856895, -20.0768, -10.466, -73.6818, -16.734499, -10.4822, -70.8193, -20.0768, -10.466, -70.856895, -26.7572, -10.4337, -73.7615, -23.4177, -10.4499, -76.5937, -23.4177, -10.4499, -73.721596, -23.4177, -10.4499, -76.5937, -20.0768, -10.466, -73.6818, -23.4177, -10.4499, -73.721596, -26.7572, -10.4337, -73.7615, -26.7572, -10.4337, -76.6203, -23.4177, -10.4499, -76.5937, -26.7572, -10.4337, -76.6203, -23.4177, -10.4499, -79.1102, -23.4177, -10.4499, -76.5937, -26.7572, -10.4337, -76.6203, -26.7572, -10.4337, -79.0804, -23.4177, -10.4499, -79.1102, -23.4177, -10.4499, -79.1102, -20.0768, -10.466, -76.567, -23.4177, -10.4499, -76.5937, -23.4177, -10.4499, -76.5937, -20.0768, -10.466, -76.567, -20.0768, -10.466, -73.6818, -23.4177, -10.4499, -79.1102, -20.0768, -10.466, -79.14, -20.0768, -10.466, -76.567, -20.0768, -10.466, -73.6818, -16.734499, -10.4822, -73.6419, -16.734499, -10.4822, -70.8193, -20.0768, -10.466, -76.567, -16.734499, -10.4822, -73.6419, -20.0768, -10.466, -73.6818, -16.734499, -10.4822, -73.6419, -13.3908, -10.4984, -70.7818, -16.734499, -10.4822, -70.8193, -20.0768, -10.466, -79.14, -16.734499, -10.4822, -76.5403, -20.0768, -10.466, -76.567, -20.0768, -10.466, -76.567, -16.734499, -10.4822, -76.5403, -16.734499, -10.4822, -73.6419, -20.0768, -10.466, -79.14, -16.734499, -10.4822, -79.1699, -16.734499, -10.4822, -76.5403, -16.734499, -10.4822, -73.6419, -13.3909, -10.4984, -73.602, -13.3908, -10.4984, -70.7818, -16.734499, -10.4822, -76.5403, -13.3909, -10.4984, -73.602, -16.734499, -10.4822, -73.6419, -13.3909, -10.4984, -73.602, -10.045801, -10.5146, -70.7442, -13.3908, -10.4984, -70.7818, -16.734499, -10.4822, -79.1699, -13.3909, -10.4984, -76.513596, -16.734499, -10.4822, -76.5403, -16.734499, -10.4822, -76.5403, -13.3909, -10.4984, -76.513596, -13.3909, -10.4984, -73.602, -16.734499, -10.4822, -79.1699, -13.3909, -10.4984, -79.1997, -13.3909, -10.4984, -76.513596, -13.3909, -10.4984, -73.602, -10.045801, -10.5146, -73.562195, -10.045801, -10.5146, -70.7442, -13.3909, -10.4984, -76.513596, -10.045801, -10.5146, -73.562195, -13.3909, -10.4984, -73.602, -10.045801, -10.5146, -73.562195, -6.6993003, -10.5309, -70.7066, -10.045801, -10.5146, -70.7442, -13.3909, -10.4984, -79.1997, -10.045801, -10.5146, -76.4869, -13.3909, -10.4984, -76.513596, -13.3909, -10.4984, -76.513596, -10.045801, -10.5146, -76.4869, -10.045801, -10.5146, -73.562195, -13.3909, -10.4984, -79.1997, -10.045801, -10.5146, -79.2295, -10.045801, -10.5146, -76.4869, -10.045801, -10.5146, -73.562195, -6.6993003, -10.5309, -73.5222, -6.6993003, -10.5309, -70.7066, -10.045801, -10.5146, -76.4869, -6.6993003, -10.5309, -73.5222, -10.045801, -10.5146, -73.562195, -6.6993003, -10.5309, -73.5222, -3.3514, -10.5471, -70.669, -6.6993003, -10.5309, -70.7066, -10.045801, -10.5146, -79.2295, -6.6993003, -10.5309, -76.4602, -10.045801, -10.5146, -76.4869, -10.045801, -10.5146, -76.4869, -6.6993003, -10.5309, -76.4602, -6.6993003, -10.5309, -73.5222, -10.045801, -10.5146, -79.2295, -6.6993003, -10.5309, -79.2594, -6.6993003, -10.5309, -76.4602, -6.6993003, -10.5309, -73.5222, -3.3514, -10.5471, -73.4823, -3.3514, -10.5471, -70.669, -6.6993003, -10.5309, -76.4602, -3.3514, -10.5471, -73.4823, -6.6993003, -10.5309, -73.5222, -3.3514, -10.5471, -73.4823, -0.0020999908, -10.5633, -70.6314, -3.3514, -10.5471, -70.669, -6.6993003, -10.5309, -79.2594, -3.3514, -10.5471, -76.433395, -6.6993003, -10.5309, -76.4602, -6.6993003, -10.5309, -76.4602, -3.3514, -10.5471, -76.433395, -3.3514, -10.5471, -73.4823, -6.6993003, -10.5309, -79.2594, -3.3514, -10.5471, -79.2893, -3.3514, -10.5471, -76.433395, -3.3514, -10.5471, -73.4823, -0.0020999908, -10.5633, -73.4424, -0.0020999908, -10.5633, -70.6314, -3.3514, -10.5471, -76.433395, -0.0020999908, -10.5633, -73.4424, -3.3514, -10.5471, -73.4823, -0.0020999908, -10.5633, -73.4424, 3.3486998, -10.579599, -70.5937, -0.0020999908, -10.5633, -70.6314, -3.3514, -10.5471, -79.2893, -0.0020999908, -10.5633, -76.4067, -3.3514, -10.5471, -76.433395, -3.3514, -10.5471, -76.433395, -0.0020999908, -10.5633, -76.4067, -0.0020999908, -10.5633, -73.4424, -3.3514, -10.5471, -79.2893, -0.0020999908, -10.5633, -79.3192, -0.0020999908, -10.5633, -76.4067, -0.0020999908, -10.5633, -73.4424, 3.3486998, -10.579599, -73.4024, 3.3486998, -10.579599, -70.5937, -0.0020999908, -10.5633, -76.4067, 3.3486998, -10.579599, -73.4024, -0.0020999908, -10.5633, -73.4424, 3.3486998, -10.579599, -73.4024, 6.7008, -10.595799, -70.5561, 3.3486998, -10.579599, -70.5937, -0.0020999908, -10.5633, -79.3192, 3.3486998, -10.579599, -76.3799, -0.0020999908, -10.5633, -76.4067, -0.0020999908, -10.5633, -76.4067, 3.3486998, -10.579599, -76.3799, 3.3486998, -10.579599, -73.4024, -0.0020999908, -10.5633, -79.3192, 3.3486998, -10.579599, -79.3491, 3.3486998, -10.579599, -76.3799, 3.3486998, -10.579599, -73.4024, 6.7008, -10.595799, -73.3624, 6.7008, -10.595799, -70.5561, 3.3486998, -10.579599, -76.3799, 6.7008, -10.595799, -73.3624, 3.3486998, -10.579599, -73.4024, 6.7008, -10.595799, -73.3624, 10.054299, -10.6119995, -70.518394, 6.7008, -10.595799, -70.5561, 3.3486998, -10.579599, -79.3491, 6.7008, -10.595799, -76.353195, 3.3486998, -10.579599, -76.3799, 3.3486998, -10.579599, -76.3799, 6.7008, -10.595799, -76.353195, 6.7008, -10.595799, -73.3624, 3.3486998, -10.579599, -79.3491, 6.7008, -10.595799, -79.379, 6.7008, -10.595799, -76.353195, 6.7008, -10.595799, -73.3624, 10.054299, -10.6119995, -73.322395, 10.054299, -10.6119995, -70.518394, 6.7008, -10.595799, -76.353195, 10.054299, -10.6119995, -73.322395, 6.7008, -10.595799, -73.3624, 10.054299, -10.6119995, -73.322395, 13.4093, -10.6283, -70.4807, 10.054299, -10.6119995, -70.518394, 6.7008, -10.595799, -79.379, 10.054299, -10.6119995, -76.3264, 6.7008, -10.595799, -76.353195, 6.7008, -10.595799, -76.353195, 10.054299, -10.6119995, -76.3264, 10.054299, -10.6119995, -73.322395, 6.7008, -10.595799, -79.379, 10.054299, -10.6119995, -79.4089, 10.054299, -10.6119995, -76.3264, 10.054299, -10.6119995, -73.322395, 13.4093, -10.6283, -73.282394, 13.4093, -10.6283, -70.4807, 10.054299, -10.6119995, -76.3264, 13.4093, -10.6283, -73.282394, 10.054299, -10.6119995, -73.322395, 13.4093, -10.6283, -73.282394, 16.7656, -10.6446, -70.443, 13.4093, -10.6283, -70.4807, 10.054299, -10.6119995, -79.4089, 13.4093, -10.6283, -76.2996, 10.054299, -10.6119995, -76.3264, 10.054299, -10.6119995, -76.3264, 13.4093, -10.6283, -76.2996, 13.4093, -10.6283, -73.282394, 10.054299, -10.6119995, -79.4089, 13.4093, -10.6283, -79.4388, 13.4093, -10.6283, -76.2996, 13.4093, -10.6283, -73.282394, 16.7656, -10.6446, -73.2424, 16.7656, -10.6446, -70.443, 13.4093, -10.6283, -76.2996, 16.7656, -10.6446, -73.2424, 13.4093, -10.6283, -73.282394, 16.7656, -10.6446, -73.2424, 20.1234, -10.6608, -70.4053, 16.7656, -10.6446, -70.443, 13.4093, -10.6283, -79.4388, 16.7656, -10.6446, -76.2728, 13.4093, -10.6283, -76.2996, 13.4093, -10.6283, -76.2996, 16.7656, -10.6446, -76.2728, 16.7656, -10.6446, -73.2424, 13.4093, -10.6283, -79.4388, 16.7656, -10.6446, -79.468796, 16.7656, -10.6446, -76.2728, 16.7656, -10.6446, -73.2424, 20.1234, -10.6608, -73.2023, 20.1234, -10.6608, -70.4053, 16.7656, -10.6446, -76.2728, 20.1234, -10.6608, -73.2023, 16.7656, -10.6446, -73.2424, 20.1234, -10.6608, -73.2023, 23.812, -10.6786995, -70.3639, 20.1234, -10.6608, -70.4053, 16.7656, -10.6446, -79.468796, 20.1234, -10.6608, -76.245995, 16.7656, -10.6446, -76.2728, 16.7656, -10.6446, -76.2728, 20.1234, -10.6608, -76.245995, 20.1234, -10.6608, -73.2023, 16.7656, -10.6446, -79.468796, 20.1234, -10.6608, -79.498695, 20.1234, -10.6608, -76.245995, 20.1234, -10.6608, -73.2023, 23.7337, -10.6783, -73.1593, 23.812, -10.6786995, -70.3639, 20.1234, -10.6608, -76.245995, 23.7337, -10.6783, -73.1593, 20.1234, -10.6608, -73.2023, 23.7337, -10.6783, -73.1593, 26.7572, -10.693, -70.330795, 23.812, -10.6786995, -70.3639, 23.7337, -10.6783, -73.1593, 26.7572, -10.693, -73.1232, 26.7572, -10.693, -70.330795, 20.1234, -10.6608, -76.245995, 23.6481, -10.677899, -76.2178, 23.7337, -10.6783, -73.1593, 23.6481, -10.677899, -76.2178, 26.7572, -10.693, -73.1232, 23.7337, -10.6783, -73.1593, 20.1234, -10.6608, -79.498695, 23.6481, -10.677899, -76.2178, 20.1234, -10.6608, -76.245995, 23.6481, -10.677899, -76.2178, 26.7572, -10.693, -76.193, 26.7572, -10.693, -73.1232, 20.1234, -10.6608, -79.498695, 23.555399, -10.6775, -79.529396, 23.6481, -10.677899, -76.2178, 23.555399, -10.6775, -79.529396, 26.7572, -10.693, -76.193, 23.6481, -10.677899, -76.2178, 23.555399, -10.6775, -79.529396, 26.7572, -10.693, -79.5579, 26.7572, -10.693, -76.193, -26.7572, -10.4337, -79.0804, -23.412498, -10.4337, -82.2434, -23.4177, -10.4499, -79.1102, -26.7572, -10.4337, -79.0804, -26.7572, -10.4337, -82.2434, -23.412498, -10.4337, -82.2434, 23.412498, -10.4337, -82.2434, 26.7572, -10.693, -79.5579, 23.555399, -10.6775, -79.529396, 23.412498, -10.4337, -82.2434, 26.7572, -10.693, -82.2434, 26.7572, -10.693, -79.5579, 23.812, -10.6786995, -70.3639, 26.7572, -10.693, -68.371895, 23.808699, -10.464399, -68.371895, 23.812, -10.6786995, -70.3639, 26.7572, -10.693, -70.330795, 26.7572, -10.693, -68.371895, 20.0679, -10.4337, -82.2434, 23.555399, -10.6775, -79.529396, 20.1234, -10.6608, -79.498695, 20.0679, -10.4337, -82.2434, 23.412498, -10.4337, -82.2434, 23.555399, -10.6775, -79.529396, 23.812, -10.6786995, -70.3639, 20.0679, -10.4337, -68.371895, 20.1234, -10.6608, -70.4053, 20.0679, -10.4337, -68.371895, 23.812, -10.6786995, -70.3639, 23.808699, -10.464399, -68.371895, 20.0679, -10.4337, -68.371895, 23.808699, -10.464399, -68.371895, 23.412498, -10.4337, -68.371895, 16.7232, -10.4337, -82.2434, 20.1234, -10.6608, -79.498695, 16.7656, -10.6446, -79.468796, 16.7232, -10.4337, -82.2434, 20.0679, -10.4337, -82.2434, 20.1234, -10.6608, -79.498695, 16.7656, -10.6446, -70.443, 20.0679, -10.4337, -68.371895, 16.7232, -10.4337, -68.371895, 16.7656, -10.6446, -70.443, 20.1234, -10.6608, -70.4053, 20.0679, -10.4337, -68.371895, 13.378599, -10.4337, -82.2434, 16.7656, -10.6446, -79.468796, 13.4093, -10.6283, -79.4388, 13.378599, -10.4337, -82.2434, 16.7232, -10.4337, -82.2434, 16.7656, -10.6446, -79.468796, 13.4093, -10.6283, -70.4807, 16.7232, -10.4337, -68.371895, 13.378599, -10.4337, -68.371895, 13.4093, -10.6283, -70.4807, 16.7656, -10.6446, -70.443, 16.7232, -10.4337, -68.371895, 10.033899, -10.4337, -82.2434, 13.4093, -10.6283, -79.4388, 10.054299, -10.6119995, -79.4089, 10.033899, -10.4337, -82.2434, 13.378599, -10.4337, -82.2434, 13.4093, -10.6283, -79.4388, 10.054299, -10.6119995, -70.518394, 13.378599, -10.4337, -68.371895, 10.033899, -10.4337, -68.371895, 10.054299, -10.6119995, -70.518394, 13.4093, -10.6283, -70.4807, 13.378599, -10.4337, -68.371895, 6.6893, -10.4337, -82.2434, 10.054299, -10.6119995, -79.4089, 6.7008, -10.595799, -79.379, 6.6893, -10.4337, -82.2434, 10.033899, -10.4337, -82.2434, 10.054299, -10.6119995, -79.4089, 6.7008, -10.595799, -70.5561, 10.033899, -10.4337, -68.371895, 6.6893, -10.4337, -68.371895, 6.7008, -10.595799, -70.5561, 10.054299, -10.6119995, -70.518394, 10.033899, -10.4337, -68.371895, 3.3446, -10.4337, -82.2434, 6.7008, -10.595799, -79.379, 3.3486998, -10.579599, -79.3491, 3.3446, -10.4337, -82.2434, 6.6893, -10.4337, -82.2434, 6.7008, -10.595799, -79.379, 3.3486998, -10.579599, -70.5937, 6.6893, -10.4337, -68.371895, 3.3446, -10.4337, -68.371895, 3.3486998, -10.579599, -70.5937, 6.7008, -10.595799, -70.5561, 6.6893, -10.4337, -68.371895, 0, -10.4337, -82.2434, 3.3486998, -10.579599, -79.3491, -0.0020999908, -10.5633, -79.3192, 0, -10.4337, -82.2434, 3.3446, -10.4337, -82.2434, 3.3486998, -10.579599, -79.3491, -0.0020999908, -10.5633, -70.6314, 3.3446, -10.4337, -68.371895, 0, -10.4337, -68.371895, -0.0020999908, -10.5633, -70.6314, 3.3486998, -10.579599, -70.5937, 3.3446, -10.4337, -68.371895, -3.3446002, -10.4337, -82.2434, -0.0020999908, -10.5633, -79.3192, -3.3514, -10.5471, -79.2893, -3.3446002, -10.4337, -82.2434, 0, -10.4337, -82.2434, -0.0020999908, -10.5633, -79.3192, -3.3514, -10.5471, -70.669, -6.6893, -10.4337, -68.371895, -6.6993003, -10.5309, -70.7066, -3.3514, -10.5471, -70.669, -3.3446002, -10.4337, -68.371895, -6.6893, -10.4337, -68.371895, -6.6893, -10.4337, -68.371895, -10.045801, -10.5146, -70.7442, -6.6993003, -10.5309, -70.7066, -6.6893, -10.4337, -68.371895, -10.033899, -10.4337, -68.371895, -10.045801, -10.5146, -70.7442, -6.6893, -10.4337, -82.2434, -3.3514, -10.5471, -79.2893, -6.6993003, -10.5309, -79.2594, -6.6893, -10.4337, -82.2434, -3.3446002, -10.4337, -82.2434, -3.3514, -10.5471, -79.2893, -10.033899, -10.4337, -82.2434, -6.6993003, -10.5309, -79.2594, -10.045801, -10.5146, -79.2295, -10.033899, -10.4337, -82.2434, -6.6893, -10.4337, -82.2434, -6.6993003, -10.5309, -79.2594, -10.033899, -10.4337, -68.371895, -13.3908, -10.4984, -70.7818, -10.045801, -10.5146, -70.7442, -10.033899, -10.4337, -68.371895, -13.378601, -10.4337, -68.371895, -13.3908, -10.4984, -70.7818, -13.378601, -10.4337, -82.2434, -10.045801, -10.5146, -79.2295, -13.3909, -10.4984, -79.1997, -13.378601, -10.4337, -82.2434, -10.033899, -10.4337, -82.2434, -10.045801, -10.5146, -79.2295, -13.378601, -10.4337, -68.371895, -16.734499, -10.4822, -70.8193, -13.3908, -10.4984, -70.7818, -13.378601, -10.4337, -68.371895, -16.7232, -10.4337, -68.371895, -16.734499, -10.4822, -70.8193, -16.7232, -10.4337, -68.371895, -20.0768, -10.466, -70.856895, -16.734499, -10.4822, -70.8193, -16.7232, -10.4337, -68.371895, -20.0679, -10.4337, -68.371895, -20.0768, -10.466, -70.856895, -16.7232, -10.4337, -82.2434, -13.3909, -10.4984, -79.1997, -16.734499, -10.4822, -79.1699, -16.7232, -10.4337, -82.2434, -13.378601, -10.4337, -82.2434, -13.3909, -10.4984, -79.1997, -20.0679, -10.4337, -68.371895, -23.4177, -10.4499, -70.8944, -20.0768, -10.466, -70.856895, -20.0679, -10.4337, -68.371895, -23.412498, -10.4337, -68.371895, -23.4177, -10.4499, -70.8944, -20.0679, -10.4337, -82.2434, -16.734499, -10.4822, -79.1699, -20.0768, -10.466, -79.14, -20.0679, -10.4337, -82.2434, -16.7232, -10.4337, -82.2434, -16.734499, -10.4822, -79.1699, -23.412498, -10.4337, -68.371895, -26.7572, -10.4337, -70.9319, -23.4177, -10.4499, -70.8944, -23.412498, -10.4337, -68.371895, -26.7572, -10.4337, -68.371895, -26.7572, -10.4337, -70.9319, -23.412498, -10.4337, -82.2434, -20.0768, -10.466, -79.14, -23.4177, -10.4499, -79.1102, -23.412498, -10.4337, -82.2434, -20.0679, -10.4337, -82.2434, -20.0768, -10.466, -79.14, 13.378599, -1.0746, 20.0679, 13.378599, -2.2719998, 23.3902, 10.033899, -0.501, 23.412498, 20.0679, -1.0746, 13.378601, 16.7232, -1.0746, 16.7232, 16.7232, -1.0746, 13.378601, 16.7232, -1.0746, 16.7232, 15.0508995, -1.0746, 20.0679, 13.378599, -1.0746, 20.0679, 16.7232, -1.0746, 16.7232, 16.7232, -1.8294, 20.0679, 15.0508995, -1.0746, 20.0679, 23.412498, -0.35529998, 10.033899, 23.412498, -1.8294, 13.378601, 20.0679, -1.0746, 13.378601, 10.501598, 0, 20.5087, 6.6893, 0, 20.0679, 10.080299, 0, 20.0679, 10.501598, 0, 20.5087, 6.6893, -0.2814, 23.412498, 6.6893, 0, 20.0679, -20.0679, 0, 13.378601, -16.7232, 0, 13.868401, -16.7232, -0.26209998, 16.7232, -20.0679, 0, 13.378601, -17.213, 0, 13.378601, -16.7232, 0, 13.868401, -16.7232, -0.26209998, 16.7232, -13.378601, 0, 16.7232, -13.378601, 0, 20.0679, -24.056599, 0, 10.033899, -25.9681, -0.2875, 13.378601, -26.0077, -0.2465, 10.033899, -25.9681, -0.2875, 13.378601, -24.056599, 0, 10.033899, -23.412498, 0, 10.6779995, -25.9681, -0.2875, 13.378601, -23.412498, 0, 10.6779995, -23.412498, 0, 13.378601, -23.8078, 0, 6.6893, -26.0077, -0.2465, 10.033899, -25.945799, -0.25779998, 6.6893, -26.0077, -0.2465, 10.033899, -23.8078, 0, 6.6893, -23.489, 0, 9.386499, -26.0077, -0.2465, 10.033899, -23.489, 0, 9.386499, -24.056599, 0, 10.033899, -25.4212, -0.5907, 16.7232, -23.412498, -0.692, 20.0679, -25.174, -0.7391, 20.0679, -25.479, -0.4588, 0.143, -23.412498, 0, 3.3446, -25.869999, -0.2764, 3.3446, -25.479, -0.4588, 0.143, -23.412498, -0.2913, 0.26119995, -23.412498, 0, 3.3446, -25.869999, -0.2764, 3.3446, -23.8078, 0, 6.6893, -25.945799, -0.25779998, 6.6893, -25.869999, -0.2764, 3.3446, -23.412498, 0, 3.3446, -23.8078, 0, 6.6893, -17.2383, -0.66719997, -19.6364, -20.0679, -0.43429998, -16.7232, -20.0679, -1.7572, -20.0679, -20.0679, -0.43429998, -16.7232, -20.0679, 0, -13.378599, -23.412498, 0, -13.378599, -9.318001, -0.3969, -19.413, -6.6893, -0.9271, -20.0679, -6.6893, 0, -16.7232, -6.6893, 0, -16.7232, -3.3446002, -0.9271, -16.7232, -3.3446002, 0, -13.7127, 16.7232, 0, -20.0679, 20.0679, -0.2837, -20.0679, 20.0679, 0, -16.7232, 13.378599, 0, -23.412498, 16.7232, -0.3105, -23.412498, 16.7232, 0, -20.0679, 20.0679, 0, -16.7232, 23.412498, -0.456, -16.7232, 23.412498, 0, -13.378599, 23.412498, 0, -6.6893, 23.412498, 0, -3.3446002, 22.5396, -0.014599999, -3.3446002, 15.0508995, -0.40039998, 16.7232, 13.378599, 0, 16.7232, 15.0508995, -0.6288, 13.378601, 14.439199, 0, 13.6437, 15.0508995, 0, 10.033899, 15.0508995, -0.6288, 13.378601, 15.0508995, 0, 10.033899, 14.439199, 0, 13.6437, 13.8046, 0, 13.2202, 15.0508995, 0, 10.033899, 13.8046, 0, 13.2202, 13.8046, 0, 10.033899, 3.0140998, 0, -16.7232, 3.3446, -0.3989, -12.9443, 0, 0, -13.378599, -23.412498, -0.692, 20.0679, -25.4212, -0.5907, 16.7232, -23.412498, -0.36479998, 16.7232, -23.412498, -0.692, 20.0679, -20.0679, -0.36479998, 20.0679, -20.0679, -0.5589, 23.412498, -16.7232, -0.36479998, 23.412498, -13.378601, -0.2814, 23.412498, -13.378601, -1.1209999, 26.7572, -20.0679, -0.36479998, 16.7232, -16.7232, -0.26209998, 16.7232, -16.7232, -0.36479998, 20.0679, -16.7232, -0.36479998, 20.0679, -13.378601, 0, 20.0679, -13.378601, -0.2814, 23.412498, -23.412498, -0.7373, 23.412498, -20.0679, -0.5589, 23.412498, -20.0679, -1.1374999, 26.7572, -25.174, -0.7391, 20.0679, -23.412498, -0.692, 20.0679, -23.412498, -0.7373, 23.412498, -20.0679, -0.5589, 23.412498, -16.7232, -0.36479998, 23.412498, -16.7232, -1.1374999, 26.7572, 26.7582, -1.7623999, 10.033899, 26.7582, -1.8294, 13.378601, 23.412498, -1.8294, 13.378601, 13.378599, 0, 16.7232, 14.439199, 0, 13.6437, 15.0508995, -0.6288, 13.378601, 13.378599, 0, 16.7232, 13.700699, 0, 14.602699, 14.439199, 0, 13.6437, 15.0508995, -0.6288, 13.378601, 15.0508995, 0, 10.033899, 16.7232, 0, 10.033899, 15.0508995, -0.40039998, 16.7232, 16.7232, -1.0746, 13.378601, 16.7232, -1.0746, 16.7232, 13.378599, 0, 16.7232, 13.378599, -1.0746, 20.0679, 11.0191, 0, 20.0679, 15.0508995, -0.40039998, 16.7232, 13.378599, -1.0746, 20.0679, 13.378599, 0, 16.7232, 20.0679, -0.2837, -20.0679, 23.412498, -1.0924, -20.0679, 23.412498, -0.456, -16.7232, 26.572199, -0.95549995, -13.659599, 23.412498, 0, -13.378599, 23.412498, -0.456, -16.7232, 13.378599, -0.8401, -26.7572, 16.7232, -1.3382, -26.7572, 16.7232, -0.3105, -23.412498, 16.7232, -0.3105, -23.412498, 20.0679, -0.8222, -23.412498, 20.0679, -0.2837, -20.0679, 16.7232, -1.3382, -26.7572, 13.378599, -0.8401, -26.7572, 13.378599, -1.582, -30.410397, 16.7232, -1.3382, -26.7572, 20.0679, -1.1922, -26.7572, 20.0679, -0.8222, -23.412498, 26.7577, -0.8804, -16.7232, 23.412498, -0.456, -16.7232, 23.412498, -1.0924, -20.0679, 20.0679, -0.8222, -23.412498, 23.412498, -1.0924, -23.412498, 23.412498, -1.0924, -20.0679, 3.3446, -0.3434, -23.412498, 0, -0.9271, -20.0679, 0, -0.9271, -23.412498, -10.033899, -0.9271, -23.412498, -6.6893, -1.3241999, -23.412498, -6.6893, -0.9271, -20.0679, 2.3184, 0, -20.4362, 0, -0.9271, -16.7232, 0, -0.9271, -20.0679, 39.877598, -3.6573, 23.412498, 36.078598, -3.0746999, 26.7572, 36.2121, -2.9357, 23.412498, 39.877598, -3.6573, 23.412498, 39.877598, -3.6573, 26.7572, 36.078598, -3.0746999, 26.7572, 52.997097, -8.1437, 23.412498, 49.5743, -6.9732, 26.7572, 49.5645, -6.9698997, 23.412498, 52.997097, -8.1437, 23.412498, 52.997097, -8.1437, 26.7572, 49.5743, -6.9732, 26.7572, 52.997097, -8.1437, 20.0679, 52.997097, -8.1437, 23.412498, 49.5645, -6.9698997, 23.412498, 49.5743, -6.9732, 26.7572, 46.556797, -5.9413, 23.412498, 49.5645, -6.9698997, 23.412498, 49.5743, -6.9732, 26.7572, 46.577698, -5.9484997, 26.7572, 46.556797, -5.9413, 23.412498, 52.997097, -8.1437, 20.0679, 49.5645, -6.9698997, 23.412498, 49.5547, -6.9665, 20.0679, 52.997097, -8.1437, 16.7232, 52.997097, -8.1437, 20.0679, 49.5547, -6.9665, 20.0679, 52.997097, -8.1437, 16.7232, 49.5547, -6.9665, 20.0679, 49.5449, -6.9631996, 16.7232, 49.5547, -6.9665, 20.0679, 46.5149, -5.927, 16.7232, 49.5449, -6.9631996, 16.7232, 49.5645, -6.9698997, 23.412498, 46.535797, -5.9342, 20.0679, 49.5547, -6.9665, 20.0679, 49.5547, -6.9665, 20.0679, 46.535797, -5.9342, 20.0679, 46.5149, -5.927, 16.7232, 49.5645, -6.9698997, 23.412498, 46.556797, -5.9413, 23.412498, 46.535797, -5.9342, 20.0679, 46.535797, -5.9342, 20.0679, 43.1641, -4.7812, 16.7232, 46.5149, -5.927, 16.7232, 46.535797, -5.9342, 20.0679, 43.1877, -4.7892, 20.0679, 43.1641, -4.7812, 16.7232, 46.556797, -5.9413, 23.412498, 43.1877, -4.7892, 20.0679, 46.535797, -5.9342, 20.0679, 43.1877, -4.7892, 20.0679, 39.877598, -3.6573, 16.7232, 43.1641, -4.7812, 16.7232, 43.1877, -4.7892, 20.0679, 39.877598, -3.6573, 20.0679, 39.877598, -3.6573, 16.7232, 46.556797, -5.9413, 23.412498, 43.2113, -4.7973, 23.412498, 43.1877, -4.7892, 20.0679, 43.2113, -4.7973, 23.412498, 39.877598, -3.6573, 20.0679, 43.1877, -4.7892, 20.0679, 46.577698, -5.9484997, 26.7572, 43.2113, -4.7973, 23.412498, 46.556797, -5.9413, 23.412498, 43.2113, -4.7973, 23.412498, 39.877598, -3.6573, 23.412498, 39.877598, -3.6573, 20.0679, 46.577698, -5.9484997, 26.7572, 43.234898, -4.8054, 26.7572, 43.2113, -4.7973, 23.412498, 43.234898, -4.8054, 26.7572, 39.877598, -3.6573, 23.412498, 43.2113, -4.7973, 23.412498, 43.234898, -4.8054, 26.7572, 39.877598, -3.6573, 26.7572, 39.877598, -3.6573, 23.412498, 39.877598, -3.6573, 20.0679, 36.2121, -2.9357, 23.412498, 36.2075, -2.9348, 20.0679, 39.877598, -3.6573, 20.0679, 39.877598, -3.6573, 23.412498, 36.2121, -2.9357, 23.412498, 39.877598, -3.6573, 16.7232, 39.877598, -3.6573, 20.0679, 36.2075, -2.9348, 20.0679, 39.877598, -3.6573, 16.7232, 36.2075, -2.9348, 20.0679, 36.2028, -2.9338999, 16.7232, 39.877598, -3.7507, 13.378601, 36.2028, -2.9338999, 16.7232, 36.1422, -2.9887998, 13.378601, 39.877598, -3.7507, 13.378601, 39.877598, -3.6573, 16.7232, 36.2028, -2.9338999, 16.7232, 52.997097, -8.1437, 13.378601, 49.5449, -6.9631996, 16.7232, 49.520397, -6.9795, 13.378601, 52.997097, -8.1437, 13.378601, 52.997097, -8.1437, 16.7232, 49.5449, -6.9631996, 16.7232, 39.877598, -3.7507, 10.033899, 36.1422, -2.9887998, 13.378601, 36.153297, -2.972, 10.033899, 39.877598, -3.7507, 10.033899, 39.877598, -3.7507, 13.378601, 36.1422, -2.9887998, 13.378601, 52.997097, -8.1437, 10.033899, 49.520397, -6.9795, 13.378601, 49.510597, -6.9763, 10.033899, 52.997097, -8.1437, 10.033899, 52.997097, -8.1437, 13.378601, 49.520397, -6.9795, 13.378601, 52.997097, -8.1437, 6.6893, 52.997097, -8.1437, 10.033899, 49.510597, -6.9763, 10.033899, 49.520397, -6.9795, 13.378601, 46.4435, -5.9493, 10.033899, 49.510597, -6.9763, 10.033899, 49.520397, -6.9795, 13.378601, 46.4646, -5.9563, 13.378601, 46.4435, -5.9493, 10.033899, 52.997097, -8.1437, 6.6893, 49.510597, -6.9763, 10.033899, 49.500698, -6.973, 6.6893, 52.997097, -8.1437, 3.3446, 52.997097, -8.1437, 6.6893, 49.500698, -6.973, 6.6893, 49.510597, -6.9763, 10.033899, 46.4435, -5.9493, 10.033899, 46.4225, -5.9421997, 6.6893, 49.510597, -6.9763, 10.033899, 46.4225, -5.9421997, 6.6893, 49.500698, -6.973, 6.6893, 46.4646, -5.9563, 13.378601, 43.0695, -4.8195, 10.033899, 46.4435, -5.9493, 10.033899, 46.4646, -5.9563, 13.378601, 43.0932, -4.8275, 13.378601, 43.0695, -4.8195, 10.033899, 43.0932, -4.8275, 13.378601, 39.877598, -3.7507, 10.033899, 43.0695, -4.8195, 10.033899, 43.0932, -4.8275, 13.378601, 39.877598, -3.7507, 13.378601, 39.877598, -3.7507, 10.033899, 43.0695, -4.8195, 10.033899, 39.877598, -3.7507, 10.033899, 39.877598, -3.7507, 6.6893, 46.4435, -5.9493, 10.033899, 43.0695, -4.8195, 10.033899, 43.0458, -4.8115997, 6.6893, 43.0695, -4.8195, 10.033899, 39.877598, -3.7507, 6.6893, 43.0458, -4.8115997, 6.6893, 46.4435, -5.9493, 10.033899, 43.0458, -4.8115997, 6.6893, 46.4225, -5.9421997, 6.6893, 43.0458, -4.8115997, 6.6893, 39.877598, -3.7507, 6.6893, 39.877598, -3.7507, 3.3446, 43.0458, -4.8115997, 6.6893, 39.877598, -3.7507, 3.3446, 43.0221, -4.8036, 3.3446, 46.4225, -5.9421997, 6.6893, 43.0458, -4.8115997, 6.6893, 43.0221, -4.8036, 3.3446, 43.0221, -4.8036, 3.3446, 39.877598, -3.7507, 3.3446, 39.877598, -3.7507, 0, 46.4225, -5.9421997, 6.6893, 43.0221, -4.8036, 3.3446, 46.4015, -5.9351997, 3.3446, 49.500698, -6.973, 6.6893, 46.4225, -5.9421997, 6.6893, 46.4015, -5.9351997, 3.3446, 43.0221, -4.8036, 3.3446, 39.877598, -3.7507, 0, 42.998398, -4.7957, 0, 46.4015, -5.9351997, 3.3446, 43.0221, -4.8036, 3.3446, 42.998398, -4.7957, 0, 42.998398, -4.7957, 0, 39.877598, -3.7507, 0, 39.877598, -3.7507, -3.3446002, 49.500698, -6.973, 6.6893, 46.4015, -5.9351997, 3.3446, 49.4909, -6.9697, 3.3446, 52.997097, -8.1437, 3.3446, 49.500698, -6.973, 6.6893, 49.4909, -6.9697, 3.3446, 52.997097, -8.1437, 0, 52.997097, -8.1437, 3.3446, 49.4909, -6.9697, 3.3446, 49.4909, -6.9697, 3.3446, 46.4015, -5.9351997, 3.3446, 46.380398, -5.9282, 0, 46.4015, -5.9351997, 3.3446, 42.998398, -4.7957, 0, 46.380398, -5.9282, 0, 52.997097, -8.1437, 0, 49.4909, -6.9697, 3.3446, 49.4811, -6.9663997, 0, 49.4909, -6.9697, 3.3446, 46.380398, -5.9282, 0, 49.4811, -6.9663997, 0, 52.997097, -8.1437, -3.3446002, 52.997097, -8.1437, 0, 49.4811, -6.9663997, 0, 42.998398, -4.7957, 0, 39.877598, -3.7507, -3.3446002, 42.974697, -4.7878, -3.3446002, 46.380398, -5.9282, 0, 42.998398, -4.7957, 0, 42.974697, -4.7878, -3.3446002, 42.974697, -4.7878, -3.3446002, 39.877598, -3.7507, -3.3446002, 39.877598, -3.7507, -6.6893, 42.974697, -4.7878, -3.3446002, 39.877598, -3.7507, -6.6893, 42.951, -4.7798, -6.6893, 46.380398, -5.9282, 0, 42.974697, -4.7878, -3.3446002, 46.359398, -5.9210997, -3.3446002, 46.359398, -5.9210997, -3.3446002, 42.974697, -4.7878, -3.3446002, 42.951, -4.7798, -6.6893, 49.4811, -6.9663997, 0, 46.380398, -5.9282, 0, 46.359398, -5.9210997, -3.3446002, 46.359398, -5.9210997, -3.3446002, 42.951, -4.7798, -6.6893, 46.338398, -5.9140997, -6.6893, 52.997097, -8.1437, -3.3446002, 49.4811, -6.9663997, 0, 49.4712, -6.9631, -3.3446002, 49.4811, -6.9663997, 0, 46.359398, -5.9210997, -3.3446002, 49.4712, -6.9631, -3.3446002, 49.4712, -6.9631, -3.3446002, 46.359398, -5.9210997, -3.3446002, 46.338398, -5.9140997, -6.6893, 52.997097, -8.1437, -6.6893, 52.997097, -8.1437, -3.3446002, 49.4712, -6.9631, -3.3446002, 49.4712, -6.9631, -3.3446002, 46.338398, -5.9140997, -6.6893, 49.4614, -6.9598, -6.6893, 52.997097, -8.1437, -6.6893, 49.4712, -6.9631, -3.3446002, 49.4614, -6.9598, -6.6893, 39.877598, -3.7507, 6.6893, 36.153297, -2.972, 10.033899, 36.1898, -2.9299998, 6.6893, 39.877598, -3.7507, 6.6893, 39.877598, -3.7507, 10.033899, 36.153297, -2.972, 10.033899, 39.877598, -3.7507, 3.3446, 36.1898, -2.9299998, 6.6893, 36.2081, -2.9062, 3.3446, 39.877598, -3.7507, 3.3446, 39.877598, -3.7507, 6.6893, 36.1898, -2.9299998, 6.6893, 39.877598, -3.7507, 0, 36.2081, -2.9062, 3.3446, 36.211597, -2.8971, 0, 39.877598, -3.7507, 0, 39.877598, -3.7507, 3.3446, 36.2081, -2.9062, 3.3446, 39.877598, -3.7507, -3.3446002, 36.211597, -2.8971, 0, 36.2533, -2.8497999, -3.3446002, 39.877598, -3.7507, -3.3446002, 39.877598, -3.7507, 0, 36.211597, -2.8971, 0, 39.877598, -3.7507, -6.6893, 36.2533, -2.8497999, -3.3446002, 36.2803, -2.8172998, -6.6893, 39.877598, -3.7507, -6.6893, 39.877598, -3.7507, -3.3446002, 36.2533, -2.8497999, -3.3446002, 52.997097, -8.1437, -10.033899, 49.4614, -6.9598, -6.6893, 49.4666, -6.9364, -10.033899, 52.997097, -8.1437, -10.033899, 52.997097, -8.1437, -6.6893, 49.4614, -6.9598, -6.6893, 39.877598, -3.6573, -10.033899, 36.2803, -2.8172998, -6.6893, 36.3083, -2.7835999, -10.109299, 39.877598, -3.6573, -10.033899, 39.877598, -3.7507, -6.6893, 36.2803, -2.8172998, -6.6893, 39.877598, -3.6573, -13.378599, 36.3083, -2.7835999, -10.109299, 36.1797, -2.9064, -13.456699, 39.877598, -3.6573, -13.378599, 39.877598, -3.6573, -10.033899, 36.3083, -2.7835999, -10.109299, 39.877598, -3.6573, -16.7232, 36.1797, -2.9064, -13.456699, 36.2015, -2.8792, -16.7232, 39.877598, -3.6573, -16.7232, 39.877598, -3.6573, -13.378599, 36.1797, -2.9064, -13.456699, 39.877598, -3.6573, -20.0679, 36.2015, -2.8792, -16.7232, 36.1471, -2.928, -20.0679, 39.877598, -3.6573, -20.0679, 39.877598, -3.6573, -16.7232, 36.2015, -2.8792, -16.7232, 39.877598, -3.6573, -23.412498, 42.8416, -4.6944, -26.7572, 42.881, -4.6844, -23.412498, 39.877598, -3.6573, -23.412498, 39.877598, -3.6808999, -26.7572, 42.8416, -4.6944, -26.7572, 42.8416, -4.6944, -26.7572, 46.2636, -5.8410997, -23.412498, 42.881, -4.6844, -23.412498, 42.8416, -4.6944, -26.7572, 46.2278, -5.8524, -26.7572, 46.2636, -5.8410997, -23.412498, 46.2278, -5.8524, -26.7572, 49.427498, -6.923, -23.412498, 46.2636, -5.8410997, -23.412498, 46.2278, -5.8524, -26.7572, 49.4036, -6.9384, -26.7572, 49.427498, -6.923, -23.412498, 49.4036, -6.9384, -26.7572, 52.997097, -8.1437, -23.412498, 49.427498, -6.923, -23.412498, 49.4036, -6.9384, -26.7572, 52.997097, -8.1672, -26.7572, 52.997097, -8.1437, -23.412498, 52.997097, -8.1437, -23.412498, 56.4827, -8.7755995, -26.7572, 56.4571, -8.7476, -23.412498, 52.997097, -8.1437, -23.412498, 52.997097, -8.1672, -26.7572, 56.4827, -8.7755995, -26.7572, 56.4827, -8.7755995, -26.7572, 59.414497, -9.2638, -23.412498, 56.4571, -8.7476, -23.412498, 56.4827, -8.7755995, -26.7572, 59.4335, -9.2907, -26.7572, 59.414497, -9.2638, -23.412498, 59.4335, -9.2907, -26.7572, 62.3756, -9.7807, -23.412498, 59.414497, -9.2638, -23.412498, 59.4335, -9.2907, -26.7572, 62.356697, -9.8008995, -26.7572, 62.3756, -9.7807, -23.412498, 62.356697, -9.8008995, -26.7572, 66.1166, -10.4337, -23.412498, 62.3756, -9.7807, -23.412498, 62.356697, -9.8008995, -26.7572, 66.1166, -10.4572, -26.7572, 66.1166, -10.4337, -23.412498, 39.877598, -3.6573, -23.412498, 36.1471, -2.928, -20.0679, 36.1424, -2.9269998, -23.412498, 39.877598, -3.6573, -23.412498, 39.877598, -3.6573, -20.0679, 36.1471, -2.928, -20.0679, 36.1471, -2.928, -20.0679, 33.0948, -2.3312, -23.412498, 36.1424, -2.9269998, -23.412498, 36.1471, -2.928, -20.0679, 33.1148, -2.3351, -20.0679, 33.0948, -2.3312, -23.412498, 33.1148, -2.3351, -20.0679, 29.564798, -1.6410999, -23.412498, 33.0948, -2.3312, -23.412498, 33.1148, -2.3351, -20.0679, 29.562698, -1.6407, -20.0679, 29.564798, -1.6410999, -23.412498, 29.562698, -1.6407, -20.0679, 26.7582, -1.0924, -23.412498, 29.564798, -1.6410999, -23.412498, 29.562698, -1.6407, -20.0679, 26.7582, -1.0924, -20.0679, 26.7582, -1.0924, -23.412498, 29.6302, -1.5764999, -13.594999, 26.7577, -0.8804, -16.7232, 29.7123, -1.5057, -16.7232, 29.6302, -1.5764999, -13.594999, 26.572199, -0.95549995, -13.659599, 26.7577, -0.8804, -16.7232, 30.0488, -1.2003, -6.6893, 26.572199, -0.4003, -10.314899, 30.0059, -1.2408999, -10.242399, 30.0488, -1.2003, -6.6893, 26.7577, -0.3464, -6.6893, 26.572199, -0.4003, -10.314899, 29.536499, -2.2303, 13.378601, 26.7582, -1.7623999, 10.033899, 29.586699, -2.188, 10.033899, 29.536499, -2.2303, 13.378601, 26.7582, -1.8294, 13.378601, 26.7582, -1.7623999, 10.033899, 29.8112, -1.4067, 0, 26.7577, -0.4894, -3.3446002, 29.9525, -1.2836, -3.3446002, 29.8112, -1.4067, 0, 26.7577, -0.6956, 0, 26.7577, -0.4894, -3.3446002, 29.550499, -2.2133, 20.0679, 26.7582, -1.8294, 16.7232, 29.552599, -2.2137, 16.7232, 29.550499, -2.2133, 20.0679, 26.7582, -1.8294, 20.0679, 26.7582, -1.8294, 16.7232, 29.3928, -1.796, -26.7572, 33.0948, -2.3312, -23.412498, 29.564798, -1.6410999, -23.412498, 29.3928, -1.796, -26.7572, 32.9589, -2.4371, -26.7572, 33.0948, -2.3312, -23.412498, 29.7136, -1.4886999, 6.6893, 26.7577, -0.73109996, 3.3446, 29.7848, -1.4277999, 3.3446, 29.7136, -1.4886999, 6.6893, 26.7582, -0.83089995, 6.6893, 26.7577, -0.73109996, 3.3446, 29.1145, -2.5956, 26.7572, 26.7582, -2.2719998, 23.3902, 29.548399, -2.2129, 23.412498, 29.1145, -2.5956, 26.7572, 26.7582, -2.7837, 26.6955, 26.7582, -2.2719998, 23.3902, 29.7123, -1.5057, -16.7232, 26.7582, -1.0924, -20.0679, 29.562698, -1.6407, -20.0679, 29.7123, -1.5057, -16.7232, 26.7577, -0.8804, -16.7232, 26.7582, -1.0924, -20.0679, 30.0059, -1.2408999, -10.242399, 26.572199, -0.95549995, -13.659599, 29.6302, -1.5764999, -13.594999, 30.0059, -1.2408999, -10.242399, 26.572199, -0.4003, -10.314899, 26.572199, -0.95549995, -13.659599, 29.586699, -2.188, 10.033899, 26.7582, -0.83089995, 6.6893, 29.7136, -1.4886999, 6.6893, 29.586699, -2.188, 10.033899, 26.7582, -1.7623999, 10.033899, 26.7582, -0.83089995, 6.6893, 29.9525, -1.2836, -3.3446002, 26.7577, -0.3464, -6.6893, 30.0488, -1.2003, -6.6893, 29.9525, -1.2836, -3.3446002, 26.7577, -0.4894, -3.3446002, 26.7577, -0.3464, -6.6893, 29.552599, -2.2137, 16.7232, 26.7582, -1.8294, 13.378601, 29.536499, -2.2303, 13.378601, 29.552599, -2.2137, 16.7232, 26.7582, -1.8294, 16.7232, 26.7582, -1.8294, 13.378601, 29.7848, -1.4277999, 3.3446, 26.7577, -0.6956, 0, 29.8112, -1.4067, 0, 29.7848, -1.4277999, 3.3446, 26.7577, -0.73109996, 3.3446, 26.7577, -0.6956, 0, 29.548399, -2.2129, 23.412498, 26.7582, -1.8294, 20.0679, 29.550499, -2.2133, 20.0679, 29.548399, -2.2129, 23.412498, 26.7582, -2.2719998, 23.3902, 26.7582, -1.8294, 20.0679, 33.1982, -2.3009999, -13.5196, 29.7123, -1.5057, -16.7232, 33.2289, -2.25, -16.7232, 33.1982, -2.3009999, -13.5196, 29.6302, -1.5764999, -13.594999, 29.7123, -1.5057, -16.7232, 33.4719, -2.0886, -6.6893, 30.0059, -1.2408999, -10.242399, 33.4514, -2.0843, -10.169699, 33.4719, -2.0886, -6.6893, 30.0488, -1.2003, -6.6893, 30.0059, -1.2408999, -10.242399, 33.2822, -2.9943, 13.378601, 29.586699, -2.188, 10.033899, 33.2915, -2.9626, 10.033899, 33.2822, -2.9943, 13.378601, 29.536499, -2.2303, 13.378601, 29.586699, -2.188, 10.033899, 33.3661, -2.2345, 0, 29.9525, -1.2836, -3.3446002, 33.4326, -2.1487, -3.3446002, 33.3661, -2.2345, 0, 29.8112, -1.4067, 0, 29.9525, -1.2836, -3.3446002, 33.3628, -2.9636998, 20.0679, 29.552599, -2.2137, 16.7232, 33.3428, -2.9598, 16.7232, 33.3628, -2.9636998, 20.0679, 29.550499, -2.2133, 20.0679, 29.552599, -2.2137, 16.7232, 33.3828, -2.9677, 23.412498, 29.550499, -2.2133, 20.0679, 33.3628, -2.9636998, 20.0679, 33.3828, -2.9677, 23.412498, 29.548399, -2.2129, 23.412498, 29.550499, -2.2133, 20.0679, 33.347797, -2.2975, 6.6893, 29.7848, -1.4277999, 3.3446, 33.370598, -2.2531, 3.3446, 33.347797, -2.2975, 6.6893, 29.7136, -1.4886999, 6.6893, 29.7848, -1.4277999, 3.3446, 33.146698, -3.214, 26.7572, 29.548399, -2.2129, 23.412498, 33.3828, -2.9677, 23.412498, 33.146698, -3.214, 26.7572, 29.1145, -2.5956, 26.7572, 29.548399, -2.2129, 23.412498, 33.2289, -2.25, -16.7232, 29.562698, -1.6407, -20.0679, 33.1148, -2.3351, -20.0679, 33.2289, -2.25, -16.7232, 29.7123, -1.5057, -16.7232, 29.562698, -1.6407, -20.0679, 32.9589, -2.4371, -26.7572, 36.1424, -2.9269998, -23.412498, 33.0948, -2.3312, -23.412498, 32.9589, -2.4371, -26.7572, 36.0678, -2.9959998, -26.7572, 36.1424, -2.9269998, -23.412498, 33.4514, -2.0843, -10.169699, 29.6302, -1.5764999, -13.594999, 33.1982, -2.3009999, -13.5196, 33.4514, -2.0843, -10.169699, 30.0059, -1.2408999, -10.242399, 29.6302, -1.5764999, -13.594999, 33.2915, -2.9626, 10.033899, 29.7136, -1.4886999, 6.6893, 33.347797, -2.2975, 6.6893, 33.2915, -2.9626, 10.033899, 29.586699, -2.188, 10.033899, 29.7136, -1.4886999, 6.6893, 33.4326, -2.1487, -3.3446002, 30.0488, -1.2003, -6.6893, 33.4719, -2.0886, -6.6893, 33.4326, -2.1487, -3.3446002, 29.9525, -1.2836, -3.3446002, 30.0488, -1.2003, -6.6893, 33.3428, -2.9598, 16.7232, 29.536499, -2.2303, 13.378601, 33.2822, -2.9943, 13.378601, 33.3428, -2.9598, 16.7232, 29.552599, -2.2137, 16.7232, 29.536499, -2.2303, 13.378601, 33.370598, -2.2531, 3.3446, 29.8112, -1.4067, 0, 33.3661, -2.2345, 0, 33.370598, -2.2531, 3.3446, 29.7848, -1.4277999, 3.3446, 29.8112, -1.4067, 0, 36.1797, -2.9064, -13.456699, 33.2289, -2.25, -16.7232, 36.2015, -2.8792, -16.7232, 36.1797, -2.9064, -13.456699, 33.1982, -2.3009999, -13.5196, 33.2289, -2.25, -16.7232, 36.2803, -2.8172998, -6.6893, 33.4514, -2.0843, -10.169699, 36.3083, -2.7835999, -10.109299, 36.2803, -2.8172998, -6.6893, 33.4719, -2.0886, -6.6893, 33.4514, -2.0843, -10.169699, 36.1422, -2.9887998, 13.378601, 33.2915, -2.9626, 10.033899, 36.153297, -2.972, 10.033899, 36.1422, -2.9887998, 13.378601, 33.2822, -2.9943, 13.378601, 33.2915, -2.9626, 10.033899, 36.211597, -2.8971, 0, 33.4326, -2.1487, -3.3446002, 36.2533, -2.8497999, -3.3446002, 36.211597, -2.8971, 0, 33.3661, -2.2345, 0, 33.4326, -2.1487, -3.3446002, 36.2075, -2.9348, 20.0679, 33.3428, -2.9598, 16.7232, 36.2028, -2.9338999, 16.7232, 36.2075, -2.9348, 20.0679, 33.3628, -2.9636998, 20.0679, 33.3428, -2.9598, 16.7232, 36.153297, -2.972, 10.033899, 33.347797, -2.2975, 6.6893, 36.1898, -2.9299998, 6.6893, 36.153297, -2.972, 10.033899, 33.2915, -2.9626, 10.033899, 33.347797, -2.2975, 6.6893, 36.1898, -2.9299998, 6.6893, 33.370598, -2.2531, 3.3446, 36.2081, -2.9062, 3.3446, 36.1898, -2.9299998, 6.6893, 33.347797, -2.2975, 6.6893, 33.370598, -2.2531, 3.3446, 36.078598, -3.0746999, 26.7572, 33.3828, -2.9677, 23.412498, 36.2121, -2.9357, 23.412498, 36.078598, -3.0746999, 26.7572, 33.146698, -3.214, 26.7572, 33.3828, -2.9677, 23.412498, 36.2015, -2.8792, -16.7232, 33.1148, -2.3351, -20.0679, 36.1471, -2.928, -20.0679, 36.2015, -2.8792, -16.7232, 33.2289, -2.25, -16.7232, 33.1148, -2.3351, -20.0679, 36.3083, -2.7835999, -10.109299, 33.1982, -2.3009999, -13.5196, 36.1797, -2.9064, -13.456699, 36.3083, -2.7835999, -10.109299, 33.4514, -2.0843, -10.169699, 33.1982, -2.3009999, -13.5196, 36.0678, -2.9959998, -26.7572, 39.877598, -3.6573, -23.412498, 36.1424, -2.9269998, -23.412498, 36.0678, -2.9959998, -26.7572, 39.877598, -3.6808999, -26.7572, 39.877598, -3.6573, -23.412498, 36.2533, -2.8497999, -3.3446002, 33.4719, -2.0886, -6.6893, 36.2803, -2.8172998, -6.6893, 36.2533, -2.8497999, -3.3446002, 33.4326, -2.1487, -3.3446002, 33.4719, -2.0886, -6.6893, 36.2028, -2.9338999, 16.7232, 33.2822, -2.9943, 13.378601, 36.1422, -2.9887998, 13.378601, 36.2028, -2.9338999, 16.7232, 33.3428, -2.9598, 16.7232, 33.2822, -2.9943, 13.378601, 36.2081, -2.9062, 3.3446, 33.3661, -2.2345, 0, 36.211597, -2.8971, 0, 36.2081, -2.9062, 3.3446, 33.370598, -2.2531, 3.3446, 33.3661, -2.2345, 0, 36.2121, -2.9357, 23.412498, 33.3628, -2.9636998, 20.0679, 36.2075, -2.9348, 20.0679, 36.2121, -2.9357, 23.412498, 33.3828, -2.9677, 23.412498, 33.3628, -2.9636998, 20.0679, 42.951, -4.7798, -6.6893, 39.877598, -3.6573, -10.033899, 42.9754, -4.7166, -10.033899, 42.951, -4.7798, -6.6893, 39.877598, -3.7507, -6.6893, 39.877598, -3.6573, -10.033899, 43.1641, -4.7812, 16.7232, 39.877598, -3.7507, 13.378601, 43.0932, -4.8275, 13.378601, 43.1641, -4.7812, 16.7232, 39.877598, -3.6573, 16.7232, 39.877598, -3.7507, 13.378601, 46.338398, -5.9140997, -6.6893, 42.9754, -4.7166, -10.033899, 46.3474, -5.8697, -10.033899, 46.338398, -5.9140997, -6.6893, 42.951, -4.7798, -6.6893, 42.9754, -4.7166, -10.033899, 46.5149, -5.927, 16.7232, 43.0932, -4.8275, 13.378601, 46.4646, -5.9563, 13.378601, 46.5149, -5.927, 16.7232, 43.1641, -4.7812, 16.7232, 43.0932, -4.8275, 13.378601, 49.4614, -6.9598, -6.6893, 46.3474, -5.8697, -10.033899, 49.4666, -6.9364, -10.033899, 49.4614, -6.9598, -6.6893, 46.338398, -5.9140997, -6.6893, 46.3474, -5.8697, -10.033899, 49.5449, -6.9631996, 16.7232, 46.4646, -5.9563, 13.378601, 49.520397, -6.9795, 13.378601, 49.5449, -6.9631996, 16.7232, 46.5149, -5.927, 16.7232, 46.4646, -5.9563, 13.378601, -23.412498, -3.8518999, 39.456898, -26.7572, -3.2777, 36.6322, -23.412498, -3.2477999, 36.6305, -23.412498, -3.8518999, 39.456898, -26.7572, -3.8518999, 39.456898, -26.7572, -3.2777, 36.6322, -16.7232, -3.8518999, 39.456898, -13.378601, -3.243, 36.6252, -13.378601, -3.8518999, 39.456898, -16.7232, -3.8518999, 39.456898, -16.7232, -3.247, 36.6269, -13.378601, -3.243, 36.6252, -13.378601, -1.1209999, 26.7572, -10.033899, -1.8925999, 30.345499, -13.378601, -1.8938999, 30.3512, -10.033899, -1.8925999, 30.345499, -13.378601, -2.619, 33.7235, -13.378601, -1.8938999, 30.3512, -13.378601, -1.1209999, 26.7572, -10.033899, -1.1209999, 26.7572, -10.033899, -1.8925999, 30.345499, -10.033899, -1.8925999, 30.345499, -10.033899, -2.6181998, 33.7199, -13.378601, -2.619, 33.7235, -10.033899, -2.6181998, 33.7199, -13.378601, -3.243, 36.6252, -13.378601, -2.619, 33.7235, -10.033899, -1.1209999, 26.7572, -6.6893, -1.8914, 30.3399, -10.033899, -1.8925999, 30.345499, -6.6893, -1.8914, 30.3399, -10.033899, -2.6181998, 33.7199, -10.033899, -1.8925999, 30.345499, -10.033899, -1.1209999, 26.7572, -6.6893, -1.1209999, 26.7572, -6.6893, -1.8914, 30.3399, -10.033899, -2.6181998, 33.7199, -10.033899, -3.2426, 36.623398, -13.378601, -3.243, 36.6252, -10.033899, -3.2426, 36.623398, -13.378601, -3.8518999, 39.456898, -13.378601, -3.243, 36.6252, -10.033899, -3.2426, 36.623398, -10.033899, -3.8518999, 39.456898, -13.378601, -3.8518999, 39.456898, -6.6893, -2.6174998, 33.7163, -10.033899, -3.2426, 36.623398, -10.033899, -2.6181998, 33.7199, -6.6893, -1.8914, 30.3399, -6.6893, -2.6174998, 33.7163, -10.033899, -2.6181998, 33.7199, -6.6893, -3.2422, 36.6217, -10.033899, -3.8518999, 39.456898, -10.033899, -3.2426, 36.623398, -6.6893, -2.6174998, 33.7163, -6.6893, -3.2422, 36.6217, -10.033899, -3.2426, 36.623398, -6.6893, -3.2422, 36.6217, -6.6893, -3.8518999, 39.456898, -10.033899, -3.8518999, 39.456898, -3.3446002, -1.8901999, 30.3342, -6.6893, -2.6174998, 33.7163, -6.6893, -1.8914, 30.3399, -6.6893, -1.1209999, 26.7572, -3.3446002, -1.8901999, 30.3342, -6.6893, -1.8914, 30.3399, -6.6893, -1.1209999, 26.7572, -3.3446002, -1.1209999, 26.7572, -3.3446002, -1.8901999, 30.3342, -3.3446002, -1.8901999, 30.3342, -3.3446002, -2.6167, 33.7128, -6.6893, -2.6174998, 33.7163, -3.3446002, -2.6167, 33.7128, -6.6893, -3.2422, 36.6217, -6.6893, -2.6174998, 33.7163, -3.3446002, -1.1209999, 26.7572, 0, -1.8889999, 30.3286, -3.3446002, -1.8901999, 30.3342, 0, -1.8889999, 30.3286, -3.3446002, -2.6167, 33.7128, -3.3446002, -1.8901999, 30.3342, -3.3446002, -1.1209999, 26.7572, 0, -1.1209999, 26.7572, 0, -1.8889999, 30.3286, -3.3446002, -3.2417998, 36.6199, -6.6893, -3.8518999, 39.456898, -6.6893, -3.2422, 36.6217, -3.3446002, -2.6167, 33.7128, -3.3446002, -3.2417998, 36.6199, -6.6893, -3.2422, 36.6217, -3.3446002, -3.2417998, 36.6199, -3.3446002, -3.8518999, 39.456898, -6.6893, -3.8518999, 39.456898, 0, -1.8889999, 30.3286, 0, -2.616, 33.709198, -3.3446002, -2.6167, 33.7128, 0, -2.616, 33.709198, -3.3446002, -3.2417998, 36.6199, -3.3446002, -2.6167, 33.7128, 0, -1.1209999, 26.7572, 3.3446, -1.8878, 30.323, 0, -1.8889999, 30.3286, 3.3446, -1.8878, 30.323, 0, -2.616, 33.709198, 0, -1.8889999, 30.3286, 0, -1.1209999, 26.7572, 3.3446, -1.1209999, 26.7572, 3.3446, -1.8878, 30.323, 0, -3.2415, 36.6182, -3.3446002, -3.8518999, 39.456898, -3.3446002, -3.2417998, 36.6199, 0, -2.616, 33.709198, 0, -3.2415, 36.6182, -3.3446002, -3.2417998, 36.6199, 0, -3.2415, 36.6182, 0, -3.8518999, 39.456898, -3.3446002, -3.8518999, 39.456898, 3.3446, -1.8878, 30.323, 3.3446, -2.6152, 33.7057, 0, -2.616, 33.709198, 3.3446, -2.6152, 33.7057, 0, -3.2415, 36.6182, 0, -2.616, 33.709198, 3.3446, -1.1209999, 26.7572, 6.6893, -1.8865999, 30.317299, 3.3446, -1.8878, 30.323, 6.6893, -1.8865999, 30.317299, 3.3446, -2.6152, 33.7057, 3.3446, -1.8878, 30.323, 3.3446, -1.1209999, 26.7572, 6.6893, -1.1209999, 26.7572, 6.6893, -1.8865999, 30.317299, 6.6893, -1.1209999, 26.7572, 10.033899, -1.8853999, 30.311699, 6.6893, -1.8865999, 30.317299, 6.6893, -1.1209999, 26.7572, 10.033899, -1.1209999, 26.7572, 10.033899, -1.8853999, 30.311699, 10.033899, -1.8853999, 30.311699, 6.6893, -2.6144, 33.7021, 6.6893, -1.8865999, 30.317299, 6.6893, -1.8865999, 30.317299, 6.6893, -2.6144, 33.7021, 3.3446, -2.6152, 33.7057, 10.033899, -1.8853999, 30.311699, 10.033899, -2.6137, 33.6986, 6.6893, -2.6144, 33.7021, 3.3446, -2.6152, 33.7057, 3.3446, -3.2410998, 36.616398, 0, -3.2415, 36.6182, 3.3446, -3.2410998, 36.616398, 0, -3.8518999, 39.456898, 0, -3.2415, 36.6182, 6.6893, -2.6144, 33.7021, 3.3446, -3.2410998, 36.616398, 3.3446, -2.6152, 33.7057, 3.3446, -3.2410998, 36.616398, 3.3446, -3.8518999, 39.456898, 0, -3.8518999, 39.456898, 10.033899, -2.6137, 33.6986, 6.6893, -3.2407, 36.6147, 6.6893, -2.6144, 33.7021, 6.6893, -2.6144, 33.7021, 6.6893, -3.2407, 36.6147, 3.3446, -3.2410998, 36.616398, 6.6893, -3.2407, 36.6147, 3.3446, -3.8518999, 39.456898, 3.3446, -3.2410998, 36.616398, 10.033899, -2.6137, 33.6986, 10.033899, -3.2403, 36.6129, 6.6893, -3.2407, 36.6147, 6.6893, -3.2407, 36.6147, 6.6893, -3.8518999, 39.456898, 3.3446, -3.8518999, 39.456898, 10.033899, -3.2403, 36.6129, 6.6893, -3.8518999, 39.456898, 6.6893, -3.2407, 36.6147, 10.033899, -3.2403, 36.6129, 10.033899, -3.8518999, 39.456898, 6.6893, -3.8518999, 39.456898, 10.033899, -1.1209999, 26.7572, 13.378599, -2.6734, 30.306, 10.033899, -1.8853999, 30.311699, 10.033899, -1.1209999, 26.7572, 13.378599, -2.2194998, 26.781, 13.378599, -2.6734, 30.306, 13.378599, -2.2194998, 26.781, 16.7232, -2.6727, 30.3004, 13.378599, -2.6734, 30.306, 16.7232, -2.6727, 30.3004, 13.378599, -3.1099, 33.695, 13.378599, -2.6734, 30.306, 13.378599, -2.2194998, 26.781, 16.7232, -2.2194998, 26.781, 16.7232, -2.6727, 30.3004, 16.7232, -2.6727, 30.3004, 16.7232, -3.1094, 33.691498, 13.378599, -3.1099, 33.695, 16.7232, -3.1094, 33.691498, 13.378599, -3.4854, 36.6112, 13.378599, -3.1099, 33.695, 16.7232, -2.2194998, 26.781, 20.0679, -2.672, 30.294699, 16.7232, -2.6727, 30.3004, 20.0679, -2.672, 30.294699, 16.7232, -3.1094, 33.691498, 16.7232, -2.6727, 30.3004, 16.7232, -2.2194998, 26.781, 20.0679, -2.2194998, 26.781, 20.0679, -2.672, 30.294699, 20.0679, -2.2194998, 26.781, 23.412498, -2.6713, 30.289099, 20.0679, -2.672, 30.294699, 20.0679, -2.2194998, 26.781, 23.412498, -2.2194998, 26.781, 23.412498, -2.6713, 30.289099, 23.412498, -2.6713, 30.289099, 20.0679, -3.109, 33.6879, 20.0679, -2.672, 30.294699, 20.0679, -2.672, 30.294699, 20.0679, -3.109, 33.6879, 16.7232, -3.1094, 33.691498, 23.412498, -2.6713, 30.289099, 23.412498, -3.1085, 33.6844, 20.0679, -3.109, 33.6879, 16.7232, -3.1094, 33.691498, 16.7232, -3.4852, 36.609398, 13.378599, -3.4854, 36.6112, 20.0679, -3.109, 33.6879, 16.7232, -3.4852, 36.609398, 16.7232, -3.1094, 33.691498, 16.7232, -3.4852, 36.609398, 13.378599, -3.8518999, 39.456898, 13.378599, -3.4854, 36.6112, 16.7232, -3.4852, 36.609398, 16.7232, -3.8518999, 39.456898, 13.378599, -3.8518999, 39.456898, 20.0679, -3.109, 33.6879, 20.0679, -3.485, 36.607597, 16.7232, -3.4852, 36.609398, 20.0679, -3.485, 36.607597, 16.7232, -3.8518999, 39.456898, 16.7232, -3.4852, 36.609398, 23.412498, -3.1085, 33.6844, 20.0679, -3.485, 36.607597, 20.0679, -3.109, 33.6879, 20.0679, -3.485, 36.607597, 20.0679, -3.8518999, 39.456898, 16.7232, -3.8518999, 39.456898, 23.412498, -3.1085, 33.6844, 23.412498, -3.4847, 36.6059, 20.0679, -3.485, 36.607597, 23.412498, -3.4847, 36.6059, 20.0679, -3.8518999, 39.456898, 20.0679, -3.485, 36.607597, 23.412498, -3.4847, 36.6059, 23.412498, -3.8518999, 39.456898, 20.0679, -3.8518999, 39.456898, 23.412498, -2.2194998, 26.781, 26.7582, -3.0839999, 30.2834, 23.412498, -2.6713, 30.289099, 23.412498, -2.2194998, 26.781, 26.7582, -2.7837, 26.6955, 26.7582, -3.0839999, 30.2834, -26.7572, -3.2777, 36.6322, -23.412498, -2.6287, 33.7341, -23.412498, -3.2477999, 36.6305, -26.7572, -3.2777, 36.6322, -26.7572, -2.6892, 33.737698, -23.412498, -2.6287, 33.7341, -16.7232, -3.247, 36.6269, -13.378601, -2.619, 33.7235, -13.378601, -3.243, 36.6252, -16.7232, -3.247, 36.6269, -16.7232, -2.6272, 33.726997, -13.378601, -2.619, 33.7235, 26.7582, -3.6130998, 36.6041, 23.412498, -3.8518999, 39.456898, 23.412498, -3.4847, 36.6059, 26.7582, -3.6130998, 36.6041, 26.7582, -3.8518999, 39.456898, 23.412498, -3.8518999, 39.456898, 13.378599, -3.4854, 36.6112, 10.033899, -3.8518999, 39.456898, 10.033899, -3.2403, 36.6129, 13.378599, -3.4854, 36.6112, 13.378599, -3.8518999, 39.456898, 10.033899, -3.8518999, 39.456898, 26.7582, -3.3683999, 33.680798, 23.412498, -3.4847, 36.6059, 23.412498, -3.1085, 33.6844, 26.7582, -3.3683999, 33.680798, 26.7582, -3.6130998, 36.6041, 23.412498, -3.4847, 36.6059, -26.7572, -2.6892, 33.737698, -23.412498, -1.9093, 30.3681, -23.412498, -2.6287, 33.7341, -26.7572, -2.6892, 33.737698, -26.7572, -2.0054, 30.3737, -23.412498, -1.9093, 30.3681, -16.7232, -2.6272, 33.726997, -13.378601, -1.8938999, 30.3512, -13.378601, -2.619, 33.7235, -16.7232, -2.6272, 33.726997, -16.7232, -1.9068999, 30.3568, -13.378601, -1.8938999, 30.3512, 13.378599, -3.1099, 33.695, 10.033899, -3.2403, 36.6129, 10.033899, -2.6137, 33.6986, 13.378599, -3.1099, 33.695, 13.378599, -3.4854, 36.6112, 10.033899, -3.2403, 36.6129, -26.7572, -2.0054, 30.3737, -23.412498, -1.1374999, 26.7572, -23.412498, -1.9093, 30.3681, -26.7572, -2.0054, 30.3737, -26.7572, -1.2701, 26.7572, -23.412498, -1.1374999, 26.7572, 26.7582, -3.0839999, 30.2834, 23.412498, -3.1085, 33.6844, 23.412498, -2.6713, 30.289099, 26.7582, -3.0839999, 30.2834, 26.7582, -3.3683999, 33.680798, 23.412498, -3.1085, 33.6844, 13.378599, -2.6734, 30.306, 10.033899, -2.6137, 33.6986, 10.033899, -1.8853999, 30.311699, 13.378599, -2.6734, 30.306, 13.378599, -3.1099, 33.695, 10.033899, -2.6137, 33.6986, -16.7232, -1.9068999, 30.3568, -13.378601, -1.1209999, 26.7572, -13.378601, -1.8938999, 30.3512, -16.7232, -1.9068999, 30.3568, -16.7232, -1.1374999, 26.7572, -13.378601, -1.1209999, 26.7572, -38.5239, -3.6573, -23.412498, -36.0882, -3.5405, -26.7572, -36.0928, -3.4731998, -23.412498, -38.5239, -3.6573, -23.412498, -38.5239, -3.6573, -26.7572, -36.0882, -3.5405, -26.7572, -38.5239, -3.6573, -20.3888, -36.0928, -3.4731998, -23.412498, -36.0969, -3.2475998, -20.410799, -38.5239, -3.6573, -20.3888, -38.5239, -3.6573, -23.412498, -36.0928, -3.4731998, -23.412498, -38.5239, -3.6573, -20.0679, -36.101498, -3.2484, -17.0662, -38.5239, -3.6573, -17.0441, -36.101498, -3.2484, -17.0662, -38.5239, -3.6573, -20.0679, -38.5239, -3.6573, -20.3888, -36.101498, -3.2484, -17.0662, -38.5239, -3.6573, -20.3888, -36.0969, -3.2475998, -20.410799, -36.0969, -3.2475998, -20.410799, -33.3005, -2.7756, -17.0916, -36.101498, -3.2484, -17.0662, -36.0969, -3.2475998, -20.410799, -33.2906, -2.7739, -20.4364, -33.3005, -2.7756, -17.0916, -33.2906, -2.7739, -20.4364, -30.219301, -2.2554998, -17.1196, -33.3005, -2.7756, -17.0916, -33.2906, -2.7739, -20.4364, -30.2036, -2.2528, -20.4644, -30.219301, -2.2554998, -17.1196, -30.2036, -2.2528, -20.4644, -26.7572, -1.6710999, -17.1511, -30.219301, -2.2554998, -17.1196, -30.2036, -2.2528, -20.4644, -26.7572, -1.6710999, -20.4958, -26.7572, -1.6710999, -17.1511, -38.5239, -3.6573, -16.7232, -36.106598, -2.8727, -13.378599, -38.5239, -3.6573, -13.378599, -36.106598, -2.8727, -13.378599, -38.5239, -3.6573, -16.7232, -38.5239, -3.6573, -17.0441, -36.106598, -2.8727, -13.378599, -38.5239, -3.6573, -17.0441, -36.101498, -3.2484, -17.0662, -38.5239, -3.6573, -10.033899, -36.106598, -2.8727, -13.378599, -36.1112, -2.8741999, -10.033899, -38.5239, -3.6573, -10.033899, -38.5239, -3.6573, -13.378599, -36.106598, -2.8727, -13.378599, -38.5239, -3.6573, -6.6893, -38.5239, -3.6573, -10.033899, -36.1112, -2.8741999, -10.033899, -38.5239, -3.6573, -6.6893, -36.1112, -2.8741999, -10.033899, -36.1158, -2.8757, -6.6893, -36.1112, -2.8741999, -10.033899, -33.3313, -1.9719, -6.6893, -36.1158, -2.8757, -6.6893, -36.106598, -2.8727, -13.378599, -33.3214, -1.9686999, -10.033899, -36.1112, -2.8741999, -10.033899, -36.1112, -2.8741999, -10.033899, -33.3214, -1.9686999, -10.033899, -33.3313, -1.9719, -6.6893, -36.106598, -2.8727, -13.378599, -33.3115, -1.9655, -13.378599, -33.3214, -1.9686999, -10.033899, -33.3214, -1.9686999, -10.033899, -30.2685, -0.9777, -6.6893, -33.3313, -1.9719, -6.6893, -33.3115, -1.9655, -13.378599, -30.252699, -0.9726, -10.033899, -33.3214, -1.9686999, -10.033899, -33.3214, -1.9686999, -10.033899, -30.252699, -0.9726, -10.033899, -30.2685, -0.9777, -6.6893, -30.252699, -0.9726, -10.033899, -29.294899, -0.6617, -6.6893, -30.2685, -0.9777, -6.6893, -33.3115, -1.9655, -13.378599, -30.237001, -0.9675, -13.378599, -30.252699, -0.9726, -10.033899, -30.252699, -0.9726, -10.033899, -29.294899, -0.6617, -10.033899, -29.294899, -0.6617, -6.6893, -30.237001, -0.9675, -13.378599, -29.294899, -0.6617, -10.033899, -30.252699, -0.9726, -10.033899, -30.237001, -0.9675, -13.378599, -29.294899, -0.6617, -13.378599, -29.294899, -0.6617, -10.033899, -38.5239, -3.6573, -3.3446002, -36.1158, -2.8757, -6.6893, -36.1204, -2.9744, -3.3446002, -38.5239, -3.6573, -3.3446002, -38.5239, -3.6573, -6.6893, -36.1158, -2.8757, -6.6893, -38.5239, -3.6573, 0, -36.1204, -2.9744, -3.3446002, -36.125, -2.9757, 0, -38.5239, -3.6573, 0, -38.5239, -3.6573, -3.3446002, -36.1204, -2.9744, -3.3446002, -36.1204, -2.9744, -3.3446002, -33.3512, -2.1875, 0, -36.125, -2.9757, 0, -36.1204, -2.9744, -3.3446002, -33.341198, -2.1847, -3.3446002, -33.3512, -2.1875, 0, -33.341198, -2.1847, -3.3446002, -30.300001, -1.3205999, 0, -33.3512, -2.1875, 0, -33.341198, -2.1847, -3.3446002, -30.2842, -1.3161, -3.3446002, -30.300001, -1.3205999, 0, -30.2842, -1.3161, -3.3446002, -27.9812, -0.6617, 0, -30.300001, -1.3205999, 0, -30.2842, -1.3161, -3.3446002, -27.9812, -0.6617, -3.3446002, -27.9812, -0.6617, 0, -29.294899, -0.6617, 3.3446, -30.3315, -0.9982, 6.6893, -30.315699, -0.9931, 3.3446, -29.294899, -0.6617, 3.3446, -29.294899, -0.6617, 6.6893, -30.3315, -0.9982, 6.6893, -29.294899, -0.6617, 10.033899, -30.3315, -0.9982, 6.6893, -29.294899, -0.6617, 6.6893, -30.3315, -0.9982, 6.6893, -29.294899, -0.6617, 10.033899, -29.294899, -0.6617, 13.378601, -30.3315, -0.9982, 6.6893, -33.3611, -1.9814999, 3.3446, -30.315699, -0.9931, 3.3446, -30.3315, -0.9982, 6.6893, -29.294899, -0.6617, 13.378601, -30.363, -1.0084, 13.378601, -30.3315, -0.9982, 6.6893, -33.371, -1.9848, 6.6893, -33.3611, -1.9814999, 3.3446, -30.363, -1.0084, 13.378601, -33.371, -1.9848, 6.6893, -30.3315, -0.9982, 6.6893, -33.371, -1.9848, 6.6893, -36.1296, -2.8801, 3.3446, -33.3611, -1.9814999, 3.3446, -30.363, -1.0084, 13.378601, -33.3908, -1.9912, 13.378601, -33.371, -1.9848, 6.6893, -33.371, -1.9848, 6.6893, -36.134197, -2.8816, 6.6893, -36.1296, -2.8801, 3.3446, -33.3908, -1.9912, 13.378601, -36.134197, -2.8816, 6.6893, -33.371, -1.9848, 6.6893, -36.134197, -2.8816, 6.6893, -38.5239, -3.6573, 3.3446, -36.1296, -2.8801, 3.3446, -33.3908, -1.9912, 13.378601, -36.1433, -2.8846, 13.378601, -36.134197, -2.8816, 6.6893, -36.134197, -2.8816, 6.6893, -38.5239, -3.6573, 6.6893, -38.5239, -3.6573, 3.3446, -38.5239, -3.6573, 13.378601, -36.134197, -2.8816, 6.6893, -36.1433, -2.8846, 13.378601, -36.134197, -2.8816, 6.6893, -38.5239, -3.6573, 10.033899, -38.5239, -3.6573, 6.6893, -36.134197, -2.8816, 6.6893, -38.5239, -3.6573, 13.378601, -38.5239, -3.6573, 10.033899, -29.294899, -1.0265, 16.7232, -30.394499, -1.8736, 20.0679, -30.378698, -1.3354, 16.7232, -29.294899, -1.0265, 16.7232, -26.7572, -1.0756, 20.0679, -30.394499, -1.8736, 20.0679, -26.7572, -1.0756, 20.0679, -30.4102, -1.8771, 23.412498, -30.394499, -1.8736, 20.0679, -26.7572, -1.0756, 20.0679, -26.7572, -1.0756, 23.412498, -30.4102, -1.8771, 23.412498, -30.4102, -1.8771, 23.412498, -33.4106, -2.5354, 20.0679, -30.394499, -1.8736, 20.0679, -30.4102, -1.8771, 23.412498, -33.420498, -2.5376, 23.412498, -33.4106, -2.5354, 20.0679, -33.420498, -2.5376, 23.412498, -36.1525, -3.1369998, 20.0679, -33.4106, -2.5354, 20.0679, -33.420498, -2.5376, 23.412498, -36.1571, -3.138, 23.412498, -36.1525, -3.1369998, 20.0679, -36.1571, -3.138, 23.412498, -38.5239, -3.6573, 20.0679, -36.1525, -3.1369998, 20.0679, -36.1571, -3.138, 23.412498, -38.5239, -3.6573, 23.412498, -38.5239, -3.6573, 20.0679, -26.7572, -1.0756, 23.412498, -30.426, -2.0144, 26.7572, -30.4102, -1.8771, 23.412498, -26.7572, -1.0756, 23.412498, -26.7572, -1.2701, 26.7572, -30.426, -2.0144, 26.7572, -29.294899, -0.6617, 13.378601, -30.378698, -1.3354, 16.7232, -30.363, -1.0084, 13.378601, -29.294899, -0.6617, 13.378601, -29.294899, -1.0265, 16.7232, -30.378698, -1.3354, 16.7232, -30.173899, -3.2568, -26.7572, -26.7572, -2.7663999, -23.412498, -30.1897, -3.0263, -23.412498, -30.173899, -3.2568, -26.7572, -26.7572, -3.0929, -26.7572, -26.7572, -2.7663999, -23.412498, -30.426, -2.0144, 26.7572, -33.420498, -2.5376, 23.412498, -30.4102, -1.8771, 23.412498, -30.426, -2.0144, 26.7572, -33.4304, -2.6239998, 26.7572, -33.420498, -2.5376, 23.412498, -30.219301, -2.2554998, -17.1196, -29.294899, -0.6617, -13.378599, -30.237001, -0.9675, -13.378599, -30.219301, -2.2554998, -17.1196, -26.7572, -1.6710999, -17.1511, -29.294899, -0.6617, -13.378599, -30.394499, -1.8736, 20.0679, -33.4007, -2.1969, 16.7232, -30.378698, -1.3354, 16.7232, -30.394499, -1.8736, 20.0679, -33.4106, -2.5354, 20.0679, -33.4007, -2.1969, 16.7232, -30.1897, -3.0263, -23.412498, -26.7572, -1.6710999, -20.4958, -30.2036, -2.2528, -20.4644, -30.1897, -3.0263, -23.412498, -26.7572, -2.7663999, -23.412498, -26.7572, -1.6710999, -20.4958, -30.315699, -0.9931, 3.3446, -33.3512, -2.1875, 0, -30.300001, -1.3205999, 0, -30.315699, -0.9931, 3.3446, -33.3611, -1.9814999, 3.3446, -33.3512, -2.1875, 0, -30.2685, -0.9777, -6.6893, -27.9812, -0.6617, -3.3446002, -30.2842, -1.3161, -3.3446002, -30.2685, -0.9777, -6.6893, -29.294899, -0.6617, -6.6893, -27.9812, -0.6617, -3.3446002, -30.378698, -1.3354, 16.7232, -33.3908, -1.9912, 13.378601, -30.363, -1.0084, 13.378601, -30.378698, -1.3354, 16.7232, -33.4007, -2.1969, 16.7232, -33.3908, -1.9912, 13.378601, -33.2719, -3.4053998, -26.7572, -30.1897, -3.0263, -23.412498, -33.2818, -3.2603998, -23.412498, -33.2719, -3.4053998, -26.7572, -30.173899, -3.2568, -26.7572, -30.1897, -3.0263, -23.412498, -33.4007, -2.1969, 16.7232, -36.1433, -2.8846, 13.378601, -33.3908, -1.9912, 13.378601, -33.4007, -2.1969, 16.7232, -36.1479, -2.98, 16.7232, -36.1433, -2.8846, 13.378601, -33.4304, -2.6239998, 26.7572, -36.1571, -3.138, 23.412498, -33.420498, -2.5376, 23.412498, -33.4304, -2.6239998, 26.7572, -36.161697, -3.1780999, 26.7572, -36.1571, -3.138, 23.412498, -33.3005, -2.7756, -17.0916, -30.237001, -0.9675, -13.378599, -33.3115, -1.9655, -13.378599, -33.3005, -2.7756, -17.0916, -30.219301, -2.2554998, -17.1196, -30.237001, -0.9675, -13.378599, -33.2818, -3.2603998, -23.412498, -30.2036, -2.2528, -20.4644, -33.2906, -2.7739, -20.4364, -33.2818, -3.2603998, -23.412498, -30.1897, -3.0263, -23.412498, -30.2036, -2.2528, -20.4644, -33.3611, -1.9814999, 3.3446, -36.125, -2.9757, 0, -33.3512, -2.1875, 0, -33.3611, -1.9814999, 3.3446, -36.1296, -2.8801, 3.3446, -36.125, -2.9757, 0, -33.4106, -2.5354, 20.0679, -36.1479, -2.98, 16.7232, -33.4007, -2.1969, 16.7232, -33.4106, -2.5354, 20.0679, -36.1525, -3.1369998, 20.0679, -36.1479, -2.98, 16.7232, -33.3313, -1.9719, -6.6893, -30.2842, -1.3161, -3.3446002, -33.341198, -2.1847, -3.3446002, -33.3313, -1.9719, -6.6893, -30.2685, -0.9777, -6.6893, -30.2842, -1.3161, -3.3446002, -36.161697, -3.1780999, 26.7572, -38.5239, -3.6573, 23.412498, -36.1571, -3.138, 23.412498, -36.161697, -3.1780999, 26.7572, -38.5239, -3.6573, 26.7572, -38.5239, -3.6573, 23.412498, -36.101498, -3.2484, -17.0662, -33.3115, -1.9655, -13.378599, -36.106598, -2.8727, -13.378599, -36.101498, -3.2484, -17.0662, -33.3005, -2.7756, -17.0916, -33.3115, -1.9655, -13.378599, -36.0928, -3.4731998, -23.412498, -33.2906, -2.7739, -20.4364, -36.0969, -3.2475998, -20.410799, -36.0928, -3.4731998, -23.412498, -33.2818, -3.2603998, -23.412498, -33.2906, -2.7739, -20.4364, -36.1296, -2.8801, 3.3446, -38.5239, -3.6573, 0, -36.125, -2.9757, 0, -36.1296, -2.8801, 3.3446, -38.5239, -3.6573, 3.3446, -38.5239, -3.6573, 0, -36.1158, -2.8757, -6.6893, -33.341198, -2.1847, -3.3446002, -36.1204, -2.9744, -3.3446002, -36.1158, -2.8757, -6.6893, -33.3313, -1.9719, -6.6893, -33.341198, -2.1847, -3.3446002, -36.1525, -3.1369998, 20.0679, -38.5239, -3.6573, 16.7232, -36.1479, -2.98, 16.7232, -36.1525, -3.1369998, 20.0679, -38.5239, -3.6573, 20.0679, -38.5239, -3.6573, 16.7232, -36.0882, -3.5405, -26.7572, -33.2818, -3.2603998, -23.412498, -36.0928, -3.4731998, -23.412498, -36.0882, -3.5405, -26.7572, -33.2719, -3.4053998, -26.7572, -33.2818, -3.2603998, -23.412498, -36.1479, -2.98, 16.7232, -38.5239, -3.6573, 13.378601, -36.1433, -2.8846, 13.378601, -36.1479, -2.98, 16.7232, -38.5239, -3.6573, 16.7232, -38.5239, -3.6573, 13.378601, -41.627, -4.8403997, 26.7572, -38.5239, -3.6573, 26.7572, -40.2616, -4.8514, 28.2242, -44.537098, -5.95, 26.7572, -41.627, -4.8403997, 26.7572, -43.2833, -5.9677997, 28.143099, -47.4473, -7.0596, 26.7572, -44.537098, -5.95, 26.7572, -46.202698, -7.0731997, 28.132399, -53.117798, -8.6939, 26.7572, -50.290497, -8.1437, 26.7572, -51.906998, -8.6923, 28.058699, -55.5951, -9.176, 26.7572, -53.117798, -8.6939, 26.7572, -54.5561, -9.1761, 27.885199, -58.463497, -9.7343, 26.7572, -55.5951, -9.176, 26.7572, -57.2836, -9.7381, 28.062199, -33.0801, -3.7473, 32.6325, -32.8819, -4.9104, 36.1535, -34.7309, -4.8956, 34.1667, -33.0801, -3.7473, 32.6325, -31.247301, -3.7775998, 34.6107, -32.8819, -4.9104, 36.1535, -34.7309, -4.8956, 34.1667, -34.5837, -6.0910997, 37.759598, -36.416798, -6.0650997, 35.7334, -34.7309, -4.8956, 34.1667, -32.8819, -4.9104, 36.1535, -34.5837, -6.0910997, 37.759598, -36.416798, -6.0650997, 35.7334, -36.1511, -7.1832, 39.2388, -37.9957, -7.1629996, 37.2007, -36.416798, -6.0650997, 35.7334, -34.5837, -6.0910997, 37.759598, -36.1511, -7.1832, 39.2388, -37.9957, -7.1629996, 37.2007, -37.5247, -8.1437, 40.5352, -39.4027, -8.1437, 38.5083, -37.9957, -7.1629996, 37.2007, -36.1511, -7.1832, 39.2388, -37.5247, -8.1437, 40.5352, -39.4027, -8.1437, 38.5083, -39.0032, -8.6748, 41.930298, -40.895798, -8.6774, 39.8957, -39.4027, -8.1437, 38.5083, -37.5247, -8.1437, 40.5352, -39.0032, -8.6748, 41.930298, -40.895798, -8.6774, 39.8957, -40.403297, -9.1775, 43.2515, -42.2959, -9.1772995, 41.196598, -40.895798, -8.6774, 39.8957, -39.0032, -8.6748, 41.930298, -40.403297, -9.1775, 43.2515, -42.2959, -9.1772995, 41.196598, -42.1009, -9.787, 44.8533, -43.9867, -9.7809, 42.7677, -42.2959, -9.1772995, 41.196598, -40.403297, -9.1775, 43.2515, -42.1009, -9.787, 44.8533, -43.9867, -9.7809, 42.7677, -43.8985, -10.4337, 46.549698, -45.8121, -10.4337, 44.463898, -43.9867, -9.7809, 42.7677, -42.1009, -9.787, 44.8533, -43.8985, -10.4337, 46.549698, -31.247301, -3.7775998, 34.6107, -31.153502, -4.9242997, 38.010498, -32.8819, -4.9104, 36.1535, -31.247301, -3.7775998, 34.6107, -29.5455, -3.8058, 36.4474, -31.153502, -4.9242997, 38.010498, -32.8819, -4.9104, 36.1535, -32.857998, -6.1155996, 39.6672, -34.5837, -6.0910997, 37.759598, -32.8819, -4.9104, 36.1535, -31.153502, -4.9242997, 38.010498, -32.857998, -6.1155996, 39.6672, -34.5837, -6.0910997, 37.759598, -34.403698, -7.2022996, 41.169598, -36.1511, -7.1832, 39.2388, -34.5837, -6.0910997, 37.759598, -32.857998, -6.1155996, 39.6672, -34.403698, -7.2022996, 41.169598, -36.1511, -7.1832, 39.2388, -35.7366, -8.1437, 42.4652, -37.5247, -8.1437, 40.5352, -36.1511, -7.1832, 39.2388, -34.403698, -7.2022996, 41.169598, -35.7366, -8.1437, 42.4652, -37.5247, -8.1437, 40.5352, -37.1909, -8.672299, 43.878498, -39.0032, -8.6748, 41.930298, -37.5247, -8.1437, 40.5352, -35.7366, -8.1437, 42.4652, -37.1909, -8.672299, 43.878498, -42.1009, -9.787, 44.8533, -42.032497, -10.4337, 48.5836, -43.8985, -10.4337, 46.549698, -42.1009, -9.787, 44.8533, -40.2735, -9.7929, 46.8743, -42.032497, -10.4337, 48.5836, -39.0032, -8.6748, 41.930298, -38.5812, -9.1777, 45.2297, -40.403297, -9.1775, 43.2515, -39.0032, -8.6748, 41.930298, -37.1909, -8.672299, 43.878498, -38.5812, -9.1777, 45.2297, -40.403297, -9.1775, 43.2515, -40.2735, -9.7929, 46.8743, -42.1009, -9.787, 44.8533, -40.403297, -9.1775, 43.2515, -38.5812, -9.1777, 45.2297, -40.2735, -9.7929, 46.8743, -40.2735, -9.7929, 46.8743, -40.572998, -10.4337, 50.1744, -42.032497, -10.4337, 48.5836, -40.2735, -9.7929, 46.8743, -38.8322, -9.7975, 48.4683, -40.572998, -10.4337, 50.1744, -32.857998, -6.1155996, 39.6672, -32.985, -7.2179, 42.7371, -34.403698, -7.2022996, 41.169598, -32.857998, -6.1155996, 39.6672, -31.445799, -6.1355996, 41.2283, -32.985, -7.2179, 42.7371, -38.5812, -9.1777, 45.2297, -38.8322, -9.7975, 48.4683, -40.2735, -9.7929, 46.8743, -38.5812, -9.1777, 45.2297, -37.1326, -9.1778, 46.802498, -38.8322, -9.7975, 48.4683, -34.403698, -7.2022996, 41.169598, -34.2949, -8.1437, 44.0212, -35.7366, -8.1437, 42.4652, -34.403698, -7.2022996, 41.169598, -32.985, -7.2179, 42.7371, -34.2949, -8.1437, 44.0212, -35.7366, -8.1437, 42.4652, -35.7403, -8.6704, 45.4379, -37.1909, -8.672299, 43.878498, -35.7366, -8.1437, 42.4652, -34.2949, -8.1437, 44.0212, -35.7403, -8.6704, 45.4379, -29.5455, -3.8058, 36.4474, -29.727, -4.9357, 39.5433, -31.153502, -4.9242997, 38.010498, -29.5455, -3.8058, 36.4474, -28.1288, -3.8291998, 37.976498, -29.727, -4.9357, 39.5433, -37.1909, -8.672299, 43.878498, -37.1326, -9.1778, 46.802498, -38.5812, -9.1777, 45.2297, -37.1909, -8.672299, 43.878498, -35.7403, -8.6704, 45.4379, -37.1326, -9.1778, 46.802498, -31.153502, -4.9242997, 38.010498, -31.445799, -6.1355996, 41.2283, -32.857998, -6.1155996, 39.6672, -31.153502, -4.9242997, 38.010498, -29.727, -4.9357, 39.5433, -31.445799, -6.1355996, 41.2283, -28.1288, -3.8291998, 37.976498, -28.3464, -4.9467, 41.0267, -29.727, -4.9357, 39.5433, -28.1288, -3.8291998, 37.976498, -26.7572, -3.8518999, 39.456898, -28.3464, -4.9467, 41.0267, -29.727, -4.9357, 39.5433, -30.0795, -6.1549, 42.738598, -31.445799, -6.1355996, 41.2283, -29.727, -4.9357, 39.5433, -28.3464, -4.9467, 41.0267, -30.0795, -6.1549, 42.738598, -38.8322, -9.7975, 48.4683, -39.1638, -10.4337, 51.7104, -40.572998, -10.4337, 50.1744, -38.8322, -9.7975, 48.4683, -37.44, -9.802, 50.008, -39.1638, -10.4337, 51.7104, -31.445799, -6.1355996, 41.2283, -31.612902, -7.2328997, 44.2532, -32.985, -7.2179, 42.7371, -31.445799, -6.1355996, 41.2283, -30.0795, -6.1549, 42.738598, -31.612902, -7.2328997, 44.2532, -37.1326, -9.1778, 46.802498, -37.44, -9.802, 50.008, -38.8322, -9.7975, 48.4683, -37.1326, -9.1778, 46.802498, -35.7329, -9.177899, 48.322197, -37.44, -9.802, 50.008, -32.985, -7.2179, 42.7371, -32.901, -8.1437, 45.5256, -34.2949, -8.1437, 44.0212, -32.985, -7.2179, 42.7371, -31.612902, -7.2328997, 44.2532, -32.901, -8.1437, 45.5256, -34.2949, -8.1437, 44.0212, -34.3383, -8.6685, 46.945, -35.7403, -8.6704, 45.4379, -34.2949, -8.1437, 44.0212, -32.901, -8.1437, 45.5256, -34.3383, -8.6685, 46.945, -35.7403, -8.6704, 45.4379, -35.7329, -9.177899, 48.322197, -37.1326, -9.1778, 46.802498, -35.7403, -8.6704, 45.4379, -34.3383, -8.6685, 46.945, -35.7329, -9.177899, 48.322197, -34.3383, -8.6685, 46.945, -34.0797, -9.1781, 50.1171, -35.7329, -9.177899, 48.322197, -34.3383, -8.6685, 46.945, -32.6904, -8.6662, 48.7166, -34.0797, -9.1781, 50.1171, -26.7572, -3.8518999, 39.456898, -26.7572, -4.9595, 42.7343, -28.3464, -4.9467, 41.0267, -28.3464, -4.9467, 41.0267, -28.496698, -6.1773996, 44.4883, -30.0795, -6.1549, 42.738598, -28.3464, -4.9467, 41.0267, -26.7572, -4.9595, 42.7343, -28.496698, -6.1773996, 44.4883, -37.44, -9.802, 50.008, -37.4804, -10.4337, 53.5453, -39.1638, -10.4337, 51.7104, -37.44, -9.802, 50.008, -35.786, -9.8073, 51.8372, -37.4804, -10.4337, 53.5453, -30.0795, -6.1549, 42.738598, -30.0148, -7.2503, 46.0191, -31.612902, -7.2328997, 44.2532, -30.0795, -6.1549, 42.738598, -28.496698, -6.1773996, 44.4883, -30.0148, -7.2503, 46.0191, -32.901, -8.1437, 45.5256, -32.6904, -8.6662, 48.7166, -34.3383, -8.6685, 46.945, -32.901, -8.1437, 45.5256, -31.270601, -8.1437, 47.285297, -32.6904, -8.6662, 48.7166, -35.7329, -9.177899, 48.322197, -35.786, -9.8073, 51.8372, -37.44, -9.802, 50.008, -35.7329, -9.177899, 48.322197, -34.0797, -9.1781, 50.1171, -35.786, -9.8073, 51.8372, -31.612902, -7.2328997, 44.2532, -31.270601, -8.1437, 47.285297, -32.901, -8.1437, 45.5256, -31.612902, -7.2328997, 44.2532, -30.0148, -7.2503, 46.0191, -31.270601, -8.1437, 47.285297, -26.7572, -4.9595, 42.7343, -26.7572, -6.2019997, 46.4111, -28.496698, -6.1773996, 44.4883, -35.786, -9.8073, 51.8372, -35.735397, -10.4337, 55.4473, -37.4804, -10.4337, 53.5453, -35.786, -9.8073, 51.8372, -34.0528, -9.8129, 53.753998, -35.735397, -10.4337, 55.4473, -28.496698, -6.1773996, 44.4883, -28.2762, -7.2693996, 47.940197, -30.0148, -7.2503, 46.0191, -28.496698, -6.1773996, 44.4883, -26.7572, -6.2019997, 46.4111, -28.2762, -7.2693996, 47.940197, -32.6904, -8.6662, 48.7166, -32.3284, -9.1783, 52.0186, -34.0797, -9.1781, 50.1171, -32.6904, -8.6662, 48.7166, -30.9289, -8.663899, 50.6101, -32.3284, -9.1783, 52.0186, -31.270601, -8.1437, 47.285297, -30.9289, -8.663899, 50.6101, -32.6904, -8.6662, 48.7166, -31.270601, -8.1437, 47.285297, -29.511599, -8.1437, 49.1838, -30.9289, -8.663899, 50.6101, -34.0797, -9.1781, 50.1171, -34.0528, -9.8129, 53.753998, -35.786, -9.8073, 51.8372, -34.0797, -9.1781, 50.1171, -32.3284, -9.1783, 52.0186, -34.0528, -9.8129, 53.753998, -30.0148, -7.2503, 46.0191, -29.511599, -8.1437, 49.1838, -31.270601, -8.1437, 47.285297, -30.0148, -7.2503, 46.0191, -28.2762, -7.2693996, 47.940197, -29.511599, -8.1437, 49.1838, -28.2762, -7.2693996, 47.940197, -27.9641, -8.1437, 50.853897, -29.511599, -8.1437, 49.1838, -28.2762, -7.2693996, 47.940197, -26.7572, -7.286, 49.6186, -27.9641, -8.1437, 50.853897, -34.0528, -9.8129, 53.753998, -34.1461, -10.4337, 57.1796, -35.735397, -10.4337, 55.4473, -34.0528, -9.8129, 53.753998, -32.4888, -9.8179, 55.4837, -34.1461, -10.4337, 57.1796, -26.7572, -6.2019997, 46.4111, -26.7572, -7.286, 49.6186, -28.2762, -7.2693996, 47.940197, -30.9289, -8.663899, 50.6101, -30.7632, -9.1784, 53.718, -32.3284, -9.1783, 52.0186, -30.9289, -8.663899, 50.6101, -29.3669, -8.6617, 52.2893, -30.7632, -9.1784, 53.718, -29.511599, -8.1437, 49.1838, -29.3669, -8.6617, 52.2893, -30.9289, -8.663899, 50.6101, -29.511599, -8.1437, 49.1838, -27.9641, -8.1437, 50.853897, -29.3669, -8.6617, 52.2893, -32.3284, -9.1783, 52.0186, -32.4888, -9.8179, 55.4837, -34.0528, -9.8129, 53.753998, -32.3284, -9.1783, 52.0186, -30.7632, -9.1784, 53.718, -32.4888, -9.8179, 55.4837, -29.3669, -8.6617, 52.2893, -29.525799, -9.1785, 55.061497, -30.7632, -9.1784, 53.718, -29.3669, -8.6617, 52.2893, -28.140299, -8.6601, 53.6078, -29.525799, -9.1785, 55.061497, -27.9641, -8.1437, 50.853897, -28.140299, -8.6601, 53.6078, -29.3669, -8.6617, 52.2893, -27.9641, -8.1437, 50.853897, -26.7572, -8.1437, 52.156597, -28.140299, -8.6601, 53.6078, -30.7632, -9.1784, 53.718, -31.2423, -9.821899, 56.862297, -32.4888, -9.8179, 55.4837, -30.7632, -9.1784, 53.718, -29.525799, -9.1785, 55.061497, -31.2423, -9.821899, 56.862297, -26.7572, -7.286, 49.6186, -26.7572, -8.1437, 52.156597, -27.9641, -8.1437, 50.853897, -32.4888, -9.8179, 55.4837, -32.870197, -10.4337, 58.570297, -34.1461, -10.4337, 57.1796, -32.4888, -9.8179, 55.4837, -31.2423, -9.821899, 56.862297, -32.870197, -10.4337, 58.570297, -28.140299, -8.6601, 53.6078, -28.1322, -9.1786995, 56.5746, -29.525799, -9.1785, 55.061497, -28.140299, -8.6601, 53.6078, -26.7572, -8.658199, 55.0947, -28.1322, -9.1786995, 56.5746, -26.7572, -8.1437, 52.156597, -26.7572, -8.658199, 55.0947, -28.140299, -8.6601, 53.6078, -29.525799, -9.1785, 55.061497, -29.8403, -9.8265, 58.4128, -31.2423, -9.821899, 56.862297, -29.525799, -9.1785, 55.061497, -28.1322, -9.1786995, 56.5746, -29.8403, -9.8265, 58.4128, -31.2423, -9.821899, 56.862297, -31.437601, -10.4337, 60.131798, -32.870197, -10.4337, 58.570297, -31.2423, -9.821899, 56.862297, -29.8403, -9.8265, 58.4128, -31.437601, -10.4337, 60.131798, -26.7572, -8.658199, 55.0947, -26.7572, -9.1788, 58.067497, -28.1322, -9.1786995, 56.5746, -28.1322, -9.1786995, 56.5746, -28.4674, -9.8309, 59.9312, -29.8403, -9.8265, 58.4128, -28.1322, -9.1786995, 56.5746, -26.7572, -9.1788, 58.067497, -28.4674, -9.8309, 59.9312, -29.8403, -9.8265, 58.4128, -30.044802, -10.4337, 61.649998, -31.437601, -10.4337, 60.131798, -29.8403, -9.8265, 58.4128, -28.4674, -9.8309, 59.9312, -30.044802, -10.4337, 61.649998, -28.4674, -9.8309, 59.9312, -28.2834, -10.4337, 63.569798, -30.044802, -10.4337, 61.649998, -28.4674, -9.8309, 59.9312, -26.7572, -9.8364, 61.822598, -28.2834, -10.4337, 63.569798, -26.7572, -9.1788, 58.067497, -26.7572, -9.8364, 61.822598, -28.4674, -9.8309, 59.9312, -26.7572, -9.8364, 61.822598, -26.7572, -10.4337, 65.2334, -28.2834, -10.4337, 63.569798, -39.7387, -7.144, 35.2747, -39.4027, -8.1437, 38.5083, -41.179398, -8.1437, 36.5907, -39.7387, -7.144, 35.2747, -37.9957, -7.1629996, 37.2007, -39.4027, -8.1437, 38.5083, -34.806297, -3.7187998, 30.769499, -34.7309, -4.8956, 34.1667, -36.474598, -4.8817, 32.293198, -34.806297, -3.7187998, 30.769499, -33.0801, -3.7473, 32.6325, -34.7309, -4.8956, 34.1667, -45.7693, -9.7752, 40.7963, -45.8121, -10.4337, 44.463898, -47.620697, -10.4337, 42.4927, -45.7693, -9.7752, 40.7963, -43.9867, -9.7809, 42.7677, -45.8121, -10.4337, 44.463898, -36.474598, -4.8817, 32.293198, -36.416798, -6.0650997, 35.7334, -38.147, -6.0406, 33.8208, -36.474598, -4.8817, 32.293198, -34.7309, -4.8956, 34.1667, -36.416798, -6.0650997, 35.7334, -38.147, -6.0406, 33.8208, -37.9957, -7.1629996, 37.2007, -39.7387, -7.144, 35.2747, -38.147, -6.0406, 33.8208, -36.416798, -6.0650997, 35.7334, -37.9957, -7.1629996, 37.2007, -41.179398, -8.1437, 36.5907, -40.895798, -8.6774, 39.8957, -42.6861, -8.6798, 37.9712, -41.179398, -8.1437, 36.5907, -39.4027, -8.1437, 38.5083, -40.895798, -8.6774, 39.8957, -42.6861, -8.6798, 37.9712, -42.2959, -9.1772995, 41.196598, -44.0855, -9.1771, 39.253498, -42.6861, -8.6798, 37.9712, -40.895798, -8.6774, 39.8957, -42.2959, -9.1772995, 41.196598, -44.0855, -9.1771, 39.253498, -43.9867, -9.7809, 42.7677, -45.7693, -9.7752, 40.7963, -44.0855, -9.1771, 39.253498, -42.2959, -9.1772995, 41.196598, -43.9867, -9.7809, 42.7677, -41.209297, -7.1278996, 33.6499, -41.179398, -8.1437, 36.5907, -42.6902, -8.1437, 34.960197, -41.209297, -7.1278996, 33.6499, -39.7387, -7.144, 35.2747, -41.179398, -8.1437, 36.5907, -36.2241, -3.6952999, 29.2393, -36.474598, -4.8817, 32.293198, -37.9203, -4.8701, 30.739899, -36.2241, -3.6952999, 29.2393, -34.806297, -3.7187998, 30.769499, -36.474598, -4.8817, 32.293198, -47.322998, -9.7702, 39.078, -47.620697, -10.4337, 42.4927, -49.212498, -10.4337, 40.7576, -47.322998, -9.7702, 39.078, -45.7693, -9.7752, 40.7963, -47.620697, -10.4337, 42.4927, -37.9203, -4.8701, 30.739899, -38.147, -6.0406, 33.8208, -39.5943, -6.0200996, 32.221, -37.9203, -4.8701, 30.739899, -36.474598, -4.8817, 32.293198, -38.147, -6.0406, 33.8208, -39.5943, -6.0200996, 32.221, -39.7387, -7.144, 35.2747, -41.209297, -7.1278996, 33.6499, -39.5943, -6.0200996, 32.221, -38.147, -6.0406, 33.8208, -39.7387, -7.144, 35.2747, -42.6902, -8.1437, 34.960197, -42.6861, -8.6798, 37.9712, -44.2212, -8.6819, 36.321, -42.6902, -8.1437, 34.960197, -41.179398, -8.1437, 36.5907, -42.6861, -8.6798, 37.9712, -44.2212, -8.6819, 36.321, -44.0855, -9.1771, 39.253498, -45.6317, -9.177, 37.5747, -44.2212, -8.6819, 36.321, -42.6861, -8.6798, 37.9712, -44.0855, -9.1771, 39.253498, -45.6317, -9.177, 37.5747, -45.7693, -9.7752, 40.7963, -47.322998, -9.7702, 39.078, -45.6317, -9.177, 37.5747, -44.0855, -9.1771, 39.253498, -45.7693, -9.7752, 40.7963, -42.4946, -7.1138, 32.2296, -42.6902, -8.1437, 34.960197, -44.0089, -8.1437, 33.5369, -42.4946, -7.1138, 32.2296, -41.209297, -7.1278996, 33.6499, -42.6902, -8.1437, 34.960197, -37.4711, -3.6747, 27.8934, -37.9203, -4.8701, 30.739899, -39.1893, -4.8599997, 29.3764, -37.4711, -3.6747, 27.8934, -36.2241, -3.6952999, 29.2393, -37.9203, -4.8701, 30.739899, -48.6723, -9.7657995, 37.585697, -49.212498, -10.4337, 40.7576, -50.5928, -10.4337, 39.2532, -48.6723, -9.7657995, 37.585697, -47.322998, -9.7702, 39.078, -49.212498, -10.4337, 40.7576, -39.1893, -4.8599997, 29.3764, -39.5943, -6.0200996, 32.221, -40.8617, -6.0021, 30.82, -39.1893, -4.8599997, 29.3764, -37.9203, -4.8701, 30.739899, -39.5943, -6.0200996, 32.221, -40.8617, -6.0021, 30.82, -41.209297, -7.1278996, 33.6499, -42.4946, -7.1138, 32.2296, -40.8617, -6.0021, 30.82, -39.5943, -6.0200996, 32.221, -41.209297, -7.1278996, 33.6499, -44.0089, -8.1437, 33.5369, -44.2212, -8.6819, 36.321, -45.559097, -8.6837, 34.882698, -44.0089, -8.1437, 33.5369, -42.6902, -8.1437, 34.960197, -44.2212, -8.6819, 36.321, -45.559097, -8.6837, 34.882698, -45.6317, -9.177, 37.5747, -46.9771, -9.1769, 36.114, -45.559097, -8.6837, 34.882698, -44.2212, -8.6819, 36.321, -45.6317, -9.177, 37.5747, -46.9771, -9.1769, 36.114, -47.322998, -9.7702, 39.078, -48.6723, -9.7657995, 37.585697, -46.9771, -9.1769, 36.114, -45.6317, -9.177, 37.5747, -47.322998, -9.7702, 39.078, -43.5821, -7.1018996, 31.028, -44.0089, -8.1437, 33.5369, -45.125797, -8.1437, 32.3315, -43.5821, -7.1018996, 31.028, -42.4946, -7.1138, 32.2296, -44.0089, -8.1437, 33.5369, -38.5239, -3.6573, 26.7572, -39.1893, -4.8599997, 29.3764, -40.2616, -4.8514, 28.2242, -38.5239, -3.6573, 26.7572, -37.4711, -3.6747, 27.8934, -39.1893, -4.8599997, 29.3764, -49.816998, -9.7621, 36.319798, -50.5928, -10.4337, 39.2532, -51.764698, -10.4337, 37.9757, -49.816998, -9.7621, 36.319798, -48.6723, -9.7657995, 37.585697, -50.5928, -10.4337, 39.2532, -40.2616, -4.8514, 28.2242, -40.8617, -6.0021, 30.82, -41.9332, -5.9869, 29.6356, -40.2616, -4.8514, 28.2242, -39.1893, -4.8599997, 29.3764, -40.8617, -6.0021, 30.82, -41.9332, -5.9869, 29.6356, -42.4946, -7.1138, 32.2296, -43.5821, -7.1018996, 31.028, -41.9332, -5.9869, 29.6356, -40.8617, -6.0021, 30.82, -42.4946, -7.1138, 32.2296, -45.125797, -8.1437, 32.3315, -45.559097, -8.6837, 34.882698, -46.692997, -8.6852, 33.6638, -45.125797, -8.1437, 32.3315, -44.0089, -8.1437, 33.5369, -45.559097, -8.6837, 34.882698, -46.692997, -8.6852, 33.6638, -46.9771, -9.1769, 36.114, -48.118, -9.1768, 34.875298, -46.692997, -8.6852, 33.6638, -45.559097, -8.6837, 34.882698, -46.9771, -9.1769, 36.114, -48.118, -9.1768, 34.875298, -48.6723, -9.7657995, 37.585697, -49.816998, -9.7621, 36.319798, -48.118, -9.1768, 34.875298, -46.9771, -9.1769, 36.114, -48.6723, -9.7657995, 37.585697, -44.939, -7.0871, 29.5287, -45.125797, -8.1437, 32.3315, -46.506897, -8.1437, 30.840899, -44.939, -7.0871, 29.5287, -43.5821, -7.1018996, 31.028, -45.125797, -8.1437, 32.3315, -51.1965, -9.7577, 34.794, -51.764698, -10.4337, 37.9757, -53.163, -10.4337, 36.4517, -51.1965, -9.7577, 34.794, -49.816998, -9.7621, 36.319798, -51.764698, -10.4337, 37.9757, -41.627, -4.8403997, 26.7572, -41.9332, -5.9869, 29.6356, -43.2833, -5.9677997, 28.143099, -41.627, -4.8403997, 26.7572, -40.2616, -4.8514, 28.2242, -41.9332, -5.9869, 29.6356, -43.2833, -5.9677997, 28.143099, -43.5821, -7.1018996, 31.028, -44.939, -7.0871, 29.5287, -43.2833, -5.9677997, 28.143099, -41.9332, -5.9869, 29.6356, -43.5821, -7.1018996, 31.028, -46.506897, -8.1437, 30.840899, -46.692997, -8.6852, 33.6638, -48.083, -8.687099, 32.1695, -46.506897, -8.1437, 30.840899, -45.125797, -8.1437, 32.3315, -46.692997, -8.6852, 33.6638, -48.083, -8.687099, 32.1695, -48.118, -9.1768, 34.875298, -49.5056, -9.1765995, 33.3687, -48.083, -8.687099, 32.1695, -46.692997, -8.6852, 33.6638, -48.118, -9.1768, 34.875298, -49.5056, -9.1765995, 33.3687, -49.816998, -9.7621, 36.319798, -51.1965, -9.7577, 34.794, -49.5056, -9.1765995, 33.3687, -48.118, -9.1768, 34.875298, -49.816998, -9.7621, 36.319798, -46.202698, -7.0731997, 28.132399, -46.506897, -8.1437, 30.840899, -47.7968, -8.1437, 29.4487, -46.202698, -7.0731997, 28.132399, -44.939, -7.0871, 29.5287, -46.506897, -8.1437, 30.840899, -52.4946, -9.7535, 33.3584, -53.163, -10.4337, 36.4517, -54.4828, -10.4337, 35.0131, -52.4946, -9.7535, 33.3584, -51.1965, -9.7577, 34.794, -53.163, -10.4337, 36.4517, -44.537098, -5.95, 26.7572, -44.939, -7.0871, 29.5287, -46.202698, -7.0731997, 28.132399, -44.537098, -5.95, 26.7572, -43.2833, -5.9677997, 28.143099, -44.939, -7.0871, 29.5287, -47.7968, -8.1437, 29.4487, -48.083, -8.687099, 32.1695, -49.384697, -8.6889, 30.770199, -47.7968, -8.1437, 29.4487, -46.506897, -8.1437, 30.840899, -48.083, -8.687099, 32.1695, -49.384697, -8.6889, 30.770199, -49.5056, -9.1765995, 33.3687, -50.808, -9.176499, 31.954699, -49.384697, -8.6889, 30.770199, -48.083, -8.687099, 32.1695, -49.5056, -9.1765995, 33.3687, -50.808, -9.176499, 31.954699, -51.1965, -9.7577, 34.794, -52.4946, -9.7535, 33.3584, -50.808, -9.176499, 31.954699, -49.5056, -9.1765995, 33.3687, -51.1965, -9.7577, 34.794, -47.4473, -7.0596, 26.7572, -47.7968, -8.1437, 29.4487, -49.074398, -8.1437, 28.0697, -47.4473, -7.0596, 26.7572, -46.202698, -7.0731997, 28.132399, -47.7968, -8.1437, 29.4487, -53.7992, -9.7493, 31.915699, -54.4828, -10.4337, 35.0131, -55.8173, -10.4337, 33.5585, -53.7992, -9.7493, 31.915699, -52.4946, -9.7535, 33.3584, -54.4828, -10.4337, 35.0131, -49.074398, -8.1437, 28.0697, -49.384697, -8.6889, 30.770199, -50.6806, -8.690599, 29.3771, -49.074398, -8.1437, 28.0697, -47.7968, -8.1437, 29.4487, -49.384697, -8.6889, 30.770199, -50.6806, -8.690599, 29.3771, -50.808, -9.176499, 31.954699, -52.1102, -9.1764, 30.5408, -50.6806, -8.690599, 29.3771, -49.384697, -8.6889, 30.770199, -50.808, -9.176499, 31.954699, -52.1102, -9.1764, 30.5408, -52.4946, -9.7535, 33.3584, -53.7992, -9.7493, 31.915699, -52.1102, -9.1764, 30.5408, -50.808, -9.176499, 31.954699, -52.4946, -9.7535, 33.3584, -50.290497, -8.1437, 26.7572, -50.6806, -8.690599, 29.3771, -51.906998, -8.6923, 28.058699, -50.290497, -8.1437, 26.7572, -49.074398, -8.1437, 28.0697, -50.6806, -8.690599, 29.3771, -51.906998, -8.6923, 28.058699, -52.1102, -9.1764, 30.5408, -53.3363, -9.1763, 29.2095, -51.906998, -8.6923, 28.058699, -50.6806, -8.690599, 29.3771, -52.1102, -9.1764, 30.5408, -55.0202, -9.745399, 30.5653, -55.8173, -10.4337, 33.5585, -57.058, -10.4337, 32.2062, -55.0202, -9.745399, 30.5653, -53.7992, -9.7493, 31.915699, -55.8173, -10.4337, 33.5585, -53.3363, -9.1763, 29.2095, -53.7992, -9.7493, 31.915699, -55.0202, -9.745399, 30.5653, -53.3363, -9.1763, 29.2095, -52.1102, -9.1764, 30.5408, -53.7992, -9.7493, 31.915699, -53.117798, -8.6939, 26.7572, -53.3363, -9.1763, 29.2095, -54.5561, -9.1761, 27.885199, -53.117798, -8.6939, 26.7572, -51.906998, -8.6923, 28.058699, -53.3363, -9.1763, 29.2095, -56.245598, -9.7414, 29.2101, -57.058, -10.4337, 32.2062, -58.316597, -10.4337, 30.834398, -56.245598, -9.7414, 29.2101, -55.0202, -9.745399, 30.5653, -57.058, -10.4337, 32.2062, -54.5561, -9.1761, 27.885199, -55.0202, -9.745399, 30.5653, -56.245598, -9.7414, 29.2101, -54.5561, -9.1761, 27.885199, -53.3363, -9.1763, 29.2095, -55.0202, -9.745399, 30.5653, -57.2836, -9.7381, 28.062199, -58.316597, -10.4337, 30.834398, -59.3761, -10.4337, 29.679499, -57.2836, -9.7381, 28.062199, -56.245598, -9.7414, 29.2101, -58.316597, -10.4337, 30.834398, -55.5951, -9.176, 26.7572, -56.245598, -9.7414, 29.2101, -57.2836, -9.7381, 28.062199, -55.5951, -9.176, 26.7572, -54.5561, -9.1761, 27.885199, -56.245598, -9.7414, 29.2101, -58.463497, -9.7343, 26.7572, -59.3761, -10.4337, 29.679499, -60.611, -10.4337, 28.3335, -58.463497, -9.7343, 26.7572, -57.2836, -9.7381, 28.062199, -59.3761, -10.4337, 29.679499, 20.0676, 0.0021, 3.3446, 23.4123, 0, -0.000100016594, 23.4123, 0, 3.3446, 20.0676, 0.0021, 3.3446, 20.229, 0.030399999, -0.05219996, 23.4123, 0, -0.000100016594, 6.6893, 3.3913999, 3.3446, 10.0336, 3.1929998, -0.000100016594, 10.0336, 3.1929998, 3.3446, 6.6893, 3.3913999, 3.3446, 6.6893, 3.3913999, -0.000100016594, 10.0336, 3.1929998, -0.000100016594, 23.4123, 0, 3.3446, 26.7582, -0.83089995, 6.6893, 23.4123, 0, 6.6893, 23.4123, 0, 3.3446, 26.7575, -0.7312, 3.3446, 26.7582, -0.83089995, 6.6893, 23.4123, 0, 6.6893, 26.7582, -0.83089995, 6.6893, 23.4123, -0.35529998, 10.033899, 20.0676, 0.0021, 3.3446, 20.0676, 0, 10.0338, 17.491, 0.0034999999, 7.408, 17.491, 0.0034999999, 7.408, 14.0257, 0.0442, 7.3251996, 20.0676, 0.0021, 3.3446, 20.0676, 0, 10.0338, 23.4123, 0, 6.6893, 23.4123, -0.35529998, 10.033899, 20.0676, 0.0021, 3.3446, 23.4123, 0, 3.3446, 23.4123, 0, 6.6893, 12.7055, 1.032, 4.0926, 11.277899, 2.3706, -0.000100016594, 14.261799, 0.9069, 1.1804999, 12.7055, 1.032, 4.0926, 11.2782, 2.1174, 3.3446, 11.277899, 2.3706, -0.000100016594, 10.0336, 3.1929998, 3.3446, 11.277899, 2.3706, -0.000100016594, 11.2782, 2.1174, 3.3446, 10.0336, 3.1929998, 3.3446, 10.0336, 3.1929998, -0.000100016594, 11.277899, 2.3706, -0.000100016594, 20.229, 0.030399999, -0.05219996, 20.0676, 0.0021, 3.3446, 14.261799, 0.9069, 1.1804999, 14.0257, 0.0442, 7.3251996, 14.261799, 0.9069, 1.1804999, 20.0676, 0.0021, 3.3446, 12.7055, 1.032, 4.0926, 14.261799, 0.9069, 1.1804999, 14.0257, 0.0442, 7.3251996, 26.7575, -0.7312, 3.3446, 23.4123, 0, 3.3446, 23.4123, 0, -0.000100016594, 20.0676, 0, 10.0338, 20.0676, 0.0021, 3.3446, 23.4123, 0, 6.6893, 17.253021, -20.068901, 7.9789844, 17.227175, -19.735691, 9.261204, 17.026821, -20.231876, 8.073181, 17.253021, -20.068901, 7.9789844, 17.434578, -19.605183, 9.12792, 17.227175, -19.735691, 9.261204, 17.434578, -19.605183, 9.12792, 17.571707, -18.471199, 10.41548, 17.227175, -19.735691, 9.261204, 17.434578, -19.605183, 9.12792, 17.629164, -18.471626, 10.358021, 17.571707, -18.471199, 10.41548, 17.227175, -19.735691, 9.261204, 17.571707, -18.471199, 10.41548, 17.608658, -18.470558, 10.487461, 17.026821, -20.231876, 8.073181, 17.227175, -19.735691, 9.261204, 17.33739, -19.946938, 9.406449, 17.227175, -19.735691, 9.261204, 17.608658, -18.470558, 10.487461, 17.33739, -19.946938, 9.406449, 17.026821, -20.231876, 8.073181, 17.33739, -19.946938, 9.406449, 17.131271, -20.495667, 8.150929, 17.33739, -19.946938, 9.406449, 17.608658, -18.470558, 10.487461, 17.688543, -18.470558, 10.474859, 17.131271, -20.495667, 8.150929, 17.33739, -19.946938, 9.406449, 17.61293, -19.946938, 9.362875, 17.33739, -19.946938, 9.406449, 17.688543, -18.470558, 10.474859, 17.61293, -19.946938, 9.362875, 17.131271, -20.495667, 8.150929, 17.61293, -19.946938, 9.362875, 17.421762, -20.495667, 8.105006, 17.61293, -19.946938, 9.362875, 17.688543, -18.470558, 10.474859, 17.701359, -18.471199, 10.394974, 17.421762, -20.495667, 8.105006, 17.61293, -19.946938, 9.362875, 17.67295, -19.735691, 9.190718, 17.61293, -19.946938, 9.362875, 17.701359, -18.471199, 10.394974, 17.67295, -19.735691, 9.190718, 17.67295, -19.735691, 9.190718, 17.701359, -18.471199, 10.394974, 17.629164, -18.471626, 10.358021, 17.421762, -20.495667, 8.105006, 17.67295, -19.735691, 9.190718, 17.497162, -20.231876, 7.998849, 17.67295, -19.735691, 9.190718, 17.629164, -18.471626, 10.358021, 17.434578, -19.605183, 9.12792, 17.497162, -20.231876, 7.998849, 17.67295, -19.735691, 9.190718, 17.434578, -19.605183, 9.12792, 17.497162, -20.231876, 7.998849, 17.434578, -19.605183, 9.12792, 17.253021, -20.068901, 7.9789844, 16.28308, -22.030998, 7.9881697, 17.28207, -19.97385, 8.213941, 16.7107, -22.030998, 8.612513, 16.28308, -22.030998, 7.9881697, 17.120804, -19.944588, 7.9881687, 17.28207, -19.97385, 8.213941, 17.120804, -19.944588, 7.9881687, 17.36345, -17.907732, 8.087917, 17.28207, -19.97385, 8.213941, 17.120804, -19.944588, 7.9881687, 17.291254, -17.900043, 7.9881682, 17.36345, -17.907732, 8.087917, 17.28207, -19.97385, 8.213941, 17.36345, -17.907732, 8.087917, 17.480074, -17.92012, 8.049685, 16.7107, -22.030998, 8.612513, 17.28207, -19.97385, 8.213941, 17.543299, -20.021269, 8.127647, 17.28207, -19.97385, 8.213941, 17.480074, -17.92012, 8.049685, 17.543299, -20.021269, 8.127647, 16.7107, -22.030998, 8.612513, 17.543299, -20.021269, 8.127647, 17.402325, -22.030998, 8.373924, 17.543299, -20.021269, 8.127647, 17.480074, -17.92012, 8.049685, 17.480074, -17.92012, 7.926439, 17.402325, -22.030998, 8.373924, 17.543299, -20.021269, 8.127647, 17.543299, -20.02127, 7.8486905, 17.543299, -20.021269, 8.127647, 17.480074, -17.92012, 7.926439, 17.543299, -20.02127, 7.8486905, 17.402325, -22.030998, 8.373924, 17.543299, -20.02127, 7.8486905, 17.402325, -22.030998, 7.602201, 17.543299, -20.02127, 7.8486905, 17.480074, -17.92012, 7.926439, 17.36345, -17.907732, 7.8884187, 17.402325, -22.030998, 7.602201, 17.543299, -20.02127, 7.8486905, 17.28207, -19.97385, 7.7623973, 17.543299, -20.02127, 7.8486905, 17.36345, -17.907732, 7.8884187, 17.28207, -19.97385, 7.7623973, 17.28207, -19.97385, 7.7623973, 17.36345, -17.907732, 7.8884187, 17.291254, -17.900043, 7.9881682, 17.402325, -22.030998, 7.602201, 17.28207, -19.97385, 7.7623973, 16.7107, -22.030998, 7.363827, 17.28207, -19.97385, 7.7623973, 17.291254, -17.900043, 7.9881682, 17.120804, -19.944588, 7.9881687, 16.7107, -22.030998, 7.363827, 17.28207, -19.97385, 7.7623973, 17.120804, -19.944588, 7.9881687, 16.7107, -22.030998, 7.363827, 17.120804, -19.944588, 7.9881687, 16.28308, -22.030998, 7.9881697, 17.194283, -19.802975, 7.602841, 18.323994, -19.463997, 6.9496627, 17.395275, -19.968939, 7.750009, 17.194283, -19.802975, 7.602841, 18.09865, -19.331139, 6.83902, 18.323994, -19.463997, 6.9496627, 18.09865, -19.331139, 6.83902, 19.147194, -18.177078, 6.041237, 18.323994, -19.463997, 6.9496627, 18.09865, -19.331139, 6.83902, 19.067095, -18.177505, 6.0213723, 19.147194, -18.177078, 6.041237, 18.323994, -19.463997, 6.9496627, 19.147194, -18.177078, 6.041237, 19.190767, -18.176437, 5.9711766, 17.395275, -19.968939, 7.750009, 18.323994, -19.463997, 6.9496627, 18.392344, -19.679089, 6.777077, 18.323994, -19.463997, 6.9496627, 19.190767, -18.176437, 5.9711766, 18.392344, -19.679089, 6.777077, 17.395275, -19.968939, 7.750009, 18.392344, -19.679089, 6.777077, 17.408092, -20.237429, 7.618006, 18.392344, -19.679089, 6.777077, 19.190767, -18.176437, 5.9711766, 19.137367, -18.176437, 5.908166, 17.408092, -20.237429, 7.618006, 18.392344, -19.679089, 6.777077, 18.209078, -19.679089, 6.560063, 18.392344, -19.679089, 6.777077, 19.137367, -18.176437, 5.908166, 18.209078, -19.679089, 6.560063, 17.408092, -20.237429, 7.618006, 18.209078, -19.679089, 6.560063, 17.214787, -20.237429, 7.389458, 18.209078, -19.679089, 6.560063, 19.137367, -18.176437, 5.908166, 19.061113, -18.177078, 5.9391375, 17.214787, -20.237429, 7.389458, 18.209078, -19.679089, 6.560063, 18.027735, -19.463997, 6.5985103, 18.209078, -19.679089, 6.560063, 19.061113, -18.177078, 5.9391375, 18.027735, -19.463997, 6.5985103, 18.027735, -19.463997, 6.5985103, 19.061113, -18.177078, 5.9391375, 19.067095, -18.177505, 6.0213723, 17.214787, -20.237429, 7.389458, 18.027735, -19.463997, 6.5985103, 17.082785, -19.968939, 7.379846, 18.027735, -19.463997, 6.5985103, 19.067095, -18.177505, 6.0213723, 18.09865, -19.331139, 6.83902, 17.082785, -19.968939, 7.379846, 18.027735, -19.463997, 6.5985103, 18.09865, -19.331139, 6.83902, 17.082785, -19.968939, 7.379846, 18.09865, -19.331139, 6.83902, 17.194283, -19.802975, 7.602841, 19.916355, -18.10766, 4.50975, 18.669378, -17.361996, 4.594761, 18.997677, -18.38085, 4.7551727, 18.997677, -18.38085, 4.7551727, 18.669378, -17.361996, 4.594761, 17.938025, -17.356228, 5.7366476, 18.997677, -18.38085, 4.7551727, 17.938025, -17.356228, 5.7366476, 18.45151, -18.10766, 5.7464733, 19.916355, -18.10766, 4.50975, 19.861246, -17.356228, 4.1126738, 18.669378, -17.361996, 4.594761, 20.759848, -18.352869, 5.1768117, 19.861246, -17.356228, 4.1126738, 19.916355, -18.10766, 4.50975, 18.669378, -17.361996, 4.594761, 18.361372, -16.59625, 5.750745, 17.938025, -17.356228, 5.7366476, 20.759848, -18.352869, 5.1768117, 20.69171, -17.339567, 4.9839334, 19.861246, -17.356228, 4.1126738, 20.916626, -18.072844, 6.2943482, 20.69171, -17.339567, 4.9839334, 20.759848, -18.352869, 5.1768117, 19.861246, -17.356228, 4.1126738, 18.80138, -16.33182, 5.093936, 18.669378, -17.361996, 4.594761, 18.669378, -17.361996, 4.594761, 18.80138, -16.33182, 5.093936, 18.361372, -16.59625, 5.750745, 20.69171, -17.339567, 4.9839334, 19.58528, -16.596252, 4.7173653, 19.861246, -17.356228, 4.1126738, 19.861246, -17.356228, 4.1126738, 19.58528, -16.596252, 4.7173653, 18.80138, -16.33182, 5.093936, 20.916626, -18.072844, 6.2943482, 20.971521, -17.322693, 6.3201933, 20.69171, -17.339567, 4.9839334, 20.971521, -17.322693, 6.3201933, 20.916626, -18.072844, 6.2943482, 20.598795, -18.324886, 7.2226386, 20.69171, -17.339567, 4.9839334, 20.07292, -16.326265, 5.255842, 19.58528, -16.596252, 4.7173653, 20.971521, -17.322693, 6.3201933, 20.07292, -16.326265, 5.255842, 20.69171, -17.339567, 4.9839334, 19.58528, -16.596252, 4.7173653, 19.312944, -15.988569, 5.813969, 18.80138, -16.33182, 5.093936, 19.58528, -16.596252, 4.7173653, 20.07292, -16.326265, 5.255842, 19.312944, -15.988569, 5.813969, 20.971521, -17.322693, 6.3201933, 20.39054, -16.581512, 6.067722, 20.07292, -16.326265, 5.255842, 20.971521, -17.322693, 6.3201933, 20.598795, -18.324886, 7.2226386, 20.51122, -17.317139, 7.2331047, 20.39054, -16.581512, 6.067722, 20.971521, -17.322693, 6.3201933, 20.51122, -17.317139, 7.2331047, 20.51122, -17.317139, 7.2331047, 20.598795, -18.324886, 7.2226386, 19.692719, -18.072844, 7.327728, 20.07292, -16.326265, 5.255842, 20.39054, -16.581512, 6.067722, 19.963133, -16.320711, 6.583985, 20.39054, -16.581512, 6.067722, 20.51122, -17.317139, 7.2331047, 19.963133, -16.320711, 6.583985, 20.07292, -16.326265, 5.255842, 19.963133, -16.320711, 6.583985, 19.312944, -15.988569, 5.813969, 20.51122, -17.317139, 7.2331047, 19.692719, -18.072844, 7.327728, 19.590406, -17.322693, 7.4862165, 19.963133, -16.320711, 6.583985, 20.51122, -17.317139, 7.2331047, 19.590406, -17.322693, 7.4862165, 18.836624, -18.352867, 6.800999, 19.590406, -17.322693, 7.4862165, 19.692719, -18.072844, 7.327728, 19.312944, -15.988569, 5.813969, 19.963133, -16.320711, 6.583985, 19.407354, -16.581512, 6.8975444, 19.963133, -16.320711, 6.583985, 19.590406, -17.322693, 7.4862165, 19.407354, -16.581512, 6.8975444, 18.836624, -18.352867, 6.800999, 18.488676, -17.339567, 6.8439317, 19.590406, -17.322693, 7.4862165, 18.488676, -17.339567, 6.8439317, 19.407354, -16.581512, 6.8975444, 19.590406, -17.322693, 7.4862165, 18.45151, -18.10766, 5.7464733, 18.488676, -17.339567, 6.8439317, 18.836624, -18.352867, 6.800999, 18.45151, -18.10766, 5.7464733, 17.938025, -17.356228, 5.7366476, 18.488676, -17.339567, 6.8439317, 18.488676, -17.339567, 6.8439317, 18.691593, -16.326265, 6.4220786, 19.407354, -16.581512, 6.8975444, 19.312944, -15.988569, 5.813969, 19.407354, -16.581512, 6.8975444, 18.691593, -16.326265, 6.4220786, 17.938025, -17.356228, 5.7366476, 18.691593, -16.326265, 6.4220786, 18.488676, -17.339567, 6.8439317, 18.80138, -16.33182, 5.093936, 19.312944, -15.988569, 5.813969, 18.691593, -16.326265, 6.4220786, 17.938025, -17.356228, 5.7366476, 18.361372, -16.59625, 5.750745, 18.691593, -16.326265, 6.4220786, 18.80138, -16.33182, 5.093936, 18.691593, -16.326265, 6.4220786, 18.361372, -16.59625, 5.750745, 20.916626, -18.072844, 6.2943482, 19.867655, -18.690779, 6.0138965, 20.598795, -18.324886, 7.2226386, 20.916626, -18.072844, 6.2943482, 20.759848, -18.352869, 5.1768117, 19.867655, -18.690779, 6.0138965, 20.598795, -18.324886, 7.2226386, 19.867655, -18.690779, 6.0138965, 18.836624, -18.352867, 6.800999, 20.598795, -18.324886, 7.2226386, 18.836624, -18.352867, 6.800999, 19.692719, -18.072844, 7.327728, 19.867655, -18.690779, 6.0138965, 18.45151, -18.10766, 5.7464733, 18.836624, -18.352867, 6.800999, 19.867655, -18.690779, 6.0138965, 18.997677, -18.38085, 4.7551727, 18.45151, -18.10766, 5.7464733, 20.759848, -18.352869, 5.1768117, 18.997677, -18.38085, 4.7551727, 19.867655, -18.690779, 6.0138965, 20.759848, -18.352869, 5.1768117, 19.916355, -18.10766, 4.50975, 18.997677, -18.38085, 4.7551727, 15.432323, -17.738777, 11.597307, 17.151134, -15.819399, 12.648415, 17.029385, -18.463295, 12.383129, 17.029385, -18.463295, 12.383129, 17.151134, -15.819399, 12.648415, 19.233913, -15.752116, 11.624861, 17.029385, -18.463295, 12.383129, 19.233913, -15.752116, 11.624861, 18.862041, -17.774446, 11.419596, 15.432323, -17.738777, 11.597307, 15.174299, -15.860622, 12.197086, 17.151134, -15.819399, 12.648415, 14.790466, -18.280245, 9.459635, 15.174299, -15.860622, 12.197086, 15.432323, -17.738777, 11.597307, 17.151134, -15.819399, 12.648415, 18.632425, -13.811806, 11.039606, 19.233913, -15.752116, 11.624861, 14.790466, -18.280245, 9.459635, 14.663164, -15.672873, 9.612782, 15.174299, -15.860622, 12.197086, 15.765963, -17.546755, 7.471905, 14.663164, -15.672873, 9.612782, 14.790466, -18.280245, 9.459635, 15.174299, -15.860622, 12.197086, 17.378614, -13.149656, 11.438818, 17.151134, -15.819399, 12.648415, 17.151134, -15.819399, 12.648415, 17.378614, -13.149656, 11.438818, 18.632425, -13.811806, 11.039606, 14.663164, -15.672873, 9.612782, 16.05389, -13.860292, 11.293999, 15.174299, -15.860622, 12.197086, 15.174299, -15.860622, 12.197086, 16.05389, -13.860292, 11.293999, 17.378614, -13.149656, 11.438818, 15.765963, -17.546755, 7.471905, 15.501957, -15.53254, 7.0716248, 14.663164, -15.672873, 9.612782, 15.501957, -15.53254, 7.0716248, 15.765963, -17.546755, 7.471905, 17.558678, -18.333218, 6.7520857, 14.663164, -15.672873, 9.612782, 15.88579, -13.113132, 9.809076, 16.05389, -13.860292, 11.293999, 15.501957, -15.53254, 7.0716248, 15.88579, -13.113132, 9.809076, 14.663164, -15.672873, 9.612782, 16.05389, -13.860292, 11.293999, 17.454443, -12.259815, 9.87465, 17.378614, -13.149656, 11.438818, 16.05389, -13.860292, 11.293999, 15.88579, -13.113132, 9.809076, 17.454443, -12.259815, 9.87465, 15.501957, -15.53254, 7.0716248, 16.199562, -13.714193, 8.2419195, 15.88579, -13.113132, 9.809076, 15.501957, -15.53254, 7.0716248, 17.558678, -18.333218, 6.7520857, 17.574484, -15.715379, 6.749949, 16.199562, -13.714193, 8.2419195, 15.501957, -15.53254, 7.0716248, 17.574484, -15.715379, 6.749949, 17.574484, -15.715379, 6.749949, 17.558678, -18.333218, 6.7520857, 19.186922, -17.80478, 7.9181085, 15.88579, -13.113132, 9.809076, 16.199562, -13.714193, 8.2419195, 17.48456, -13.123599, 8.222482, 16.199562, -13.714193, 8.2419195, 17.574484, -15.715379, 6.749949, 17.48456, -13.123599, 8.222482, 15.88579, -13.113132, 9.809076, 17.48456, -13.123599, 8.222482, 17.454443, -12.259815, 9.87465, 17.574484, -15.715379, 6.749949, 19.186922, -17.80478, 7.9181085, 19.541065, -15.924276, 7.9029427, 17.48456, -13.123599, 8.222482, 17.574484, -15.715379, 6.749949, 19.541065, -15.924276, 7.9029427, 19.797594, -18.516268, 9.675581, 19.541065, -15.924276, 7.9029427, 19.186922, -17.80478, 7.9181085, 17.454443, -12.259815, 9.87465, 17.48456, -13.123599, 8.222482, 18.768915, -13.888488, 8.611227, 17.48456, -13.123599, 8.222482, 19.541065, -15.924276, 7.9029427, 18.768915, -13.888488, 8.611227, 19.797594, -18.516268, 9.675581, 20.062454, -15.861905, 9.785582, 19.541065, -15.924276, 7.9029427, 20.062454, -15.861905, 9.785582, 18.768915, -13.888488, 8.611227, 19.541065, -15.924276, 7.9029427, 18.862041, -17.774446, 11.419596, 20.062454, -15.861905, 9.785582, 19.797594, -18.516268, 9.675581, 18.862041, -17.774446, 11.419596, 19.233913, -15.752116, 11.624861, 20.062454, -15.861905, 9.785582, 20.062454, -15.861905, 9.785582, 18.977385, -13.160124, 9.852436, 18.768915, -13.888488, 8.611227, 17.454443, -12.259815, 9.87465, 18.768915, -13.888488, 8.611227, 18.977385, -13.160124, 9.852436, 19.233913, -15.752116, 11.624861, 18.977385, -13.160124, 9.852436, 20.062454, -15.861905, 9.785582, 17.378614, -13.149656, 11.438818, 17.454443, -12.259815, 9.87465, 18.977385, -13.160124, 9.852436, 19.233913, -15.752116, 11.624861, 18.632425, -13.811806, 11.039606, 18.977385, -13.160124, 9.852436, 17.378614, -13.149656, 11.438818, 18.977385, -13.160124, 9.852436, 18.632425, -13.811806, 11.039606, 15.765963, -17.546755, 7.471905, 17.271177, -19.275177, 9.523714, 17.558678, -18.333218, 6.7520857, 15.765963, -17.546755, 7.471905, 14.790466, -18.280245, 9.459635, 17.271177, -19.275177, 9.523714, 17.558678, -18.333218, 6.7520857, 17.271177, -19.275177, 9.523714, 19.797594, -18.516268, 9.675581, 17.558678, -18.333218, 6.7520857, 19.797594, -18.516268, 9.675581, 19.186922, -17.80478, 7.9181085, 17.271177, -19.275177, 9.523714, 18.862041, -17.774446, 11.419596, 19.797594, -18.516268, 9.675581, 17.271177, -19.275177, 9.523714, 17.029385, -18.463295, 12.383129, 18.862041, -17.774446, 11.419596, 14.790466, -18.280245, 9.459635, 17.029385, -18.463295, 12.383129, 17.271177, -19.275177, 9.523714, 14.790466, -18.280245, 9.459635, 15.432323, -17.738777, 11.597307, 17.029385, -18.463295, 12.383129, 6.450511, 5.6386614, 17.721281, 5.116558, 6.049283, 18.568323, 6.1998763, 5.437825, 17.553066, 6.450511, 5.6386614, 17.721281, 5.394739, 6.2101097, 18.690458, 5.116558, 6.049283, 18.568323, 5.394739, 6.2101097, 18.690458, 4.166137, 7.607539, 19.708622, 5.116558, 6.049283, 18.568323, 5.394739, 6.2101097, 18.690458, 4.2640667, 7.6070127, 19.728611, 4.166137, 7.607539, 19.708622, 5.116558, 6.049283, 18.568323, 4.166137, 7.607539, 19.708622, 4.117188, 7.608329, 19.795757, 6.1998763, 5.437825, 17.553066, 5.116558, 6.049283, 18.568323, 5.0425253, 5.7889595, 18.780462, 5.116558, 6.049283, 18.568323, 4.117188, 7.608329, 19.795757, 5.0425253, 5.7889595, 18.780462, 6.1998763, 5.437825, 17.553066, 5.0425253, 5.7889595, 18.780462, 6.190998, 5.1124864, 17.713438, 5.0425253, 5.7889595, 18.780462, 4.117188, 7.608329, 19.795757, 4.1845627, 7.608329, 19.869196, 6.190998, 5.1124864, 17.713438, 5.0425253, 5.7889595, 18.780462, 5.2750225, 5.7889595, 19.03369, 5.0425253, 5.7889595, 18.780462, 4.1845627, 7.608329, 19.869196, 5.2750225, 5.7889595, 19.03369, 6.190998, 5.1124864, 17.713438, 5.2750225, 5.7889595, 19.03369, 6.436242, 5.1124864, 17.980635, 5.2750225, 5.7889595, 19.03369, 4.1845627, 7.608329, 19.869196, 4.2755394, 7.607539, 19.827774, 6.436242, 5.1124864, 17.980635, 5.2750225, 5.7889595, 19.03369, 5.492837, 6.049283, 18.978226, 5.2750225, 5.7889595, 19.03369, 4.2755394, 7.607539, 19.827774, 5.492837, 6.049283, 18.978226, 5.492837, 6.049283, 18.978226, 4.2755394, 7.607539, 19.827774, 4.2640667, 7.6070127, 19.728611, 6.436242, 5.1124864, 17.980635, 5.492837, 6.049283, 18.978226, 6.596695, 5.437825, 17.985352, 5.492837, 6.049283, 18.978226, 4.2640667, 7.6070127, 19.728611, 5.394739, 6.2101097, 18.690458, 6.596695, 5.437825, 17.985352, 5.492837, 6.049283, 18.978226, 5.394739, 6.2101097, 18.690458, 6.596695, 5.437825, 17.985352, 5.394739, 6.2101097, 18.690458, 6.450511, 5.6386614, 17.721281, 5.7805123, 3.2207327, 16.731695, 6.2294216, 5.7555304, 17.911285, 5.4306893, 3.2207327, 17.595985, 5.7805123, 3.2207327, 16.731695, 6.351206, 5.7918544, 17.591637, 6.2294216, 5.7555304, 17.911285, 6.351206, 5.7918544, 17.591637, 6.4141273, 8.301909, 17.908752, 6.2294216, 5.7555304, 17.911285, 6.351206, 5.7918544, 17.591637, 6.4673533, 8.311122, 17.766653, 6.4141273, 8.301909, 17.908752, 6.2294216, 5.7555304, 17.911285, 6.4141273, 8.301909, 17.908752, 6.532635, 8.286643, 18.002592, 5.4306893, 3.2207327, 17.595985, 6.2294216, 5.7555304, 17.911285, 6.495885, 5.697096, 18.12049, 6.2294216, 5.7555304, 17.911285, 6.532635, 8.286643, 18.002592, 6.495885, 5.697096, 18.12049, 5.4306893, 3.2207327, 17.595985, 6.495885, 5.697096, 18.12049, 6.146731, 3.2207327, 18.143703, 6.495885, 5.697096, 18.12049, 6.532635, 8.286643, 18.002592, 6.6594005, 8.286643, 17.918467, 6.146731, 3.2207327, 18.143703, 6.495885, 5.697096, 18.12049, 6.7823133, 5.697096, 17.930405, 6.495885, 5.697096, 18.12049, 6.6594005, 8.286643, 17.918467, 6.7823133, 5.697096, 17.930405, 6.146731, 3.2207327, 18.143703, 6.7823133, 5.697096, 17.930405, 6.939343, 3.2207327, 17.617693, 6.7823133, 5.697096, 17.930405, 6.6594005, 8.286643, 17.918467, 6.6189694, 8.301909, 17.77281, 6.939343, 3.2207327, 17.617693, 6.7823133, 5.697096, 17.930405, 6.693058, 5.7555304, 17.603598, 6.7823133, 5.697096, 17.930405, 6.6189694, 8.301909, 17.77281, 6.693058, 5.7555304, 17.603598, 6.693058, 5.7555304, 17.603598, 6.6189694, 8.301909, 17.77281, 6.4673533, 8.311122, 17.766653, 6.939343, 3.2207327, 17.617693, 6.693058, 5.7555304, 17.603598, 6.712817, 3.2207322, 16.745113, 6.693058, 5.7555304, 17.603598, 6.4673533, 8.311122, 17.766653, 6.351206, 5.7918544, 17.591637, 6.712817, 3.2207322, 16.745113, 6.693058, 5.7555304, 17.603598, 6.351206, 5.7918544, 17.591637, 6.712817, 3.2207322, 16.745113, 6.351206, 5.7918544, 17.591637, 5.7805123, 3.2207327, 16.731695, 6.732394, 5.966105, 17.783781, 8.337761, 6.384096, 17.883148, 6.83874, 5.7618475, 18.072077, 6.83874, 5.7618475, 18.072077, 6.302865, 5.6723533, 17.875813, 6.732394, 5.966105, 17.783781, 6.83874, 5.7618475, 18.072077, 6.3696475, 5.543639, 18.05737, 6.302865, 5.6723533, 17.875813, 6.732394, 5.966105, 17.783781, 8.181509, 6.5478187, 17.616283, 8.337761, 6.384096, 17.883148, 8.181509, 6.5478187, 17.616283, 9.801905, 7.9697266, 17.51171, 8.337761, 6.384096, 17.883148, 8.181509, 6.5478187, 17.616283, 9.733292, 7.9692, 17.436882, 9.801905, 7.9697266, 17.51171, 8.337761, 6.384096, 17.883148, 9.801905, 7.9697266, 17.51171, 9.894417, 7.970516, 17.469269, 8.337761, 6.384096, 17.883148, 9.894417, 7.970516, 17.469269, 8.525363, 6.119035, 17.752645, 6.83874, 5.7618475, 18.072077, 8.337761, 6.384096, 17.883148, 8.525363, 6.119035, 17.752645, 8.525363, 6.119035, 17.752645, 9.894417, 7.970516, 17.469269, 9.882729, 7.970516, 17.368353, 6.9416494, 5.4307184, 17.94534, 6.3696475, 5.543639, 18.05737, 6.83874, 5.7618475, 18.072077, 6.83874, 5.7618475, 18.072077, 8.525363, 6.119035, 17.752645, 6.9416494, 5.4307184, 17.94534, 6.9416494, 5.4307184, 17.94534, 6.4345694, 5.33517, 17.977638, 6.3696475, 5.543639, 18.05737, 8.525363, 6.119035, 17.752645, 9.882729, 7.970516, 17.368353, 8.485138, 6.119035, 17.40499, 6.9416494, 5.4307184, 17.94534, 8.525363, 6.119035, 17.752645, 8.485138, 6.119035, 17.40499, 8.485138, 6.119035, 17.40499, 9.882729, 7.970516, 17.368353, 9.783121, 7.9697266, 17.348215, 6.899346, 5.4307184, 17.578844, 6.4345694, 5.33517, 17.977638, 6.9416494, 5.4307184, 17.94534, 6.9416494, 5.4307184, 17.94534, 8.485138, 6.119035, 17.40499, 6.899346, 5.4307184, 17.578844, 6.899346, 5.4307184, 17.578844, 6.4079695, 5.33517, 17.746672, 6.4345694, 5.33517, 17.977638, 8.485138, 6.119035, 17.40499, 9.783121, 7.9697266, 17.348215, 8.2728, 6.384096, 17.320663, 6.899346, 5.4307184, 17.578844, 8.485138, 6.119035, 17.40499, 8.2728, 6.384096, 17.320663, 8.2728, 6.384096, 17.320663, 9.783121, 7.9697266, 17.348215, 9.733292, 7.9692, 17.436882, 8.2728, 6.384096, 17.320663, 9.733292, 7.9692, 17.436882, 8.181509, 6.5478187, 17.616283, 6.899346, 5.4307184, 17.578844, 8.2728, 6.384096, 17.320663, 6.7699003, 5.7618475, 17.478994, 6.7699003, 5.7618475, 17.478994, 6.4079695, 5.33517, 17.746672, 6.899346, 5.4307184, 17.578844, 6.7699003, 5.7618475, 17.478994, 8.2728, 6.384096, 17.320663, 8.181509, 6.5478187, 17.616283, 6.7699003, 5.7618475, 17.478994, 6.326483, 5.543639, 17.683863, 6.4079695, 5.33517, 17.746672, 6.7699003, 5.7618475, 17.478994, 8.181509, 6.5478187, 17.616283, 6.732394, 5.966105, 17.783781, 6.732394, 5.966105, 17.783781, 6.326483, 5.543639, 17.683863, 6.7699003, 5.7618475, 17.478994, 6.732394, 5.966105, 17.783781, 6.302865, 5.6723533, 17.875813, 6.326483, 5.543639, 17.683863, 11.635334, 8.055535, 16.46335, 10.297312, 8.974432, 15.70101, 10.525072, 7.7188787, 16.089432, 10.525072, 7.7188787, 16.089432, 10.297312, 8.974432, 15.70101, 8.768291, 8.9812765, 16.37455, 10.525072, 7.7188787, 16.089432, 8.768291, 8.9812765, 16.37455, 9.2888565, 8.055536, 16.734821, 11.635334, 8.055535, 16.46335, 11.849512, 8.981276, 16.018257, 10.297312, 8.974432, 15.70101, 12.046843, 7.75336, 17.723677, 11.849512, 8.981276, 16.018257, 11.635334, 8.055535, 16.46335, 10.297312, 8.974432, 15.70101, 9.193269, 9.9178095, 16.677896, 8.768291, 8.9812765, 16.37455, 12.046843, 7.75336, 17.723677, 12.1083145, 9.00207, 17.478806, 11.849512, 8.981276, 16.018257, 11.446236, 8.09844, 18.977428, 12.1083145, 9.00207, 17.478806, 12.046843, 7.75336, 17.723677, 11.849512, 8.981276, 16.018257, 10.092733, 10.2439375, 16.303373, 10.297312, 8.974432, 15.70101, 10.297312, 8.974432, 15.70101, 10.092733, 10.2439375, 16.303373, 9.193269, 9.9178095, 16.677896, 12.1083145, 9.00207, 17.478806, 11.154192, 9.917809, 16.450953, 11.849512, 8.981276, 16.018257, 11.849512, 8.981276, 16.018257, 11.154192, 9.917809, 16.450953, 10.092733, 10.2439375, 16.303373, 11.446236, 8.09844, 18.977428, 11.4849415, 9.022602, 19.041462, 12.1083145, 9.00207, 17.478806, 11.4849415, 9.022602, 19.041462, 11.446236, 8.09844, 18.977428, 10.487244, 7.7878428, 19.713997, 12.1083145, 9.00207, 17.478806, 11.287758, 10.250781, 17.336258, 11.154192, 9.917809, 16.450953, 11.4849415, 9.022602, 19.041462, 11.287758, 10.250781, 17.336258, 12.1083145, 9.00207, 17.478806, 11.154192, 9.917809, 16.450953, 10.127245, 10.667193, 17.391205, 10.092733, 10.2439375, 16.303373, 11.154192, 9.917809, 16.450953, 11.287758, 10.250781, 17.336258, 10.127245, 10.667193, 17.391205, 11.4849415, 9.022602, 19.041462, 11.060484, 9.936234, 18.386164, 11.287758, 10.250781, 17.336258, 11.4849415, 9.022602, 19.041462, 10.487244, 7.7878428, 19.713997, 10.390107, 9.029709, 19.664736, 11.060484, 9.936234, 18.386164, 11.4849415, 9.022602, 19.041462, 10.390107, 9.029709, 19.664736, 10.390107, 9.029709, 19.664736, 10.487244, 7.7878428, 19.713997, 9.485313, 8.098441, 19.204372, 11.287758, 10.250781, 17.336258, 11.060484, 9.936234, 18.386164, 10.269789, 10.257888, 18.624687, 11.060484, 9.936234, 18.386164, 10.390107, 9.029709, 19.664736, 10.269789, 10.257888, 18.624687, 11.287758, 10.250781, 17.336258, 10.269789, 10.257888, 18.624687, 10.127245, 10.667193, 17.391205, 10.390107, 9.029709, 19.664736, 9.485313, 8.098441, 19.204372, 9.272093, 9.022602, 19.297224, 10.269789, 10.257888, 18.624687, 10.390107, 9.029709, 19.664736, 9.272093, 9.022602, 19.297224, 8.965256, 7.7533607, 18.079897, 9.272093, 9.022602, 19.297224, 9.485313, 8.098441, 19.204372, 10.127245, 10.667193, 17.391205, 10.269789, 10.257888, 18.624687, 9.485554, 9.936234, 18.568289, 10.269789, 10.257888, 18.624687, 9.272093, 9.022602, 19.297224, 9.485554, 9.936234, 18.568289, 8.965256, 7.7533607, 18.079897, 8.57874, 9.002071, 17.886866, 9.272093, 9.022602, 19.297224, 8.57874, 9.002071, 17.886866, 9.485554, 9.936234, 18.568289, 9.272093, 9.022602, 19.297224, 9.2888565, 8.055536, 16.734821, 8.57874, 9.002071, 17.886866, 8.965256, 7.7533607, 18.079897, 9.2888565, 8.055536, 16.734821, 8.768291, 8.9812765, 16.37455, 8.57874, 9.002071, 17.886866, 8.57874, 9.002071, 17.886866, 9.07469, 10.250781, 17.592167, 9.485554, 9.936234, 18.568289, 10.127245, 10.667193, 17.391205, 9.485554, 9.936234, 18.568289, 9.07469, 10.250781, 17.592167, 8.768291, 8.9812765, 16.37455, 9.07469, 10.250781, 17.592167, 8.57874, 9.002071, 17.886866, 10.092733, 10.2439375, 16.303373, 10.127245, 10.667193, 17.391205, 9.07469, 10.250781, 17.592167, 8.768291, 8.9812765, 16.37455, 9.193269, 9.9178095, 16.677896, 9.07469, 10.250781, 17.592167, 10.092733, 10.2439375, 16.303373, 9.07469, 10.250781, 17.592167, 9.193269, 9.9178095, 16.677896, 11.446236, 8.09844, 18.977428, 10.560175, 7.3369484, 17.97454, 10.487244, 7.7878428, 19.713997, 11.446236, 8.09844, 18.977428, 12.046843, 7.75336, 17.723677, 10.560175, 7.3369484, 17.97454, 10.487244, 7.7878428, 19.713997, 10.560175, 7.3369484, 17.97454, 8.965256, 7.7533607, 18.079897, 10.487244, 7.7878428, 19.713997, 8.965256, 7.7533607, 18.079897, 9.485313, 8.098441, 19.204372, 10.560175, 7.3369484, 17.97454, 9.2888565, 8.055536, 16.734821, 8.965256, 7.7533607, 18.079897, 10.560175, 7.3369484, 17.97454, 10.525072, 7.7188787, 16.089432, 9.2888565, 8.055536, 16.734821, 12.046843, 7.75336, 17.723677, 10.525072, 7.7188787, 16.089432, 10.560175, 7.3369484, 17.97454, 12.046843, 7.75336, 17.723677, 11.635334, 8.055535, 16.46335, 10.525072, 7.7188787, 16.089432, 1.4948497, 8.510117, 18.317255, 1.5868134, 10.875402, 20.798342, 1.7763877, 7.617279, 20.49278, 1.7763877, 7.617279, 20.49278, 1.5868134, 10.875402, 20.798342, 4.0570173, 10.958316, 22.239437, 1.7763877, 7.617279, 20.49278, 4.0570173, 10.958316, 22.239437, 4.0145273, 8.465897, 21.717955, 1.4948497, 8.510117, 18.317255, 0.70318604, 10.8246, 18.46102, 1.5868134, 10.875402, 20.798342, 3.2524045, 7.8428564, 16.201567, 0.70318604, 10.8246, 18.46102, 1.4948497, 8.510117, 18.317255, 1.5868134, 10.875402, 20.798342, 4.248084, 13.349396, 21.22304, 4.0570173, 10.958316, 22.239437, 3.2524045, 7.8428564, 16.201567, 3.0084083, 11.055706, 16.17521, 0.70318604, 10.8246, 18.46102, 5.9580865, 8.746749, 15.848719, 3.0084083, 11.055706, 16.17521, 3.2524045, 7.8428564, 16.201567, 0.70318604, 10.8246, 18.46102, 2.983596, 14.165375, 20.207823, 1.5868134, 10.875402, 20.798342, 1.5868134, 10.875402, 20.798342, 2.983596, 14.165375, 20.207823, 4.248084, 13.349396, 21.22304, 3.0084083, 11.055706, 16.17521, 2.2301898, 13.289908, 18.748863, 0.70318604, 10.8246, 18.46102, 0.70318604, 10.8246, 18.46102, 2.2301898, 13.289908, 18.748863, 2.983596, 14.165375, 20.207823, 5.9580865, 8.746749, 15.848719, 6.1891904, 11.228903, 15.304886, 3.0084083, 11.055706, 16.17521, 6.1891904, 11.228903, 15.304886, 5.9580865, 8.746749, 15.848719, 7.9187675, 7.777577, 17.198952, 3.0084083, 11.055706, 16.17521, 3.6397526, 14.210384, 17.564486, 2.2301898, 13.289908, 18.748863, 6.1891904, 11.228903, 15.304886, 3.6397526, 14.210384, 17.564486, 3.0084083, 11.055706, 16.17521, 2.2301898, 13.289908, 18.748863, 4.6415443, 15.261944, 19.219688, 2.983596, 14.165375, 20.207823, 2.2301898, 13.289908, 18.748863, 3.6397526, 14.210384, 17.564486, 4.6415443, 15.261944, 19.219688, 6.1891904, 11.228903, 15.304886, 5.462911, 13.469423, 16.818632, 3.6397526, 14.210384, 17.564486, 6.1891904, 11.228903, 15.304886, 7.9187675, 7.777577, 17.198952, 7.931513, 11.003588, 17.213871, 5.462911, 13.469423, 16.818632, 6.1891904, 11.228903, 15.304886, 7.931513, 11.003588, 17.213871, 7.931513, 11.003588, 17.213871, 7.9187675, 7.777577, 17.198952, 7.831026, 8.428781, 19.665352, 3.6397526, 14.210384, 17.564486, 5.462911, 13.469423, 16.818632, 6.3584847, 14.197486, 18.1248, 5.462911, 13.469423, 16.818632, 7.931513, 11.003588, 17.213871, 6.3584847, 14.197486, 18.1248, 3.6397526, 14.210384, 17.564486, 6.3584847, 14.197486, 18.1248, 4.6415443, 15.261944, 19.219688, 7.931513, 11.003588, 17.213871, 7.831026, 8.428781, 19.665352, 8.087843, 10.745896, 20.01901, 6.3584847, 14.197486, 18.1248, 7.931513, 11.003588, 17.213871, 8.087843, 10.745896, 20.01901, 6.4428244, 7.5519996, 21.489801, 8.087843, 10.745896, 20.01901, 7.831026, 8.428781, 19.665352, 4.6415443, 15.261944, 19.219688, 6.3584847, 14.197486, 18.1248, 6.8342867, 13.254899, 19.708595, 6.3584847, 14.197486, 18.1248, 8.087843, 10.745896, 20.01901, 6.8342867, 13.254899, 19.708595, 6.4428244, 7.5519996, 21.489801, 6.510137, 10.823021, 21.836857, 8.087843, 10.745896, 20.01901, 6.510137, 10.823021, 21.836857, 6.8342867, 13.254899, 19.708595, 8.087843, 10.745896, 20.01901, 4.0145273, 8.465897, 21.717955, 6.510137, 10.823021, 21.836857, 6.4428244, 7.5519996, 21.489801, 4.0145273, 8.465897, 21.717955, 4.0570173, 10.958316, 22.239437, 6.510137, 10.823021, 21.836857, 6.510137, 10.823021, 21.836857, 5.702328, 14.152213, 20.768137, 6.8342867, 13.254899, 19.708595, 4.6415443, 15.261944, 19.219688, 6.8342867, 13.254899, 19.708595, 5.702328, 14.152213, 20.768137, 4.0570173, 10.958316, 22.239437, 5.702328, 14.152213, 20.768137, 6.510137, 10.823021, 21.836857, 2.983596, 14.165375, 20.207823, 4.6415443, 15.261944, 19.219688, 5.702328, 14.152213, 20.768137, 4.0570173, 10.958316, 22.239437, 4.248084, 13.349396, 21.22304, 5.702328, 14.152213, 20.768137, 2.983596, 14.165375, 20.207823, 5.702328, 14.152213, 20.768137, 4.248084, 13.349396, 21.22304, 5.9580865, 8.746749, 15.848719, 4.877001, 6.61652, 18.79238, 7.9187675, 7.777577, 17.198952, 5.9580865, 8.746749, 15.848719, 3.2524045, 7.8428564, 16.201567, 4.877001, 6.61652, 18.79238, 7.9187675, 7.777577, 17.198952, 4.877001, 6.61652, 18.79238, 6.4428244, 7.5519996, 21.489801, 7.9187675, 7.777577, 17.198952, 6.4428244, 7.5519996, 21.489801, 7.831026, 8.428781, 19.665352, 4.877001, 6.61652, 18.79238, 4.0145273, 8.465897, 21.717955, 6.4428244, 7.5519996, 21.489801, 4.877001, 6.61652, 18.79238, 1.7763877, 7.617279, 20.49278, 4.0145273, 8.465897, 21.717955, 3.2524045, 7.8428564, 16.201567, 1.7763877, 7.617279, 20.49278, 4.877001, 6.61652, 18.79238, 3.2524045, 7.8428564, 16.201567, 1.4948497, 8.510117, 18.317255, 1.7763877, 7.617279, 20.49278, -17.758068, 7.5774293, -6.836121, -20.570257, 8.332888, -7.573155, -17.84524, 7.2079325, -7.384581, -17.758068, 7.5774293, -6.836121, -20.386482, 8.628776, -7.04528, -20.570257, 8.332888, -7.573155, -20.386482, 8.628776, -7.04528, -23.297365, 11.199757, -7.426018, -20.570257, 8.332888, -7.573155, -20.386482, 8.628776, -7.04528, -23.201662, 11.198789, -7.2690005, -23.297365, 11.199757, -7.426018, -20.570257, 8.332888, -7.573155, -23.297365, 11.199757, -7.426018, -23.476107, 11.20121, -7.3828626, -17.84524, 7.2079325, -7.384581, -20.570257, 8.332888, -7.573155, -20.948885, 7.853947, -7.4072576, -20.570257, 8.332888, -7.573155, -23.476107, 11.20121, -7.3828626, -20.948885, 7.853947, -7.4072576, -17.84524, 7.2079325, -7.384581, -20.948885, 7.853947, -7.4072576, -18.072498, 6.6093764, -7.195704, -20.948885, 7.853947, -7.4072576, -23.476107, 11.20121, -7.3828626, -23.490705, 11.20121, -7.200089, -18.072498, 6.6093764, -7.195704, -20.948885, 7.853947, -7.4072576, -20.999002, 7.853947, -6.776777, -20.948885, 7.853947, -7.4072576, -23.490705, 11.20121, -7.200089, -20.999002, 7.853947, -6.776777, -18.072498, 6.6093764, -7.195704, -20.999002, 7.853947, -6.776777, -18.12548, 6.6093764, -6.5305486, -20.999002, 7.853947, -6.776777, -23.490705, 11.20121, -7.200089, -23.320944, 11.199757, -7.129349, -18.12548, 6.6093764, -6.5305486, -20.999002, 7.853947, -6.776777, -20.651468, 8.332888, -6.5526786, -20.999002, 7.853947, -6.776777, -23.320944, 11.199757, -7.129349, -20.651468, 8.332888, -6.5526786, -20.651468, 8.332888, -6.5526786, -23.320944, 11.199757, -7.129349, -23.201662, 11.198789, -7.2690005, -18.12548, 6.6093764, -6.5305486, -20.651468, 8.332888, -6.5526786, -17.930893, 7.2079325, -6.308391, -20.651468, 8.332888, -6.5526786, -23.201662, 11.198789, -7.2690005, -20.386482, 8.628776, -7.04528, -17.930893, 7.2079325, -6.308391, -20.651468, 8.332888, -6.5526786, -20.386482, 8.628776, -7.04528, -17.930893, 7.2079325, -6.308391, -20.386482, 8.628776, -7.04528, -17.758068, 7.5774293, -6.836121, -17.263433, 3.1289406, -8.978432, -18.291029, 7.792444, -6.8961415, -18.866385, 3.1289406, -8.367504, -17.263433, 3.1289406, -8.978432, -17.707705, 7.8592725, -7.132322, -18.291029, 7.792444, -6.8961415, -17.707705, 7.8592725, -7.132322, -18.056295, 12.477256, -6.650377, -18.291029, 7.792444, -6.8961415, -17.707705, 7.8592725, -7.132322, -17.798122, 12.494205, -6.756602, -18.056295, 12.477256, -6.650377, -18.291029, 7.792444, -6.8961415, -18.056295, 12.477256, -6.650377, -18.034353, 12.449168, -6.373137, -18.866385, 3.1289406, -8.367504, -18.291029, 7.792444, -6.8961415, -18.239275, 7.6849365, -6.2750163, -18.291029, 7.792444, -6.8961415, -18.034353, 12.449168, -6.373137, -18.239275, 7.6849365, -6.2750163, -18.866385, 3.1289406, -8.367504, -18.239275, 7.6849365, -6.2750163, -18.707829, 3.1289406, -6.716517, -18.239275, 7.6849365, -6.2750163, -18.034353, 12.449168, -6.373137, -17.762217, 12.449168, -6.3076463, -18.707829, 3.1289406, -6.716517, -18.239275, 7.6849365, -6.2750163, -17.624376, 7.6849365, -6.1270385, -18.239275, 7.6849365, -6.2750163, -17.762217, 12.449168, -6.3076463, -17.624376, 7.6849365, -6.1270385, -18.707829, 3.1289406, -6.716517, -17.624376, 7.6849365, -6.1270385, -17.006262, 3.1289406, -6.3070283, -17.624376, 7.6849365, -6.1270385, -17.762217, 12.449168, -6.3076463, -17.616545, 12.477256, -6.5445485, -17.006262, 3.1289406, -6.3070283, -17.624376, 7.6849365, -6.1270385, -17.295702, 7.792444, -6.656613, -17.624376, 7.6849365, -6.1270385, -17.616545, 12.477256, -6.5445485, -17.295702, 7.792444, -6.656613, -17.295702, 7.792444, -6.656613, -17.616545, 12.477256, -6.5445485, -17.798122, 12.494205, -6.756602, -17.006262, 3.1289406, -6.3070283, -17.295702, 7.792444, -6.656613, -16.113934, 3.1289406, -7.705115, -17.295702, 7.792444, -6.656613, -17.798122, 12.494205, -6.756602, -17.707705, 7.8592725, -7.132322, -16.113934, 3.1289406, -7.705115, -17.295702, 7.792444, -6.656613, -17.707705, 7.8592725, -7.132322, -16.113934, 3.1289406, -7.705115, -17.707705, 7.8592725, -7.132322, -17.263433, 3.1289406, -8.978432, -17.48928, 8.179858, -6.3779426, -15.612703, 8.948875, -4.0898643, -17.744648, 7.804066, -5.8735633, -17.744648, 7.804066, -5.8735633, -18.151243, 7.6394153, -6.841582, -17.48928, 8.179858, -6.3779426, -17.744648, 7.804066, -5.8735633, -18.312298, 7.402608, -6.524203, -18.151243, 7.6394153, -6.841582, -17.48928, 8.179858, -6.3779426, -15.448719, 9.250092, -4.6346655, -15.612703, 8.948875, -4.0898643, -15.448719, 9.250092, -4.6346655, -13.278458, 11.866108, -2.5817409, -15.612703, 8.948875, -4.0898643, -15.448719, 9.250092, -4.6346655, -13.263538, 11.865139, -2.7679238, -13.278458, 11.866108, -2.5817409, -15.612703, 8.948875, -4.0898643, -13.278458, 11.866108, -2.5817409, -13.1054, 11.867559, -2.5102086, -15.612703, 8.948875, -4.0898643, -13.1054, 11.867559, -2.5102086, -15.201872, 8.461218, -4.00046, -17.744648, 7.804066, -5.8735633, -15.612703, 8.948875, -4.0898643, -15.201872, 8.461218, -4.00046, -15.201872, 8.461218, -4.00046, -13.1054, 11.867559, -2.5102086, -12.98403, 11.867559, -2.6523442, -17.444958, 7.1948566, -5.8935885, -18.312298, 7.402608, -6.524203, -17.744648, 7.804066, -5.8735633, -17.744648, 7.804066, -5.8735633, -15.201872, 8.461218, -4.00046, -17.444958, 7.1948566, -5.8935885, -17.444958, 7.1948566, -5.8935885, -18.123537, 7.0190673, -6.536556, -18.312298, 7.402608, -6.524203, -15.201872, 8.461218, -4.00046, -12.98403, 11.867559, -2.6523442, -14.783697, 8.461218, -4.490066, -17.444958, 7.1948566, -5.8935885, -15.201872, 8.461218, -4.00046, -14.783697, 8.461218, -4.490066, -14.783697, 8.461218, -4.490066, -12.98403, 11.867559, -2.6523442, -13.081631, 11.866107, -2.811812, -17.003992, 7.1948566, -6.4095883, -18.123537, 7.0190673, -6.536556, -17.444958, 7.1948566, -5.8935885, -17.444958, 7.1948566, -5.8935885, -14.783697, 8.461218, -4.490066, -17.003992, 7.1948566, -6.4095883, -17.003992, 7.1948566, -6.4095883, -17.845564, 7.0190673, -6.8616605, -18.123537, 7.0190673, -6.536556, -14.783697, 8.461218, -4.490066, -13.081631, 11.866107, -2.811812, -14.935968, 8.948875, -4.8818517, -17.003992, 7.1948566, -6.4095883, -14.783697, 8.461218, -4.490066, -14.935968, 8.948875, -4.8818517, -14.935968, 8.948875, -4.8818517, -13.081631, 11.866107, -2.811812, -13.263538, 11.865139, -2.7679238, -14.935968, 8.948875, -4.8818517, -13.263538, 11.865139, -2.7679238, -15.448719, 9.250092, -4.6346655, -17.003992, 7.1948566, -6.4095883, -14.935968, 8.948875, -4.8818517, -17.031534, 7.8040657, -6.7090955, -17.031534, 7.8040657, -6.7090955, -17.845564, 7.0190673, -6.8616605, -17.003992, 7.1948566, -6.4095883, -17.031534, 7.8040657, -6.7090955, -14.935968, 8.948875, -4.8818517, -15.448719, 9.250092, -4.6346655, -17.031534, 7.8040657, -6.7090955, -17.862965, 7.402608, -7.050143, -17.845564, 7.0190673, -6.8616605, -17.031534, 7.8040657, -6.7090955, -15.448719, 9.250092, -4.6346655, -17.48928, 8.179858, -6.3779426, -17.48928, 8.179858, -6.3779426, -17.862965, 7.402608, -7.050143, -17.031534, 7.8040657, -6.7090955, -17.48928, 8.179858, -6.3779426, -18.151243, 7.6394153, -6.841582, -17.862965, 7.402608, -7.050143, -9.569414, 12.023977, -1.423661, -10.217659, 13.714559, -4.1817064, -10.455915, 11.404599, -3.3882995, -10.455915, 11.404599, -3.3882995, -10.217659, 13.714559, -4.1817064, -13.040308, 13.727151, -5.3989296, -10.455915, 11.404599, -3.3882995, -13.040308, 13.727151, -5.3989296, -12.873928, 12.023979, -4.2461476, -9.569414, 12.023977, -1.423661, -8.701311, 13.727149, -1.6924205, -10.217659, 13.714559, -4.1817064, -10.752665, 11.468038, 0.7093334, -8.701311, 13.727149, -1.6924205, -9.569414, 12.023977, -1.423661, -10.217659, 13.714559, -4.1817064, -12.916918, 15.450177, -4.4462667, -13.040308, 13.727151, -5.3989296, -10.752665, 11.468038, 0.7093334, -10.345652, 13.765407, 0.48551416, -8.701311, 13.727149, -1.6924205, -13.194582, 12.102914, 1.4700174, -10.345652, 13.765407, 0.48551416, -10.752665, 11.468038, 0.7093334, -8.701311, 13.727149, -1.6924205, -11.285702, 16.050184, -3.7030501, -10.217659, 13.714559, -4.1817064, -10.217659, 13.714559, -4.1817064, -11.285702, 16.050184, -3.7030501, -12.916918, 15.450177, -4.4462667, -10.345652, 13.765407, 0.48551416, -10.15527, 15.450176, -2.0876474, -8.701311, 13.727149, -1.6924205, -8.701311, 13.727149, -1.6924205, -10.15527, 15.450176, -2.0876474, -11.285702, 16.050184, -3.7030501, -13.194582, 12.102914, 1.4700174, -13.23241, 13.80318, 1.6023726, -10.345652, 13.765407, 0.48551416, -13.23241, 13.80318, 1.6023726, -13.194582, 12.102914, 1.4700174, -15.388298, 11.531479, 1.0999866, -10.345652, 13.765407, 0.48551416, -11.1811695, 16.062777, -0.7989111, -10.15527, 15.450176, -2.0876474, -13.23241, 13.80318, 1.6023726, -11.1811695, 16.062777, -0.7989111, -10.345652, 13.765407, 0.48551416, -10.15527, 15.450176, -2.0876474, -12.708605, 16.828888, -2.2941785, -11.285702, 16.050184, -3.7030501, -10.15527, 15.450176, -2.0876474, -11.1811695, 16.062777, -0.7989111, -12.708605, 16.828888, -2.2941785, -13.23241, 13.80318, 1.6023726, -12.880806, 15.484076, 0.2096405, -11.1811695, 16.062777, -0.7989111, -13.23241, 13.80318, 1.6023726, -15.388298, 11.531479, 1.0999866, -15.443556, 13.8162565, 0.90737486, -12.880806, 15.484076, 0.2096405, -13.23241, 13.80318, 1.6023726, -15.443556, 13.8162565, 0.90737486, -15.443556, 13.8162565, 0.90737486, -15.388298, 11.531479, 1.0999866, -15.956232, 12.102915, -0.88860226, -11.1811695, 16.062777, -0.7989111, -12.880806, 15.484076, 0.2096405, -14.192514, 16.075851, -0.5573001, -12.880806, 15.484076, 0.2096405, -15.443556, 13.8162565, 0.90737486, -14.192514, 16.075851, -0.5573001, -11.1811695, 16.062777, -0.7989111, -14.192514, 16.075851, -0.5573001, -12.708605, 16.828888, -2.2941785, -15.443556, 13.8162565, 0.90737486, -15.956232, 12.102915, -0.88860226, -16.3484, 13.803182, -1.0596855, -14.192514, 16.075851, -0.5573001, -15.443556, 13.8162565, 0.90737486, -16.3484, 13.803182, -1.0596855, -15.09202, 11.4680395, -2.9977593, -16.3484, 13.803182, -1.0596855, -15.956232, 12.102915, -0.88860226, -12.708605, 16.828888, -2.2941785, -14.192514, 16.075851, -0.5573001, -15.09865, 15.4840765, -1.6848848, -14.192514, 16.075851, -0.5573001, -16.3484, 13.803182, -1.0596855, -15.09865, 15.4840765, -1.6848848, -15.09202, 11.4680395, -2.9977593, -15.31592, 13.7654085, -3.7604294, -16.3484, 13.803182, -1.0596855, -15.31592, 13.7654085, -3.7604294, -15.09865, 15.4840765, -1.6848848, -16.3484, 13.803182, -1.0596855, -12.873928, 12.023979, -4.2461476, -15.31592, 13.7654085, -3.7604294, -15.09202, 11.4680395, -2.9977593, -12.873928, 12.023979, -4.2461476, -13.040308, 13.727151, -5.3989296, -15.31592, 13.7654085, -3.7604294, -15.31592, 13.7654085, -3.7604294, -14.29763, 16.062777, -3.461082, -15.09865, 15.4840765, -1.6848848, -12.708605, 16.828888, -2.2941785, -15.09865, 15.4840765, -1.6848848, -14.29763, 16.062777, -3.461082, -13.040308, 13.727151, -5.3989296, -14.29763, 16.062777, -3.461082, -15.31592, 13.7654085, -3.7604294, -11.285702, 16.050184, -3.7030501, -12.708605, 16.828888, -2.2941785, -14.29763, 16.062777, -3.461082, -13.040308, 13.727151, -5.3989296, -12.916918, 15.450177, -4.4462667, -14.29763, 16.062777, -3.461082, -11.285702, 16.050184, -3.7030501, -14.29763, 16.062777, -3.461082, -12.916918, 15.450177, -4.4462667, -13.194582, 12.102914, 1.4700174, -12.95261, 10.701926, -0.98015237, -15.388298, 11.531479, 1.0999866, -13.194582, 12.102914, 1.4700174, -10.752665, 11.468038, 0.7093334, -12.95261, 10.701926, -0.98015237, -15.388298, 11.531479, 1.0999866, -12.95261, 10.701926, -0.98015237, -15.09202, 11.4680395, -2.9977593, -15.388298, 11.531479, 1.0999866, -15.09202, 11.4680395, -2.9977593, -15.956232, 12.102915, -0.88860226, -12.95261, 10.701926, -0.98015237, -12.873928, 12.023979, -4.2461476, -15.09202, 11.4680395, -2.9977593, -12.95261, 10.701926, -0.98015237, -10.455915, 11.404599, -3.3882995, -12.873928, 12.023979, -4.2461476, -10.752665, 11.468038, 0.7093334, -10.455915, 11.404599, -3.3882995, -12.95261, 10.701926, -0.98015237, -10.752665, 11.468038, 0.7093334, -9.569414, 12.023977, -1.423661, -10.455915, 11.404599, -3.3882995, -24.767572, 12.860314, -12.76874, -27.996283, 17.21195, -9.537579, -27.347048, 11.217676, -9.664753, -27.347048, 11.217676, -9.664753, -27.996283, 17.21195, -9.537579, -26.84493, 17.364494, -4.4035864, -27.347048, 11.217676, -9.664753, -26.84493, 17.364494, -4.4035864, -26.195316, 12.778957, -5.113938, -24.767572, 12.860314, -12.76874, -25.952778, 17.118486, -13.655661, -27.996283, 17.21195, -9.537579, -19.715057, 11.632692, -13.049604, -25.952778, 17.118486, -13.655661, -24.767572, 12.860314, -12.76874, -27.996283, 17.21195, -9.537579, -25.235796, 21.763588, -5.4189744, -26.84493, 17.364494, -4.4035864, -19.715057, 11.632692, -13.049604, -19.985107, 17.543673, -13.411457, -25.952778, 17.118486, -13.655661, -15.851015, 13.295669, -9.844912, -19.985107, 17.543673, -13.411457, -19.715057, 11.632692, -13.049604, -25.952778, 17.118486, -13.655661, -25.451134, 23.26482, -8.394608, -27.996283, 17.21195, -9.537579, -27.996283, 17.21195, -9.537579, -25.451134, 23.26482, -8.394608, -25.235796, 21.763588, -5.4189744, -19.985107, 17.543673, -13.411457, -24.42836, 21.654142, -11.237154, -25.952778, 17.118486, -13.655661, -25.952778, 17.118486, -13.655661, -24.42836, 21.654142, -11.237154, -25.451134, 23.26482, -8.394608, -15.851015, 13.295669, -9.844912, -14.828638, 17.862318, -10.214518, -19.985107, 17.543673, -13.411457, -14.828638, 17.862318, -10.214518, -15.851015, 13.295669, -9.844912, -15.215309, 11.512592, -5.5114245, -19.985107, 17.543673, -13.411457, -21.066832, 23.347628, -10.820686, -24.42836, 21.654142, -11.237154, -14.828638, 17.862318, -10.214518, -21.066832, 23.347628, -10.820686, -19.985107, 17.543673, -13.411457, -24.42836, 21.654142, -11.237154, -22.043024, 25.28228, -7.397609, -25.451134, 23.26482, -8.394608, -24.42836, 21.654142, -11.237154, -21.066832, 23.347628, -10.820686, -22.043024, 25.28228, -7.397609, -14.828638, 17.862318, -10.214518, -17.778353, 21.984411, -9.297602, -21.066832, 23.347628, -10.820686, -14.828638, 17.862318, -10.214518, -15.215309, 11.512592, -5.5114245, -15.219456, 17.447784, -5.475563, -17.778353, 21.984411, -9.297602, -14.828638, 17.862318, -10.214518, -15.219456, 17.447784, -5.475563, -15.219456, 17.447784, -5.475563, -15.215309, 11.512592, -5.5114245, -18.649284, 12.710672, -2.540853, -21.066832, 23.347628, -10.820686, -17.778353, 21.984411, -9.297602, -18.417158, 23.323898, -6.4548, -17.778353, 21.984411, -9.297602, -15.219456, 17.447784, -5.475563, -18.417158, 23.323898, -6.4548, -21.066832, 23.347628, -10.820686, -18.417158, 23.323898, -6.4548, -22.043024, 25.28228, -7.397609, -15.219456, 17.447784, -5.475563, -18.649284, 12.710672, -2.540853, -18.8043, 16.973686, -1.7518203, -18.417158, 23.323898, -6.4548, -15.219456, 17.447784, -5.475563, -18.8043, 16.973686, -1.7518203, -22.846716, 11.097576, -2.1269307, -18.8043, 16.973686, -1.7518203, -18.649284, 12.710672, -2.540853, -22.043024, 25.28228, -7.397609, -18.417158, 23.323898, -6.4548, -19.955843, 21.589733, -3.8300514, -18.417158, 23.323898, -6.4548, -18.8043, 16.973686, -1.7518203, -19.955843, 21.589733, -3.8300514, -22.846716, 11.097576, -2.1269307, -23.23016, 17.115578, -1.6015713, -18.8043, 16.973686, -1.7518203, -23.23016, 17.115578, -1.6015713, -19.955843, 21.589733, -3.8300514, -18.8043, 16.973686, -1.7518203, -26.195316, 12.778957, -5.113938, -23.23016, 17.115578, -1.6015713, -22.846716, 11.097576, -2.1269307, -26.195316, 12.778957, -5.113938, -26.84493, 17.364494, -4.4035864, -23.23016, 17.115578, -1.6015713, -23.23016, 17.115578, -1.6015713, -22.801462, 23.240604, -4.0287204, -19.955843, 21.589733, -3.8300514, -22.043024, 25.28228, -7.397609, -19.955843, 21.589733, -3.8300514, -22.801462, 23.240604, -4.0287204, -26.84493, 17.364494, -4.4035864, -22.801462, 23.240604, -4.0287204, -23.23016, 17.115578, -1.6015713, -25.451134, 23.26482, -8.394608, -22.043024, 25.28228, -7.397609, -22.801462, 23.240604, -4.0287204, -26.84493, 17.364494, -4.4035864, -25.235796, 21.763588, -5.4189744, -22.801462, 23.240604, -4.0287204, -25.451134, 23.26482, -8.394608, -22.801462, 23.240604, -4.0287204, -25.235796, 21.763588, -5.4189744, -15.851015, 13.295669, -9.844912, -21.172243, 9.376487, -7.615418, -15.215309, 11.512592, -5.5114245, -15.851015, 13.295669, -9.844912, -19.715057, 11.632692, -13.049604, -21.172243, 9.376487, -7.615418, -15.215309, 11.512592, -5.5114245, -21.172243, 9.376487, -7.615418, -22.846716, 11.097576, -2.1269307, -15.215309, 11.512592, -5.5114245, -22.846716, 11.097576, -2.1269307, -18.649284, 12.710672, -2.540853, -21.172243, 9.376487, -7.615418, -26.195316, 12.778957, -5.113938, -22.846716, 11.097576, -2.1269307, -21.172243, 9.376487, -7.615418, -27.347048, 11.217676, -9.664753, -26.195316, 12.778957, -5.113938, -19.715057, 11.632692, -13.049604, -27.347048, 11.217676, -9.664753, -21.172243, 9.376487, -7.615418, -19.715057, 11.632692, -13.049604, -24.767572, 12.860314, -12.76874, -27.347048, 11.217676, -9.664753, 15.271845, 5.6313887, -13.373863, 13.937893, 6.0420103, -12.526823, 15.02121, 5.4305525, -13.542078, 15.271845, 5.6313887, -13.373863, 14.216074, 6.202837, -12.404688, 13.937893, 6.0420103, -12.526823, 14.216074, 6.202837, -12.404688, 12.987471, 7.6002665, -11.386524, 13.937893, 6.0420103, -12.526823, 14.216074, 6.202837, -12.404688, 13.085402, 7.59974, -11.366533, 12.987471, 7.6002665, -11.386524, 13.937893, 6.0420103, -12.526823, 12.987471, 7.6002665, -11.386524, 12.938522, 7.601056, -11.299387, 15.02121, 5.4305525, -13.542078, 13.937893, 6.0420103, -12.526823, 13.863859, 5.781687, -12.314682, 13.937893, 6.0420103, -12.526823, 12.938522, 7.601056, -11.299387, 13.863859, 5.781687, -12.314682, 15.02121, 5.4305525, -13.542078, 13.863859, 5.781687, -12.314682, 15.012333, 5.1052136, -13.381706, 13.863859, 5.781687, -12.314682, 12.938522, 7.601056, -11.299387, 13.0058975, 7.601056, -11.22595, 15.012333, 5.1052136, -13.381706, 13.863859, 5.781687, -12.314682, 14.096357, 5.781687, -12.061455, 13.863859, 5.781687, -12.314682, 13.0058975, 7.601056, -11.22595, 14.096357, 5.781687, -12.061455, 15.012333, 5.1052136, -13.381706, 14.096357, 5.781687, -12.061455, 15.257576, 5.1052136, -13.11451, 14.096357, 5.781687, -12.061455, 13.0058975, 7.601056, -11.22595, 13.096874, 7.6002665, -11.26737, 15.257576, 5.1052136, -13.11451, 14.096357, 5.781687, -12.061455, 14.314171, 6.0420103, -12.116919, 14.096357, 5.781687, -12.061455, 13.096874, 7.6002665, -11.26737, 14.314171, 6.0420103, -12.116919, 14.314171, 6.0420103, -12.116919, 13.096874, 7.6002665, -11.26737, 13.085402, 7.59974, -11.366533, 15.257576, 5.1052136, -13.11451, 14.314171, 6.0420103, -12.116919, 15.41803, 5.4305525, -13.109793, 14.314171, 6.0420103, -12.116919, 13.085402, 7.59974, -11.366533, 14.216074, 6.202837, -12.404688, 15.41803, 5.4305525, -13.109793, 14.314171, 6.0420103, -12.116919, 14.216074, 6.202837, -12.404688, 15.41803, 5.4305525, -13.109793, 14.216074, 6.202837, -12.404688, 15.271845, 5.6313887, -13.373863, 14.601847, 3.21346, -14.363449, 15.050756, 5.7482576, -13.183859, 14.252024, 3.21346, -13.499159, 14.601847, 3.21346, -14.363449, 15.172541, 5.7845817, -13.503508, 15.050756, 5.7482576, -13.183859, 15.172541, 5.7845817, -13.503508, 15.235462, 8.294637, -13.186392, 15.050756, 5.7482576, -13.183859, 15.172541, 5.7845817, -13.503508, 15.288689, 8.303849, -13.328491, 15.235462, 8.294637, -13.186392, 15.050756, 5.7482576, -13.183859, 15.235462, 8.294637, -13.186392, 15.35397, 8.27937, -13.092552, 14.252024, 3.21346, -13.499159, 15.050756, 5.7482576, -13.183859, 15.317219, 5.689823, -12.974655, 15.050756, 5.7482576, -13.183859, 15.35397, 8.27937, -13.092552, 15.317219, 5.689823, -12.974655, 14.252024, 3.21346, -13.499159, 15.317219, 5.689823, -12.974655, 14.968065, 3.21346, -12.951441, 15.317219, 5.689823, -12.974655, 15.35397, 8.27937, -13.092552, 15.480734, 8.27937, -13.17668, 14.968065, 3.21346, -12.951441, 15.317219, 5.689823, -12.974655, 15.603647, 5.689823, -13.16474, 15.317219, 5.689823, -12.974655, 15.480734, 8.27937, -13.17668, 15.603647, 5.689823, -13.16474, 14.968065, 3.21346, -12.951441, 15.603647, 5.689823, -13.16474, 15.760677, 3.21346, -13.477451, 15.603647, 5.689823, -13.16474, 15.480734, 8.27937, -13.17668, 15.440304, 8.294637, -13.322334, 15.760677, 3.21346, -13.477451, 15.603647, 5.689823, -13.16474, 15.514393, 5.7482576, -13.491547, 15.603647, 5.689823, -13.16474, 15.440304, 8.294637, -13.322334, 15.514393, 5.7482576, -13.491547, 15.514393, 5.7482576, -13.491547, 15.440304, 8.294637, -13.322334, 15.288689, 8.303849, -13.328491, 15.760677, 3.21346, -13.477451, 15.514393, 5.7482576, -13.491547, 15.534151, 3.2134595, -14.350031, 15.514393, 5.7482576, -13.491547, 15.288689, 8.303849, -13.328491, 15.172541, 5.7845817, -13.503508, 15.534151, 3.2134595, -14.350031, 15.514393, 5.7482576, -13.491547, 15.172541, 5.7845817, -13.503508, 15.534151, 3.2134595, -14.350031, 15.172541, 5.7845817, -13.503508, 14.601847, 3.21346, -14.363449, 15.553728, 5.9588323, -13.311363, 17.159096, 6.3768234, -13.211996, 15.660074, 5.754575, -13.023067, 15.660074, 5.754575, -13.023067, 15.124199, 5.6650805, -13.219332, 15.553728, 5.9588323, -13.311363, 15.660074, 5.754575, -13.023067, 15.190983, 5.5363665, -13.037777, 15.124199, 5.6650805, -13.219332, 15.553728, 5.9588323, -13.311363, 17.002844, 6.540546, -13.478861, 17.159096, 6.3768234, -13.211996, 17.002844, 6.540546, -13.478861, 18.62324, 7.962454, -13.583435, 17.159096, 6.3768234, -13.211996, 17.002844, 6.540546, -13.478861, 18.554626, 7.9619274, -13.658262, 18.62324, 7.962454, -13.583435, 17.159096, 6.3768234, -13.211996, 18.62324, 7.962454, -13.583435, 18.715752, 7.9632435, -13.625875, 17.159096, 6.3768234, -13.211996, 18.715752, 7.9632435, -13.625875, 17.346697, 6.111762, -13.342499, 15.660074, 5.754575, -13.023067, 17.159096, 6.3768234, -13.211996, 17.346697, 6.111762, -13.342499, 17.346697, 6.111762, -13.342499, 18.715752, 7.9632435, -13.625875, 18.704063, 7.9632435, -13.726791, 15.762983, 5.4234457, -13.149805, 15.190983, 5.5363665, -13.037777, 15.660074, 5.754575, -13.023067, 15.660074, 5.754575, -13.023067, 17.346697, 6.111762, -13.342499, 15.762983, 5.4234457, -13.149805, 15.762983, 5.4234457, -13.149805, 15.255903, 5.327897, -13.117506, 15.190983, 5.5363665, -13.037777, 17.346697, 6.111762, -13.342499, 18.704063, 7.9632435, -13.726791, 17.30647, 6.111762, -13.690155, 15.762983, 5.4234457, -13.149805, 17.346697, 6.111762, -13.342499, 17.30647, 6.111762, -13.690155, 17.30647, 6.111762, -13.690155, 18.704063, 7.9632435, -13.726791, 18.604456, 7.962454, -13.746929, 15.72068, 5.4234457, -13.5163, 15.255903, 5.327897, -13.117506, 15.762983, 5.4234457, -13.149805, 15.762983, 5.4234457, -13.149805, 17.30647, 6.111762, -13.690155, 15.72068, 5.4234457, -13.5163, 15.72068, 5.4234457, -13.5163, 15.229303, 5.327897, -13.348473, 15.255903, 5.327897, -13.117506, 17.30647, 6.111762, -13.690155, 18.604456, 7.962454, -13.746929, 17.094133, 6.3768234, -13.774481, 15.72068, 5.4234457, -13.5163, 17.30647, 6.111762, -13.690155, 17.094133, 6.3768234, -13.774481, 17.094133, 6.3768234, -13.774481, 18.604456, 7.962454, -13.746929, 18.554626, 7.9619274, -13.658262, 17.094133, 6.3768234, -13.774481, 18.554626, 7.9619274, -13.658262, 17.002844, 6.540546, -13.478861, 15.72068, 5.4234457, -13.5163, 17.094133, 6.3768234, -13.774481, 15.591234, 5.754575, -13.61615, 15.591234, 5.754575, -13.61615, 15.229303, 5.327897, -13.348473, 15.72068, 5.4234457, -13.5163, 15.591234, 5.754575, -13.61615, 17.094133, 6.3768234, -13.774481, 17.002844, 6.540546, -13.478861, 15.591234, 5.754575, -13.61615, 15.147818, 5.5363665, -13.411282, 15.229303, 5.327897, -13.348473, 15.591234, 5.754575, -13.61615, 17.002844, 6.540546, -13.478861, 15.553728, 5.9588323, -13.311363, 15.553728, 5.9588323, -13.311363, 15.147818, 5.5363665, -13.411282, 15.591234, 5.754575, -13.61615, 15.553728, 5.9588323, -13.311363, 15.124199, 5.6650805, -13.219332, 15.147818, 5.5363665, -13.411282, 20.456669, 8.048263, -14.631794, 19.118647, 8.967159, -15.3941345, 19.346407, 7.711606, -15.0057125, 19.346407, 7.711606, -15.0057125, 19.118647, 8.967159, -15.3941345, 17.589626, 8.974004, -14.720594, 19.346407, 7.711606, -15.0057125, 17.589626, 8.974004, -14.720594, 18.110191, 8.048264, -14.360323, 20.456669, 8.048263, -14.631794, 20.670847, 8.974003, -15.076887, 19.118647, 8.967159, -15.3941345, 20.868176, 7.746087, -13.371468, 20.670847, 8.974003, -15.076887, 20.456669, 8.048263, -14.631794, 19.118647, 8.967159, -15.3941345, 18.014603, 9.910537, -14.417248, 17.589626, 8.974004, -14.720594, 20.868176, 7.746087, -13.371468, 20.929647, 8.994798, -13.616339, 20.670847, 8.974003, -15.076887, 20.26757, 8.091167, -12.117716, 20.929647, 8.994798, -13.616339, 20.868176, 7.746087, -13.371468, 20.670847, 8.974003, -15.076887, 18.914066, 10.236665, -14.791771, 19.118647, 8.967159, -15.3941345, 19.118647, 8.967159, -15.3941345, 18.914066, 10.236665, -14.791771, 18.014603, 9.910537, -14.417248, 20.929647, 8.994798, -13.616339, 19.975527, 9.910536, -14.644192, 20.670847, 8.974003, -15.076887, 20.670847, 8.974003, -15.076887, 19.975527, 9.910536, -14.644192, 18.914066, 10.236665, -14.791771, 20.26757, 8.091167, -12.117716, 20.306274, 9.015329, -12.053684, 20.929647, 8.994798, -13.616339, 20.306274, 9.015329, -12.053684, 20.26757, 8.091167, -12.117716, 19.308578, 7.78057, -11.381147, 20.929647, 8.994798, -13.616339, 20.10909, 10.243508, -13.758886, 19.975527, 9.910536, -14.644192, 20.306274, 9.015329, -12.053684, 20.10909, 10.243508, -13.758886, 20.929647, 8.994798, -13.616339, 19.975527, 9.910536, -14.644192, 18.948578, 10.659921, -13.703939, 18.914066, 10.236665, -14.791771, 19.975527, 9.910536, -14.644192, 20.10909, 10.243508, -13.758886, 18.948578, 10.659921, -13.703939, 20.306274, 9.015329, -12.053684, 19.881817, 9.928962, -12.708981, 20.10909, 10.243508, -13.758886, 20.306274, 9.015329, -12.053684, 19.308578, 7.78057, -11.381147, 19.211441, 9.022436, -11.43041, 19.881817, 9.928962, -12.708981, 20.306274, 9.015329, -12.053684, 19.211441, 9.022436, -11.43041, 19.211441, 9.022436, -11.43041, 19.308578, 7.78057, -11.381147, 18.306646, 8.091168, -11.890772, 20.10909, 10.243508, -13.758886, 19.881817, 9.928962, -12.708981, 19.091122, 10.250615, -12.470457, 19.881817, 9.928962, -12.708981, 19.211441, 9.022436, -11.43041, 19.091122, 10.250615, -12.470457, 20.10909, 10.243508, -13.758886, 19.091122, 10.250615, -12.470457, 18.948578, 10.659921, -13.703939, 19.211441, 9.022436, -11.43041, 18.306646, 8.091168, -11.890772, 18.093428, 9.015329, -11.79792, 19.091122, 10.250615, -12.470457, 19.211441, 9.022436, -11.43041, 18.093428, 9.015329, -11.79792, 17.78659, 7.746088, -13.015247, 18.093428, 9.015329, -11.79792, 18.306646, 8.091168, -11.890772, 18.948578, 10.659921, -13.703939, 19.091122, 10.250615, -12.470457, 18.306887, 9.928962, -12.526855, 19.091122, 10.250615, -12.470457, 18.093428, 9.015329, -11.79792, 18.306887, 9.928962, -12.526855, 17.78659, 7.746088, -13.015247, 17.400074, 8.994799, -13.208279, 18.093428, 9.015329, -11.79792, 17.400074, 8.994799, -13.208279, 18.306887, 9.928962, -12.526855, 18.093428, 9.015329, -11.79792, 18.110191, 8.048264, -14.360323, 17.400074, 8.994799, -13.208279, 17.78659, 7.746088, -13.015247, 18.110191, 8.048264, -14.360323, 17.589626, 8.974004, -14.720594, 17.400074, 8.994799, -13.208279, 17.400074, 8.994799, -13.208279, 17.896025, 10.243508, -13.502977, 18.306887, 9.928962, -12.526855, 18.948578, 10.659921, -13.703939, 18.306887, 9.928962, -12.526855, 17.896025, 10.243508, -13.502977, 17.589626, 8.974004, -14.720594, 17.896025, 10.243508, -13.502977, 17.400074, 8.994799, -13.208279, 18.914066, 10.236665, -14.791771, 18.948578, 10.659921, -13.703939, 17.896025, 10.243508, -13.502977, 17.589626, 8.974004, -14.720594, 18.014603, 9.910537, -14.417248, 17.896025, 10.243508, -13.502977, 18.914066, 10.236665, -14.791771, 17.896025, 10.243508, -13.502977, 18.014603, 9.910537, -14.417248, 20.26757, 8.091167, -12.117716, 19.381508, 7.3296757, -13.120605, 19.308578, 7.78057, -11.381147, 20.26757, 8.091167, -12.117716, 20.868176, 7.746087, -13.371468, 19.381508, 7.3296757, -13.120605, 19.308578, 7.78057, -11.381147, 19.381508, 7.3296757, -13.120605, 17.78659, 7.746088, -13.015247, 19.308578, 7.78057, -11.381147, 17.78659, 7.746088, -13.015247, 18.306646, 8.091168, -11.890772, 19.381508, 7.3296757, -13.120605, 18.110191, 8.048264, -14.360323, 17.78659, 7.746088, -13.015247, 19.381508, 7.3296757, -13.120605, 19.346407, 7.711606, -15.0057125, 18.110191, 8.048264, -14.360323, 20.868176, 7.746087, -13.371468, 19.346407, 7.711606, -15.0057125, 19.381508, 7.3296757, -13.120605, 20.868176, 7.746087, -13.371468, 20.456669, 8.048263, -14.631794, 19.346407, 7.711606, -15.0057125, 10.316184, 8.502844, -12.777889, 10.408148, 10.86813, -10.2968025, 10.597721, 7.6100063, -10.6023655, 10.597721, 7.6100063, -10.6023655, 10.408148, 10.86813, -10.2968025, 12.878351, 10.951043, -8.855707, 10.597721, 7.6100063, -10.6023655, 12.878351, 10.951043, -8.855707, 12.835861, 8.458624, -9.37719, 10.316184, 8.502844, -12.777889, 9.524521, 10.8173275, -12.634127, 10.408148, 10.86813, -10.2968025, 12.073738, 7.8355837, -14.893578, 9.524521, 10.8173275, -12.634127, 10.316184, 8.502844, -12.777889, 10.408148, 10.86813, -10.2968025, 13.069418, 13.342123, -9.872105, 12.878351, 10.951043, -8.855707, 12.073738, 7.8355837, -14.893578, 11.829742, 11.048433, -14.919933, 9.524521, 10.8173275, -12.634127, 14.779421, 8.739476, -15.246426, 11.829742, 11.048433, -14.919933, 12.073738, 7.8355837, -14.893578, 9.524521, 10.8173275, -12.634127, 11.80493, 14.158102, -10.887323, 10.408148, 10.86813, -10.2968025, 10.408148, 10.86813, -10.2968025, 11.80493, 14.158102, -10.887323, 13.069418, 13.342123, -9.872105, 11.829742, 11.048433, -14.919933, 11.051523, 13.282636, -12.346281, 9.524521, 10.8173275, -12.634127, 9.524521, 10.8173275, -12.634127, 11.051523, 13.282636, -12.346281, 11.80493, 14.158102, -10.887323, 14.779421, 8.739476, -15.246426, 15.010525, 11.22163, -15.7902565, 11.829742, 11.048433, -14.919933, 15.010525, 11.22163, -15.7902565, 14.779421, 8.739476, -15.246426, 16.7401, 7.770304, -13.896193, 11.829742, 11.048433, -14.919933, 12.461086, 14.203112, -13.530659, 11.051523, 13.282636, -12.346281, 15.010525, 11.22163, -15.7902565, 12.461086, 14.203112, -13.530659, 11.829742, 11.048433, -14.919933, 11.051523, 13.282636, -12.346281, 13.462879, 15.254671, -11.875458, 11.80493, 14.158102, -10.887323, 11.051523, 13.282636, -12.346281, 12.461086, 14.203112, -13.530659, 13.462879, 15.254671, -11.875458, 15.010525, 11.22163, -15.7902565, 14.284246, 13.462151, -14.276512, 12.461086, 14.203112, -13.530659, 15.010525, 11.22163, -15.7902565, 16.7401, 7.770304, -13.896193, 16.752848, 10.996315, -13.881273, 14.284246, 13.462151, -14.276512, 15.010525, 11.22163, -15.7902565, 16.752848, 10.996315, -13.881273, 16.752848, 10.996315, -13.881273, 16.7401, 7.770304, -13.896193, 16.65236, 8.421508, -11.429792, 12.461086, 14.203112, -13.530659, 14.284246, 13.462151, -14.276512, 15.179819, 14.190213, -12.970345, 14.284246, 13.462151, -14.276512, 16.752848, 10.996315, -13.881273, 15.179819, 14.190213, -12.970345, 12.461086, 14.203112, -13.530659, 15.179819, 14.190213, -12.970345, 13.462879, 15.254671, -11.875458, 16.752848, 10.996315, -13.881273, 16.65236, 8.421508, -11.429792, 16.909176, 10.738624, -11.076134, 15.179819, 14.190213, -12.970345, 16.752848, 10.996315, -13.881273, 16.909176, 10.738624, -11.076134, 15.264158, 7.544727, -9.605343, 16.909176, 10.738624, -11.076134, 16.65236, 8.421508, -11.429792, 13.462879, 15.254671, -11.875458, 15.179819, 14.190213, -12.970345, 15.655621, 13.247626, -11.386549, 15.179819, 14.190213, -12.970345, 16.909176, 10.738624, -11.076134, 15.655621, 13.247626, -11.386549, 15.264158, 7.544727, -9.605343, 15.3314705, 10.815748, -9.258287, 16.909176, 10.738624, -11.076134, 15.3314705, 10.815748, -9.258287, 15.655621, 13.247626, -11.386549, 16.909176, 10.738624, -11.076134, 12.835861, 8.458624, -9.37719, 15.3314705, 10.815748, -9.258287, 15.264158, 7.544727, -9.605343, 12.835861, 8.458624, -9.37719, 12.878351, 10.951043, -8.855707, 15.3314705, 10.815748, -9.258287, 15.3314705, 10.815748, -9.258287, 14.523663, 14.14494, -10.327007, 15.655621, 13.247626, -11.386549, 13.462879, 15.254671, -11.875458, 15.655621, 13.247626, -11.386549, 14.523663, 14.14494, -10.327007, 12.878351, 10.951043, -8.855707, 14.523663, 14.14494, -10.327007, 15.3314705, 10.815748, -9.258287, 11.80493, 14.158102, -10.887323, 13.462879, 15.254671, -11.875458, 14.523663, 14.14494, -10.327007, 12.878351, 10.951043, -8.855707, 13.069418, 13.342123, -9.872105, 14.523663, 14.14494, -10.327007, 11.80493, 14.158102, -10.887323, 14.523663, 14.14494, -10.327007, 13.069418, 13.342123, -9.872105, 14.779421, 8.739476, -15.246426, 13.698336, 6.609247, -12.302765, 16.7401, 7.770304, -13.896193, 14.779421, 8.739476, -15.246426, 12.073738, 7.8355837, -14.893578, 13.698336, 6.609247, -12.302765, 16.7401, 7.770304, -13.896193, 13.698336, 6.609247, -12.302765, 15.264158, 7.544727, -9.605343, 16.7401, 7.770304, -13.896193, 15.264158, 7.544727, -9.605343, 16.65236, 8.421508, -11.429792, 13.698336, 6.609247, -12.302765, 12.835861, 8.458624, -9.37719, 15.264158, 7.544727, -9.605343, 13.698336, 6.609247, -12.302765, 10.597721, 7.6100063, -10.6023655, 12.835861, 8.458624, -9.37719, 12.073738, 7.8355837, -14.893578, 10.597721, 7.6100063, -10.6023655, 13.698336, 6.609247, -12.302765, 12.073738, 7.8355837, -14.893578, 10.316184, 8.502844, -12.777889, 10.597721, 7.6100063, -10.6023655, 0.9335377, -18.661976, -2.173924, 1.8889831, -18.823338, -0.58916974, 1.5114222, -18.399822, -1.4170885, 0.9335377, -18.661976, -2.173924, 0.9335377, -18.661974, 1.0975094, 1.8889831, -18.823338, -0.58916974, 1.8889831, -18.823338, -0.58916974, 0.9335377, -18.661974, 1.0975094, 1.6508096, -18.476696, 0.3862325, -0.9279604, -18.475744, -2.1898937, 0.9335377, -18.661976, -2.173924, -0.001098156, -18.845234, -2.413155, -1.7685199, -18.399822, -0.5382087, 0.9335377, -18.661976, -2.173924, -0.9279604, -18.475744, -2.1898937, 0.9335377, -18.661974, 1.0975094, 0.9335377, -18.661976, -2.173924, -1.7685199, -18.399822, -0.5382087, -1.7685199, -18.399822, -0.5382087, -0.9279604, -18.475744, -2.1898937, -1.6464877, -18.661976, -1.4825313, 0.9335377, -18.661974, 1.0975094, -1.7685199, -18.399822, -0.5382087, -0.95520806, -18.661974, 1.0975094, -0.95520806, -18.661974, 1.0975094, -1.7685199, -18.399822, -0.5382087, -1.6464877, -18.661974, 0.40619445, 0.9335377, -18.661974, 1.0975094, -0.95520806, -18.661974, 1.0975094, -0.010835171, -18.399822, 1.2195511, 1.5114222, -18.399822, -1.4170885, -0.010835171, -14.884386, -0.5382099, 0.9335377, -18.661976, -2.173924, 0.9335377, -18.661976, -2.173924, -0.010835171, -14.884386, -0.5382099, -0.001098156, -18.845234, -2.413155, -0.001098156, -18.845234, -2.413155, -0.010835171, -14.884386, -0.5382099, -0.9279604, -18.475744, -2.1898937, -0.9279604, -18.475744, -2.1898937, -0.010835171, -14.884386, -0.5382099, -1.6464877, -18.661976, -1.4825313, -1.6464877, -18.661976, -1.4825313, -0.010835171, -14.884386, -0.5382099, -1.7685199, -18.399822, -0.5382087, -1.7685199, -18.399822, -0.5382087, -0.010835171, -14.884386, -0.5382099, -1.6464877, -18.661974, 0.40619445, -1.6464877, -18.661974, 0.40619445, -0.010835171, -14.884386, -0.5382099, -0.95520806, -18.661974, 1.0975094, -0.95520806, -18.661974, 1.0975094, -0.010835171, -14.884386, -0.5382099, -0.010835171, -18.399822, 1.2195511, -0.010835171, -18.399822, 1.2195511, -0.010835171, -14.884386, -0.5382099, 0.9335377, -18.661974, 1.0975094, 0.9335377, -18.661974, 1.0975094, -0.010835171, -14.884386, -0.5382099, 1.6508096, -18.476696, 0.3862325, 1.6508096, -18.476696, 0.3862325, -0.010835171, -14.884386, -0.5382099, 1.8889831, -18.823338, -0.58916974, 1.8889831, -18.823338, -0.58916974, -0.010835171, -14.884386, -0.5382099, 1.5114222, -18.399822, -1.4170885, 0.79053855, -17.29707, -2.0162632, 1.2353985, -16.7235, -0.5382092, 1.198884, -17.024681, -1.2366474, 0.79053855, -17.29707, -2.0162632, 0.4979446, -16.83131, 0.34912467, 1.2353985, -16.7235, -0.5382092, 1.2353985, -16.7235, -0.5382092, 0.4979446, -16.83131, 0.34912467, 1.198884, -17.024681, 0.16022909, 0.4979446, -16.83131, 0.34912467, -0.88492775, -17.22686, 1.0175039, -0.010835171, -17.024681, 0.8586674, 0.4979446, -16.83131, 0.34912467, -1.2205544, -17.024681, 0.16022909, -0.88492775, -17.22686, 1.0175039, 0.79053855, -17.29707, -2.0162632, -1.2205544, -17.024681, 0.16022909, 0.4979446, -16.83131, 0.34912467, -1.2205544, -17.024681, 0.16022909, 0.79053855, -17.29707, -2.0162632, -0.6996014, -16.880219, -1.4757214, -0.6996014, -16.880219, -1.4757214, 0.79053855, -17.29707, -2.0162632, -0.010835171, -17.024681, -1.9350855, -1.2205544, -17.024681, 0.16022909, -0.6996014, -16.880219, -1.4757214, -1.2205544, -17.024681, -1.2366474, -1.2205544, -17.024681, 0.16022909, -1.2205544, -17.024681, -1.2366474, -1.5400834, -17.234833, -0.5375037, 1.198884, -17.024681, -1.2366474, -0.010835171, -14.231086, -0.53821015, 0.79053855, -17.29707, -2.0162632, 0.79053855, -17.29707, -2.0162632, -0.010835171, -14.231086, -0.53821015, -0.010835171, -17.024681, -1.9350855, -0.010835171, -17.024681, -1.9350855, -0.010835171, -14.231086, -0.53821015, -0.6996014, -16.880219, -1.4757214, -0.6996014, -16.880219, -1.4757214, -0.010835171, -14.231086, -0.53821015, -1.2205544, -17.024681, -1.2366474, -1.2205544, -17.024681, -1.2366474, -0.010835171, -14.231086, -0.53821015, -1.5400834, -17.234833, -0.5375037, -1.5400834, -17.234833, -0.5375037, -0.010835171, -14.231086, -0.53821015, -1.2205544, -17.024681, 0.16022909, -1.2205544, -17.024681, 0.16022909, -0.010835171, -14.231086, -0.53821015, -0.88492775, -17.22686, 1.0175039, -0.88492775, -17.22686, 1.0175039, -0.010835171, -14.231086, -0.53821015, -0.010835171, -17.024681, 0.8586674, -0.010835171, -17.024681, 0.8586674, -0.010835171, -14.231086, -0.53821015, 0.4979446, -16.83131, 0.34912467, 0.4979446, -16.83131, 0.34912467, -0.010835171, -14.231086, -0.53821015, 1.198884, -17.024681, 0.16022909, 1.198884, -17.024681, 0.16022909, -0.010835171, -14.231086, -0.53821015, 1.2353985, -16.7235, -0.5382092, 1.2353985, -16.7235, -0.5382092, -0.010835171, -14.231086, -0.53821015, 1.198884, -17.024681, -1.2366474, 1.3094504, -20.552734, -2.7694182, 2.5816762, -20.552734, -0.51041746, 2.2008963, -20.875694, -1.8151531, 1.3094504, -20.552734, -2.7694182, 1.2661028, -20.875694, 1.6735137, 2.5816762, -20.552734, -0.51041746, 2.5816762, -20.552734, -0.51041746, 1.2661028, -20.875694, 1.6735137, 2.2298722, -20.624132, 0.7323996, -1.2877731, -20.875696, -2.7499266, 1.3094504, -20.552734, -2.7694182, -0.039105892, -21.061094, -3.1164474, -2.5646338, -20.875694, -0.53820777, 1.3094504, -20.552734, -2.7694182, -1.2877731, -20.875696, -2.7499266, 1.2661028, -20.875694, 1.6735137, 1.3094504, -20.552734, -2.7694182, -2.5646338, -20.875694, -0.53820777, -2.5646338, -20.875694, -0.53820777, -1.2877731, -20.875696, -2.7499266, -2.1870723, -20.562729, -1.6952248, 1.2661028, -20.875694, 1.6735137, -2.5646338, -20.875694, -0.53820777, -1.2877731, -20.875694, 1.6735137, -1.2877731, -20.875694, 1.6735137, -2.5646338, -20.875694, -0.53820777, -2.1694045, -20.59831, 0.7562758, 1.2661028, -20.875694, 1.6735137, -1.2877731, -20.875694, 1.6735137, -0.033530712, -21.08287, 2.0138073, 2.2008963, -20.875694, -1.8151531, -0.010835171, -15.767945, -0.5382097, 1.3094504, -20.552734, -2.7694182, 1.3094504, -20.552734, -2.7694182, -0.010835171, -15.767945, -0.5382097, -0.039105892, -21.061094, -3.1164474, -0.039105892, -21.061094, -3.1164474, -0.010835171, -15.767945, -0.5382097, -1.2877731, -20.875696, -2.7499266, -1.2877731, -20.875696, -2.7499266, -0.010835171, -15.767945, -0.5382097, -2.1870723, -20.562729, -1.6952248, -2.1870723, -20.562729, -1.6952248, -0.010835171, -15.767945, -0.5382097, -2.5646338, -20.875694, -0.53820777, -2.5646338, -20.875694, -0.53820777, -0.010835171, -15.767945, -0.5382097, -2.1694045, -20.59831, 0.7562758, -2.1694045, -20.59831, 0.7562758, -0.010835171, -15.767945, -0.5382097, -1.2877731, -20.875694, 1.6735137, -1.2877731, -20.875694, 1.6735137, -0.010835171, -15.767945, -0.5382097, -0.033530712, -21.08287, 2.0138073, -0.033530712, -21.08287, 2.0138073, -0.010835171, -15.767945, -0.5382097, 1.2661028, -20.875694, 1.6735137, 1.2661028, -20.875694, 1.6735137, -0.010835171, -15.767945, -0.5382097, 2.2298722, -20.624132, 0.7323996, 2.2298722, -20.624132, 0.7323996, -0.010835171, -15.767945, -0.5382097, 2.5816762, -20.552734, -0.51041746, 2.5816762, -20.552734, -0.51041746, -0.010835171, -15.767945, -0.5382097, 2.2008963, -20.875694, -1.8151531, 0.5583327, -21.275528, -0.82769513, 0.37442207, -20.354485, -1.1662683, 0.31780314, -21.275528, -1.0682597, 0.5583327, -21.275528, -0.82769513, 0.65641344, -20.354485, -0.8842943, 0.37442207, -20.354485, -1.1662683, 0.6890812, -22.029617, -0.9031601, 0.5583327, -21.275528, -0.82769513, 0.31780314, -21.275528, -1.0682597, 0.6890812, -22.029617, -0.9031601, 0.31780314, -21.275528, -1.0682597, 0.39326835, -22.029617, -1.1989906, 0.31780314, -21.275528, -1.0682597, -0.010835171, -20.354485, -1.2695241, -0.010835171, -21.275528, -1.1563258, 0.31780314, -21.275528, -1.0682597, 0.37442207, -20.354485, -1.1662683, -0.010835171, -20.354485, -1.2695241, 0.39326835, -22.029617, -1.1989906, 0.31780314, -21.275528, -1.0682597, -0.010835171, -21.275528, -1.1563258, 0.39326835, -22.029617, -1.1989906, -0.010835171, -21.275528, -1.1563258, -0.010835171, -22.029617, -1.307256, -0.010835171, -21.275528, -1.1563258, -0.3960147, -20.354485, -1.1662683, -0.339396, -21.275528, -1.0682597, -0.010835171, -21.275528, -1.1563258, -0.010835171, -20.354485, -1.2695241, -0.3960147, -20.354485, -1.1662683, -0.010835171, -22.029617, -1.307256, -0.010835171, -21.275528, -1.1563258, -0.339396, -21.275528, -1.0682597, -0.010835171, -22.029617, -1.307256, -0.339396, -21.275528, -1.0682597, -0.4148612, -22.029617, -1.1989906, -0.339396, -21.275528, -1.0682597, -0.6780064, -20.354485, -0.8842943, -0.580003, -21.275528, -0.82769513, -0.339396, -21.275528, -1.0682597, -0.3960147, -20.354485, -1.1662683, -0.6780064, -20.354485, -0.8842943, -0.4148612, -22.029617, -1.1989906, -0.339396, -21.275528, -1.0682597, -0.580003, -21.275528, -0.82769513, -0.4148612, -22.029617, -1.1989906, -0.580003, -21.275528, -0.82769513, -0.71067405, -22.029617, -0.9031601, -0.580003, -21.275528, -0.82769513, -0.78126955, -20.354485, -0.49906468, -0.6680341, -21.275528, -0.49906445, -0.580003, -21.275528, -0.82769513, -0.6780064, -20.354485, -0.8842943, -0.78126955, -20.354485, -0.49906468, -0.71067405, -22.029617, -0.9031601, -0.580003, -21.275528, -0.82769513, -0.6680341, -21.275528, -0.49906445, -0.71067405, -22.029617, -0.9031601, -0.6680341, -21.275528, -0.49906445, -0.8189645, -22.029617, -0.49906397, -0.6680341, -21.275528, -0.49906445, -0.6780064, -20.354485, -0.11391497, -0.580003, -21.275528, -0.17051363, -0.6680341, -21.275528, -0.49906445, -0.78126955, -20.354485, -0.49906468, -0.6780064, -20.354485, -0.11391497, -0.8189645, -22.029617, -0.49906397, -0.6680341, -21.275528, -0.49906445, -0.580003, -21.275528, -0.17051363, -0.8189645, -22.029617, -0.49906397, -0.580003, -21.275528, -0.17051363, -0.71067405, -22.029617, -0.09504819, -0.580003, -21.275528, -0.17051363, -0.3960147, -20.354485, 0.16813636, -0.339396, -21.275528, 0.07004857, -0.580003, -21.275528, -0.17051363, -0.6780064, -20.354485, -0.11391497, -0.3960147, -20.354485, 0.16813636, -0.71067405, -22.029617, -0.09504819, -0.580003, -21.275528, -0.17051363, -0.339396, -21.275528, 0.07004857, -0.71067405, -22.029617, -0.09504819, -0.339396, -21.275528, 0.07004857, -0.4148612, -22.029617, 0.2007823, -0.339396, -21.275528, 0.07004857, -0.010835171, -20.354485, 0.27131462, -0.010835171, -21.275528, 0.15811706, -0.339396, -21.275528, 0.07004857, -0.3960147, -20.354485, 0.16813636, -0.010835171, -20.354485, 0.27131462, -0.4148612, -22.029617, 0.2007823, -0.339396, -21.275528, 0.07004857, -0.010835171, -21.275528, 0.15811706, -0.4148612, -22.029617, 0.2007823, -0.010835171, -21.275528, 0.15811706, -0.010835171, -22.029617, 0.3090477, -0.010835171, -21.275528, 0.15811706, 0.37442207, -20.354485, 0.16813636, 0.31780314, -21.275528, 0.07004857, -0.010835171, -21.275528, 0.15811706, -0.010835171, -20.354485, 0.27131462, 0.37442207, -20.354485, 0.16813636, -0.010835171, -22.029617, 0.3090477, -0.010835171, -21.275528, 0.15811706, 0.31780314, -21.275528, 0.07004857, -0.010835171, -22.029617, 0.3090477, 0.31780314, -21.275528, 0.07004857, 0.39326835, -22.029617, 0.2007823, 0.31780314, -21.275528, 0.07004857, 0.65641344, -20.354485, -0.11391497, 0.5583327, -21.275528, -0.17051363, 0.31780314, -21.275528, 0.07004857, 0.37442207, -20.354485, 0.16813636, 0.65641344, -20.354485, -0.11391497, 0.39326835, -22.029617, 0.2007823, 0.31780314, -21.275528, 0.07004857, 0.5583327, -21.275528, -0.17051363, 0.39326835, -22.029617, 0.2007823, 0.5583327, -21.275528, -0.17051363, 0.6890812, -22.029617, -0.09504819, 0.5583327, -21.275528, -0.17051363, 0.759599, -20.354485, -0.49906468, 0.64644134, -21.275528, -0.49906445, 0.5583327, -21.275528, -0.17051363, 0.65641344, -20.354485, -0.11391497, 0.759599, -20.354485, -0.49906468, 0.6890812, -22.029617, -0.09504819, 0.5583327, -21.275528, -0.17051363, 0.64644134, -21.275528, -0.49906445, 0.6890812, -22.029617, -0.09504819, 0.64644134, -21.275528, -0.49906445, 0.7973716, -22.029617, -0.49906397, 0.64644134, -21.275528, -0.49906445, 0.65641344, -20.354485, -0.8842943, 0.5583327, -21.275528, -0.82769513, 0.64644134, -21.275528, -0.49906445, 0.759599, -20.354485, -0.49906468, 0.65641344, -20.354485, -0.8842943, 0.7973716, -22.029617, -0.49906397, 0.64644134, -21.275528, -0.49906445, 0.5583327, -21.275528, -0.82769513, 0.7973716, -22.029617, -0.49906397, 0.5583327, -21.275528, -0.82769513, 0.6890812, -22.029617, -0.9031601, 0.39326835, -22.029617, -1.1989906, -0.010835171, -22.029617, -0.49906397, 0.6890812, -22.029617, -0.9031601, 0.6890812, -22.029617, -0.9031601, -0.010835171, -22.029617, -0.49906397, 0.7973716, -22.029617, -0.49906397, -0.010835171, -22.029617, -1.307256, -0.010835171, -22.029617, -0.49906397, 0.39326835, -22.029617, -1.1989906, 0.7973716, -22.029617, -0.49906397, -0.010835171, -22.029617, -0.49906397, 0.6890812, -22.029617, -0.09504819, -0.4148612, -22.029617, -1.1989906, -0.010835171, -22.029617, -0.49906397, -0.010835171, -22.029617, -1.307256, 0.6890812, -22.029617, -0.09504819, -0.010835171, -22.029617, -0.49906397, 0.39326835, -22.029617, 0.2007823, -0.71067405, -22.029617, -0.9031601, -0.010835171, -22.029617, -0.49906397, -0.4148612, -22.029617, -1.1989906, 0.39326835, -22.029617, 0.2007823, -0.010835171, -22.029617, -0.49906397, -0.010835171, -22.029617, 0.3090477, -0.8189645, -22.029617, -0.49906397, -0.010835171, -22.029617, -0.49906397, -0.71067405, -22.029617, -0.9031601, -0.010835171, -22.029617, 0.3090477, -0.010835171, -22.029617, -0.49906397, -0.4148612, -22.029617, 0.2007823, -0.71067405, -22.029617, -0.09504819, -0.010835171, -22.029617, -0.49906397, -0.8189645, -22.029617, -0.49906397, -0.4148612, -22.029617, 0.2007823, -0.010835171, -22.029617, -0.49906397, -0.71067405, -22.029617, -0.09504819, 9.266797, -17.581049, 9.7409115, 10.985607, -16.33984, 10.792019, 10.863857, -18.049467, 10.526733, 10.863857, -18.049467, 10.526733, 10.985607, -16.33984, 10.792019, 13.068386, -16.296267, 9.768465, 10.863857, -18.049467, 10.526733, 13.068386, -16.296267, 9.768465, 12.696516, -17.604118, 9.563199, 9.266797, -17.581049, 9.7409115, 9.008772, -16.366539, 10.340904, 10.985607, -16.33984, 10.792019, 8.624725, -17.931135, 7.6034517, 9.008772, -16.366539, 10.340904, 9.266797, -17.581049, 9.7409115, 10.985607, -16.33984, 10.792019, 12.4669, -15.041601, 9.18321, 13.068386, -16.296267, 9.768465, 8.624725, -17.931135, 7.6034517, 8.497637, -16.245218, 7.7565994, 9.008772, -16.366539, 10.340904, 9.600649, -17.456738, 5.615509, 8.497637, -16.245218, 7.7565994, 8.624725, -17.931135, 7.6034517, 9.008772, -16.366539, 10.340904, 11.213087, -14.61334, 9.582636, 10.985607, -16.33984, 10.792019, 10.985607, -16.33984, 10.792019, 11.213087, -14.61334, 9.582636, 12.4669, -15.041601, 9.18321, 8.497637, -16.245218, 7.7565994, 9.8885765, -15.072786, 9.437603, 9.008772, -16.366539, 10.340904, 9.008772, -16.366539, 10.340904, 9.8885765, -15.072786, 9.437603, 11.213087, -14.61334, 9.582636, 9.600649, -17.456738, 5.615509, 9.33643, -16.15444, 5.2154427, 8.497637, -16.245218, 7.7565994, 9.33643, -16.15444, 5.2154427, 9.600649, -17.456738, 5.615509, 11.392937, -17.965525, 4.8956895, 8.497637, -16.245218, 7.7565994, 9.720263, -14.589846, 7.952894, 9.8885765, -15.072786, 9.437603, 9.33643, -16.15444, 5.2154427, 9.720263, -14.589846, 7.952894, 8.497637, -16.245218, 7.7565994, 9.8885765, -15.072786, 9.437603, 11.288914, -14.037912, 8.018254, 11.213087, -14.61334, 9.582636, 9.8885765, -15.072786, 9.437603, 9.720263, -14.589846, 7.952894, 11.288914, -14.037912, 8.018254, 9.33643, -16.15444, 5.2154427, 10.034036, -14.978592, 6.3855233, 9.720263, -14.589846, 7.952894, 9.33643, -16.15444, 5.2154427, 11.392937, -17.965525, 4.8956895, 11.408957, -16.27256, 4.8937664, 10.034036, -14.978592, 6.3855233, 9.33643, -16.15444, 5.2154427, 11.408957, -16.27256, 4.8937664, 11.408957, -16.27256, 4.8937664, 11.392937, -17.965525, 4.8956895, 13.021395, -17.62377, 6.061926, 9.720263, -14.589846, 7.952894, 10.034036, -14.978592, 6.3855233, 11.318819, -14.596681, 6.3662996, 10.034036, -14.978592, 6.3855233, 11.408957, -16.27256, 4.8937664, 11.318819, -14.596681, 6.3662996, 9.720263, -14.589846, 7.952894, 11.318819, -14.596681, 6.3662996, 11.288914, -14.037912, 8.018254, 11.408957, -16.27256, 4.8937664, 13.021395, -17.62377, 6.061926, 13.375538, -16.407764, 6.04676, 11.318819, -14.596681, 6.3662996, 11.408957, -16.27256, 4.8937664, 13.375538, -16.407764, 6.04676, 13.632067, -18.083643, 7.819184, 13.375538, -16.407764, 6.04676, 13.021395, -17.62377, 6.061926, 11.288914, -14.037912, 8.018254, 11.318819, -14.596681, 6.3662996, 12.603388, -15.091156, 6.7550454, 11.318819, -14.596681, 6.3662996, 13.375538, -16.407764, 6.04676, 12.603388, -15.091156, 6.7550454, 13.632067, -18.083643, 7.819184, 13.896927, -16.367395, 7.9291854, 13.375538, -16.407764, 6.04676, 13.896927, -16.367395, 7.9291854, 12.603388, -15.091156, 6.7550454, 13.375538, -16.407764, 6.04676, 12.696516, -17.604118, 9.563199, 13.896927, -16.367395, 7.9291854, 13.632067, -18.083643, 7.819184, 12.696516, -17.604118, 9.563199, 13.068386, -16.296267, 9.768465, 13.896927, -16.367395, 7.9291854, 13.896927, -16.367395, 7.9291854, 12.811857, -14.620176, 7.996041, 12.603388, -15.091156, 6.7550454, 11.288914, -14.037912, 8.018254, 12.603388, -15.091156, 6.7550454, 12.811857, -14.620176, 7.996041, 13.068386, -16.296267, 9.768465, 12.811857, -14.620176, 7.996041, 13.896927, -16.367395, 7.9291854, 11.213087, -14.61334, 9.582636, 11.288914, -14.037912, 8.018254, 12.811857, -14.620176, 7.996041, 13.068386, -16.296267, 9.768465, 12.4669, -15.041601, 9.18321, 12.811857, -14.620176, 7.996041, 11.213087, -14.61334, 9.582636, 12.811857, -14.620176, 7.996041, 12.4669, -15.041601, 9.18321, 9.600649, -17.456738, 5.615509, 11.105434, -18.574488, 7.6675305, 11.392937, -17.965525, 4.8956895, 9.600649, -17.456738, 5.615509, 8.624725, -17.931135, 7.6034517, 11.105434, -18.574488, 7.6675305, 11.392937, -17.965525, 4.8956895, 11.105434, -18.574488, 7.6675305, 13.632067, -18.083643, 7.819184, 11.392937, -17.965525, 4.8956895, 13.632067, -18.083643, 7.819184, 13.021395, -17.62377, 6.061926, 11.105434, -18.574488, 7.6675305, 12.696516, -17.604118, 9.563199, 13.632067, -18.083643, 7.819184, 11.105434, -18.574488, 7.6675305, 10.863857, -18.049467, 10.526733, 12.696516, -17.604118, 9.563199, 8.624725, -17.931135, 7.6034517, 10.863857, -18.049467, 10.526733, 11.105434, -18.574488, 7.6675305, 8.624725, -17.931135, 7.6034517, 9.266797, -17.581049, 9.7409115, 10.863857, -18.049467, 10.526733, 7.21563, -18.140032, 8.584928, 8.205864, -17.407396, 9.311369, 8.061045, -18.408522, 8.982858, 8.061045, -18.408522, 8.982858, 8.205864, -17.407396, 9.311369, 9.478685, -17.401842, 8.917924, 8.061045, -18.408522, 8.982858, 9.478685, -17.401842, 8.917924, 9.09955, -18.140032, 8.584928, 7.21563, -18.140032, 8.584928, 7.005238, -17.401842, 8.917924, 8.205864, -17.407396, 9.311369, 7.005238, -18.380968, 7.5489845, 7.005238, -17.401842, 8.917924, 7.21563, -18.140032, 8.584928, 8.205864, -17.407396, 9.311369, 9.169825, -16.65511, 8.638754, 9.478685, -17.401842, 8.917924, 7.005238, -18.380968, 7.5489845, 6.93411, -17.385181, 7.7371626, 7.005238, -17.401842, 8.917924, 7.595832, -18.105644, 6.610869, 6.93411, -17.385181, 7.7371626, 7.005238, -18.380968, 7.5489845, 7.005238, -17.401842, 8.917924, 8.423091, -16.394949, 8.852991, 8.205864, -17.407396, 9.311369, 8.205864, -17.407396, 9.311369, 8.423091, -16.394949, 8.852991, 9.169825, -16.65511, 8.638754, 6.93411, -17.385181, 7.7371626, 7.595832, -16.65511, 8.638754, 7.005238, -17.401842, 8.917924, 7.005238, -17.401842, 8.917924, 7.595832, -16.65511, 8.638754, 8.423091, -16.394949, 8.852991, 7.595832, -18.105644, 6.610869, 7.571055, -17.368736, 6.5566154, 6.93411, -17.385181, 7.7371626, 7.571055, -17.368736, 6.5566154, 7.595832, -18.105644, 6.610869, 8.423091, -18.353416, 6.1153255, 6.93411, -17.385181, 7.7371626, 7.571055, -16.389395, 7.925341, 7.595832, -16.65511, 8.638754, 7.571055, -17.368736, 6.5566154, 7.571055, -16.389395, 7.925341, 6.93411, -17.385181, 7.7371626, 7.595832, -16.65511, 8.638754, 8.495287, -16.05768, 7.988138, 8.423091, -16.394949, 8.852991, 7.595832, -16.65511, 8.638754, 7.571055, -16.389395, 7.925341, 8.495287, -16.05768, 7.988138, 7.571055, -17.368736, 6.5566154, 7.847235, -16.640371, 7.1145287, 7.571055, -16.389395, 7.925341, 7.571055, -17.368736, 6.5566154, 8.423091, -18.353416, 6.1153255, 8.495287, -17.363182, 6.1631703, 7.847235, -16.640371, 7.1145287, 7.571055, -17.368736, 6.5566154, 8.495287, -17.363182, 6.1631703, 8.495287, -17.363182, 6.1631703, 8.423091, -18.353416, 6.1153255, 9.169825, -18.105644, 6.610869, 7.571055, -16.389395, 7.925341, 7.847235, -16.640371, 7.1145287, 8.495287, -16.384056, 6.9979053, 7.847235, -16.640371, 7.1145287, 8.495287, -17.363182, 6.1631703, 8.495287, -16.384056, 6.9979053, 7.571055, -16.389395, 7.925341, 8.495287, -16.384056, 6.9979053, 8.495287, -16.05768, 7.988138, 8.495287, -17.363182, 6.1631703, 9.169825, -18.105644, 6.610869, 9.347322, -17.368736, 6.5566154, 8.495287, -16.384056, 6.9979053, 8.495287, -17.363182, 6.1631703, 9.347322, -17.368736, 6.5566154, 9.478685, -18.380968, 7.5489845, 9.347322, -17.368736, 6.5566154, 9.169825, -18.105644, 6.610869, 8.495287, -16.05768, 7.988138, 8.495287, -16.384056, 6.9979053, 9.1112995, -16.640371, 7.1145287, 8.495287, -16.384056, 6.9979053, 9.347322, -17.368736, 6.5566154, 9.1112995, -16.640371, 7.1145287, 9.478685, -18.380968, 7.5489845, 9.767254, -17.385181, 7.7371626, 9.347322, -17.368736, 6.5566154, 9.767254, -17.385181, 7.7371626, 9.1112995, -16.640371, 7.1145287, 9.347322, -17.368736, 6.5566154, 9.09955, -18.140032, 8.584928, 9.767254, -17.385181, 7.7371626, 9.478685, -18.380968, 7.5489845, 9.09955, -18.140032, 8.584928, 9.478685, -17.401842, 8.917924, 9.767254, -17.385181, 7.7371626, 9.767254, -17.385181, 7.7371626, 9.347322, -16.389395, 7.925341, 9.1112995, -16.640371, 7.1145287, 8.495287, -16.05768, 7.988138, 9.1112995, -16.640371, 7.1145287, 9.347322, -16.389395, 7.925341, 9.478685, -17.401842, 8.917924, 9.347322, -16.389395, 7.925341, 9.767254, -17.385181, 7.7371626, 8.423091, -16.394949, 8.852991, 8.495287, -16.05768, 7.988138, 9.347322, -16.389395, 7.925341, 9.478685, -17.401842, 8.917924, 9.169825, -16.65511, 8.638754, 9.347322, -16.389395, 7.925341, 8.423091, -16.394949, 8.852991, 9.347322, -16.389395, 7.925341, 9.169825, -16.65511, 8.638754, 7.595832, -18.105644, 6.610869, 8.205864, -18.712898, 7.486401, 8.423091, -18.353416, 6.1153255, 7.595832, -18.105644, 6.610869, 7.005238, -18.380968, 7.5489845, 8.205864, -18.712898, 7.486401, 8.423091, -18.353416, 6.1153255, 8.205864, -18.712898, 7.486401, 9.478685, -18.380968, 7.5489845, 8.423091, -18.353416, 6.1153255, 9.478685, -18.380968, 7.5489845, 9.169825, -18.105644, 6.610869, 8.205864, -18.712898, 7.486401, 9.09955, -18.140032, 8.584928, 9.478685, -18.380968, 7.5489845, 8.205864, -18.712898, 7.486401, 8.061045, -18.408522, 8.982858, 9.09955, -18.140032, 8.584928, 7.005238, -18.380968, 7.5489845, 8.061045, -18.408522, 8.982858, 8.205864, -18.712898, 7.486401, 7.005238, -18.380968, 7.5489845, 7.21563, -18.140032, 8.584928, 8.061045, -18.408522, 8.982858, 11.220137, -19.80587, 7.9881396, 9.957781, -19.472874, 7.7623677, 11.16268, -19.969059, 7.7499795, 11.220137, -19.80587, 7.9881396, 10.0568905, -19.342154, 7.988139, 9.957781, -19.472874, 7.7623677, 10.0568905, -19.342154, 7.988139, 8.76399, -18.20817, 7.922565, 9.957781, -19.472874, 7.7623677, 10.0568905, -19.342154, 7.988139, 8.811623, -18.20881, 7.9881387, 8.76399, -18.20817, 7.922565, 9.957781, -19.472874, 7.7623677, 8.76399, -18.20817, 7.922565, 8.686882, -18.207743, 7.9475555, 11.16268, -19.969059, 7.7499795, 9.957781, -19.472874, 7.7623677, 9.797157, -19.68412, 7.848661, 9.957781, -19.472874, 7.7623677, 8.686882, -18.207743, 7.9475555, 9.797157, -19.68412, 7.848661, 11.16268, -19.969059, 7.7499795, 9.797157, -19.68412, 7.848661, 11.069338, -20.23285, 7.8409715, 9.797157, -19.68412, 7.848661, 8.686882, -18.207743, 7.9475555, 8.686882, -18.207743, 8.028723, 11.069338, -20.23285, 7.8409715, 9.797157, -19.68412, 7.848661, 9.797157, -19.68412, 8.127618, 9.797157, -19.68412, 7.848661, 8.686882, -18.207743, 8.028723, 9.797157, -19.68412, 8.127618, 11.069338, -20.23285, 7.8409715, 9.797157, -19.68412, 8.127618, 11.069338, -20.23285, 8.135094, 9.797157, -19.68412, 8.127618, 8.686882, -18.207743, 8.028723, 8.76399, -18.20817, 8.053713, 11.069338, -20.23285, 8.135094, 9.797157, -19.68412, 8.127618, 9.957781, -19.472874, 8.213911, 9.797157, -19.68412, 8.127618, 8.76399, -18.20817, 8.053713, 9.957781, -19.472874, 8.213911, 9.957781, -19.472874, 8.213911, 8.76399, -18.20817, 8.053713, 8.811623, -18.20881, 7.9881387, 11.069338, -20.23285, 8.135094, 9.957781, -19.472874, 8.213911, 11.16268, -19.969059, 8.226086, 9.957781, -19.472874, 8.213911, 8.811623, -18.20881, 7.9881387, 10.0568905, -19.342154, 7.988139, 11.16268, -19.969059, 8.226086, 9.957781, -19.472874, 8.213911, 10.0568905, -19.342154, 7.988139, 11.16268, -19.969059, 8.226086, 10.0568905, -19.342154, 7.988139, 11.220137, -19.80587, 7.9881396, 10.050482, -22.030905, 7.98814, 11.049473, -19.97397, 8.213911, 10.477888, -22.030905, 8.612482, 10.050482, -22.030905, 7.98814, 10.888208, -19.944494, 7.9881396, 11.049473, -19.97397, 8.213911, 10.888208, -19.944494, 7.9881396, 11.13064, -17.907639, 8.087889, 11.049473, -19.97397, 8.213911, 10.888208, -19.944494, 7.9881396, 11.058659, -17.900164, 7.9881387, 11.13064, -17.907639, 8.087889, 11.049473, -19.97397, 8.213911, 11.13064, -17.907639, 8.087889, 11.247263, -17.92024, 8.049868, 10.477888, -22.030905, 8.612482, 11.049473, -19.97397, 8.213911, 11.310488, -20.021389, 8.127618, 11.049473, -19.97397, 8.213911, 11.247263, -17.92024, 8.049868, 11.310488, -20.021389, 8.127618, 10.477888, -22.030905, 8.612482, 11.310488, -20.021389, 8.127618, 11.169514, -22.031118, 8.374109, 11.310488, -20.021389, 8.127618, 11.247263, -17.92024, 8.049868, 11.247263, -17.92024, 7.9264092, 11.169514, -22.031118, 8.374109, 11.310488, -20.021389, 8.127618, 11.310488, -20.021389, 7.848661, 11.310488, -20.021389, 8.127618, 11.247263, -17.92024, 7.9264092, 11.310488, -20.021389, 7.848661, 11.169514, -22.031118, 8.374109, 11.310488, -20.021389, 7.848661, 11.169514, -22.031118, 7.6021714, 11.310488, -20.021389, 7.848661, 11.247263, -17.92024, 7.9264092, 11.13064, -17.907639, 7.888389, 11.169514, -22.031118, 7.6021714, 11.310488, -20.021389, 7.848661, 11.049473, -19.97397, 7.762368, 11.310488, -20.021389, 7.848661, 11.13064, -17.907639, 7.888389, 11.049473, -19.97397, 7.762368, 11.049473, -19.97397, 7.762368, 11.13064, -17.907639, 7.888389, 11.058659, -17.900164, 7.9881387, 11.169514, -22.031118, 7.6021714, 11.049473, -19.97397, 7.762368, 10.477888, -22.030905, 7.3637977, 11.049473, -19.97397, 7.762368, 11.058659, -17.900164, 7.9881387, 10.888208, -19.944494, 7.9881396, 10.477888, -22.030905, 7.3637977, 11.049473, -19.97397, 7.762368, 10.888208, -19.944494, 7.9881396, 10.477888, -22.030905, 7.3637977, 10.888208, -19.944494, 7.9881396, 10.050482, -22.030905, 7.98814, 11.023628, -19.860125, 7.836486, 10.902519, -19.637772, 6.988935, 11.16268, -19.969059, 7.7499795, 11.023628, -19.860125, 7.836486, 10.7801285, -19.55041, 7.099151, 10.902519, -19.637772, 6.988935, 10.7801285, -19.55041, 7.099151, 10.55094, -18.793425, 6.265697, 10.902519, -19.637772, 6.988935, 10.7801285, -19.55041, 7.099151, 10.519327, -18.793852, 6.309698, 10.55094, -18.793425, 6.265697, 10.902519, -19.637772, 6.988935, 10.55094, -18.793425, 6.265697, 10.5189, -18.792997, 6.2221236, 11.16268, -19.969059, 7.7499795, 10.902519, -19.637772, 6.988935, 10.814302, -19.778744, 6.9052052, 10.902519, -19.637772, 6.988935, 10.5189, -18.792997, 6.2221236, 10.814302, -19.778744, 6.9052052, 11.16268, -19.969059, 7.7499795, 10.814302, -19.778744, 6.9052052, 11.085358, -20.145061, 7.710037, 10.814302, -19.778744, 6.9052052, 10.5189, -18.792997, 6.2221236, 10.4674225, -18.792997, 6.238998, 11.085358, -20.145061, 7.710037, 10.814302, -19.778744, 6.9052052, 10.637232, -19.778744, 6.963517, 10.814302, -19.778744, 6.9052052, 10.4674225, -18.792997, 6.238998, 10.637232, -19.778744, 6.963517, 11.085358, -20.145061, 7.710037, 10.637232, -19.778744, 6.963517, 10.898888, -20.145061, 7.771766, 10.637232, -19.778744, 6.963517, 10.4674225, -18.792997, 6.238998, 10.46785, -18.793425, 6.293038, 10.898888, -20.145061, 7.771766, 10.637232, -19.778744, 6.963517, 10.616299, -19.637772, 7.083345, 10.637232, -19.778744, 6.963517, 10.46785, -18.793425, 6.293038, 10.616299, -19.637772, 7.083345, 10.616299, -19.637772, 7.083345, 10.46785, -18.793425, 6.293038, 10.519327, -18.793852, 6.309698, 10.898888, -20.145061, 7.771766, 10.616299, -19.637772, 7.083345, 10.860653, -19.969059, 7.849729, 10.616299, -19.637772, 7.083345, 10.519327, -18.793852, 6.309698, 10.7801285, -19.55041, 7.099151, 10.860653, -19.969059, 7.849729, 10.616299, -19.637772, 7.083345, 10.7801285, -19.55041, 7.099151, 10.860653, -19.969059, 7.849729, 10.7801285, -19.55041, 7.099151, 11.023628, -19.860125, 7.836486, 9.806982, -18.747929, 5.422632, 9.553658, -18.258793, 6.2026863, 9.731583, -18.927135, 6.042062, 9.731583, -18.927135, 6.042062, 9.553658, -18.258793, 6.2026863, 10.069706, -18.254948, 6.927205, 9.731583, -18.927135, 6.042062, 10.069706, -18.254948, 6.927205, 10.201282, -18.747929, 6.6170635, 9.806982, -18.747929, 5.422632, 9.551735, -18.254948, 5.359194, 9.553658, -18.258793, 6.2026863, 10.419577, -18.908766, 5.0725474, 9.551735, -18.254948, 5.359194, 9.806982, -18.747929, 5.422632, 9.553658, -18.258793, 6.2026863, 10.181845, -17.756413, 6.672812, 10.069706, -18.254948, 6.927205, 10.419577, -18.908766, 5.0725474, 10.285225, -18.244055, 5.06678, 9.551735, -18.254948, 5.359194, 11.137901, -18.725073, 5.250473, 10.285225, -18.244055, 5.06678, 10.419577, -18.908766, 5.0725474, 9.551735, -18.254948, 5.359194, 9.889858, -17.582973, 6.244337, 9.553658, -18.258793, 6.2026863, 9.553658, -18.258793, 6.2026863, 9.889858, -17.582973, 6.244337, 10.181845, -17.756413, 6.672812, 10.285225, -18.244055, 5.06678, 9.852264, -17.756414, 5.6751027, 9.551735, -18.254948, 5.359194, 9.551735, -18.254948, 5.359194, 9.852264, -17.756414, 5.6751027, 9.889858, -17.582973, 6.244337, 11.137901, -18.725073, 5.250473, 11.16695, -18.232948, 5.223346, 10.285225, -18.244055, 5.06678, 11.16695, -18.232948, 5.223346, 11.137901, -18.725073, 5.250473, 11.625116, -18.890398, 5.671045, 10.285225, -18.244055, 5.06678, 10.299322, -17.579128, 5.5099926, 9.852264, -17.756414, 5.6751027, 11.16695, -18.232948, 5.223346, 10.299322, -17.579128, 5.5099926, 10.285225, -18.244055, 5.06678, 9.852264, -17.756414, 5.6751027, 10.453112, -17.357628, 6.1091304, 9.889858, -17.582973, 6.244337, 9.852264, -17.756414, 5.6751027, 10.299322, -17.579128, 5.5099926, 10.453112, -17.357628, 6.1091304, 11.16695, -18.232948, 5.223346, 10.871334, -17.746588, 5.5153327, 10.299322, -17.579128, 5.5099926, 11.16695, -18.232948, 5.223346, 11.625116, -18.890398, 5.671045, 11.610165, -18.229317, 5.727007, 10.871334, -17.746588, 5.5153327, 11.16695, -18.232948, 5.223346, 11.610165, -18.229317, 5.727007, 11.610165, -18.229317, 5.727007, 11.625116, -18.890398, 5.671045, 11.467482, -18.725073, 6.2481823, 10.299322, -17.579128, 5.5099926, 10.871334, -17.746588, 5.5153327, 11.080872, -17.575497, 5.9017286, 10.871334, -17.746588, 5.5153327, 11.610165, -18.229317, 5.727007, 11.080872, -17.575497, 5.9017286, 10.299322, -17.579128, 5.5099926, 11.080872, -17.575497, 5.9017286, 10.453112, -17.357628, 6.1091304, 11.610165, -18.229317, 5.727007, 11.467482, -18.725073, 6.2481823, 11.539036, -18.232946, 6.3494267, 11.080872, -17.575497, 5.9017286, 11.610165, -18.229317, 5.727007, 11.539036, -18.232946, 6.3494267, 10.937548, -18.908766, 6.640559, 11.539036, -18.232946, 6.3494267, 11.467482, -18.725073, 6.2481823, 10.453112, -17.357628, 6.1091304, 11.080872, -17.575497, 5.9017286, 11.135979, -17.746588, 6.316746, 11.080872, -17.575497, 5.9017286, 11.539036, -18.232946, 6.3494267, 11.135979, -17.746588, 6.316746, 10.937548, -18.908766, 6.640559, 10.878382, -18.244053, 6.8629127, 11.539036, -18.232946, 6.3494267, 10.878382, -18.244053, 6.8629127, 11.135979, -17.746588, 6.316746, 11.539036, -18.232946, 6.3494267, 10.201282, -18.747929, 6.6170635, 10.878382, -18.244053, 6.8629127, 10.937548, -18.908766, 6.640559, 10.201282, -18.747929, 6.6170635, 10.069706, -18.254948, 6.927205, 10.878382, -18.244053, 6.8629127, 10.878382, -18.244053, 6.8629127, 10.671408, -17.579128, 6.636073, 11.135979, -17.746588, 6.316746, 10.453112, -17.357628, 6.1091304, 11.135979, -17.746588, 6.316746, 10.671408, -17.579128, 6.636073, 10.069706, -18.254948, 6.927205, 10.671408, -17.579128, 6.636073, 10.878382, -18.244053, 6.8629127, 9.889858, -17.582973, 6.244337, 10.453112, -17.357628, 6.1091304, 10.671408, -17.579128, 6.636073, 10.069706, -18.254948, 6.927205, 10.181845, -17.756413, 6.672812, 10.671408, -17.579128, 6.636073, 9.889858, -17.582973, 6.244337, 10.671408, -17.579128, 6.636073, 10.181845, -17.756413, 6.672812, 11.137901, -18.725073, 5.250473, 10.710709, -19.13048, 5.8203487, 11.625116, -18.890398, 5.671045, 11.137901, -18.725073, 5.250473, 10.419577, -18.908766, 5.0725474, 10.710709, -19.13048, 5.8203487, 11.625116, -18.890398, 5.671045, 10.710709, -19.13048, 5.8203487, 10.937548, -18.908766, 6.640559, 11.625116, -18.890398, 5.671045, 10.937548, -18.908766, 6.640559, 11.467482, -18.725073, 6.2481823, 10.710709, -19.13048, 5.8203487, 10.201282, -18.747929, 6.6170635, 10.937548, -18.908766, 6.640559, 10.710709, -19.13048, 5.8203487, 9.731583, -18.927135, 6.042062, 10.201282, -18.747929, 6.6170635, 10.419577, -18.908766, 5.0725474, 9.731583, -18.927135, 6.042062, 10.710709, -19.13048, 5.8203487, 10.419577, -18.908766, 5.0725474, 9.806982, -18.747929, 5.422632, 9.731583, -18.927135, 6.042062, 15.540274, 10.966449, -3.3071837, 18.560066, 13.1471405, -1.460484, 18.346163, 10.143484, -1.9265671, 18.346163, 10.143484, -1.9265671, 18.560066, 13.1471405, -1.460484, 22.219316, 13.223694, -3.2587752, 18.346163, 10.143484, -1.9265671, 22.219316, 13.223694, -3.2587752, 21.565973, 10.92592, -3.6194077, 15.540274, 10.966449, -3.3071837, 15.086948, 13.100231, -2.2530527, 18.560066, 13.1471405, -1.460484, 14.412214, 10.35138, -7.0625033, 15.086948, 13.100231, -2.2530527, 15.540274, 10.966449, -3.3071837, 18.560066, 13.1471405, -1.460484, 21.16256, 15.42765, -4.2870145, 22.219316, 13.223694, -3.2587752, 14.412214, 10.35138, -7.0625033, 14.188929, 13.313381, -6.7934375, 15.086948, 13.100231, -2.2530527, 16.12682, 11.184852, -10.555136, 14.188929, 13.313381, -6.7934375, 14.412214, 10.35138, -7.0625033, 15.086948, 13.100231, -2.2530527, 18.959728, 16.180443, -3.5852609, 18.560066, 13.1471405, -1.460484, 18.560066, 13.1471405, -1.460484, 18.959728, 16.180443, -3.5852609, 21.16256, 15.42765, -4.2870145, 14.188929, 13.313381, -6.7934375, 16.632683, 15.373238, -3.8400683, 15.086948, 13.100231, -2.2530527, 15.086948, 13.100231, -2.2530527, 16.632683, 15.373238, -3.8400683, 18.959728, 16.180443, -3.5852609, 16.12682, 11.184852, -10.555136, 15.662611, 13.473244, -11.258017, 14.188929, 13.313381, -6.7934375, 15.662611, 13.473244, -11.258017, 16.12682, 11.184852, -10.555136, 19.275705, 10.291335, -11.819794, 14.188929, 13.313381, -6.7934375, 16.33697, 16.22172, -6.448566, 16.632683, 15.373238, -3.8400683, 15.662611, 13.473244, -11.258017, 16.33697, 16.22172, -6.448566, 14.188929, 13.313381, -6.7934375, 16.632683, 15.373238, -3.8400683, 19.092949, 17.191416, -6.333734, 18.959728, 16.180443, -3.5852609, 16.632683, 15.373238, -3.8400683, 16.33697, 16.22172, -6.448566, 19.092949, 17.191416, -6.333734, 15.662611, 13.473244, -11.258017, 16.88824, 15.538728, -9.202293, 16.33697, 16.22172, -6.448566, 15.662611, 13.473244, -11.258017, 19.275705, 10.291335, -11.819794, 19.30385, 13.265345, -11.823172, 16.88824, 15.538728, -9.202293, 15.662611, 13.473244, -11.258017, 19.30385, 13.265345, -11.823172, 19.30385, 13.265345, -11.823172, 19.275705, 10.291335, -11.819794, 22.136759, 10.891392, -9.770823, 16.33697, 16.22172, -6.448566, 16.88824, 15.538728, -9.202293, 19.145487, 16.20971, -9.236067, 16.88824, 15.538728, -9.202293, 19.30385, 13.265345, -11.823172, 19.145487, 16.20971, -9.236067, 16.33697, 16.22172, -6.448566, 19.145487, 16.20971, -9.236067, 19.092949, 17.191416, -6.333734, 19.30385, 13.265345, -11.823172, 22.136759, 10.891392, -9.770823, 22.758955, 13.0278, -9.797468, 19.145487, 16.20971, -9.236067, 19.30385, 13.265345, -11.823172, 22.758955, 13.0278, -9.797468, 23.209654, 10.083063, -6.6834817, 22.758955, 13.0278, -9.797468, 22.136759, 10.891392, -9.770823, 19.092949, 17.191416, -6.333734, 19.145487, 16.20971, -9.236067, 21.402355, 15.340961, -8.553076, 19.145487, 16.20971, -9.236067, 22.758955, 13.0278, -9.797468, 21.402355, 15.340961, -8.553076, 23.209654, 10.083063, -6.6834817, 23.674988, 13.098728, -6.4902196, 22.758955, 13.0278, -9.797468, 23.674988, 13.098728, -6.4902196, 21.402355, 15.340961, -8.553076, 22.758955, 13.0278, -9.797468, 21.565973, 10.92592, -3.6194077, 23.674988, 13.098728, -6.4902196, 23.209654, 10.083063, -6.6834817, 21.565973, 10.92592, -3.6194077, 22.219316, 13.223694, -3.2587752, 23.674988, 13.098728, -6.4902196, 23.674988, 13.098728, -6.4902196, 21.768618, 16.168056, -6.372762, 21.402355, 15.340961, -8.553076, 19.092949, 17.191416, -6.333734, 21.402355, 15.340961, -8.553076, 21.768618, 16.168056, -6.372762, 22.219316, 13.223694, -3.2587752, 21.768618, 16.168056, -6.372762, 23.674988, 13.098728, -6.4902196, 18.959728, 16.180443, -3.5852609, 19.092949, 17.191416, -6.333734, 21.768618, 16.168056, -6.372762, 22.219316, 13.223694, -3.2587752, 21.16256, 15.42765, -4.2870145, 21.768618, 16.168056, -6.372762, 18.959728, 16.180443, -3.5852609, 21.768618, 16.168056, -6.372762, 21.16256, 15.42765, -4.2870145, 16.12682, 11.184852, -10.555136, 18.770592, 9.221069, -6.949922, 19.275705, 10.291335, -11.819794, 16.12682, 11.184852, -10.555136, 14.412214, 10.35138, -7.0625033, 18.770592, 9.221069, -6.949922, 19.275705, 10.291335, -11.819794, 18.770592, 9.221069, -6.949922, 23.209654, 10.083063, -6.6834817, 19.275705, 10.291335, -11.819794, 23.209654, 10.083063, -6.6834817, 22.136759, 10.891392, -9.770823, 18.770592, 9.221069, -6.949922, 21.565973, 10.92592, -3.6194077, 23.209654, 10.083063, -6.6834817, 18.770592, 9.221069, -6.949922, 18.346163, 10.143484, -1.9265671, 21.565973, 10.92592, -3.6194077, 14.412214, 10.35138, -7.0625033, 18.346163, 10.143484, -1.9265671, 18.770592, 9.221069, -6.949922, 14.412214, 10.35138, -7.0625033, 15.540274, 10.966449, -3.3071837, 18.346163, 10.143484, -1.9265671, 11.936562, 9.984368, -5.338141, 13.67631, 11.271917, -4.06185, 13.421877, 9.512654, -4.639014, 13.421877, 9.512654, -4.639014, 13.67631, 11.271917, -4.06185, 15.91254, 11.2813, -4.7530966, 13.421877, 9.512654, -4.639014, 15.91254, 11.2813, -4.7530966, 15.246437, 9.984368, -5.338141, 11.936562, 9.984368, -5.338141, 11.566921, 11.2813, -4.7530966, 13.67631, 11.271917, -4.06185, 11.566921, 9.561063, -7.158197, 11.566921, 11.2813, -4.7530966, 11.936562, 9.984368, -5.338141, 13.67631, 11.271917, -4.06185, 15.369902, 12.5936165, -5.243574, 15.91254, 11.2813, -4.7530966, 11.566921, 9.561063, -7.158197, 11.441956, 11.310569, -6.8275857, 11.566921, 11.2813, -4.7530966, 12.604542, 10.044409, -8.806381, 11.441956, 11.310569, -6.8275857, 11.566921, 9.561063, -7.158197, 11.566921, 11.2813, -4.7530966, 14.057959, 13.050319, -4.8671794, 13.67631, 11.271917, -4.06185, 13.67631, 11.271917, -4.06185, 14.057959, 13.050319, -4.8671794, 15.369902, 12.5936165, -5.243574, 11.441956, 11.310569, -6.8275857, 12.604542, 12.5936165, -5.243574, 11.566921, 11.2813, -4.7530966, 11.566921, 11.2813, -4.7530966, 12.604542, 12.5936165, -5.243574, 14.057959, 13.050319, -4.8671794, 12.604542, 10.044409, -8.806381, 12.56101, 11.339464, -8.901699, 11.441956, 11.310569, -6.8275857, 12.56101, 11.339464, -8.901699, 12.604542, 10.044409, -8.806381, 14.057959, 9.609097, -9.677006, 11.441956, 11.310569, -6.8275857, 12.56101, 13.0597, -6.4969745, 12.604542, 12.5936165, -5.243574, 12.56101, 11.339464, -8.901699, 12.56101, 13.0597, -6.4969745, 11.441956, 11.310569, -6.8275857, 12.604542, 12.5936165, -5.243574, 14.184801, 13.643244, -6.386646, 14.057959, 13.050319, -4.8671794, 12.604542, 12.5936165, -5.243574, 12.56101, 13.0597, -6.4969745, 14.184801, 13.643244, -6.386646, 12.56101, 11.339464, -8.901699, 13.046232, 12.619133, -7.921497, 12.56101, 13.0597, -6.4969745, 12.56101, 11.339464, -8.901699, 14.057959, 9.609097, -9.677006, 14.184801, 11.34922, -9.592945, 13.046232, 12.619133, -7.921497, 12.56101, 11.339464, -8.901699, 14.184801, 11.34922, -9.592945, 14.184801, 11.34922, -9.592945, 14.057959, 9.609097, -9.677006, 15.369902, 10.044409, -8.806381, 12.56101, 13.0597, -6.4969745, 13.046232, 12.619133, -7.921497, 14.184801, 13.069456, -8.126394, 13.046232, 12.619133, -7.921497, 14.184801, 11.34922, -9.592945, 14.184801, 13.069456, -8.126394, 12.56101, 13.0597, -6.4969745, 14.184801, 13.069456, -8.126394, 14.184801, 13.643244, -6.386646, 14.184801, 11.34922, -9.592945, 15.369902, 10.044409, -8.806381, 15.681749, 11.339464, -8.901699, 14.184801, 13.069456, -8.126394, 14.184801, 11.34922, -9.592945, 15.681749, 11.339464, -8.901699, 15.91254, 9.561063, -7.158197, 15.681749, 11.339464, -8.901699, 15.369902, 10.044409, -8.806381, 14.184801, 13.643244, -6.386646, 14.184801, 13.069456, -8.126394, 15.2670765, 12.619133, -7.921497, 14.184801, 13.069456, -8.126394, 15.681749, 11.339464, -8.901699, 15.2670765, 12.619133, -7.921497, 15.91254, 9.561063, -7.158197, 16.419529, 11.310569, -6.8275857, 15.681749, 11.339464, -8.901699, 16.419529, 11.310569, -6.8275857, 15.2670765, 12.619133, -7.921497, 15.681749, 11.339464, -8.901699, 15.246437, 9.984368, -5.338141, 16.419529, 11.310569, -6.8275857, 15.91254, 9.561063, -7.158197, 15.246437, 9.984368, -5.338141, 15.91254, 11.2813, -4.7530966, 16.419529, 11.310569, -6.8275857, 16.419529, 11.310569, -6.8275857, 15.681749, 13.0597, -6.4969745, 15.2670765, 12.619133, -7.921497, 14.184801, 13.643244, -6.386646, 15.2670765, 12.619133, -7.921497, 15.681749, 13.0597, -6.4969745, 15.91254, 11.2813, -4.7530966, 15.681749, 13.0597, -6.4969745, 16.419529, 11.310569, -6.8275857, 14.057959, 13.050319, -4.8671794, 14.184801, 13.643244, -6.386646, 15.681749, 13.0597, -6.4969745, 15.91254, 11.2813, -4.7530966, 15.369902, 12.5936165, -5.243574, 15.681749, 13.0597, -6.4969745, 14.057959, 13.050319, -4.8671794, 15.681749, 13.0597, -6.4969745, 15.369902, 12.5936165, -5.243574, 12.604542, 10.044409, -8.806381, 13.67631, 8.977895, -7.268151, 14.057959, 9.609097, -9.677006, 12.604542, 10.044409, -8.806381, 11.566921, 9.561063, -7.158197, 13.67631, 8.977895, -7.268151, 14.057959, 9.609097, -9.677006, 13.67631, 8.977895, -7.268151, 15.91254, 9.561063, -7.158197, 14.057959, 9.609097, -9.677006, 15.91254, 9.561063, -7.158197, 15.369902, 10.044409, -8.806381, 13.67631, 8.977895, -7.268151, 15.246437, 9.984368, -5.338141, 15.91254, 9.561063, -7.158197, 13.67631, 8.977895, -7.268151, 13.421877, 9.512654, -4.639014, 15.246437, 9.984368, -5.338141, 11.566921, 9.561063, -7.158197, 13.421877, 9.512654, -4.639014, 13.67631, 8.977895, -7.268151, 11.566921, 9.561063, -7.158197, 11.936562, 9.984368, -5.338141, 13.421877, 9.512654, -4.639014, 16.48933, 8.916348, -10.894003, 16.04426, 9.775716, -9.5235195, 16.35686, 8.601498, -9.805721, 16.35686, 8.601498, -9.805721, 16.04426, 9.775716, -9.5235195, 16.95091, 9.782472, -8.250607, 16.35686, 8.601498, -9.805721, 16.95091, 9.782472, -8.250607, 17.182077, 8.916349, -8.795498, 16.48933, 8.916348, -10.894003, 16.040882, 9.78247, -11.005459, 16.04426, 9.775716, -9.5235195, 17.565601, 8.63377, -11.509069, 16.040882, 9.78247, -11.005459, 16.48933, 8.916348, -10.894003, 16.04426, 9.775716, -9.5235195, 17.147928, 10.65835, -8.697552, 16.95091, 9.782472, -8.250607, 17.565601, 8.63377, -11.509069, 17.329557, 9.801608, -11.519203, 16.040882, 9.78247, -11.005459, 18.827633, 8.956502, -11.19647, 17.329557, 9.801608, -11.519203, 17.565601, 8.63377, -11.509069, 16.040882, 9.78247, -11.005459, 16.634933, 10.963444, -9.450344, 16.04426, 9.775716, -9.5235195, 16.04426, 9.775716, -9.5235195, 16.634933, 10.963444, -9.450344, 17.147928, 10.65835, -8.697552, 17.329557, 9.801608, -11.519203, 16.568888, 10.658349, -10.450436, 16.040882, 9.78247, -11.005459, 16.040882, 9.78247, -11.005459, 16.568888, 10.658349, -10.450436, 16.634933, 10.963444, -9.450344, 18.827633, 8.956502, -11.19647, 18.87867, 9.821122, -11.244131, 17.329557, 9.801608, -11.519203, 18.87867, 9.821122, -11.244131, 18.827633, 8.956502, -11.19647, 19.683622, 8.666044, -10.457565, 17.329557, 9.801608, -11.519203, 17.354326, 10.969822, -10.740519, 16.568888, 10.658349, -10.450436, 18.87867, 9.821122, -11.244131, 17.354326, 10.969822, -10.740519, 17.329557, 9.801608, -11.519203, 16.568888, 10.658349, -10.450436, 17.62452, 11.358977, -9.687889, 16.634933, 10.963444, -9.450344, 16.568888, 10.658349, -10.450436, 17.354326, 10.969822, -10.740519, 17.62452, 11.358977, -9.687889, 18.87867, 9.821122, -11.244131, 18.359297, 10.6756115, -10.731136, 17.354326, 10.969822, -10.740519, 18.87867, 9.821122, -11.244131, 19.683622, 8.666044, -10.457565, 19.657354, 9.827502, -10.359245, 18.359297, 10.6756115, -10.731136, 18.87867, 9.821122, -11.244131, 19.657354, 9.827502, -10.359245, 19.657354, 9.827502, -10.359245, 19.683622, 8.666044, -10.457565, 19.406673, 8.956503, -9.443586, 17.354326, 10.969822, -10.740519, 18.359297, 10.6756115, -10.731136, 18.727436, 10.976202, -10.052275, 18.359297, 10.6756115, -10.731136, 19.657354, 9.827502, -10.359245, 18.727436, 10.976202, -10.052275, 17.354326, 10.969822, -10.740519, 18.727436, 10.976202, -10.052275, 17.62452, 11.358977, -9.687889, 19.657354, 9.827502, -10.359245, 19.406673, 8.956503, -9.443586, 19.532389, 9.821123, -9.265711, 18.727436, 10.976202, -10.052275, 19.657354, 9.827502, -10.359245, 19.532389, 9.821123, -9.265711, 18.47563, 8.633772, -8.754217, 19.532389, 9.821123, -9.265711, 19.406673, 8.956503, -9.443586, 17.62452, 11.358977, -9.687889, 18.727436, 10.976202, -10.052275, 18.824255, 10.6756115, -9.323126, 18.727436, 10.976202, -10.052275, 19.532389, 9.821123, -9.265711, 18.824255, 10.6756115, -9.323126, 18.47563, 8.633772, -8.754217, 18.371681, 9.80161, -8.363562, 19.532389, 9.821123, -9.265711, 18.371681, 9.80161, -8.363562, 18.824255, 10.6756115, -9.323126, 19.532389, 9.821123, -9.265711, 17.182077, 8.916349, -8.795498, 18.371681, 9.80161, -8.363562, 18.47563, 8.633772, -8.754217, 17.182077, 8.916349, -8.795498, 16.95091, 9.782472, -8.250607, 18.371681, 9.80161, -8.363562, 18.371681, 9.80161, -8.363562, 18.008045, 10.969824, -8.762098, 18.824255, 10.6756115, -9.323126, 17.62452, 11.358977, -9.687889, 18.824255, 10.6756115, -9.323126, 18.008045, 10.969824, -8.762098, 16.95091, 9.782472, -8.250607, 18.008045, 10.969824, -8.762098, 18.371681, 9.80161, -8.363562, 16.634933, 10.963444, -9.450344, 17.62452, 11.358977, -9.687889, 18.008045, 10.969824, -8.762098, 16.95091, 9.782472, -8.250607, 17.147928, 10.65835, -8.697552, 18.008045, 10.969824, -8.762098, 16.634933, 10.963444, -9.450344, 18.008045, 10.969824, -8.762098, 17.147928, 10.65835, -8.697552, 18.827633, 8.956502, -11.19647, 18.077095, 8.244242, -10.195251, 19.683622, 8.666044, -10.457565, 18.827633, 8.956502, -11.19647, 17.565601, 8.63377, -11.509069, 18.077095, 8.244242, -10.195251, 19.683622, 8.666044, -10.457565, 18.077095, 8.244242, -10.195251, 18.47563, 8.633772, -8.754217, 19.683622, 8.666044, -10.457565, 18.47563, 8.633772, -8.754217, 19.406673, 8.956503, -9.443586, 18.077095, 8.244242, -10.195251, 17.182077, 8.916349, -8.795498, 18.47563, 8.633772, -8.754217, 18.077095, 8.244242, -10.195251, 16.35686, 8.601498, -9.805721, 17.182077, 8.916349, -8.795498, 17.565601, 8.63377, -11.509069, 16.35686, 8.601498, -9.805721, 18.077095, 8.244242, -10.195251, 17.565601, 8.63377, -11.509069, 16.48933, 8.916348, -10.894003, 16.35686, 8.601498, -9.805721, 18.97211, 7.0576415, -6.386642, 16.75427, 7.642686, -6.783302, 18.871164, 6.7709355, -6.804692, 18.97211, 7.0576415, -6.386642, 16.92877, 7.871976, -6.386642, 16.75427, 7.642686, -6.783302, 16.92877, 7.871976, -6.386642, 14.656889, 9.864281, -6.5018516, 16.75427, 7.642686, -6.783302, 16.92877, 7.871976, -6.386642, 14.740574, 9.86353, -6.386643, 14.656889, 9.864281, -6.5018516, 16.75427, 7.642686, -6.783302, 14.656889, 9.864281, -6.5018516, 14.521418, 9.865407, -6.4579444, 18.871164, 6.7709355, -6.804692, 16.75427, 7.642686, -6.783302, 16.472067, 7.2715445, -6.6316934, 16.75427, 7.642686, -6.783302, 14.521418, 9.865407, -6.4579444, 16.472067, 7.2715445, -6.6316934, 18.871164, 6.7709355, -6.804692, 16.472067, 7.2715445, -6.6316934, 18.70717, 6.307478, -6.645202, 16.472067, 7.2715445, -6.6316934, 14.521418, 9.865407, -6.4579444, 14.521418, 9.865407, -6.3153424, 18.70717, 6.307478, -6.645202, 16.472067, 7.2715445, -6.6316934, 16.472067, 7.271545, -6.1415906, 16.472067, 7.2715445, -6.6316934, 14.521418, 9.865407, -6.3153424, 16.472067, 7.271545, -6.1415906, 18.70717, 6.307478, -6.645202, 16.472067, 7.271545, -6.1415906, 18.70717, 6.307478, -6.128081, 16.472067, 7.271545, -6.1415906, 14.521418, 9.865407, -6.3153424, 14.656889, 9.864282, -6.2714353, 18.70717, 6.307478, -6.128081, 16.472067, 7.271545, -6.1415906, 16.75427, 7.642687, -5.9899826, 16.472067, 7.271545, -6.1415906, 14.656889, 9.864282, -6.2714353, 16.75427, 7.642687, -5.9899826, 16.75427, 7.642687, -5.9899826, 14.656889, 9.864282, -6.2714353, 14.740574, 9.86353, -6.386643, 18.70717, 6.307478, -6.128081, 16.75427, 7.642687, -5.9899826, 18.871164, 6.770936, -5.9685917, 16.75427, 7.642687, -5.9899826, 14.740574, 9.86353, -6.386643, 16.92877, 7.871976, -6.386642, 18.871164, 6.770936, -5.9685917, 16.75427, 7.642687, -5.9899826, 16.92877, 7.871976, -6.386642, 18.871164, 6.770936, -5.9685917, 16.92877, 7.871976, -6.386642, 18.97211, 7.0576415, -6.386642, 16.917137, 3.1484604, -6.38664, 18.672272, 6.762305, -5.989982, 17.66805, 3.1484613, -5.289727, 16.917137, 3.1484604, -6.38664, 18.388943, 6.8137164, -6.386642, 18.672272, 6.762305, -5.989982, 18.388943, 6.8137164, -6.386642, 18.814873, 10.392285, -6.211393, 18.672272, 6.762305, -5.989982, 18.388943, 6.8137164, -6.386642, 18.688408, 10.405795, -6.386644, 18.814873, 10.392285, -6.211393, 18.672272, 6.762305, -5.989982, 18.814873, 10.392285, -6.211393, 19.01977, 10.370894, -6.278191, 17.66805, 3.1484613, -5.289727, 18.672272, 6.762305, -5.989982, 19.13085, 6.6789947, -6.1415906, 18.672272, 6.762305, -5.989982, 19.01977, 10.370894, -6.278191, 19.13085, 6.6789947, -6.1415906, 17.66805, 3.1484613, -5.289727, 19.13085, 6.6789947, -6.1415906, 18.883549, 3.148085, -5.708528, 19.13085, 6.6789947, -6.1415906, 19.01977, 10.370894, -6.278191, 19.01977, 10.370894, -6.4950967, 18.883549, 3.148085, -5.708528, 19.13085, 6.6789947, -6.1415906, 19.13085, 6.678994, -6.6316924, 19.13085, 6.6789947, -6.1415906, 19.01977, 10.370894, -6.4950967, 19.13085, 6.678994, -6.6316924, 18.883549, 3.148085, -5.708528, 19.13085, 6.678994, -6.6316924, 18.883549, 3.1480846, -7.064751, 19.13085, 6.678994, -6.6316924, 19.01977, 10.370894, -6.4950967, 18.814873, 10.392285, -6.561895, 18.883549, 3.1480846, -7.064751, 19.13085, 6.678994, -6.6316924, 18.672272, 6.7623043, -6.783302, 19.13085, 6.678994, -6.6316924, 18.814873, 10.392285, -6.561895, 18.672272, 6.7623043, -6.783302, 18.672272, 6.7623043, -6.783302, 18.814873, 10.392285, -6.561895, 18.688408, 10.405795, -6.386644, 18.883549, 3.1480846, -7.064751, 18.672272, 6.7623043, -6.783302, 17.66805, 3.14846, -7.4835525, 18.672272, 6.7623043, -6.783302, 18.688408, 10.405795, -6.386644, 18.388943, 6.8137164, -6.386642, 17.66805, 3.14846, -7.4835525, 18.672272, 6.7623043, -6.783302, 18.388943, 6.8137164, -6.386642, 17.66805, 3.14846, -7.4835525, 18.388943, 6.8137164, -6.386642, 16.917137, 3.1484604, -6.38664, 18.62724, 6.962323, -6.6530833, 18.414085, 7.3529778, -8.142153, 18.871164, 6.7709355, -6.804692, 18.62724, 6.962323, -6.6530833, 18.199057, 7.5060873, -7.9485135, 18.414085, 7.3529778, -8.142153, 18.199057, 7.5060873, -7.9485135, 17.796392, 8.836041, -9.412815, 18.414085, 7.3529778, -8.142153, 18.199057, 7.5060873, -7.9485135, 17.740852, 8.835667, -9.33551, 17.796392, 8.836041, -9.412815, 18.414085, 7.3529778, -8.142153, 17.796392, 8.836041, -9.412815, 17.740103, 8.836792, -9.48937, 18.871164, 6.7709355, -6.804692, 18.414085, 7.3529778, -8.142153, 18.258724, 7.1053, -8.289257, 18.414085, 7.3529778, -8.142153, 17.740103, 8.836792, -9.48937, 18.258724, 7.1053, -8.289257, 18.871164, 6.7709355, -6.804692, 18.258724, 7.1053, -8.289257, 18.735317, 6.461338, -6.8752427, 18.258724, 7.1053, -8.289257, 17.740103, 8.836792, -9.48937, 17.650038, 8.836792, -9.459724, 18.735317, 6.461338, -6.8752427, 18.258724, 7.1053, -8.289257, 17.948002, 7.1053, -8.18681, 18.258724, 7.1053, -8.289257, 17.650038, 8.836792, -9.459724, 17.948002, 7.1053, -8.18681, 18.735317, 6.461338, -6.8752427, 17.948002, 7.1053, -8.18681, 18.407707, 6.461338, -6.7671647, 17.948002, 7.1053, -8.18681, 17.650038, 8.836792, -9.459724, 17.650414, 8.836041, -9.36478, 18.407707, 6.461338, -6.7671647, 17.948002, 7.1053, -8.18681, 17.911226, 7.3529778, -7.975908, 17.948002, 7.1053, -8.18681, 17.650414, 8.836041, -9.36478, 17.911226, 7.3529778, -7.975908, 17.911226, 7.3529778, -7.975908, 17.650414, 8.836041, -9.36478, 17.740852, 8.835667, -9.33551, 18.407707, 6.461338, -6.7671647, 17.911226, 7.3529778, -7.975908, 18.340908, 6.7709355, -6.6298165, 17.911226, 7.3529778, -7.975908, 17.740852, 8.835667, -9.33551, 18.199057, 7.5060873, -7.9485135, 18.340908, 6.7709355, -6.6298165, 17.911226, 7.3529778, -7.975908, 18.199057, 7.5060873, -7.9485135, 18.340908, 6.7709355, -6.6298165, 18.199057, 7.5060873, -7.9485135, 18.62724, 6.962323, -6.6530833, -21.319002, 11.927798, 5.296257, -17.92721, 14.377124, 7.3704467, -18.167463, 11.003454, 6.8469477, -18.167463, 11.003454, 6.8469477, -17.92721, 14.377124, 7.3704467, -13.817183, 14.463108, 5.3506293, -18.167463, 11.003454, 6.8469477, -13.817183, 14.463108, 5.3506293, -14.551012, 11.882277, 4.945571, -21.319002, 11.927798, 5.296257, -21.828173, 14.324436, 6.480244, -17.92721, 14.377124, 7.3704467, -22.586025, 11.236962, 1.0783278, -21.828173, 14.324436, 6.480244, -21.319002, 11.927798, 5.296257, -17.92721, 14.377124, 7.3704467, -15.004122, 16.938564, 4.195724, -13.817183, 14.463108, 5.3506293, -22.586025, 11.236962, 1.0783278, -22.836817, 14.563845, 1.3805406, -21.828173, 14.324436, 6.480244, -20.660202, 12.173107, -2.8445535, -22.836817, 14.563845, 1.3805406, -22.586025, 11.236962, 1.0783278, -21.828173, 14.324436, 6.480244, -17.478313, 17.78409, 4.983925, -17.92721, 14.377124, 7.3704467, -17.92721, 14.377124, 7.3704467, -17.478313, 17.78409, 4.983925, -15.004122, 16.938564, 4.195724, -22.836817, 14.563845, 1.3805406, -20.092022, 16.877449, 4.697728, -21.828173, 14.324436, 6.480244, -21.828173, 14.324436, 6.480244, -20.092022, 16.877449, 4.697728, -17.478313, 17.78409, 4.983925, -20.660202, 12.173107, -2.8445535, -21.181595, 14.743402, -3.6340203, -22.836817, 14.563845, 1.3805406, -21.181595, 14.743402, -3.6340203, -20.660202, 12.173107, -2.8445535, -17.123413, 11.16952, -4.2650013, -22.836817, 14.563845, 1.3805406, -20.424162, 17.830454, 1.7678959, -20.092022, 16.877449, 4.697728, -21.181595, 14.743402, -3.6340203, -20.424162, 17.830454, 1.7678959, -22.836817, 14.563845, 1.3805406, -20.092022, 16.877449, 4.697728, -17.328682, 18.919605, 1.896874, -17.478313, 17.78409, 4.983925, -20.092022, 16.877449, 4.697728, -20.424162, 17.830454, 1.7678959, -17.328682, 18.919605, 1.896874, -21.181595, 14.743402, -3.6340203, -19.804983, 17.063326, -1.3250556, -20.424162, 17.830454, 1.7678959, -21.181595, 14.743402, -3.6340203, -17.123413, 11.16952, -4.2650013, -17.0918, 14.5098915, -4.268796, -19.804983, 17.063326, -1.3250556, -21.181595, 14.743402, -3.6340203, -17.0918, 14.5098915, -4.268796, -17.0918, 14.5098915, -4.268796, -17.123413, 11.16952, -4.2650013, -13.909912, 11.843496, -1.963623, -20.424162, 17.830454, 1.7678959, -19.804983, 17.063326, -1.3250556, -17.269672, 17.816965, -1.3629904, -19.804983, 17.063326, -1.3250556, -17.0918, 14.5098915, -4.268796, -17.269672, 17.816965, -1.3629904, -20.424162, 17.830454, 1.7678959, -17.269672, 17.816965, -1.3629904, -17.328682, 18.919605, 1.896874, -17.0918, 14.5098915, -4.268796, -13.909912, 11.843496, -1.963623, -13.211069, 14.243084, -1.9935503, -17.269672, 17.816965, -1.3629904, -17.0918, 14.5098915, -4.268796, -13.211069, 14.243084, -1.9935503, -12.704849, 10.935591, 1.5040407, -13.211069, 14.243084, -1.9935503, -13.909912, 11.843496, -1.963623, -17.328682, 18.919605, 1.896874, -17.269672, 17.816965, -1.3629904, -14.734785, 16.841198, -0.5958638, -17.269672, 17.816965, -1.3629904, -13.211069, 14.243084, -1.9935503, -14.734785, 16.841198, -0.5958638, -12.704849, 10.935591, 1.5040407, -12.182192, 14.322748, 1.7211109, -13.211069, 14.243084, -1.9935503, -12.182192, 14.322748, 1.7211109, -14.734785, 16.841198, -0.5958638, -13.211069, 14.243084, -1.9935503, -14.551012, 11.882277, 4.945571, -12.182192, 14.322748, 1.7211109, -12.704849, 10.935591, 1.5040407, -14.551012, 11.882277, 4.945571, -13.817183, 14.463108, 5.3506293, -12.182192, 14.322748, 1.7211109, -12.182192, 14.322748, 1.7211109, -14.323402, 17.77018, 1.8530385, -14.734785, 16.841198, -0.5958638, -17.328682, 18.919605, 1.896874, -14.734785, 16.841198, -0.5958638, -14.323402, 17.77018, 1.8530385, -13.817183, 14.463108, 5.3506293, -14.323402, 17.77018, 1.8530385, -12.182192, 14.322748, 1.7211109, -17.478313, 17.78409, 4.983925, -17.328682, 18.919605, 1.896874, -14.323402, 17.77018, 1.8530385, -13.817183, 14.463108, 5.3506293, -15.004122, 16.938564, 4.195724, -14.323402, 17.77018, 1.8530385, -17.478313, 17.78409, 4.983925, -14.323402, 17.77018, 1.8530385, -15.004122, 16.938564, 4.195724, -20.660202, 12.173107, -2.8445535, -17.690748, 9.96741, 1.2047776, -17.123413, 11.16952, -4.2650013, -20.660202, 12.173107, -2.8445535, -22.586025, 11.236962, 1.0783278, -17.690748, 9.96741, 1.2047776, -17.123413, 11.16952, -4.2650013, -17.690748, 9.96741, 1.2047776, -12.704849, 10.935591, 1.5040407, -17.123413, 11.16952, -4.2650013, -12.704849, 10.935591, 1.5040407, -13.909912, 11.843496, -1.963623, -17.690748, 9.96741, 1.2047776, -14.551012, 11.882277, 4.945571, -12.704849, 10.935591, 1.5040407, -17.690748, 9.96741, 1.2047776, -18.167463, 11.003454, 6.8469477, -14.551012, 11.882277, 4.945571, -22.586025, 11.236962, 1.0783278, -18.167463, 11.003454, 6.8469477, -17.690748, 9.96741, 1.2047776, -22.586025, 11.236962, 1.0783278, -21.319002, 11.927798, 5.296257, -18.167463, 11.003454, 6.8469477, -25.366648, 10.824738, 3.0151107, -23.412582, 12.270897, 4.4486246, -23.698359, 10.294915, 3.8003616, -23.698359, 10.294915, 3.8003616, -23.412582, 12.270897, 4.4486246, -20.900877, 12.281435, 3.6722255, -23.698359, 10.294915, 3.8003616, -20.900877, 12.281435, 3.6722255, -21.649036, 10.824738, 3.0151107, -25.366648, 10.824738, 3.0151107, -25.781822, 12.281435, 3.6722255, -23.412582, 12.270897, 4.4486246, -25.781822, 10.349287, 0.97084606, -25.781822, 12.281435, 3.6722255, -25.366648, 10.824738, 3.0151107, -23.412582, 12.270897, 4.4486246, -21.510363, 13.755413, 3.1213274, -20.900877, 12.281435, 3.6722255, -25.781822, 10.349287, 0.97084606, -25.922182, 12.314311, 1.342185, -25.781822, 12.281435, 3.6722255, -24.61638, 10.892176, -0.880373, -25.922182, 12.314311, 1.342185, -25.781822, 10.349287, 0.97084606, -25.781822, 12.281435, 3.6722255, -22.98392, 14.268375, 3.5440893, -23.412582, 12.270897, 4.4486246, -23.412582, 12.270897, 4.4486246, -22.98392, 14.268375, 3.5440893, -21.510363, 13.755413, 3.1213274, -25.922182, 12.314311, 1.342185, -24.61638, 13.755413, 3.1213274, -25.781822, 12.281435, 3.6722255, -25.781822, 12.281435, 3.6722255, -24.61638, 13.755413, 3.1213274, -22.98392, 14.268375, 3.5440893, -24.61638, 10.892176, -0.880373, -24.665274, 12.3467655, -0.9874339, -25.922182, 12.314311, 1.342185, -24.665274, 12.3467655, -0.9874339, -24.61638, 10.892176, -0.880373, -22.98392, 10.403238, -1.8582478, -25.922182, 12.314311, 1.342185, -24.665274, 14.278913, 1.713524, -24.61638, 13.755413, 3.1213274, -24.665274, 12.3467655, -0.9874339, -24.665274, 14.278913, 1.713524, -25.922182, 12.314311, 1.342185, -24.61638, 13.755413, 3.1213274, -22.841454, 14.934341, 1.8374442, -22.98392, 14.268375, 3.5440893, -24.61638, 13.755413, 3.1213274, -24.665274, 14.278913, 1.713524, -22.841454, 14.934341, 1.8374442, -24.665274, 12.3467655, -0.9874339, -24.120277, 13.784074, 0.11351812, -24.665274, 14.278913, 1.713524, -24.665274, 12.3467655, -0.9874339, -22.98392, 10.403238, -1.8582478, -22.841454, 12.357724, -1.763833, -24.120277, 13.784074, 0.11351812, -24.665274, 12.3467655, -0.9874339, -22.841454, 12.357724, -1.763833, -22.841454, 12.357724, -1.763833, -22.98392, 10.403238, -1.8582478, -21.510363, 10.892176, -0.880373, -24.665274, 14.278913, 1.713524, -24.120277, 13.784074, 0.11351812, -22.841454, 14.289871, -0.116620064, -24.120277, 13.784074, 0.11351812, -22.841454, 12.357724, -1.763833, -22.841454, 14.289871, -0.116620064, -24.665274, 14.278913, 1.713524, -22.841454, 14.289871, -0.116620064, -22.841454, 14.934341, 1.8374442, -22.841454, 12.357724, -1.763833, -21.510363, 10.892176, -0.880373, -21.160097, 12.3467655, -0.9874339, -22.841454, 14.289871, -0.116620064, -22.841454, 12.357724, -1.763833, -21.160097, 12.3467655, -0.9874339, -20.900877, 10.349287, 0.97084606, -21.160097, 12.3467655, -0.9874339, -21.510363, 10.892176, -0.880373, -22.841454, 14.934341, 1.8374442, -22.841454, 14.289871, -0.116620064, -21.625853, 13.784074, 0.11351812, -22.841454, 14.289871, -0.116620064, -21.160097, 12.3467655, -0.9874339, -21.625853, 13.784074, 0.11351812, -20.900877, 10.349287, 0.97084606, -20.331432, 12.314311, 1.342185, -21.160097, 12.3467655, -0.9874339, -20.331432, 12.314311, 1.342185, -21.625853, 13.784074, 0.11351812, -21.160097, 12.3467655, -0.9874339, -21.649036, 10.824738, 3.0151107, -20.331432, 12.314311, 1.342185, -20.900877, 10.349287, 0.97084606, -21.649036, 10.824738, 3.0151107, -20.900877, 12.281435, 3.6722255, -20.331432, 12.314311, 1.342185, -20.331432, 12.314311, 1.342185, -21.160097, 14.278913, 1.713524, -21.625853, 13.784074, 0.11351812, -22.841454, 14.934341, 1.8374442, -21.625853, 13.784074, 0.11351812, -21.160097, 14.278913, 1.713524, -20.900877, 12.281435, 3.6722255, -21.160097, 14.278913, 1.713524, -20.331432, 12.314311, 1.342185, -22.98392, 14.268375, 3.5440893, -22.841454, 14.934341, 1.8374442, -21.160097, 14.278913, 1.713524, -20.900877, 12.281435, 3.6722255, -21.510363, 13.755413, 3.1213274, -21.160097, 14.278913, 1.713524, -22.98392, 14.268375, 3.5440893, -21.160097, 14.278913, 1.713524, -21.510363, 13.755413, 3.1213274, -24.61638, 10.892176, -0.880373, -23.412582, 9.69428, 0.8473475, -22.98392, 10.403238, -1.8582478, -24.61638, 10.892176, -0.880373, -25.781822, 10.349287, 0.97084606, -23.412582, 9.69428, 0.8473475, -22.98392, 10.403238, -1.8582478, -23.412582, 9.69428, 0.8473475, -20.900877, 10.349287, 0.97084606, -22.98392, 10.403238, -1.8582478, -20.900877, 10.349287, 0.97084606, -21.510363, 10.892176, -0.880373, -23.412582, 9.69428, 0.8473475, -21.649036, 10.824738, 3.0151107, -20.900877, 10.349287, 0.97084606, -23.412582, 9.69428, 0.8473475, -23.698359, 10.294915, 3.8003616, -21.649036, 10.824738, 3.0151107, -25.781822, 10.349287, 0.97084606, -23.698359, 10.294915, 3.8003616, -23.412582, 9.69428, 0.8473475, -25.781822, 10.349287, 0.97084606, -25.366648, 10.824738, 3.0151107, -23.698359, 10.294915, 3.8003616, -20.253035, 9.625153, -3.2251654, -20.752932, 10.590384, -1.6858549, -20.401823, 9.271516, -2.002821, -20.401823, 9.271516, -2.002821, -20.752932, 10.590384, -1.6858549, -19.734592, 10.597971, -0.2561345, -20.401823, 9.271516, -2.002821, -19.734592, 10.597971, -0.2561345, -19.474949, 9.625154, -0.8681493, -20.253035, 9.625153, -3.2251654, -20.756725, 10.597969, -3.3503504, -20.752932, 10.590384, -1.6858549, -19.044178, 9.307764, -3.9160008, -20.756725, 10.597969, -3.3503504, -20.253035, 9.625153, -3.2251654, -20.752932, 10.590384, -1.6858549, -19.513306, 11.581747, -0.75813866, -19.734592, 10.597971, -0.2561345, -19.044178, 9.307764, -3.9160008, -19.309301, 10.619466, -3.9273815, -20.756725, 10.597969, -3.3503504, -17.62668, 9.670253, -3.5648928, -19.309301, 10.619466, -3.9273815, -19.044178, 9.307764, -3.9160008, -20.756725, 10.597969, -3.3503504, -20.089493, 11.924424, -1.6036634, -20.752932, 10.590384, -1.6858549, -20.752932, 10.590384, -1.6858549, -20.089493, 11.924424, -1.6036634, -19.513306, 11.581747, -0.75813866, -19.309301, 10.619466, -3.9273815, -20.163677, 11.581746, -2.7269554, -20.756725, 10.597969, -3.3503504, -20.756725, 10.597969, -3.3503504, -20.163677, 11.581746, -2.7269554, -20.089493, 11.924424, -1.6036634, -17.62668, 9.670253, -3.5648928, -17.569357, 10.641384, -3.6184235, -19.309301, 10.619466, -3.9273815, -17.569357, 10.641384, -3.6184235, -17.62668, 9.670253, -3.5648928, -16.665245, 9.344013, -2.7349634, -19.309301, 10.619466, -3.9273815, -19.281483, 11.931589, -3.052774, -20.163677, 11.581746, -2.7269554, -17.569357, 10.641384, -3.6184235, -19.281483, 11.931589, -3.052774, -19.309301, 10.619466, -3.9273815, -20.163677, 11.581746, -2.7269554, -18.978003, 12.368683, -1.870472, -20.089493, 11.924424, -1.6036634, -20.163677, 11.581746, -2.7269554, -19.281483, 11.931589, -3.052774, -18.978003, 12.368683, -1.870472, -17.569357, 10.641384, -3.6184235, -18.15271, 11.601134, -3.0422359, -19.281483, 11.931589, -3.052774, -17.569357, 10.641384, -3.6184235, -16.665245, 9.344013, -2.7349634, -16.69475, 10.64855, -2.6245313, -18.15271, 11.601134, -3.0422359, -17.569357, 10.641384, -3.6184235, -16.69475, 10.64855, -2.6245313, -16.69475, 10.64855, -2.6245313, -16.665245, 9.344013, -2.7349634, -16.976309, 9.670254, -1.596076, -19.281483, 11.931589, -3.052774, -18.15271, 11.601134, -3.0422359, -17.739222, 11.938755, -2.279746, -18.15271, 11.601134, -3.0422359, -16.69475, 10.64855, -2.6245313, -17.739222, 11.938755, -2.279746, -19.281483, 11.931589, -3.052774, -17.739222, 11.938755, -2.279746, -18.978003, 12.368683, -1.870472, -16.69475, 10.64855, -2.6245313, -16.976309, 9.670254, -1.596076, -16.835108, 10.641384, -1.396286, -17.739222, 11.938755, -2.279746, -16.69475, 10.64855, -2.6245313, -16.835108, 10.641384, -1.396286, -18.022047, 9.307765, -0.821784, -16.835108, 10.641384, -1.396286, -16.976309, 9.670254, -1.596076, -18.978003, 12.368683, -1.870472, -17.739222, 11.938755, -2.279746, -17.630474, 11.601135, -1.4607759, -17.739222, 11.938755, -2.279746, -16.835108, 10.641384, -1.396286, -17.630474, 11.601135, -1.4607759, -18.022047, 9.307765, -0.821784, -18.138802, 10.619467, -0.38300514, -16.835108, 10.641384, -1.396286, -18.138802, 10.619467, -0.38300514, -17.630474, 11.601135, -1.4607759, -16.835108, 10.641384, -1.396286, -19.474949, 9.625154, -0.8681493, -18.138802, 10.619467, -0.38300514, -18.022047, 9.307765, -0.821784, -19.474949, 9.625154, -0.8681493, -19.734592, 10.597971, -0.2561345, -18.138802, 10.619467, -0.38300514, -18.138802, 10.619467, -0.38300514, -18.547232, 11.93159, -0.8306365, -17.630474, 11.601135, -1.4607759, -18.978003, 12.368683, -1.870472, -17.630474, 11.601135, -1.4607759, -18.547232, 11.93159, -0.8306365, -19.734592, 10.597971, -0.2561345, -18.547232, 11.93159, -0.8306365, -18.138802, 10.619467, -0.38300514, -20.089493, 11.924424, -1.6036634, -18.978003, 12.368683, -1.870472, -18.547232, 11.93159, -0.8306365, -19.734592, 10.597971, -0.2561345, -19.513306, 11.581747, -0.75813866, -18.547232, 11.93159, -0.8306365, -20.089493, 11.924424, -1.6036634, -18.547232, 11.93159, -0.8306365, -19.513306, 11.581747, -0.75813866, -17.62668, 9.670253, -3.5648928, -18.469677, 8.87025, -2.4403362, -16.665245, 9.344013, -2.7349634, -17.62668, 9.670253, -3.5648928, -19.044178, 9.307764, -3.9160008, -18.469677, 8.87025, -2.4403362, -16.665245, 9.344013, -2.7349634, -18.469677, 8.87025, -2.4403362, -18.022047, 9.307765, -0.821784, -16.665245, 9.344013, -2.7349634, -18.022047, 9.307765, -0.821784, -16.976309, 9.670254, -1.596076, -18.469677, 8.87025, -2.4403362, -19.474949, 9.625154, -0.8681493, -18.022047, 9.307765, -0.821784, -18.469677, 8.87025, -2.4403362, -20.401823, 9.271516, -2.002821, -19.474949, 9.625154, -0.8681493, -19.044178, 9.307764, -3.9160008, -20.401823, 9.271516, -2.002821, -18.469677, 8.87025, -2.4403362, -19.044178, 9.307764, -3.9160008, -20.253035, 9.625153, -3.2251654, -20.401823, 9.271516, -2.002821, -17.464405, 7.537475, 1.8374468, -19.955458, 8.19459, 1.3919232, -17.577787, 7.2154503, 1.3678982, -17.464405, 7.537475, 1.8374468, -19.75946, 8.452126, 1.8374465, -19.955458, 8.19459, 1.3919232, -19.75946, 8.452126, 1.8374465, -22.311209, 10.6898575, 1.7080457, -19.955458, 8.19459, 1.3919232, -19.75946, 8.452126, 1.8374465, -22.217215, 10.689015, 1.8374457, -22.311209, 10.6898575, 1.7080457, -19.955458, 8.19459, 1.3919232, -22.311209, 10.6898575, 1.7080457, -22.46337, 10.691122, 1.757361, -17.577787, 7.2154503, 1.3678982, -19.955458, 8.19459, 1.3919232, -20.272423, 7.7777286, 1.5622085, -19.955458, 8.19459, 1.3919232, -22.46337, 10.691122, 1.757361, -20.272423, 7.7777286, 1.5622085, -17.577787, 7.2154503, 1.3678982, -20.272423, 7.7777286, 1.5622085, -17.761982, 6.6949005, 1.547035, -20.272423, 7.7777286, 1.5622085, -22.46337, 10.691122, 1.757361, -22.46337, 10.691122, 1.9175303, -17.761982, 6.6949005, 1.547035, -20.272423, 7.7777286, 1.5622085, -20.272423, 7.777729, 2.1126847, -20.272423, 7.7777286, 1.5622085, -22.46337, 10.691122, 1.9175303, -20.272423, 7.777729, 2.1126847, -17.761982, 6.6949005, 1.547035, -20.272423, 7.777729, 2.1126847, -17.761982, 6.694901, 2.127859, -20.272423, 7.777729, 2.1126847, -22.46337, 10.691122, 1.9175303, -22.311209, 10.689858, 1.9668455, -17.761982, 6.694901, 2.127859, -20.272423, 7.777729, 2.1126847, -19.955458, 8.194591, 2.28297, -20.272423, 7.777729, 2.1126847, -22.311209, 10.689858, 1.9668455, -19.955458, 8.194591, 2.28297, -19.955458, 8.194591, 2.28297, -22.311209, 10.689858, 1.9668455, -22.217215, 10.689015, 1.8374457, -17.761982, 6.694901, 2.127859, -19.955458, 8.194591, 2.28297, -17.577787, 7.215451, 2.3069956, -19.955458, 8.194591, 2.28297, -22.217215, 10.689015, 1.8374457, -19.75946, 8.452126, 1.8374465, -17.577787, 7.215451, 2.3069956, -19.955458, 8.194591, 2.28297, -19.75946, 8.452126, 1.8374465, -17.577787, 7.215451, 2.3069956, -19.75946, 8.452126, 1.8374465, -17.464405, 7.537475, 1.8374468, -19.772528, 3.1467314, 1.8374484, -17.801182, 7.205756, 2.2829702, -18.92911, 3.1467319, 3.0694866, -19.772528, 3.1467314, 1.8374484, -18.119411, 7.263501, 1.8374469, -17.801182, 7.205756, 2.2829702, -18.119411, 7.263501, 1.8374469, -17.641012, 11.282906, 2.034285, -17.801182, 7.205756, 2.2829702, -18.119411, 7.263501, 1.8374469, -17.783056, 11.2980795, 1.8374455, -17.641012, 11.282906, 2.034285, -17.801182, 7.205756, 2.2829702, -17.641012, 11.282906, 2.034285, -17.410873, 11.258881, 1.9592583, -18.92911, 3.1467319, 3.0694866, -17.801182, 7.205756, 2.2829702, -17.28611, 7.1121836, 2.1126852, -17.801182, 7.205756, 2.2829702, -17.410873, 11.258881, 1.9592583, -17.28611, 7.1121836, 2.1126852, -18.92911, 3.1467319, 3.0694866, -17.28611, 7.1121836, 2.1126852, -17.563877, 3.1463103, 2.599095, -17.28611, 7.1121836, 2.1126852, -17.410873, 11.258881, 1.9592583, -17.410873, 11.25888, 1.7156326, -17.563877, 3.1463103, 2.599095, -17.28611, 7.1121836, 2.1126852, -17.28611, 7.1121836, 1.5622088, -17.28611, 7.1121836, 2.1126852, -17.410873, 11.25888, 1.7156326, -17.28611, 7.1121836, 1.5622088, -17.563877, 3.1463103, 2.599095, -17.28611, 7.1121836, 1.5622088, -17.563877, 3.1463099, 1.0758016, -17.28611, 7.1121836, 1.5622088, -17.410873, 11.25888, 1.7156326, -17.641012, 11.282906, 1.6406059, -17.563877, 3.1463099, 1.0758016, -17.28611, 7.1121836, 1.5622088, -17.801182, 7.205756, 1.3919237, -17.28611, 7.1121836, 1.5622088, -17.641012, 11.282906, 1.6406059, -17.801182, 7.205756, 1.3919237, -17.801182, 7.205756, 1.3919237, -17.641012, 11.282906, 1.6406059, -17.783056, 11.2980795, 1.8374455, -17.563877, 3.1463099, 1.0758016, -17.801182, 7.205756, 1.3919237, -18.92911, 3.146731, 0.60541, -17.801182, 7.205756, 1.3919237, -17.783056, 11.2980795, 1.8374455, -18.119411, 7.263501, 1.8374469, -18.92911, 3.146731, 0.60541, -17.801182, 7.205756, 1.3919237, -18.119411, 7.263501, 1.8374469, -18.92911, 3.146731, 0.60541, -18.119411, 7.263501, 1.8374469, -19.772528, 3.1467314, 1.8374484, -17.85176, 7.430414, 1.5381833, -18.091171, 7.869193, -0.13432074, -17.577787, 7.2154503, 1.3678982, -17.85176, 7.430414, 1.5381833, -18.33269, 8.041164, 0.08317232, -18.091171, 7.869193, -0.13432074, -18.33269, 8.041164, 0.08317232, -18.784958, 9.534952, -1.5615134, -18.091171, 7.869193, -0.13432074, -18.33269, 8.041164, 0.08317232, -18.84734, 9.534531, -1.4746847, -18.784958, 9.534952, -1.5615134, -18.091171, 7.869193, -0.13432074, -18.784958, 9.534952, -1.5615134, -18.848183, 9.535795, -1.6474986, -17.577787, 7.2154503, 1.3678982, -18.091171, 7.869193, -0.13432074, -18.265673, 7.5910044, -0.29954767, -18.091171, 7.869193, -0.13432074, -18.848183, 9.535795, -1.6474986, -18.265673, 7.5910044, -0.29954767, -17.577787, 7.2154503, 1.3678982, -18.265673, 7.5910044, -0.29954767, -17.73037, 6.867715, 1.2886567, -18.265673, 7.5910044, -0.29954767, -18.848183, 9.535795, -1.6474986, -18.94934, 9.535795, -1.6142006, -17.73037, 6.867715, 1.2886567, -18.265673, 7.5910044, -0.29954767, -18.614672, 7.591005, -0.18447876, -18.265673, 7.5910044, -0.29954767, -18.94934, 9.535795, -1.6142006, -18.614672, 7.591005, -0.18447876, -17.73037, 6.867715, 1.2886567, -18.614672, 7.591005, -0.18447876, -18.098337, 6.867715, 1.4100481, -18.614672, 7.591005, -0.18447876, -18.94934, 9.535795, -1.6142006, -18.94892, 9.534952, -1.5075612, -18.098337, 6.867715, 1.4100481, -18.614672, 7.591005, -0.18447876, -18.65598, 7.869193, 0.052403092, -18.614672, 7.591005, -0.18447876, -18.94892, 9.534952, -1.5075612, -18.65598, 7.869193, 0.052403092, -18.65598, 7.869193, 0.052403092, -18.94892, 9.534952, -1.5075612, -18.84734, 9.534531, -1.4746847, -18.098337, 6.867715, 1.4100481, -18.65598, 7.869193, 0.052403092, -18.173365, 7.2154503, 1.5643163, -18.65598, 7.869193, 0.052403092, -18.84734, 9.534531, -1.4746847, -18.33269, 8.041164, 0.08317232, -18.173365, 7.2154503, 1.5643163, -18.65598, 7.869193, 0.052403092, -18.33269, 8.041164, 0.08317232, -18.173365, 7.2154503, 1.5643163, -18.33269, 8.041164, 0.08317232, -17.85176, 7.430414, 1.5381833, -18.021717, 16.363804, -17.998592, -21.997292, 20.020512, -13.591122, -21.163078, 14.983807, -13.799868, -21.163078, 14.983807, -13.799868, -21.997292, 20.020512, -13.591122, -20.16242, 20.148884, -7.004968, -21.163078, 14.983807, -13.799868, -20.16242, 20.148884, -7.004968, -19.366419, 16.295841, -7.970547, -18.021717, 16.363804, -17.998592, -19.619282, 19.941853, -19.07104, -21.997292, 20.020512, -13.591122, -11.484028, 15.332424, -18.699127, -19.619282, 19.941853, -19.07104, -18.021717, 16.363804, -17.998592, -21.997292, 20.020512, -13.591122, -18.141577, 23.844606, -8.429464, -20.16242, 20.148884, -7.004968, -11.484028, 15.332424, -18.699127, -11.858614, 20.29928, -19.150177, -19.619282, 19.941853, -19.07104, -6.256456, 16.73004, -14.795372, -11.858614, 20.29928, -19.150177, -11.484028, 15.332424, -18.699127, -19.619282, 19.941853, -19.07104, -18.61851, 25.10693, -12.27676, -21.997292, 20.020512, -13.591122, -21.997292, 20.020512, -13.591122, -18.61851, 25.10693, -12.27676, -18.141577, 23.844606, -8.429464, -11.858614, 20.29928, -19.150177, -17.480486, 23.753365, -16.033627, -19.619282, 19.941853, -19.07104, -19.619282, 19.941853, -19.07104, -17.480486, 23.753365, -16.033627, -18.61851, 25.10693, -12.27676, -6.256456, 16.73004, -14.795372, -4.954714, 20.567348, -15.343607, -11.858614, 20.29928, -19.150177, -4.954714, 20.567348, -15.343607, -6.256456, 16.73004, -14.795372, -5.1436496, 15.231738, -9.215076, -11.858614, 20.29928, -19.150177, -13.089849, 25.17615, -15.716137, -17.480486, 23.753365, -16.033627, -4.954714, 20.567348, -15.343607, -13.089849, 25.17615, -15.716137, -11.858614, 20.29928, -19.150177, -17.480486, 23.753365, -16.033627, -14.129517, 26.802193, -11.209101, -18.61851, 25.10693, -12.27676, -17.480486, 23.753365, -16.033627, -13.089849, 25.17615, -15.716137, -14.129517, 26.802193, -11.209101, -4.954714, 20.567348, -15.343607, -8.721195, 24.030872, -13.957819, -13.089849, 25.17615, -15.716137, -4.954714, 20.567348, -15.343607, -5.1436496, 15.231738, -9.215076, -5.146767, 20.21873, -9.1676445, -8.721195, 24.030872, -13.957819, -4.954714, 20.567348, -15.343607, -5.146767, 20.21873, -9.1676445, -5.146767, 20.21873, -9.1676445, -5.1436496, 15.231738, -9.215076, -9.403631, 16.237947, -5.131659, -13.089849, 25.17615, -15.716137, -8.721195, 24.030872, -13.957819, -9.362032, 25.156012, -10.226952, -8.721195, 24.030872, -13.957819, -5.146767, 20.21873, -9.1676445, -9.362032, 25.156012, -10.226952, -13.089849, 25.17615, -15.716137, -9.362032, 25.156012, -10.226952, -14.129517, 26.802193, -11.209101, -5.146767, 20.21873, -9.1676445, -9.403631, 16.237947, -5.131659, -9.5517025, 19.8204, -4.097917, -9.362032, 25.156012, -10.226952, -5.146767, 20.21873, -9.1676445, -9.5517025, 19.8204, -4.097917, -14.8233185, 14.882492, -4.315932, -9.5517025, 19.8204, -4.097917, -9.403631, 16.237947, -5.131659, -14.129517, 26.802193, -11.209101, -9.362032, 25.156012, -10.226952, -11.184143, 23.699244, -6.717871, -9.362032, 25.156012, -10.226952, -9.5517025, 19.8204, -4.097917, -11.184143, 23.699244, -6.717871, -14.8233185, 14.882492, -4.315932, -15.285444, 19.939335, -3.6085896, -9.5517025, 19.8204, -4.097917, -15.285444, 19.939335, -3.6085896, -11.184143, 23.699244, -6.717871, -9.5517025, 19.8204, -4.097917, -19.366419, 16.295841, -7.970547, -15.285444, 19.939335, -3.6085896, -14.8233185, 14.882492, -4.315932, -19.366419, 16.295841, -7.970547, -20.16242, 20.148884, -7.004968, -15.285444, 19.939335, -3.6085896, -15.285444, 19.939335, -3.6085896, -14.890806, 25.086163, -6.7869554, -11.184143, 23.699244, -6.717871, -14.129517, 26.802193, -11.209101, -11.184143, 23.699244, -6.717871, -14.890806, 25.086163, -6.7869554, -20.16242, 20.148884, -7.004968, -14.890806, 25.086163, -6.7869554, -15.285444, 19.939335, -3.6085896, -18.61851, 25.10693, -12.27676, -14.129517, 26.802193, -11.209101, -14.890806, 25.086163, -6.7869554, -20.16242, 20.148884, -7.004968, -18.141577, 23.844606, -8.429464, -14.890806, 25.086163, -6.7869554, -18.61851, 25.10693, -12.27676, -14.890806, 25.086163, -6.7869554, -18.141577, 23.844606, -8.429464, -6.256456, 16.73004, -14.795372, -13.014427, 13.437051, -11.550283, -5.1436496, 15.231738, -9.215076, -6.256456, 16.73004, -14.795372, -11.484028, 15.332424, -18.699127, -13.014427, 13.437051, -11.550283, -5.1436496, 15.231738, -9.215076, -13.014427, 13.437051, -11.550283, -14.8233185, 14.882492, -4.315932, -5.1436496, 15.231738, -9.215076, -14.8233185, 14.882492, -4.315932, -9.403631, 16.237947, -5.131659, -13.014427, 13.437051, -11.550283, -19.366419, 16.295841, -7.970547, -14.8233185, 14.882492, -4.315932, -13.014427, 13.437051, -11.550283, -21.163078, 14.983807, -13.799868, -19.366419, 16.295841, -7.970547, -11.484028, 15.332424, -18.699127, -21.163078, 14.983807, -13.799868, -13.014427, 13.437051, -11.550283, -11.484028, 15.332424, -18.699127, -18.021717, 16.363804, -17.998592, -21.163078, 14.983807, -13.799868, -13.562267, 14.716995, -23.311634, -16.202703, 16.876032, -20.837955, -15.172899, 13.925998, -21.079226, -15.172899, 13.925998, -21.079226, -16.202703, 16.876032, -20.837955, -15.753397, 16.891764, -16.938854, -15.172899, 13.925998, -21.079226, -15.753397, 16.891764, -16.938854, -14.583576, 14.716994, -17.856216, -13.562267, 14.716995, -23.311634, -14.412493, 16.891764, -24.101406, -16.202703, 16.876032, -20.837955, -10.448349, 14.0071745, -23.35928, -14.412493, 16.891764, -24.101406, -13.562267, 14.716995, -23.311634, -16.202703, 16.876032, -20.837955, -14.777542, 19.092333, -17.681902, -15.753397, 16.891764, -16.938854, -10.448349, 14.0071745, -23.35928, -10.954712, 16.940847, -23.667263, -14.412493, 16.891764, -24.101406, -8.051947, 14.8176775, -21.140478, -10.954712, 16.940847, -23.667263, -10.448349, 14.0071745, -23.35928, -14.412493, 16.891764, -24.101406, -14.993107, 19.85816, -19.960417, -16.202703, 16.876032, -20.837955, -16.202703, 16.876032, -20.837955, -14.993107, 19.85816, -19.960417, -14.777542, 19.092333, -17.681902, -10.954712, 16.940847, -23.667263, -13.92425, 19.092335, -22.239834, -14.412493, 16.891764, -24.101406, -14.412493, 16.891764, -24.101406, -13.92425, 19.092335, -22.239834, -14.993107, 19.85816, -19.960417, -8.051947, 14.8176775, -21.140478, -7.8814073, 16.989302, -21.182816, -10.954712, 16.940847, -23.667263, -7.8814073, 16.989302, -21.182816, -8.051947, 14.8176775, -21.140478, -7.065434, 14.08772, -18.476276, -10.954712, 16.940847, -23.667263, -11.844934, 19.873892, -21.924828, -13.92425, 19.092335, -22.239834, -7.8814073, 16.989302, -21.182816, -11.844934, 19.873892, -21.924828, -10.954712, 16.940847, -23.667263, -13.92425, 19.092335, -22.239834, -12.527824, 20.852411, -19.282501, -14.993107, 19.85816, -19.960417, -13.92425, 19.092335, -22.239834, -11.844934, 19.873892, -21.924828, -12.527824, 20.852411, -19.282501, -7.8814073, 16.989302, -21.182816, -9.646725, 19.135124, -20.685514, -11.844934, 19.873892, -21.924828, -7.8814073, 16.989302, -21.182816, -7.065434, 14.08772, -18.476276, -7.2431235, 17.005661, -18.293152, -9.646725, 19.135124, -20.685514, -7.8814073, 16.989302, -21.182816, -7.2431235, 17.005661, -18.293152, -7.2431235, 17.005661, -18.293152, -7.065434, 14.08772, -18.476276, -8.905237, 14.8176775, -16.582546, -11.844934, 19.873892, -21.924828, -9.646725, 19.135124, -20.685514, -9.66033, 19.890251, -18.745678, -9.646725, 19.135124, -20.685514, -7.2431235, 17.005661, -18.293152, -9.66033, 19.890251, -18.745678, -11.844934, 19.873892, -21.924828, -9.66033, 19.890251, -18.745678, -12.527824, 20.852411, -19.282501, -7.2431235, 17.005661, -18.293152, -8.905237, 14.8176775, -16.582546, -8.844357, 16.9893, -16.039139, -9.66033, 19.890251, -18.745678, -7.2431235, 17.005661, -18.293152, -8.844357, 16.9893, -16.039139, -11.789251, 14.007174, -16.196726, -8.844357, 16.9893, -16.039139, -8.905237, 14.8176775, -16.582546, -12.527824, 20.852411, -19.282501, -9.66033, 19.890251, -18.745678, -10.331999, 19.135124, -17.025066, -9.66033, 19.890251, -18.745678, -8.844357, 16.9893, -16.039139, -10.331999, 19.135124, -17.025066, -11.789251, 14.007174, -16.196726, -12.490612, 16.940847, -15.46311, -8.844357, 16.9893, -16.039139, -12.490612, 16.940847, -15.46311, -10.331999, 19.135124, -17.025066, -8.844357, 16.9893, -16.039139, -14.583576, 14.716994, -17.856216, -12.490612, 16.940847, -15.46311, -11.789251, 14.007174, -16.196726, -14.583576, 14.716994, -17.856216, -15.753397, 16.891764, -16.938854, -12.490612, 16.940847, -15.46311, -12.490612, 16.940847, -15.46311, -12.807882, 19.87389, -16.78115, -10.331999, 19.135124, -17.025066, -12.527824, 20.852411, -19.282501, -10.331999, 19.135124, -17.025066, -12.807882, 19.87389, -16.78115, -15.753397, 16.891764, -16.938854, -12.807882, 19.87389, -16.78115, -12.490612, 16.940847, -15.46311, -14.993107, 19.85816, -19.960417, -12.527824, 20.852411, -19.282501, -12.807882, 19.87389, -16.78115, -15.753397, 16.891764, -16.938854, -14.777542, 19.092333, -17.681902, -12.807882, 19.87389, -16.78115, -14.993107, 19.85816, -19.960417, -12.807882, 19.87389, -16.78115, -14.777542, 19.092333, -17.681902, -8.051947, 14.8176775, -21.140478, -10.918001, 13.029283, -19.848606, -7.065434, 14.08772, -18.476276, -8.051947, 14.8176775, -21.140478, -10.448349, 14.0071745, -23.35928, -10.918001, 13.029283, -19.848606, -7.065434, 14.08772, -18.476276, -10.918001, 13.029283, -19.848606, -11.789251, 14.007174, -16.196726, -7.065434, 14.08772, -18.476276, -11.789251, 14.007174, -16.196726, -8.905237, 14.8176775, -16.582546, -10.918001, 13.029283, -19.848606, -14.583576, 14.716994, -17.856216, -11.789251, 14.007174, -16.196726, -10.918001, 13.029283, -19.848606, -15.172899, 13.925998, -21.079226, -14.583576, 14.716994, -17.856216, -10.448349, 14.0071745, -23.35928, -15.172899, 13.925998, -21.079226, -10.918001, 13.029283, -19.848606, -10.448349, 14.0071745, -23.35928, -13.562267, 14.716995, -23.311634, -15.172899, 13.925998, -21.079226, -5.8097816, 12.926081, -14.093311, -7.931314, 14.367117, -15.249769, -7.562638, 12.39812, -14.647457, -7.562638, 12.39812, -14.647457, -7.931314, 14.367117, -15.249769, -10.30912, 14.378445, -14.14818, -7.562638, 12.39812, -14.647457, -10.30912, 14.378445, -14.14818, -9.4823475, 12.926081, -13.599033, -5.8097816, 12.926081, -14.093311, -5.4877048, 14.378444, -14.798061, -7.931314, 14.367117, -15.249769, -5.128114, 12.452237, -12.129587, -5.4877048, 14.378444, -14.798061, -5.8097816, 12.926081, -14.093311, -7.931314, 14.367117, -15.249769, -9.633245, 15.847169, -13.685543, -10.30912, 14.378445, -14.14818, -5.128114, 12.452237, -12.129587, -5.038579, 14.410537, -12.515514, -5.4877048, 14.378444, -14.798061, -6.032766, 12.993412, -10.145935, -5.038579, 14.410537, -12.515514, -5.128114, 12.452237, -12.129587, -5.4877048, 14.378444, -14.798061, -8.234188, 16.358768, -14.298784, -7.931314, 14.367117, -15.249769, -7.931314, 14.367117, -15.249769, -8.234188, 16.358768, -14.298784, -9.633245, 15.847169, -13.685543, -5.038579, 14.410537, -12.515514, -6.565431, 15.847169, -14.099052, -5.4877048, 14.378444, -14.798061, -5.4877048, 14.378444, -14.798061, -6.565431, 15.847169, -14.099052, -8.234188, 16.358768, -14.298784, -6.032766, 12.993412, -10.145935, -5.9699607, 14.443258, -10.047108, -5.038579, 14.410537, -12.515514, -5.9699607, 14.443258, -10.047108, -6.032766, 12.993412, -10.145935, -7.5147758, 12.506355, -8.963072, -5.038579, 14.410537, -12.515514, -6.3296666, 16.369465, -12.714966, -6.565431, 15.847169, -14.099052, -5.9699607, 14.443258, -10.047108, -6.3296666, 16.369465, -12.714966, -5.038579, 14.410537, -12.515514, -6.565431, 15.847169, -14.099052, -8.14801, 17.022022, -12.594429, -8.234188, 16.358768, -14.298784, -6.565431, 15.847169, -14.099052, -6.3296666, 16.369465, -12.714966, -8.14801, 17.022022, -12.594429, -5.9699607, 14.443258, -10.047108, -6.655229, 15.876115, -11.061441, -6.3296666, 16.369465, -12.714966, -5.9699607, 14.443258, -10.047108, -7.5147758, 12.506355, -8.963072, -7.6687236, 14.453957, -9.036707, -6.655229, 15.876115, -11.061441, -5.9699607, 14.443258, -10.047108, -7.6687236, 14.453957, -9.036707, -7.6687236, 14.453957, -9.036707, -7.5147758, 12.506355, -8.963072, -9.10058, 12.993413, -9.732424, -6.3296666, 16.369465, -12.714966, -6.655229, 15.876115, -11.061441, -7.8877406, 16.380163, -10.664139, -6.655229, 15.876115, -11.061441, -7.6687236, 14.453957, -9.036707, -7.8877406, 16.380163, -10.664139, -6.3296666, 16.369465, -12.714966, -7.8877406, 16.380163, -10.664139, -8.14801, 17.022022, -12.594429, -7.6687236, 14.453957, -9.036707, -9.10058, 12.993413, -9.732424, -9.432554, 14.443259, -9.580103, -7.8877406, 16.380163, -10.664139, -7.6687236, 14.453957, -9.036707, -9.432554, 14.443259, -9.580103, -9.94953, 12.452238, -11.479706, -9.432554, 14.443259, -9.580103, -9.10058, 12.993413, -9.732424, -8.14801, 17.022022, -12.594429, -7.8877406, 16.380163, -10.664139, -9.119415, 15.876115, -10.7295475, -7.8877406, 16.380163, -10.664139, -9.432554, 14.443259, -9.580103, -9.119415, 15.876115, -10.7295475, -9.94953, 12.452238, -11.479706, -10.561342, 14.410537, -11.77158, -9.432554, 14.443259, -9.580103, -10.561342, 14.410537, -11.77158, -9.119415, 15.876115, -10.7295475, -9.432554, 14.443259, -9.580103, -9.4823475, 12.926081, -13.599033, -10.561342, 14.410537, -11.77158, -9.94953, 12.452238, -11.479706, -9.4823475, 12.926081, -13.599033, -10.30912, 14.378445, -14.14818, -10.561342, 14.410537, -11.77158, -10.561342, 14.410537, -11.77158, -9.792261, 16.369465, -12.247959, -9.119415, 15.876115, -10.7295475, -8.14801, 17.022022, -12.594429, -9.119415, 15.876115, -10.7295475, -9.792261, 16.369465, -12.247959, -10.30912, 14.378445, -14.14818, -9.792261, 16.369465, -12.247959, -10.561342, 14.410537, -11.77158, -8.234188, 16.358768, -14.298784, -8.14801, 17.022022, -12.594429, -9.792261, 16.369465, -12.247959, -10.30912, 14.378445, -14.14818, -9.633245, 15.847169, -13.685543, -9.792261, 16.369465, -12.247959, -8.234188, 16.358768, -14.298784, -9.792261, 16.369465, -12.247959, -9.633245, 15.847169, -13.685543, -6.032766, 12.993412, -10.145935, -7.45141, 11.799051, -11.691931, -7.5147758, 12.506355, -8.963072, -6.032766, 12.993412, -10.145935, -5.128114, 12.452237, -12.129587, -7.45141, 11.799051, -11.691931, -7.5147758, 12.506355, -8.963072, -7.45141, 11.799051, -11.691931, -9.94953, 12.452238, -11.479706, -7.5147758, 12.506355, -8.963072, -9.94953, 12.452238, -11.479706, -9.10058, 12.993413, -9.732424, -7.45141, 11.799051, -11.691931, -9.4823475, 12.926081, -13.599033, -9.94953, 12.452238, -11.479706, -7.45141, 11.799051, -11.691931, -7.562638, 12.39812, -14.647457, -9.4823475, 12.926081, -13.599033, -5.128114, 12.452237, -12.129587, -7.562638, 12.39812, -14.647457, -7.45141, 11.799051, -11.691931, -5.128114, 12.452237, -12.129587, -5.8097816, 12.926081, -14.093311, -7.562638, 12.39812, -14.647457, -14.00502, 9.80929, -11.391943, -12.666889, 10.790327, -14.925047, -13.28483, 9.328525, -11.429331, -14.00502, 9.80929, -11.391943, -13.374517, 11.174813, -14.759827, -12.666889, 10.790327, -14.925047, -13.374517, 11.174813, -14.759827, -12.483606, 14.515627, -18.468845, -12.666889, 10.790327, -14.925047, -13.374517, 11.174813, -14.759827, -12.699318, 14.514368, -18.366463, -12.483606, 14.515627, -18.468845, -12.666889, 10.790327, -14.925047, -12.483606, 14.515627, -18.468845, -12.5141735, 14.517514, -18.70568, -13.28483, 9.328525, -11.429331, -12.666889, 10.790327, -14.925047, -12.829697, 10.167975, -15.43696, -12.666889, 10.790327, -14.925047, -12.5141735, 14.517514, -18.70568, -12.829697, 10.167975, -15.43696, -13.28483, 9.328525, -11.429331, -12.829697, 10.167975, -15.43696, -13.497103, 8.551372, -11.74884, -12.829697, 10.167975, -15.43696, -12.5141735, 14.517514, -18.70568, -12.749214, 14.517514, -18.749683, -13.497103, 8.551372, -11.74884, -12.829697, 10.167975, -15.43696, -13.637495, 10.167976, -15.588188, -12.829697, 10.167975, -15.43696, -12.749214, 14.517514, -18.749683, -13.637495, 10.167976, -15.588188, -13.497103, 8.551372, -11.74884, -13.637495, 10.167976, -15.588188, -14.349434, 8.551372, -11.908405, -13.637495, 10.167976, -15.588188, -12.749214, 14.517514, -18.749683, -12.863384, 14.515627, -18.539944, -14.349434, 8.551372, -11.908405, -13.637495, 10.167976, -15.588188, -13.974457, 10.790327, -15.169838, -13.637495, 10.167976, -15.588188, -12.863384, 14.515627, -18.539944, -13.974457, 10.790327, -15.169838, -13.974457, 10.790327, -15.169838, -12.863384, 14.515627, -18.539944, -12.699318, 14.514368, -18.366463, -14.349434, 8.551372, -11.908405, -13.974457, 10.790327, -15.169838, -14.662912, 9.328525, -11.687323, -13.974457, 10.790327, -15.169838, -12.699318, 14.514368, -18.366463, -13.374517, 11.174813, -14.759827, -14.662912, 9.328525, -11.687323, -13.974457, 10.790327, -15.169838, -13.374517, 11.174813, -14.759827, -14.662912, 9.328525, -11.687323, -13.374517, 11.174813, -14.759827, -14.00502, 9.80929, -11.391943, -13.370928, 3.2541475, -14.779001, -14.566284, 9.314051, -12.008541, -15.410591, 3.2541475, -13.879795, -13.370928, 3.2541475, -14.779001, -13.825075, 9.400261, -12.353134, -14.566284, 9.314051, -12.008541, -13.825075, 9.400261, -12.353134, -14.245354, 15.401014, -11.705181, -14.566284, 9.314051, -12.008541, -13.825075, 9.400261, -12.353134, -13.917479, 15.423668, -11.859549, -14.245354, 15.401014, -11.705181, -14.566284, 9.314051, -12.008541, -14.245354, 15.401014, -11.705181, -14.198481, 15.365146, -11.346853, -15.410591, 3.2541475, -13.879795, -14.566284, 9.314051, -12.008541, -14.457899, 9.174353, -11.205919, -14.566284, 9.314051, -12.008541, -14.198481, 15.365146, -11.346853, -14.457899, 9.174353, -11.205919, -15.410591, 3.2541475, -13.879795, -14.457899, 9.174353, -11.205919, -15.095373, 3.253518, -11.747156, -14.457899, 9.174353, -11.205919, -14.198481, 15.365146, -11.346853, -13.840971, 15.365146, -11.279924, -15.095373, 3.253518, -11.747156, -14.457899, 9.174353, -11.205919, -13.650103, 9.174353, -11.054691, -14.457899, 9.174353, -11.205919, -13.840971, 15.365146, -11.279924, -13.650103, 9.174353, -11.054691, -15.095373, 3.253518, -11.747156, -13.650103, 9.174353, -11.054691, -12.860012, 3.253518, -11.328674, -13.650103, 9.174353, -11.054691, -13.840971, 15.365146, -11.279924, -13.667648, 15.401014, -11.597029, -12.860012, 3.253518, -11.328674, -13.650103, 9.174353, -11.054691, -13.258715, 9.314051, -11.763752, -13.650103, 9.174353, -11.054691, -13.667648, 15.401014, -11.597029, -13.258715, 9.314051, -11.763752, -13.258715, 9.314051, -11.763752, -13.667648, 15.401014, -11.597029, -13.917479, 15.423668, -11.859549, -12.860012, 3.253518, -11.328674, -13.258715, 9.314051, -11.763752, -11.794676, 3.2541475, -13.20286, -13.258715, 9.314051, -11.763752, -13.917479, 15.423668, -11.859549, -13.825075, 9.400261, -12.353134, -11.794676, 3.2541475, -13.20286, -13.258715, 9.314051, -11.763752, -13.825075, 9.400261, -12.353134, -11.794676, 3.2541475, -13.20286, -13.825075, 9.400261, -12.353134, -13.370928, 3.2541475, -14.779001, -13.45945, 9.649454, -11.878155, -10.93936, 10.304527, -11.770006, -13.28483, 9.328525, -11.429331, -13.45945, 9.649454, -11.878155, -11.192169, 10.561271, -12.184172, -10.93936, 10.304527, -11.770006, -11.192169, 10.561271, -12.184172, -8.654425, 12.791416, -12.396021, -10.93936, 10.304527, -11.770006, -11.192169, 10.561271, -12.184172, -8.764704, 12.790787, -12.511417, -8.654425, 12.791416, -12.396021, -10.93936, 10.304527, -11.770006, -8.654425, 12.791416, -12.396021, -8.510876, 12.792675, -12.465178, -13.28483, 9.328525, -11.429331, -10.93936, 10.304527, -11.770006, -10.648958, 9.889207, -11.980684, -10.93936, 10.304527, -11.770006, -8.510876, 12.792675, -12.465178, -10.648958, 9.889207, -11.980684, -13.28483, 9.328525, -11.429331, -10.648958, 9.889207, -11.980684, -13.126629, 8.809374, -11.63147, -10.648958, 9.889207, -11.980684, -8.510876, 12.792675, -12.465178, -8.53195, 12.792675, -12.622772, -13.126629, 8.809374, -11.63147, -10.648958, 9.889207, -11.980684, -10.721937, 9.889207, -12.524437, -10.648958, 9.889207, -11.980684, -8.53195, 12.792675, -12.622772, -10.721937, 9.889207, -12.524437, -13.126629, 8.809374, -11.63147, -10.721937, 9.889207, -12.524437, -13.203676, 8.809374, -12.204792, -10.721937, 9.889207, -12.524437, -8.53195, 12.792675, -12.622772, -8.688553, 12.791416, -12.651451, -13.203676, 8.809374, -12.204792, -10.721937, 9.889207, -12.524437, -11.058203, 10.304527, -12.650129, -10.721937, 9.889207, -12.524437, -8.688553, 12.791416, -12.651451, -11.058203, 10.304527, -12.650129, -11.058203, 10.304527, -12.650129, -8.688553, 12.791416, -12.651451, -8.764704, 12.790787, -12.511417, -13.203676, 8.809374, -12.204792, -11.058203, 10.304527, -12.650129, -13.409447, 9.328525, -12.357271, -11.058203, 10.304527, -12.650129, -8.764704, 12.790787, -12.511417, -11.192169, 10.561271, -12.184172, -13.409447, 9.328525, -12.357271, -11.058203, 10.304527, -12.650129, -11.192169, 10.561271, -12.184172, -13.409447, 9.328525, -12.357271, -11.192169, 10.561271, -12.184172, -13.45945, 9.649454, -11.878155, 1.2086613, -17.361609, 9.414333, 2.631641, -16.33421, 10.284525, 2.5310369, -17.7495, 10.064947, 2.5310369, -17.7495, 10.064947, 2.631641, -16.33421, 10.284525, 4.3560047, -16.298113, 9.437187, 2.5310369, -17.7495, 10.064947, 4.3560047, -16.298113, 9.437187, 4.0482125, -17.380833, 9.267164, 1.2086613, -17.361609, 9.414333, 0.99485135, -16.35621, 9.910944, 2.631641, -16.33421, 10.284525, 0.67701983, -17.65146, 7.644686, 0.99485135, -16.35621, 9.910944, 1.2086613, -17.361609, 9.414333, 2.631641, -16.33421, 10.284525, 3.8578982, -15.259179, 8.952537, 4.3560047, -16.298113, 9.437187, 0.67701983, -17.65146, 7.644686, 0.57171667, -16.255608, 7.7713485, 0.99485135, -16.35621, 9.910944, 1.4848416, -17.258871, 5.9989257, 0.57171667, -16.255608, 7.7713485, 0.67701983, -17.65146, 7.644686, 0.99485135, -16.35621, 9.910944, 2.820033, -14.904823, 9.283184, 2.631641, -16.33421, 10.284525, 2.631641, -16.33421, 10.284525, 2.820033, -14.904823, 9.283184, 3.8578982, -15.259179, 8.952537, 0.57171667, -16.255608, 7.7713485, 1.7232151, -15.285238, 9.163143, 0.99485135, -16.35621, 9.910944, 0.99485135, -16.35621, 9.910944, 1.7232151, -15.285238, 9.163143, 2.820033, -14.904823, 9.283184, 1.4848416, -17.258871, 5.9989257, 1.2661188, -16.180422, 5.6674232, 0.57171667, -16.255608, 7.7713485, 1.2661188, -16.180422, 5.6674232, 1.4848416, -17.258871, 5.9989257, 2.9689097, -17.679869, 5.4027777, 0.57171667, -16.255608, 7.7713485, 1.5839503, -14.885172, 7.933895, 1.7232151, -15.285238, 9.163143, 1.2661188, -16.180422, 5.6674232, 1.5839503, -14.885172, 7.933895, 0.57171667, -16.255608, 7.7713485, 1.7232151, -15.285238, 9.163143, 2.8828304, -14.428289, 7.988148, 2.820033, -14.904823, 9.283184, 1.7232151, -15.285238, 9.163143, 1.5839503, -14.885172, 7.933895, 2.8828304, -14.428289, 7.988148, 1.2661188, -16.180422, 5.6674232, 1.8436836, -15.206849, 6.6362967, 1.5839503, -14.885172, 7.933895, 1.2661188, -16.180422, 5.6674232, 2.9689097, -17.679869, 5.4027777, 2.9821527, -16.278463, 5.4012823, 1.8436836, -15.206849, 6.6362967, 1.2661188, -16.180422, 5.6674232, 2.9821527, -16.278463, 5.4012823, 2.9821527, -16.278463, 5.4012823, 2.9689097, -17.679869, 5.4027777, 4.3171306, -17.397068, 6.368234, 1.5839503, -14.885172, 7.933895, 1.8436836, -15.206849, 6.6362967, 2.9076076, -14.890726, 6.620277, 1.8436836, -15.206849, 6.6362967, 2.9821527, -16.278463, 5.4012823, 2.9076076, -14.890726, 6.620277, 1.5839503, -14.885172, 7.933895, 2.9076076, -14.890726, 6.620277, 2.8828304, -14.428289, 7.988148, 2.9821527, -16.278463, 5.4012823, 4.3171306, -17.397068, 6.368234, 4.6103983, -16.390173, 6.355845, 2.9076076, -14.890726, 6.620277, 2.9821527, -16.278463, 5.4012823, 4.6103983, -16.390173, 6.355845, 4.8227134, -17.777908, 7.823253, 4.6103983, -16.390173, 6.355845, 4.3171306, -17.397068, 6.368234, 2.8828304, -14.428289, 7.988148, 2.9076076, -14.890726, 6.620277, 3.9711041, -15.30019, 6.942167, 2.9076076, -14.890726, 6.620277, 4.6103983, -16.390173, 6.355845, 3.9711041, -15.30019, 6.942167, 4.8227134, -17.777908, 7.823253, 5.042077, -16.356638, 7.9142447, 4.6103983, -16.390173, 6.355845, 5.042077, -16.356638, 7.9142447, 3.9711041, -15.30019, 6.942167, 4.6103983, -16.390173, 6.355845, 4.0482125, -17.380833, 9.267164, 5.042077, -16.356638, 7.9142447, 4.8227134, -17.777908, 7.823253, 4.0482125, -17.380833, 9.267164, 4.3560047, -16.298113, 9.437187, 5.042077, -16.356638, 7.9142447, 5.042077, -16.356638, 7.9142447, 4.1434765, -14.910377, 7.969779, 3.9711041, -15.30019, 6.942167, 2.8828304, -14.428289, 7.988148, 3.9711041, -15.30019, 6.942167, 4.1434765, -14.910377, 7.969779, 4.3560047, -16.298113, 9.437187, 4.1434765, -14.910377, 7.969779, 5.042077, -16.356638, 7.9142447, 2.820033, -14.904823, 9.283184, 2.8828304, -14.428289, 7.988148, 4.1434765, -14.910377, 7.969779, 4.3560047, -16.298113, 9.437187, 3.8578982, -15.259179, 8.952537, 4.1434765, -14.910377, 7.969779, 2.820033, -14.904823, 9.283184, 4.1434765, -14.910377, 7.969779, 3.8578982, -15.259179, 8.952537, 1.4848416, -17.258871, 5.9989257, 2.7309632, -18.18417, 7.6976585, 2.9689097, -17.679869, 5.4027777, 1.4848416, -17.258871, 5.9989257, 0.67701983, -17.65146, 7.644686, 2.7309632, -18.18417, 7.6976585, 2.9689097, -17.679869, 5.4027777, 2.7309632, -18.18417, 7.6976585, 4.8227134, -17.777908, 7.823253, 2.9689097, -17.679869, 5.4027777, 4.8227134, -17.777908, 7.823253, 4.3171306, -17.397068, 6.368234, 2.7309632, -18.18417, 7.6976585, 4.0482125, -17.380833, 9.267164, 4.8227134, -17.777908, 7.823253, 2.7309632, -18.18417, 7.6976585, 2.5310369, -17.7495, 10.064947, 4.0482125, -17.380833, 9.267164, 0.67701983, -17.65146, 7.644686, 2.5310369, -17.7495, 10.064947, 2.7309632, -18.18417, 7.6976585, 0.67701983, -17.65146, 7.644686, 1.2086613, -17.361609, 9.414333, 2.5310369, -17.7495, 10.064947, -1.1748617, -18.139956, 8.584938, -0.18462849, -17.407104, 9.311379, -0.3294468, -18.408445, 8.982868, -0.3294468, -18.408445, 8.982868, -0.18462849, -17.407104, 9.311379, 1.0884066, -17.401766, 8.917934, -0.3294468, -18.408445, 8.982868, 1.0884066, -17.401766, 8.917934, 0.70905924, -18.139956, 8.584938, -1.1748617, -18.139956, 8.584938, -1.3850405, -17.401766, 8.917934, -0.18462849, -17.407104, 9.311379, -1.3850405, -18.381105, 7.5489955, -1.3850405, -17.401766, 8.917934, -1.1748617, -18.139956, 8.584938, -0.18462849, -17.407104, 9.311379, 0.7793324, -16.655033, 8.638763, 1.0884066, -17.401766, 8.917934, -1.3850405, -18.381105, 7.5489955, -1.4563816, -17.385319, 7.7371736, -1.3850405, -17.401766, 8.917934, -0.79465985, -18.10578, 6.6108794, -1.4563816, -17.385319, 7.7371736, -1.3850405, -18.381105, 7.5489955, -1.3850405, -17.401766, 8.917934, 0.03259921, -16.395086, 8.853001, -0.18462849, -17.407104, 9.311379, -0.18462849, -17.407104, 9.311379, 0.03259921, -16.395086, 8.853001, 0.7793324, -16.655033, 8.638763, -1.4563816, -17.385319, 7.7371736, -0.79465985, -16.655033, 8.638763, -1.3850405, -17.401766, 8.917934, -1.3850405, -17.401766, 8.917934, -0.79465985, -16.655033, 8.638763, 0.03259921, -16.395086, 8.853001, -0.79465985, -18.10578, 6.6108794, -0.8192234, -17.368872, 6.556626, -1.4563816, -17.385319, 7.7371736, -0.8192234, -17.368872, 6.556626, -0.79465985, -18.10578, 6.6108794, 0.03259921, -18.353552, 6.115336, -1.4563816, -17.385319, 7.7371736, -0.8192234, -16.389532, 7.9253516, -0.79465985, -16.655033, 8.638763, -0.8192234, -17.368872, 6.556626, -0.8192234, -16.389532, 7.9253516, -1.4563816, -17.385319, 7.7371736, -0.79465985, -16.655033, 8.638763, 0.10500836, -16.057604, 7.9881487, 0.03259921, -16.395086, 8.853001, -0.79465985, -16.655033, 8.638763, -0.8192234, -16.389532, 7.9253516, 0.10500836, -16.057604, 7.9881487, -0.8192234, -17.368872, 6.556626, -0.54325676, -16.640295, 7.1145396, -0.8192234, -16.389532, 7.9253516, -0.8192234, -17.368872, 6.556626, 0.03259921, -18.353552, 6.115336, 0.10500836, -17.36332, 6.1631813, -0.54325676, -16.640295, 7.1145396, -0.8192234, -17.368872, 6.556626, 0.10500836, -17.36332, 6.1631813, 0.10500836, -17.36332, 6.1631813, 0.03259921, -18.353552, 6.115336, 0.7793324, -18.10578, 6.6108794, -0.8192234, -16.389532, 7.9253516, -0.54325676, -16.640295, 7.1145396, 0.10500836, -16.38398, 6.9979157, -0.54325676, -16.640295, 7.1145396, 0.10500836, -17.36332, 6.1631813, 0.10500836, -16.38398, 6.9979157, -0.8192234, -16.389532, 7.9253516, 0.10500836, -16.38398, 6.9979157, 0.10500836, -16.057604, 7.9881487, 0.10500836, -17.36332, 6.1631813, 0.7793324, -18.10578, 6.6108794, 0.9570446, -17.368872, 6.556626, 0.10500836, -16.38398, 6.9979157, 0.10500836, -17.36332, 6.1631813, 0.9570446, -17.368872, 6.556626, 1.0884066, -18.381105, 7.5489955, 0.9570446, -17.368872, 6.556626, 0.7793324, -18.10578, 6.6108794, 0.10500836, -16.057604, 7.9881487, 0.10500836, -16.38398, 6.9979157, 0.7210206, -16.640295, 7.1145396, 0.10500836, -16.38398, 6.9979157, 0.9570446, -17.368872, 6.556626, 0.7210206, -16.640295, 7.1145396, 1.0884066, -18.381105, 7.5489955, 1.3767617, -17.385319, 7.7371736, 0.9570446, -17.368872, 6.556626, 1.3767617, -17.385319, 7.7371736, 0.7210206, -16.640295, 7.1145396, 0.9570446, -17.368872, 6.556626, 0.70905924, -18.139956, 8.584938, 1.3767617, -17.385319, 7.7371736, 1.0884066, -18.381105, 7.5489955, 0.70905924, -18.139956, 8.584938, 1.0884066, -17.401766, 8.917934, 1.3767617, -17.385319, 7.7371736, 1.3767617, -17.385319, 7.7371736, 0.9570446, -16.389532, 7.9253516, 0.7210206, -16.640295, 7.1145396, 0.10500836, -16.057604, 7.9881487, 0.7210206, -16.640295, 7.1145396, 0.9570446, -16.389532, 7.9253516, 1.0884066, -17.401766, 8.917934, 0.9570446, -16.389532, 7.9253516, 1.3767617, -17.385319, 7.7371736, 0.03259921, -16.395086, 8.853001, 0.10500836, -16.057604, 7.9881487, 0.9570446, -16.389532, 7.9253516, 1.0884066, -17.401766, 8.917934, 0.7793324, -16.655033, 8.638763, 0.9570446, -16.389532, 7.9253516, 0.03259921, -16.395086, 8.853001, 0.9570446, -16.389532, 7.9253516, 0.7793324, -16.655033, 8.638763, -0.79465985, -18.10578, 6.6108794, -0.18462849, -18.712822, 7.4864116, 0.03259921, -18.353552, 6.115336, -0.79465985, -18.10578, 6.6108794, -1.3850405, -18.381105, 7.5489955, -0.18462849, -18.712822, 7.4864116, 0.03259921, -18.353552, 6.115336, -0.18462849, -18.712822, 7.4864116, 1.0884066, -18.381105, 7.5489955, 0.03259921, -18.353552, 6.115336, 1.0884066, -18.381105, 7.5489955, 0.7793324, -18.10578, 6.6108794, -0.18462849, -18.712822, 7.4864116, 0.70905924, -18.139956, 8.584938, 1.0884066, -18.381105, 7.5489955, -0.18462849, -18.712822, 7.4864116, -0.3294468, -18.408445, 8.982868, 0.70905924, -18.139956, 8.584938, -1.3850405, -18.381105, 7.5489955, -0.3294468, -18.408445, 8.982868, -0.18462849, -18.712822, 7.4864116, -1.3850405, -18.381105, 7.5489955, -1.1748617, -18.139956, 8.584938, -0.3294468, -18.408445, 8.982868, 2.6649618, -19.729753, 7.98815, 1.5668626, -19.439903, 7.791855, 2.6147668, -19.871582, 7.781175, 2.6649618, -19.729753, 7.98815, 1.6531556, -19.32627, 7.98815, 1.5668626, -19.439903, 7.791855, 1.6531556, -19.32627, 7.98815, 0.52835655, -18.340096, 7.9311194, 1.5668626, -19.439903, 7.791855, 1.6531556, -19.32627, 7.98815, 0.5697943, -18.34031, 7.9881496, 0.52835655, -18.340096, 7.9311194, 1.5668626, -19.439903, 7.791855, 0.52835655, -18.340096, 7.9311194, 0.46128738, -18.339455, 7.952906, 2.6147668, -19.871582, 7.781175, 1.5668626, -19.439903, 7.791855, 1.4271705, -19.62381, 7.8668275, 1.5668626, -19.439903, 7.791855, 0.46128738, -18.339455, 7.952906, 1.4271705, -19.62381, 7.8668275, 2.6147668, -19.871582, 7.781175, 1.4271705, -19.62381, 7.8668275, 2.5338137, -20.101198, 7.860206, 1.4271705, -19.62381, 7.8668275, 0.46128738, -18.339455, 7.952906, 0.46128738, -18.339455, 8.023394, 2.5338137, -20.101198, 7.860206, 1.4271705, -19.62381, 7.8668275, 1.4271705, -19.62381, 8.109472, 1.4271705, -19.62381, 7.8668275, 0.46128738, -18.339455, 8.023394, 1.4271705, -19.62381, 8.109472, 2.5338137, -20.101198, 7.860206, 1.4271705, -19.62381, 8.109472, 2.5338137, -20.101198, 8.116095, 1.4271705, -19.62381, 8.109472, 0.46128738, -18.339455, 8.023394, 0.52835655, -18.340096, 8.045179, 2.5338137, -20.101198, 8.116095, 1.4271705, -19.62381, 8.109472, 1.5668626, -19.439903, 8.184445, 1.4271705, -19.62381, 8.109472, 0.52835655, -18.340096, 8.045179, 1.5668626, -19.439903, 8.184445, 1.5668626, -19.439903, 8.184445, 0.52835655, -18.340096, 8.045179, 0.5697943, -18.34031, 7.9881496, 2.5338137, -20.101198, 8.116095, 1.5668626, -19.439903, 8.184445, 2.6147668, -19.871582, 8.195126, 1.5668626, -19.439903, 8.184445, 0.5697943, -18.34031, 7.9881496, 1.6531556, -19.32627, 7.98815, 2.6147668, -19.871582, 8.195126, 1.5668626, -19.439903, 8.184445, 1.6531556, -19.32627, 7.98815, 2.6147668, -19.871582, 8.195126, 1.6531556, -19.32627, 7.98815, 2.6649618, -19.729753, 7.98815, 1.5335416, -22.031042, 7.988151, 2.5325322, -19.973894, 8.213709, 1.9611616, -22.031042, 8.6124935, 1.5335416, -22.031042, 7.988151, 2.3712668, -19.944632, 7.98815, 2.5325322, -19.973894, 8.213709, 2.3712668, -19.944632, 7.98815, 2.613699, -17.907776, 8.087899, 2.5325322, -19.973894, 8.213709, 2.3712668, -19.944632, 7.98815, 2.5417168, -17.900085, 7.9881496, 2.613699, -17.907776, 8.087899, 2.5325322, -19.973894, 8.213709, 2.613699, -17.907776, 8.087899, 2.730536, -17.920164, 8.049879, 1.9611616, -22.031042, 8.6124935, 2.5325322, -19.973894, 8.213709, 2.7935472, -20.021313, 8.127628, 2.5325322, -19.973894, 8.213709, 2.730536, -17.920164, 8.049879, 2.7935472, -20.021313, 8.127628, 1.9611616, -22.031042, 8.6124935, 2.7935472, -20.021313, 8.127628, 2.652787, -22.031042, 8.373906, 2.7935472, -20.021313, 8.127628, 2.730536, -17.920164, 8.049879, 2.730536, -17.920164, 7.92642, 2.652787, -22.031042, 8.373906, 2.7935472, -20.021313, 8.127628, 2.7935472, -20.021313, 7.848672, 2.7935472, -20.021313, 8.127628, 2.730536, -17.920164, 7.92642, 2.7935472, -20.021313, 7.848672, 2.652787, -22.031042, 8.373906, 2.7935472, -20.021313, 7.848672, 2.652787, -22.031042, 7.6021824, 2.7935472, -20.021313, 7.848672, 2.730536, -17.920164, 7.92642, 2.613699, -17.907776, 7.8884, 2.652787, -22.031042, 7.6021824, 2.7935472, -20.021313, 7.848672, 2.5325322, -19.973894, 7.7623787, 2.7935472, -20.021313, 7.848672, 2.613699, -17.907776, 7.8884, 2.5325322, -19.973894, 7.7623787, 2.5325322, -19.973894, 7.7623787, 2.613699, -17.907776, 7.8884, 2.5417168, -17.900085, 7.9881496, 2.652787, -22.031042, 7.6021824, 2.5325322, -19.973894, 7.7623787, 1.9611616, -22.031042, 7.3638086, 2.5325322, -19.973894, 7.7623787, 2.5417168, -17.900085, 7.9881496, 2.3712668, -19.944632, 7.98815, 1.9611616, -22.031042, 7.3638086, 2.5325322, -19.973894, 7.7623787, 2.3712668, -19.944632, 7.98815, 1.9611616, -22.031042, 7.3638086, 2.3712668, -19.944632, 7.98815, 1.5335416, -22.031042, 7.988151, 7.7761884, 7.8527765, 15.352116, 9.199167, 8.88039, 16.222307, 9.098564, 7.4648857, 16.002731, 9.098564, 7.4648857, 16.002731, 9.199167, 8.88039, 16.222307, 10.9235325, 8.916273, 15.3749695, 9.098564, 7.4648857, 16.002731, 10.9235325, 8.916273, 15.3749695, 10.61574, 7.8335533, 15.204948, 7.7761884, 7.8527765, 15.352116, 7.562378, 8.858175, 15.848726, 9.199167, 8.88039, 16.222307, 7.2445464, 7.562926, 13.58247, 7.562378, 8.858175, 15.848726, 7.7761884, 7.8527765, 15.352116, 9.199167, 8.88039, 16.222307, 10.425425, 9.955207, 14.89032, 10.9235325, 8.916273, 15.3749695, 7.2445464, 7.562926, 13.58247, 7.1392436, 8.958778, 13.709131, 7.562378, 8.858175, 15.848726, 8.052368, 7.9555154, 11.936708, 7.1392436, 8.958778, 13.709131, 7.2445464, 7.562926, 13.58247, 7.562378, 8.858175, 15.848726, 9.38756, 10.309776, 15.220966, 9.199167, 8.88039, 16.222307, 9.199167, 8.88039, 16.222307, 9.38756, 10.309776, 15.220966, 10.425425, 9.955207, 14.89032, 7.1392436, 8.958778, 13.709131, 8.290742, 9.929361, 15.100925, 7.562378, 8.858175, 15.848726, 7.562378, 8.858175, 15.848726, 8.290742, 9.929361, 15.100925, 9.38756, 10.309776, 15.220966, 8.052368, 7.9555154, 11.936708, 7.8336453, 9.033964, 11.605206, 7.1392436, 8.958778, 13.709131, 7.8336453, 9.033964, 11.605206, 8.052368, 7.9555154, 11.936708, 9.536436, 7.534303, 11.340561, 7.1392436, 8.958778, 13.709131, 8.151478, 10.329214, 13.871677, 8.290742, 9.929361, 15.100925, 7.8336453, 9.033964, 11.605206, 8.151478, 10.329214, 13.871677, 7.1392436, 8.958778, 13.709131, 8.290742, 9.929361, 15.100925, 9.450357, 10.786097, 13.925932, 9.38756, 10.309776, 15.220966, 8.290742, 9.929361, 15.100925, 8.151478, 10.329214, 13.871677, 9.450357, 10.786097, 13.925932, 7.8336453, 9.033964, 11.605206, 8.411211, 10.007323, 12.5740795, 8.151478, 10.329214, 13.871677, 7.8336453, 9.033964, 11.605206, 9.536436, 7.534303, 11.340561, 9.549679, 8.935923, 11.339066, 8.411211, 10.007323, 12.5740795, 7.8336453, 9.033964, 11.605206, 9.549679, 8.935923, 11.339066, 9.549679, 8.935923, 11.339066, 9.536436, 7.534303, 11.340561, 10.884657, 7.817319, 12.306017, 8.151478, 10.329214, 13.871677, 8.411211, 10.007323, 12.5740795, 9.475134, 10.32366, 12.55806, 8.411211, 10.007323, 12.5740795, 9.549679, 8.935923, 11.339066, 9.475134, 10.32366, 12.55806, 8.151478, 10.329214, 13.871677, 9.475134, 10.32366, 12.55806, 9.450357, 10.786097, 13.925932, 9.549679, 8.935923, 11.339066, 10.884657, 7.817319, 12.306017, 11.177925, 8.823998, 12.293627, 9.475134, 10.32366, 12.55806, 9.549679, 8.935923, 11.339066, 11.177925, 8.823998, 12.293627, 11.39024, 7.4364767, 13.761036, 11.177925, 8.823998, 12.293627, 10.884657, 7.817319, 12.306017, 9.450357, 10.786097, 13.925932, 9.475134, 10.32366, 12.55806, 10.538631, 9.914196, 12.87995, 9.475134, 10.32366, 12.55806, 11.177925, 8.823998, 12.293627, 10.538631, 9.914196, 12.87995, 11.39024, 7.4364767, 13.761036, 11.609604, 8.857534, 13.852028, 11.177925, 8.823998, 12.293627, 11.609604, 8.857534, 13.852028, 10.538631, 9.914196, 12.87995, 11.177925, 8.823998, 12.293627, 10.61574, 7.8335533, 15.204948, 11.609604, 8.857534, 13.852028, 11.39024, 7.4364767, 13.761036, 10.61574, 7.8335533, 15.204948, 10.9235325, 8.916273, 15.3749695, 11.609604, 8.857534, 13.852028, 11.609604, 8.857534, 13.852028, 10.711004, 10.304009, 13.907562, 10.538631, 9.914196, 12.87995, 9.450357, 10.786097, 13.925932, 10.538631, 9.914196, 12.87995, 10.711004, 10.304009, 13.907562, 10.9235325, 8.916273, 15.3749695, 10.711004, 10.304009, 13.907562, 11.609604, 8.857534, 13.852028, 9.38756, 10.309776, 15.220966, 9.450357, 10.786097, 13.925932, 10.711004, 10.304009, 13.907562, 10.9235325, 8.916273, 15.3749695, 10.425425, 9.955207, 14.89032, 10.711004, 10.304009, 13.907562, 9.38756, 10.309776, 15.220966, 10.711004, 10.304009, 13.907562, 10.425425, 9.955207, 14.89032, 8.052368, 7.9555154, 11.936708, 9.298491, 7.030216, 13.635441, 9.536436, 7.534303, 11.340561, 8.052368, 7.9555154, 11.936708, 7.2445464, 7.562926, 13.58247, 9.298491, 7.030216, 13.635441, 9.536436, 7.534303, 11.340561, 9.298491, 7.030216, 13.635441, 11.39024, 7.4364767, 13.761036, 9.536436, 7.534303, 11.340561, 11.39024, 7.4364767, 13.761036, 10.884657, 7.817319, 12.306017, 9.298491, 7.030216, 13.635441, 10.61574, 7.8335533, 15.204948, 11.39024, 7.4364767, 13.761036, 9.298491, 7.030216, 13.635441, 9.098564, 7.4648857, 16.002731, 10.61574, 7.8335533, 15.204948, 7.2445464, 7.562926, 13.58247, 9.098564, 7.4648857, 16.002731, 9.298491, 7.030216, 13.635441, 7.2445464, 7.562926, 13.58247, 7.7761884, 7.8527765, 15.352116, 9.098564, 7.4648857, 16.002731, 5.392665, 7.074431, 14.52272, 6.3828983, 7.807067, 15.249163, 6.23808, 6.805727, 14.9206505, 6.23808, 6.805727, 14.9206505, 6.3828983, 7.807067, 15.249163, 7.6559334, 7.8126206, 14.855719, 6.23808, 6.805727, 14.9206505, 7.6559334, 7.8126206, 14.855719, 7.276586, 7.074431, 14.52272, 5.392665, 7.074431, 14.52272, 5.1824865, 7.8126206, 14.855719, 6.3828983, 7.807067, 15.249163, 5.1824865, 6.83328, 13.486778, 5.1824865, 7.8126206, 14.855719, 5.392665, 7.074431, 14.52272, 6.3828983, 7.807067, 15.249163, 7.3468595, 8.559354, 14.576548, 7.6559334, 7.8126206, 14.855719, 5.1824865, 6.83328, 13.486778, 5.111145, 7.829067, 13.674955, 5.1824865, 7.8126206, 14.855719, 5.772867, 7.108606, 12.548662, 5.111145, 7.829067, 13.674955, 5.1824865, 6.83328, 13.486778, 5.1824865, 7.8126206, 14.855719, 6.600126, 8.819301, 14.790783, 6.3828983, 7.807067, 15.249163, 6.3828983, 7.807067, 15.249163, 6.600126, 8.819301, 14.790783, 7.3468595, 8.559354, 14.576548, 5.111145, 7.829067, 13.674955, 5.772867, 8.559354, 14.576548, 5.1824865, 7.8126206, 14.855719, 5.1824865, 7.8126206, 14.855719, 5.772867, 8.559354, 14.576548, 6.600126, 8.819301, 14.790783, 5.772867, 7.108606, 12.548662, 5.7483034, 7.8455133, 12.49441, 5.111145, 7.829067, 13.674955, 5.7483034, 7.8455133, 12.49441, 5.772867, 7.108606, 12.548662, 6.600126, 6.8608336, 12.05312, 5.111145, 7.829067, 13.674955, 5.7483034, 8.824854, 13.863134, 5.772867, 8.559354, 14.576548, 5.7483034, 7.8455133, 12.49441, 5.7483034, 8.824854, 13.863134, 5.111145, 7.829067, 13.674955, 5.772867, 8.559354, 14.576548, 6.6725354, 9.156782, 13.925932, 6.600126, 8.819301, 14.790783, 5.772867, 8.559354, 14.576548, 5.7483034, 8.824854, 13.863134, 6.6725354, 9.156782, 13.925932, 5.7483034, 7.8455133, 12.49441, 6.02427, 8.574091, 13.052322, 5.7483034, 8.824854, 13.863134, 5.7483034, 7.8455133, 12.49441, 6.600126, 6.8608336, 12.05312, 6.6725354, 7.8510666, 12.100964, 6.02427, 8.574091, 13.052322, 5.7483034, 7.8455133, 12.49441, 6.6725354, 7.8510666, 12.100964, 6.6725354, 7.8510666, 12.100964, 6.600126, 6.8608336, 12.05312, 7.3468595, 7.108606, 12.548662, 5.7483034, 8.824854, 13.863134, 6.02427, 8.574091, 13.052322, 6.6725354, 8.830407, 12.935699, 6.02427, 8.574091, 13.052322, 6.6725354, 7.8510666, 12.100964, 6.6725354, 8.830407, 12.935699, 5.7483034, 8.824854, 13.863134, 6.6725354, 8.830407, 12.935699, 6.6725354, 9.156782, 13.925932, 6.6725354, 7.8510666, 12.100964, 7.3468595, 7.108606, 12.548662, 7.5245714, 7.8455133, 12.49441, 6.6725354, 8.830407, 12.935699, 6.6725354, 7.8510666, 12.100964, 7.5245714, 7.8455133, 12.49441, 7.6559334, 6.83328, 13.486778, 7.5245714, 7.8455133, 12.49441, 7.3468595, 7.108606, 12.548662, 6.6725354, 9.156782, 13.925932, 6.6725354, 8.830407, 12.935699, 7.2885475, 8.574091, 13.052322, 6.6725354, 8.830407, 12.935699, 7.5245714, 7.8455133, 12.49441, 7.2885475, 8.574091, 13.052322, 7.6559334, 6.83328, 13.486778, 7.9442887, 7.829067, 13.674955, 7.5245714, 7.8455133, 12.49441, 7.9442887, 7.829067, 13.674955, 7.2885475, 8.574091, 13.052322, 7.5245714, 7.8455133, 12.49441, 7.276586, 7.074431, 14.52272, 7.9442887, 7.829067, 13.674955, 7.6559334, 6.83328, 13.486778, 7.276586, 7.074431, 14.52272, 7.6559334, 7.8126206, 14.855719, 7.9442887, 7.829067, 13.674955, 7.9442887, 7.829067, 13.674955, 7.5245714, 8.824854, 13.863134, 7.2885475, 8.574091, 13.052322, 6.6725354, 9.156782, 13.925932, 7.2885475, 8.574091, 13.052322, 7.5245714, 8.824854, 13.863134, 7.6559334, 7.8126206, 14.855719, 7.5245714, 8.824854, 13.863134, 7.9442887, 7.829067, 13.674955, 6.600126, 8.819301, 14.790783, 6.6725354, 9.156782, 13.925932, 7.5245714, 8.824854, 13.863134, 7.6559334, 7.8126206, 14.855719, 7.3468595, 8.559354, 14.576548, 7.5245714, 8.824854, 13.863134, 6.600126, 8.819301, 14.790783, 7.5245714, 8.824854, 13.863134, 7.3468595, 8.559354, 14.576548, 5.772867, 7.108606, 12.548662, 6.3828983, 6.5013514, 13.424194, 6.600126, 6.8608336, 12.05312, 5.772867, 7.108606, 12.548662, 5.1824865, 6.83328, 13.486778, 6.3828983, 6.5013514, 13.424194, 6.600126, 6.8608336, 12.05312, 6.3828983, 6.5013514, 13.424194, 7.6559334, 6.83328, 13.486778, 6.600126, 6.8608336, 12.05312, 7.6559334, 6.83328, 13.486778, 7.3468595, 7.108606, 12.548662, 6.3828983, 6.5013514, 13.424194, 7.276586, 7.074431, 14.52272, 7.6559334, 6.83328, 13.486778, 6.3828983, 6.5013514, 13.424194, 6.23808, 6.805727, 14.9206505, 7.276586, 7.074431, 14.52272, 5.1824865, 6.83328, 13.486778, 6.23808, 6.805727, 14.9206505, 6.3828983, 6.5013514, 13.424194, 5.1824865, 6.83328, 13.486778, 5.392665, 7.074431, 14.52272, 6.23808, 6.805727, 14.9206505, 9.232489, 5.4846325, 13.925934, 8.13439, 5.7744827, 13.729637, 9.182293, 5.342804, 13.718958, 9.232489, 5.4846325, 13.925934, 8.220682, 5.8879023, 13.925932, 8.13439, 5.7744827, 13.729637, 8.220682, 5.8879023, 13.925932, 7.0958834, 6.874291, 13.868902, 8.13439, 5.7744827, 13.729637, 8.220682, 5.8879023, 13.925932, 7.137321, 6.8738637, 13.925932, 7.0958834, 6.874291, 13.868902, 8.13439, 5.7744827, 13.729637, 7.0958834, 6.874291, 13.868902, 7.0288143, 6.874932, 13.89069, 9.182293, 5.342804, 13.718958, 8.13439, 5.7744827, 13.729637, 7.994697, 5.590576, 13.804609, 8.13439, 5.7744827, 13.729637, 7.0288143, 6.874932, 13.89069, 7.994697, 5.590576, 13.804609, 9.182293, 5.342804, 13.718958, 7.994697, 5.590576, 13.804609, 9.101341, 5.1134014, 13.797989, 7.994697, 5.590576, 13.804609, 7.0288143, 6.874932, 13.89069, 7.0288143, 6.874932, 13.961176, 9.101341, 5.1134014, 13.797989, 7.994697, 5.590576, 13.804609, 7.994697, 5.590576, 14.047256, 7.994697, 5.590576, 13.804609, 7.0288143, 6.874932, 13.961176, 7.994697, 5.590576, 14.047256, 9.101341, 5.1134014, 13.797989, 7.994697, 5.590576, 14.047256, 9.101341, 5.113402, 14.053877, 7.994697, 5.590576, 14.047256, 7.0288143, 6.874932, 13.961176, 7.0958834, 6.874291, 13.982964, 9.101341, 5.113402, 14.053877, 7.994697, 5.590576, 14.047256, 8.13439, 5.7744827, 14.122229, 7.994697, 5.590576, 14.047256, 7.0958834, 6.874291, 13.982964, 8.13439, 5.7744827, 14.122229, 8.13439, 5.7744827, 14.122229, 7.0958834, 6.874291, 13.982964, 7.137321, 6.8738637, 13.925932, 9.101341, 5.113402, 14.053877, 8.13439, 5.7744827, 14.122229, 9.182293, 5.3428044, 14.132908, 8.13439, 5.7744827, 14.122229, 7.137321, 6.8738637, 13.925932, 8.220682, 5.8879023, 13.925932, 9.182293, 5.3428044, 14.132908, 8.13439, 5.7744827, 14.122229, 8.220682, 5.8879023, 13.925932, 9.182293, 5.3428044, 14.132908, 8.220682, 5.8879023, 13.925932, 9.232489, 5.4846325, 13.925934, 8.1010685, 3.1833441, 13.925934, 9.1000595, 5.240492, 14.151705, 8.528688, 3.1833444, 14.550276, 8.1010685, 3.1833441, 13.925934, 8.938793, 5.2697544, 13.925934, 9.1000595, 5.240492, 14.151705, 8.938793, 5.2697544, 13.925934, 9.181226, 7.30661, 14.025682, 9.1000595, 5.240492, 14.151705, 8.938793, 5.2697544, 13.925934, 9.109243, 7.314086, 13.925932, 9.181226, 7.30661, 14.025682, 9.1000595, 5.240492, 14.151705, 9.181226, 7.30661, 14.025682, 9.298063, 7.2942214, 13.987661, 8.528688, 3.1833444, 14.550276, 9.1000595, 5.240492, 14.151705, 9.361288, 5.1928596, 14.0654125, 9.1000595, 5.240492, 14.151705, 9.298063, 7.2942214, 13.987661, 9.361288, 5.1928596, 14.0654125, 8.528688, 3.1833444, 14.550276, 9.361288, 5.1928596, 14.0654125, 9.220314, 3.1833444, 14.311903, 9.361288, 5.1928596, 14.0654125, 9.298063, 7.2942214, 13.987661, 9.298063, 7.2942214, 13.8642025, 9.220314, 3.1833444, 14.311903, 9.361288, 5.1928596, 14.0654125, 9.361074, 5.1928596, 13.786455, 9.361288, 5.1928596, 14.0654125, 9.298063, 7.2942214, 13.8642025, 9.361074, 5.1928596, 13.786455, 9.220314, 3.1833444, 14.311903, 9.361074, 5.1928596, 13.786455, 9.220314, 3.1833441, 13.539965, 9.361074, 5.1928596, 13.786455, 9.298063, 7.2942214, 13.8642025, 9.181226, 7.30661, 13.826183, 9.220314, 3.1833441, 13.539965, 9.361074, 5.1928596, 13.786455, 9.1000595, 5.240492, 13.700161, 9.361074, 5.1928596, 13.786455, 9.181226, 7.30661, 13.826183, 9.1000595, 5.240492, 13.700161, 9.1000595, 5.240492, 13.700161, 9.181226, 7.30661, 13.826183, 9.109243, 7.314086, 13.925932, 9.220314, 3.1833441, 13.539965, 9.1000595, 5.240492, 13.700161, 8.528688, 3.183344, 13.301592, 9.1000595, 5.240492, 13.700161, 9.109243, 7.314086, 13.925932, 8.938793, 5.2697544, 13.925934, 8.528688, 3.183344, 13.301592, 9.1000595, 5.240492, 13.700161, 8.938793, 5.2697544, 13.925934, 8.528688, 3.183344, 13.301592, 8.938793, 5.2697544, 13.925934, 8.1010685, 3.1833441, 13.925934, -21.010672, 7.8103647, 2.1272998, -19.587692, 8.837978, 2.9974916, -19.688295, 7.422474, 2.7779148, -19.688295, 7.422474, 2.7779148, -19.587692, 8.837978, 2.9974916, -17.863327, 8.873861, 2.1501544, -19.688295, 7.422474, 2.7779148, -17.863327, 8.873861, 2.1501544, -18.17112, 7.7911415, 1.9801317, -21.010672, 7.8103647, 2.1272998, -21.224482, 8.815763, 2.6239111, -19.587692, 8.837978, 2.9974916, -21.542313, 7.520514, 0.35765326, -21.224482, 8.815763, 2.6239111, -21.010672, 7.8103647, 2.1272998, -19.587692, 8.837978, 2.9974916, -18.361435, 9.912795, 1.6655035, -17.863327, 8.873861, 2.1501544, -21.542313, 7.520514, 0.35765326, -21.647615, 8.916367, 0.4843155, -21.224482, 8.815763, 2.6239111, -20.734491, 7.9131036, -1.2881074, -21.647615, 8.916367, 0.4843155, -21.542313, 7.520514, 0.35765326, -21.224482, 8.815763, 2.6239111, -19.3993, 10.2673645, 1.9961507, -19.587692, 8.837978, 2.9974916, -19.587692, 8.837978, 2.9974916, -19.3993, 10.2673645, 1.9961507, -18.361435, 9.912795, 1.6655035, -21.647615, 8.916367, 0.4843155, -20.496117, 9.88695, 1.8761096, -21.224482, 8.815763, 2.6239111, -21.224482, 8.815763, 2.6239111, -20.496117, 9.88695, 1.8761096, -19.3993, 10.2673645, 1.9961507, -20.734491, 7.9131036, -1.2881074, -20.953215, 8.991552, -1.6196096, -21.647615, 8.916367, 0.4843155, -20.953215, 8.991552, -1.6196096, -20.734491, 7.9131036, -1.2881074, -19.250423, 7.4918914, -1.8842552, -21.647615, 8.916367, 0.4843155, -20.635382, 10.286802, 0.6468619, -20.496117, 9.88695, 1.8761096, -20.953215, 8.991552, -1.6196096, -20.635382, 10.286802, 0.6468619, -21.647615, 8.916367, 0.4843155, -20.496117, 9.88695, 1.8761096, -19.336502, 10.743685, 0.70111525, -19.3993, 10.2673645, 1.9961507, -20.496117, 9.88695, 1.8761096, -20.635382, 10.286802, 0.6468619, -19.336502, 10.743685, 0.70111525, -20.953215, 8.991552, -1.6196096, -20.375648, 9.964911, -0.65073633, -20.635382, 10.286802, 0.6468619, -20.953215, 8.991552, -1.6196096, -19.250423, 7.4918914, -1.8842552, -19.23718, 8.893511, -1.885751, -20.375648, 9.964911, -0.65073633, -20.953215, 8.991552, -1.6196096, -19.23718, 8.893511, -1.885751, -19.23718, 8.893511, -1.885751, -19.250423, 7.4918914, -1.8842552, -17.902203, 7.774907, -0.91879916, -20.635382, 10.286802, 0.6468619, -20.375648, 9.964911, -0.65073633, -19.311726, 10.281248, -0.66675615, -20.375648, 9.964911, -0.65073633, -19.23718, 8.893511, -1.885751, -19.311726, 10.281248, -0.66675615, -20.635382, 10.286802, 0.6468619, -19.311726, 10.281248, -0.66675615, -19.336502, 10.743685, 0.70111525, -19.23718, 8.893511, -1.885751, -17.902203, 7.774907, -0.91879916, -17.608934, 8.781587, -0.9311881, -19.311726, 10.281248, -0.66675615, -19.23718, 8.893511, -1.885751, -17.608934, 8.781587, -0.9311881, -17.39662, 7.394065, 0.53621995, -17.608934, 8.781587, -0.9311881, -17.902203, 7.774907, -0.91879916, -19.336502, 10.743685, 0.70111525, -19.311726, 10.281248, -0.66675615, -18.248228, 9.871784, -0.34486628, -19.311726, 10.281248, -0.66675615, -17.608934, 8.781587, -0.9311881, -18.248228, 9.871784, -0.34486628, -17.39662, 7.394065, 0.53621995, -17.177256, 8.815123, 0.6272116, -17.608934, 8.781587, -0.9311881, -17.177256, 8.815123, 0.6272116, -18.248228, 9.871784, -0.34486628, -17.608934, 8.781587, -0.9311881, -18.17112, 7.7911415, 1.9801317, -17.177256, 8.815123, 0.6272116, -17.39662, 7.394065, 0.53621995, -18.17112, 7.7911415, 1.9801317, -17.863327, 8.873861, 2.1501544, -17.177256, 8.815123, 0.6272116, -17.177256, 8.815123, 0.6272116, -18.075855, 10.261598, 0.6827462, -18.248228, 9.871784, -0.34486628, -19.336502, 10.743685, 0.70111525, -18.248228, 9.871784, -0.34486628, -18.075855, 10.261598, 0.6827462, -17.863327, 8.873861, 2.1501544, -18.075855, 10.261598, 0.6827462, -17.177256, 8.815123, 0.6272116, -19.3993, 10.2673645, 1.9961507, -19.336502, 10.743685, 0.70111525, -18.075855, 10.261598, 0.6827462, -17.863327, 8.873861, 2.1501544, -18.361435, 9.912795, 1.6655035, -18.075855, 10.261598, 0.6827462, -19.3993, 10.2673645, 1.9961507, -18.075855, 10.261598, 0.6827462, -18.361435, 9.912795, 1.6655035, -20.734491, 7.9131036, -1.2881074, -19.488369, 6.9878044, 0.41062546, -19.250423, 7.4918914, -1.8842552, -20.734491, 7.9131036, -1.2881074, -21.542313, 7.520514, 0.35765326, -19.488369, 6.9878044, 0.41062546, -19.250423, 7.4918914, -1.8842552, -19.488369, 6.9878044, 0.41062546, -17.39662, 7.394065, 0.53621995, -19.250423, 7.4918914, -1.8842552, -17.39662, 7.394065, 0.53621995, -17.902203, 7.774907, -0.91879916, -19.488369, 6.9878044, 0.41062546, -18.17112, 7.7911415, 1.9801317, -17.39662, 7.394065, 0.53621995, -19.488369, 6.9878044, 0.41062546, -19.688295, 7.422474, 2.7779148, -18.17112, 7.7911415, 1.9801317, -21.542313, 7.520514, 0.35765326, -19.688295, 7.422474, 2.7779148, -19.488369, 6.9878044, 0.41062546, -21.542313, 7.520514, 0.35765326, -21.010672, 7.8103647, 2.1272998, -19.688295, 7.422474, 2.7779148, -23.394194, 7.032019, 1.297905, -22.403961, 7.764655, 2.0243464, -22.54878, 6.763315, 1.6958355, -22.54878, 6.763315, 1.6958355, -22.403961, 7.764655, 2.0243464, -21.130926, 7.770209, 1.6309018, -22.54878, 6.763315, 1.6958355, -21.130926, 7.770209, 1.6309018, -21.510273, 7.032019, 1.297905, -23.394194, 7.032019, 1.297905, -23.604374, 7.770209, 1.6309018, -22.403961, 7.764655, 2.0243464, -23.604374, 6.7908683, 0.2619624, -23.604374, 7.770209, 1.6309018, -23.394194, 7.032019, 1.297905, -22.403961, 7.764655, 2.0243464, -21.44, 8.516942, 1.3517308, -21.130926, 7.770209, 1.6309018, -23.604374, 6.7908683, 0.2619624, -23.675714, 7.7866554, 0.45014048, -23.604374, 7.770209, 1.6309018, -23.013992, 7.066194, -0.6761534, -23.675714, 7.7866554, 0.45014048, -23.604374, 6.7908683, 0.2619624, -23.604374, 7.770209, 1.6309018, -22.186733, 8.776889, 1.5659679, -22.403961, 7.764655, 2.0243464, -22.403961, 7.764655, 2.0243464, -22.186733, 8.776889, 1.5659679, -21.44, 8.516942, 1.3517308, -23.675714, 7.7866554, 0.45014048, -23.013992, 8.516942, 1.3517308, -23.604374, 7.770209, 1.6309018, -23.604374, 7.770209, 1.6309018, -23.013992, 8.516942, 1.3517308, -22.186733, 8.776889, 1.5659679, -23.013992, 7.066194, -0.6761534, -23.038557, 7.8031015, -0.73040724, -23.675714, 7.7866554, 0.45014048, -23.038557, 7.8031015, -0.73040724, -23.013992, 7.066194, -0.6761534, -22.186733, 6.818422, -1.1716971, -23.675714, 7.7866554, 0.45014048, -23.038557, 8.782442, 0.63831854, -23.013992, 8.516942, 1.3517308, -23.038557, 7.8031015, -0.73040724, -23.038557, 8.782442, 0.63831854, -23.675714, 7.7866554, 0.45014048, -23.013992, 8.516942, 1.3517308, -22.114325, 9.11437, 0.70111585, -22.186733, 8.776889, 1.5659679, -23.013992, 8.516942, 1.3517308, -23.038557, 8.782442, 0.63831854, -22.114325, 9.11437, 0.70111585, -23.038557, 7.8031015, -0.73040724, -22.76259, 8.531679, -0.17249346, -23.038557, 8.782442, 0.63831854, -23.038557, 7.8031015, -0.73040724, -22.186733, 6.818422, -1.1716971, -22.114325, 7.808655, -1.1238518, -22.76259, 8.531679, -0.17249346, -23.038557, 7.8031015, -0.73040724, -22.114325, 7.808655, -1.1238518, -22.114325, 7.808655, -1.1238518, -22.186733, 6.818422, -1.1716971, -21.44, 7.066194, -0.6761534, -23.038557, 8.782442, 0.63831854, -22.76259, 8.531679, -0.17249346, -22.114325, 8.787995, -0.28911734, -22.76259, 8.531679, -0.17249346, -22.114325, 7.808655, -1.1238518, -22.114325, 8.787995, -0.28911734, -23.038557, 8.782442, 0.63831854, -22.114325, 8.787995, -0.28911734, -22.114325, 9.11437, 0.70111585, -22.114325, 7.808655, -1.1238518, -21.44, 7.066194, -0.6761534, -21.262287, 7.8031015, -0.73040724, -22.114325, 8.787995, -0.28911734, -22.114325, 7.808655, -1.1238518, -21.262287, 7.8031015, -0.73040724, -21.130926, 6.7908683, 0.2619624, -21.262287, 7.8031015, -0.73040724, -21.44, 7.066194, -0.6761534, -22.114325, 9.11437, 0.70111585, -22.114325, 8.787995, -0.28911734, -21.498312, 8.531679, -0.17249346, -22.114325, 8.787995, -0.28911734, -21.262287, 7.8031015, -0.73040724, -21.498312, 8.531679, -0.17249346, -21.130926, 6.7908683, 0.2619624, -20.842571, 7.7866554, 0.45014048, -21.262287, 7.8031015, -0.73040724, -20.842571, 7.7866554, 0.45014048, -21.498312, 8.531679, -0.17249346, -21.262287, 7.8031015, -0.73040724, -21.510273, 7.032019, 1.297905, -20.842571, 7.7866554, 0.45014048, -21.130926, 6.7908683, 0.2619624, -21.510273, 7.032019, 1.297905, -21.130926, 7.770209, 1.6309018, -20.842571, 7.7866554, 0.45014048, -20.842571, 7.7866554, 0.45014048, -21.262287, 8.782442, 0.63831854, -21.498312, 8.531679, -0.17249346, -22.114325, 9.11437, 0.70111585, -21.498312, 8.531679, -0.17249346, -21.262287, 8.782442, 0.63831854, -21.130926, 7.770209, 1.6309018, -21.262287, 8.782442, 0.63831854, -20.842571, 7.7866554, 0.45014048, -22.186733, 8.776889, 1.5659679, -22.114325, 9.11437, 0.70111585, -21.262287, 8.782442, 0.63831854, -21.130926, 7.770209, 1.6309018, -21.44, 8.516942, 1.3517308, -21.262287, 8.782442, 0.63831854, -22.186733, 8.776889, 1.5659679, -21.262287, 8.782442, 0.63831854, -21.44, 8.516942, 1.3517308, -23.013992, 7.066194, -0.6761534, -22.403961, 6.4589396, 0.19937873, -22.186733, 6.818422, -1.1716971, -23.013992, 7.066194, -0.6761534, -23.604374, 6.7908683, 0.2619624, -22.403961, 6.4589396, 0.19937873, -22.186733, 6.818422, -1.1716971, -22.403961, 6.4589396, 0.19937873, -21.130926, 6.7908683, 0.2619624, -22.186733, 6.818422, -1.1716971, -21.130926, 6.7908683, 0.2619624, -21.44, 7.066194, -0.6761534, -22.403961, 6.4589396, 0.19937873, -21.510273, 7.032019, 1.297905, -21.130926, 6.7908683, 0.2619624, -22.403961, 6.4589396, 0.19937873, -22.54878, 6.763315, 1.6958355, -21.510273, 7.032019, 1.297905, -23.604374, 6.7908683, 0.2619624, -22.54878, 6.763315, 1.6958355, -22.403961, 6.4589396, 0.19937873, -23.604374, 6.7908683, 0.2619624, -23.394194, 7.032019, 1.297905, -22.54878, 6.763315, 1.6958355, -19.55437, 5.4422207, 0.70111716, -20.65247, 5.732071, 0.5048219, -19.604567, 5.300392, 0.49414217, -19.55437, 5.4422207, 0.70111716, -20.566177, 5.8454905, 0.70111704, -20.65247, 5.732071, 0.5048219, -20.566177, 5.8454905, 0.70111704, -21.690977, 6.831879, 0.64408636, -20.65247, 5.732071, 0.5048219, -20.566177, 5.8454905, 0.70111704, -21.649538, 6.831452, 0.7011167, -21.690977, 6.831879, 0.64408636, -20.65247, 5.732071, 0.5048219, -21.690977, 6.831879, 0.64408636, -21.758045, 6.83252, 0.66587317, -19.604567, 5.300392, 0.49414217, -20.65247, 5.732071, 0.5048219, -20.792162, 5.5481644, 0.5797943, -20.65247, 5.732071, 0.5048219, -21.758045, 6.83252, 0.66587317, -20.792162, 5.5481644, 0.5797943, -19.604567, 5.300392, 0.49414217, -20.792162, 5.5481644, 0.5797943, -19.685518, 5.0709896, 0.57317305, -20.792162, 5.5481644, 0.5797943, -21.758045, 6.83252, 0.66587317, -21.758045, 6.83252, 0.7363601, -19.685518, 5.0709896, 0.57317305, -20.792162, 5.5481644, 0.5797943, -20.792162, 5.5481644, 0.8224399, -20.792162, 5.5481644, 0.5797943, -21.758045, 6.83252, 0.7363601, -20.792162, 5.5481644, 0.8224399, -19.685518, 5.0709896, 0.57317305, -20.792162, 5.5481644, 0.8224399, -19.685518, 5.07099, 0.8290615, -20.792162, 5.5481644, 0.8224399, -21.758045, 6.83252, 0.7363601, -21.690977, 6.831879, 0.7581469, -19.685518, 5.07099, 0.8290615, -20.792162, 5.5481644, 0.8224399, -20.65247, 5.732071, 0.8974122, -20.792162, 5.5481644, 0.8224399, -21.690977, 6.831879, 0.7581469, -20.65247, 5.732071, 0.8974122, -20.65247, 5.732071, 0.8974122, -21.690977, 6.831879, 0.7581469, -21.649538, 6.831452, 0.7011167, -19.685518, 5.07099, 0.8290615, -20.65247, 5.732071, 0.8974122, -19.604567, 5.3003926, 0.90809214, -20.65247, 5.732071, 0.8974122, -21.649538, 6.831452, 0.7011167, -20.566177, 5.8454905, 0.70111704, -19.604567, 5.3003926, 0.90809214, -20.65247, 5.732071, 0.8974122, -20.566177, 5.8454905, 0.70111704, -19.604567, 5.3003926, 0.90809214, -20.566177, 5.8454905, 0.70111704, -19.55437, 5.4422207, 0.70111716, -20.685791, 3.1409323, 0.701118, -19.6868, 5.19808, 0.9268887, -20.258171, 3.1409326, 1.3254604, -20.685791, 3.1409323, 0.701118, -19.848066, 5.2273426, 0.70111716, -19.6868, 5.19808, 0.9268887, -19.848066, 5.2273426, 0.70111716, -19.605635, 7.2641983, 0.800866, -19.6868, 5.19808, 0.9268887, -19.848066, 5.2273426, 0.70111716, -19.677616, 7.271674, 0.70111644, -19.605635, 7.2641983, 0.800866, -19.6868, 5.19808, 0.9268887, -19.605635, 7.2641983, 0.800866, -19.488796, 7.2518096, 0.7628459, -20.258171, 3.1409326, 1.3254604, -19.6868, 5.19808, 0.9268887, -19.425571, 5.150448, 0.8405957, -19.6868, 5.19808, 0.9268887, -19.488796, 7.2518096, 0.7628459, -19.425571, 5.150448, 0.8405957, -20.258171, 3.1409326, 1.3254604, -19.425571, 5.150448, 0.8405957, -19.566545, 3.1409326, 1.0870868, -19.425571, 5.150448, 0.8405957, -19.488796, 7.2518096, 0.7628459, -19.488796, 7.2518096, 0.63938713, -19.566545, 3.1409326, 1.0870868, -19.425571, 5.150448, 0.8405957, -19.425785, 5.150448, 0.5616387, -19.425571, 5.150448, 0.8405957, -19.488796, 7.2518096, 0.63938713, -19.425785, 5.150448, 0.5616387, -19.566545, 3.1409326, 1.0870868, -19.425785, 5.150448, 0.5616387, -19.566545, 3.1409323, 0.3151492, -19.425785, 5.150448, 0.5616387, -19.488796, 7.2518096, 0.63938713, -19.605635, 7.2641983, 0.601367, -19.566545, 3.1409323, 0.3151492, -19.425785, 5.150448, 0.5616387, -19.6868, 5.19808, 0.47534573, -19.425785, 5.150448, 0.5616387, -19.605635, 7.2641983, 0.601367, -19.6868, 5.19808, 0.47534573, -19.6868, 5.19808, 0.47534573, -19.605635, 7.2641983, 0.601367, -19.677616, 7.271674, 0.70111644, -19.566545, 3.1409323, 0.3151492, -19.6868, 5.19808, 0.47534573, -20.258171, 3.140932, 0.07677555, -19.6868, 5.19808, 0.47534573, -19.677616, 7.271674, 0.70111644, -19.848066, 5.2273426, 0.70111716, -20.258171, 3.140932, 0.07677555, -19.6868, 5.19808, 0.47534573, -19.848066, 5.2273426, 0.70111716, -20.258171, 3.140932, 0.07677555, -19.848066, 5.2273426, 0.70111716, -20.685791, 3.1409323, 0.701118, -9.178474, 7.896264, -9.667162, -7.7554946, 8.923878, -8.79697, -7.8560977, 7.5083733, -9.016546, -7.8560977, 7.5083733, -9.016546, -7.7554946, 8.923878, -8.79697, -6.0311303, 8.959761, -9.644308, -7.8560977, 7.5083733, -9.016546, -6.0311303, 8.959761, -9.644308, -6.338922, 7.877041, -9.814329, -9.178474, 7.896264, -9.667162, -9.392284, 8.901663, -9.170551, -7.7554946, 8.923878, -8.79697, -9.710115, 7.6064134, -11.436808, -9.392284, 8.901663, -9.170551, -9.178474, 7.896264, -9.667162, -7.7554946, 8.923878, -8.79697, -6.5292373, 9.998694, -10.128958, -6.0311303, 8.959761, -9.644308, -9.710115, 7.6064134, -11.436808, -9.815418, 9.002266, -11.310146, -9.392284, 8.901663, -9.170551, -8.902294, 7.999003, -13.082569, -9.815418, 9.002266, -11.310146, -9.710115, 7.6064134, -11.436808, -9.392284, 8.901663, -9.170551, -7.567102, 10.353264, -9.798311, -7.7554946, 8.923878, -8.79697, -7.7554946, 8.923878, -8.79697, -7.567102, 10.353264, -9.798311, -6.5292373, 9.998694, -10.128958, -9.815418, 9.002266, -11.310146, -8.663919, 9.972849, -9.918352, -9.392284, 8.901663, -9.170551, -9.392284, 8.901663, -9.170551, -8.663919, 9.972849, -9.918352, -7.567102, 10.353264, -9.798311, -8.902294, 7.999003, -13.082569, -9.121016, 9.077452, -13.414072, -9.815418, 9.002266, -11.310146, -9.121016, 9.077452, -13.414072, -8.902294, 7.999003, -13.082569, -7.418226, 7.5777907, -13.678717, -9.815418, 9.002266, -11.310146, -8.8031845, 10.372702, -11.1476, -8.663919, 9.972849, -9.918352, -9.121016, 9.077452, -13.414072, -8.8031845, 10.372702, -11.1476, -9.815418, 9.002266, -11.310146, -8.663919, 9.972849, -9.918352, -7.5043044, 10.829584, -11.093346, -7.567102, 10.353264, -9.798311, -8.663919, 9.972849, -9.918352, -8.8031845, 10.372702, -11.1476, -7.5043044, 10.829584, -11.093346, -9.121016, 9.077452, -13.414072, -8.543451, 10.050811, -12.445198, -8.8031845, 10.372702, -11.1476, -9.121016, 9.077452, -13.414072, -7.418226, 7.5777907, -13.678717, -7.404982, 8.97941, -13.680212, -8.543451, 10.050811, -12.445198, -9.121016, 9.077452, -13.414072, -7.404982, 8.97941, -13.680212, -7.404982, 8.97941, -13.680212, -7.418226, 7.5777907, -13.678717, -6.070005, 7.8608065, -12.713261, -8.8031845, 10.372702, -11.1476, -8.543451, 10.050811, -12.445198, -7.479528, 10.367147, -12.461218, -8.543451, 10.050811, -12.445198, -7.404982, 8.97941, -13.680212, -7.479528, 10.367147, -12.461218, -8.8031845, 10.372702, -11.1476, -7.479528, 10.367147, -12.461218, -7.5043044, 10.829584, -11.093346, -7.404982, 8.97941, -13.680212, -6.070005, 7.8608065, -12.713261, -5.7767367, 8.867486, -12.725651, -7.479528, 10.367147, -12.461218, -7.404982, 8.97941, -13.680212, -5.7767367, 8.867486, -12.725651, -5.564422, 7.4799643, -11.258242, -5.7767367, 8.867486, -12.725651, -6.070005, 7.8608065, -12.713261, -7.5043044, 10.829584, -11.093346, -7.479528, 10.367147, -12.461218, -6.4160304, 9.957684, -12.139328, -7.479528, 10.367147, -12.461218, -5.7767367, 8.867486, -12.725651, -6.4160304, 9.957684, -12.139328, -5.564422, 7.4799643, -11.258242, -5.345058, 8.901022, -11.16725, -5.7767367, 8.867486, -12.725651, -5.345058, 8.901022, -11.16725, -6.4160304, 9.957684, -12.139328, -5.7767367, 8.867486, -12.725651, -6.338922, 7.877041, -9.814329, -5.345058, 8.901022, -11.16725, -5.564422, 7.4799643, -11.258242, -6.338922, 7.877041, -9.814329, -6.0311303, 8.959761, -9.644308, -5.345058, 8.901022, -11.16725, -5.345058, 8.901022, -11.16725, -6.2436585, 10.347497, -11.111715, -6.4160304, 9.957684, -12.139328, -7.5043044, 10.829584, -11.093346, -6.4160304, 9.957684, -12.139328, -6.2436585, 10.347497, -11.111715, -6.0311303, 8.959761, -9.644308, -6.2436585, 10.347497, -11.111715, -5.345058, 8.901022, -11.16725, -7.567102, 10.353264, -9.798311, -7.5043044, 10.829584, -11.093346, -6.2436585, 10.347497, -11.111715, -6.0311303, 8.959761, -9.644308, -6.5292373, 9.998694, -10.128958, -6.2436585, 10.347497, -11.111715, -7.567102, 10.353264, -9.798311, -6.2436585, 10.347497, -11.111715, -6.5292373, 9.998694, -10.128958, -8.902294, 7.999003, -13.082569, -7.6561713, 7.073704, -11.383837, -7.418226, 7.5777907, -13.678717, -8.902294, 7.999003, -13.082569, -9.710115, 7.6064134, -11.436808, -7.6561713, 7.073704, -11.383837, -7.418226, 7.5777907, -13.678717, -7.6561713, 7.073704, -11.383837, -5.564422, 7.4799643, -11.258242, -7.418226, 7.5777907, -13.678717, -5.564422, 7.4799643, -11.258242, -6.070005, 7.8608065, -12.713261, -7.6561713, 7.073704, -11.383837, -6.338922, 7.877041, -9.814329, -5.564422, 7.4799643, -11.258242, -7.6561713, 7.073704, -11.383837, -7.8560977, 7.5083733, -9.016546, -6.338922, 7.877041, -9.814329, -9.710115, 7.6064134, -11.436808, -7.8560977, 7.5083733, -9.016546, -7.6561713, 7.073704, -11.383837, -9.710115, 7.6064134, -11.436808, -9.178474, 7.896264, -9.667162, -7.8560977, 7.5083733, -9.016546, -11.561996, 7.1179185, -10.496557, -10.571764, 7.8505545, -9.770115, -10.716581, 6.8492146, -10.098627, -10.716581, 6.8492146, -10.098627, -10.571764, 7.8505545, -9.770115, -9.298729, 7.856108, -10.163559, -10.716581, 6.8492146, -10.098627, -9.298729, 7.856108, -10.163559, -9.678076, 7.1179185, -10.496557, -11.561996, 7.1179185, -10.496557, -11.772175, 7.856108, -10.163559, -10.571764, 7.8505545, -9.770115, -11.772175, 6.8767676, -11.532499, -11.772175, 7.856108, -10.163559, -11.561996, 7.1179185, -10.496557, -10.571764, 7.8505545, -9.770115, -9.607803, 8.602841, -10.44273, -9.298729, 7.856108, -10.163559, -11.772175, 6.8767676, -11.532499, -11.843517, 7.872555, -11.344322, -11.772175, 7.856108, -10.163559, -11.181795, 7.1520934, -12.470615, -11.843517, 7.872555, -11.344322, -11.772175, 6.8767676, -11.532499, -11.772175, 7.856108, -10.163559, -10.354536, 8.862788, -10.228495, -10.571764, 7.8505545, -9.770115, -10.571764, 7.8505545, -9.770115, -10.354536, 8.862788, -10.228495, -9.607803, 8.602841, -10.44273, -11.843517, 7.872555, -11.344322, -11.181795, 8.602841, -10.44273, -11.772175, 7.856108, -10.163559, -11.772175, 7.856108, -10.163559, -11.181795, 8.602841, -10.44273, -10.354536, 8.862788, -10.228495, -11.181795, 7.1520934, -12.470615, -11.206358, 7.889001, -12.524868, -11.843517, 7.872555, -11.344322, -11.206358, 7.889001, -12.524868, -11.181795, 7.1520934, -12.470615, -10.354536, 6.904321, -12.966158, -11.843517, 7.872555, -11.344322, -11.206358, 8.868341, -11.156143, -11.181795, 8.602841, -10.44273, -11.206358, 7.889001, -12.524868, -11.206358, 8.868341, -11.156143, -11.843517, 7.872555, -11.344322, -11.181795, 8.602841, -10.44273, -10.282127, 9.20027, -11.093346, -10.354536, 8.862788, -10.228495, -11.181795, 8.602841, -10.44273, -11.206358, 8.868341, -11.156143, -10.282127, 9.20027, -11.093346, -11.206358, 7.889001, -12.524868, -10.930391, 8.6175785, -11.966955, -11.206358, 8.868341, -11.156143, -11.206358, 7.889001, -12.524868, -10.354536, 6.904321, -12.966158, -10.282127, 7.894554, -12.918314, -10.930391, 8.6175785, -11.966955, -11.206358, 7.889001, -12.524868, -10.282127, 7.894554, -12.918314, -10.282127, 7.894554, -12.918314, -10.354536, 6.904321, -12.966158, -9.607803, 7.1520934, -12.470615, -11.206358, 8.868341, -11.156143, -10.930391, 8.6175785, -11.966955, -10.282127, 8.873895, -12.083578, -10.930391, 8.6175785, -11.966955, -10.282127, 7.894554, -12.918314, -10.282127, 8.873895, -12.083578, -11.206358, 8.868341, -11.156143, -10.282127, 8.873895, -12.083578, -10.282127, 9.20027, -11.093346, -10.282127, 7.894554, -12.918314, -9.607803, 7.1520934, -12.470615, -9.43009, 7.889001, -12.524868, -10.282127, 8.873895, -12.083578, -10.282127, 7.894554, -12.918314, -9.43009, 7.889001, -12.524868, -9.298729, 6.8767676, -11.532499, -9.43009, 7.889001, -12.524868, -9.607803, 7.1520934, -12.470615, -10.282127, 9.20027, -11.093346, -10.282127, 8.873895, -12.083578, -9.666115, 8.6175785, -11.966955, -10.282127, 8.873895, -12.083578, -9.43009, 7.889001, -12.524868, -9.666115, 8.6175785, -11.966955, -9.298729, 6.8767676, -11.532499, -9.010374, 7.872555, -11.344322, -9.43009, 7.889001, -12.524868, -9.010374, 7.872555, -11.344322, -9.666115, 8.6175785, -11.966955, -9.43009, 7.889001, -12.524868, -9.678076, 7.1179185, -10.496557, -9.010374, 7.872555, -11.344322, -9.298729, 6.8767676, -11.532499, -9.678076, 7.1179185, -10.496557, -9.298729, 7.856108, -10.163559, -9.010374, 7.872555, -11.344322, -9.010374, 7.872555, -11.344322, -9.43009, 8.868341, -11.156143, -9.666115, 8.6175785, -11.966955, -10.282127, 9.20027, -11.093346, -9.666115, 8.6175785, -11.966955, -9.43009, 8.868341, -11.156143, -9.298729, 7.856108, -10.163559, -9.43009, 8.868341, -11.156143, -9.010374, 7.872555, -11.344322, -10.354536, 8.862788, -10.228495, -10.282127, 9.20027, -11.093346, -9.43009, 8.868341, -11.156143, -9.298729, 7.856108, -10.163559, -9.607803, 8.602841, -10.44273, -9.43009, 8.868341, -11.156143, -10.354536, 8.862788, -10.228495, -9.43009, 8.868341, -11.156143, -9.607803, 8.602841, -10.44273, -11.181795, 7.1520934, -12.470615, -10.571764, 6.544839, -11.595083, -10.354536, 6.904321, -12.966158, -11.181795, 7.1520934, -12.470615, -11.772175, 6.8767676, -11.532499, -10.571764, 6.544839, -11.595083, -10.354536, 6.904321, -12.966158, -10.571764, 6.544839, -11.595083, -9.298729, 6.8767676, -11.532499, -10.354536, 6.904321, -12.966158, -9.298729, 6.8767676, -11.532499, -9.607803, 7.1520934, -12.470615, -10.571764, 6.544839, -11.595083, -9.678076, 7.1179185, -10.496557, -9.298729, 6.8767676, -11.532499, -10.571764, 6.544839, -11.595083, -10.716581, 6.8492146, -10.098627, -9.678076, 7.1179185, -10.496557, -11.772175, 6.8767676, -11.532499, -10.716581, 6.8492146, -10.098627, -10.571764, 6.544839, -11.595083, -11.772175, 6.8767676, -11.532499, -11.561996, 7.1179185, -10.496557, -10.716581, 6.8492146, -10.098627, -7.722173, 5.52812, -11.093344, -8.820272, 5.8179703, -11.28964, -7.772368, 5.3862915, -11.30032, -7.722173, 5.52812, -11.093344, -8.73398, 5.93139, -11.093346, -8.820272, 5.8179703, -11.28964, -8.73398, 5.93139, -11.093346, -9.858778, 6.9177785, -11.150375, -8.820272, 5.8179703, -11.28964, -8.73398, 5.93139, -11.093346, -9.817341, 6.9173512, -11.093346, -9.858778, 6.9177785, -11.150375, -8.820272, 5.8179703, -11.28964, -9.858778, 6.9177785, -11.150375, -9.925848, 6.9184194, -11.128588, -7.772368, 5.3862915, -11.30032, -8.820272, 5.8179703, -11.28964, -8.959965, 5.6340637, -11.214668, -8.820272, 5.8179703, -11.28964, -9.925848, 6.9184194, -11.128588, -8.959965, 5.6340637, -11.214668, -7.772368, 5.3862915, -11.30032, -8.959965, 5.6340637, -11.214668, -7.8533216, 5.156889, -11.221289, -8.959965, 5.6340637, -11.214668, -9.925848, 6.9184194, -11.128588, -9.925848, 6.9184194, -11.058102, -7.8533216, 5.156889, -11.221289, -8.959965, 5.6340637, -11.214668, -8.959965, 5.6340637, -10.972021, -8.959965, 5.6340637, -11.214668, -9.925848, 6.9184194, -11.058102, -8.959965, 5.6340637, -10.972021, -7.8533216, 5.156889, -11.221289, -8.959965, 5.6340637, -10.972021, -7.8533216, 5.1568894, -10.965401, -8.959965, 5.6340637, -10.972021, -9.925848, 6.9184194, -11.058102, -9.858778, 6.9177785, -11.036314, -7.8533216, 5.1568894, -10.965401, -8.959965, 5.6340637, -10.972021, -8.820272, 5.8179703, -10.897049, -8.959965, 5.6340637, -10.972021, -9.858778, 6.9177785, -11.036314, -8.820272, 5.8179703, -10.897049, -8.820272, 5.8179703, -10.897049, -9.858778, 6.9177785, -11.036314, -9.817341, 6.9173512, -11.093346, -7.8533216, 5.1568894, -10.965401, -8.820272, 5.8179703, -10.897049, -7.772368, 5.386292, -10.88637, -8.820272, 5.8179703, -10.897049, -9.817341, 6.9173512, -11.093346, -8.73398, 5.93139, -11.093346, -7.772368, 5.386292, -10.88637, -8.820272, 5.8179703, -10.897049, -8.73398, 5.93139, -11.093346, -7.772368, 5.386292, -10.88637, -8.73398, 5.93139, -11.093346, -7.722173, 5.52812, -11.093344, -8.853594, 3.2268317, -11.093344, -7.8546023, 5.2839794, -10.867573, -8.425974, 3.226832, -10.469002, -8.853594, 3.2268317, -11.093344, -8.015869, 5.313242, -11.093344, -7.8546023, 5.2839794, -10.867573, -8.015869, 5.313242, -11.093344, -7.773436, 7.3500977, -10.993595, -7.8546023, 5.2839794, -10.867573, -8.015869, 5.313242, -11.093344, -7.8454185, 7.3575735, -11.093346, -7.773436, 7.3500977, -10.993595, -7.8546023, 5.2839794, -10.867573, -7.773436, 7.3500977, -10.993595, -7.6565986, 7.337709, -11.031616, -8.425974, 3.226832, -10.469002, -7.8546023, 5.2839794, -10.867573, -7.5933747, 5.236347, -10.953865, -7.8546023, 5.2839794, -10.867573, -7.6565986, 7.337709, -11.031616, -7.5933747, 5.236347, -10.953865, -8.425974, 3.226832, -10.469002, -7.5933747, 5.236347, -10.953865, -7.734348, 3.226832, -10.707375, -7.5933747, 5.236347, -10.953865, -7.6565986, 7.337709, -11.031616, -7.6565986, 7.337709, -11.155075, -7.734348, 3.226832, -10.707375, -7.5933747, 5.236347, -10.953865, -7.5935884, 5.236347, -11.232822, -7.5933747, 5.236347, -10.953865, -7.6565986, 7.337709, -11.155075, -7.5935884, 5.236347, -11.232822, -7.734348, 3.226832, -10.707375, -7.5935884, 5.236347, -11.232822, -7.734348, 3.2268317, -11.479313, -7.5935884, 5.236347, -11.232822, -7.6565986, 7.337709, -11.155075, -7.773436, 7.3500977, -11.193094, -7.734348, 3.2268317, -11.479313, -7.5935884, 5.236347, -11.232822, -7.8546023, 5.2839794, -11.319117, -7.5935884, 5.236347, -11.232822, -7.773436, 7.3500977, -11.193094, -7.8546023, 5.2839794, -11.319117, -7.8546023, 5.2839794, -11.319117, -7.773436, 7.3500977, -11.193094, -7.8454185, 7.3575735, -11.093346, -7.734348, 3.2268317, -11.479313, -7.8546023, 5.2839794, -11.319117, -8.425974, 3.2268314, -11.717686, -7.8546023, 5.2839794, -11.319117, -7.8454185, 7.3575735, -11.093346, -8.015869, 5.313242, -11.093344, -8.425974, 3.2268314, -11.717686, -7.8546023, 5.2839794, -11.319117, -8.015869, 5.313242, -11.093344, -8.425974, 3.2268314, -11.717686, -8.015869, 5.313242, -11.093344, -8.853594, 3.2268317, -11.093344)
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_7ny4s"]
+resource_local_to_scene = true
+size = Vector2(16.1, 12.3675)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_agj3o"]
+resource_local_to_scene = true
+size = Vector3(16.1, 4, 12.3675)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_l6210"]
+resource_local_to_scene = true
+size = Vector3(16.1, 4.8, 12.3675)
+
+[sub_resource type="PlaneMesh" id="PlaneMesh_6upbg"]
+resource_local_to_scene = true
+size = Vector2(10000, 10000)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_umo15"]
+resource_local_to_scene = true
+size = Vector3(17, 2, 80)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_e4lmg"]
+resource_local_to_scene = true
+size = Vector3(42, 2, 80)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_eb3g5"]
+resource_local_to_scene = true
+size = Vector3(48, 2, 18)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_wsqap"]
+resource_local_to_scene = true
+size = Vector3(48, 2, 18)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_1fdkm"]
+resource_local_to_scene = true
+size = Vector3(17, 5, 80)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_y2c0j"]
+resource_local_to_scene = true
+size = Vector3(42, 5, 80)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_uwwqy"]
+resource_local_to_scene = true
+size = Vector3(48, 5, 18)
+
+[sub_resource type="BoxShape3D" id="BoxShape3D_hf28p"]
+resource_local_to_scene = true
+size = Vector3(48, 5, 18)
+
[node name="Main" type="Node3D" unique_id=704196381]
script = ExtResource("3_main")
fish_catalog = ExtResource("6_pool")
@@ -163,6 +215,10 @@ script = ExtResource("38_identity_backup")
unique_name_in_owner = true
script = ExtResource("17_network_session")
+[node name="DiscoveryClient" type="Node" parent="." unique_id=401971194]
+unique_name_in_owner = true
+script = ExtResource("57_discovery")
+
[node name="NetworkProfilePreferences" type="Node" parent="." unique_id=2119445545]
unique_name_in_owner = true
script = ExtResource("18_network_profile")
@@ -250,6 +306,70 @@ script = ExtResource("36_player_list")
[node name="TestWorld" parent="." unique_id=1334932296 instance=ExtResource("1_world")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.4475808, 0, -1.8959346)
+[node name="Sun" parent="TestWorld/Environment" index="1"]
+transform = Transform3D(0.8480481, 0.4287137, -0.31147876, 0, 0.5877853, 0.809017, 0.52991927, -0.68608534, 0.49847022, 0, 0, 0)
+
+[node name="Shape" parent="TestWorld/Regions/StarterIslandRegion/Terrain/Collision" index="0" unique_id=674742331]
+shape = SubResource("ConcavePolygonShape3D_hifdc")
+
+[node name="Pond" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies" index="0" unique_id=995477450]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.4, 2.51, 2.1)
+
+[node name="VisualWater" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Pond" index="0" unique_id=1034265960]
+mesh = SubResource("PlaneMesh_7ny4s")
+
+[node name="Shape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Pond/FishingRegion" index="0" unique_id=1185360438]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2, 0)
+shape = SubResource("BoxShape3D_agj3o")
+
+[node name="Shape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Pond/RecoveryRegion" index="0" unique_id=1718808476]
+shape = SubResource("BoxShape3D_l6210")
+
+[node name="VisualWater" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean" index="0" unique_id=1176408937]
+mesh = SubResource("PlaneMesh_6upbg")
+
+[node name="WestShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/FishingRegions/OceanFishingRegion" index="0" unique_id=357406062]
+shape = SubResource("BoxShape3D_umo15")
+
+[node name="EastShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/FishingRegions/OceanFishingRegion" index="1" unique_id=772224738]
+shape = SubResource("BoxShape3D_e4lmg")
+
+[node name="NorthShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/FishingRegions/OceanFishingRegion" index="2" unique_id=646147646]
+shape = SubResource("BoxShape3D_eb3g5")
+
+[node name="SouthShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/FishingRegions/OceanFishingRegion" index="3" unique_id=894083854]
+shape = SubResource("BoxShape3D_wsqap")
+
+[node name="WestShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/RecoveryRegions/OceanRecoveryRegion" index="0" unique_id=1183368645]
+shape = SubResource("BoxShape3D_1fdkm")
+
+[node name="EastShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/RecoveryRegions/OceanRecoveryRegion" index="1" unique_id=1742419808]
+shape = SubResource("BoxShape3D_y2c0j")
+
+[node name="NorthShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/RecoveryRegions/OceanRecoveryRegion" index="2" unique_id=1844920260]
+shape = SubResource("BoxShape3D_uwwqy")
+
+[node name="SouthShape" parent="TestWorld/Regions/StarterIslandRegion/WaterBodies/Ocean/RecoveryRegions/OceanRecoveryRegion" index="3" unique_id=1316495770]
+shape = SubResource("BoxShape3D_hf28p")
+
+[node name="FishingShopWorld" parent="TestWorld/Regions/StarterIslandRegion/Interactables" index="0" unique_id=1255373524]
+transform = Transform3D(-0.9976046, 0, -0.06917416, 0, 1, 0, 0.06917416, 0, -0.9976046, 7.3292284, 3.4012775, 14.888193)
+
+[node name="BelowWorldFailsafe" parent="TestWorld/Safety" index="0"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, -7, 0)
+
+[node name="North" parent="TestWorld/WorldBounds" index="0"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 5, 63.225395)
+
+[node name="South" parent="TestWorld/WorldBounds" index="1"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 5, -63.225395)
+
+[node name="West" parent="TestWorld/WorldBounds" index="2"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -72.4386, 5, 0)
+
+[node name="East" parent="TestWorld/WorldBounds" index="3"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 96.4386, 5, 0)
+
[node name="Players" type="Node3D" parent="." unique_id=550630144]
[node name="Player" parent="Players" unique_id=485429332 instance=ExtResource("2_player")]
@@ -284,6 +404,11 @@ stream = ExtResource("13_title_music")
volume_db = -80.0
bus = &"Music"
+[node name="DuskMusic" type="AudioStreamPlayer" parent="." unique_id=992744241]
+unique_name_in_owner = true
+stream = ExtResource("dusk_music")
+bus = &"Music"
+
[node name="ShorelineAmbience" type="Node" parent="." unique_id=1948037177]
unique_name_in_owner = true
script = ExtResource("54_shoreline_ambience")
@@ -291,7 +416,7 @@ script = ExtResource("54_shoreline_ambience")
[node name="WavesAudio" type="AudioStreamPlayer" parent="ShorelineAmbience" unique_id=193530658]
unique_name_in_owner = true
stream = ExtResource("55_waves")
-bus = &"SFX"
+bus = &"Environment"
[node name="WorldPixelationPostprocess" parent="." unique_id=344378000 instance=ExtResource("16_world_pixelation")]
unique_name_in_owner = true
@@ -318,5 +443,5 @@ unique_name_in_owner = true
[node name="PixelationResetOverlay" parent="." unique_id=291636041 instance=ExtResource("15_reset")]
unique_name_in_owner = true
-[node name="netfishing_base_character" parent="." unique_id=163901730 instance=ExtResource("44_4pcu1")]
-transform = Transform3D(-0.9976046, 0, -0.06917416, 0, 1, 0, 0.06917416, 0, -0.9976046, 8.795597, 4.184117, 7.4327927)
+[editable path="TestWorld"]
+[editable path="TestWorld/Regions/StarterIslandRegion"]
diff --git a/main/texture_sampling_policy.gd b/main/texture_sampling_policy.gd
new file mode 100644
index 0000000..3d041d0
--- /dev/null
+++ b/main/texture_sampling_policy.gd
@@ -0,0 +1,74 @@
+extends Node
+
+## Enforces NETfishing's nearest-neighbor-only artwork policy at runtime.
+##
+## Godot uses separate texture-filter enums for CanvasItem and 3D materials.
+## Applying both here prevents imported models, dynamically created controls,
+## and Sprite3D presentations from silently falling back to linear sampling.
+
+
+func _enter_tree() -> void:
+ get_tree().node_added.connect(_on_node_added)
+ call_deferred("_enforce_existing_tree")
+
+
+func _on_node_added(node: Node) -> void:
+ enforce_node(node)
+ # Some runtime presenters assign their mesh or material immediately after
+ # add_child(). Recheck once deferred so those resources are covered too.
+ call_deferred("_enforce_deferred_node", weakref(node))
+
+
+func _enforce_existing_tree() -> void:
+ enforce_subtree(get_tree().root)
+
+
+func _enforce_deferred_node(node_ref: WeakRef) -> void:
+ var node := node_ref.get_ref() as Node
+ if node != null:
+ enforce_node(node)
+
+
+static func enforce_subtree(node: Node) -> void:
+ enforce_node(node)
+ for child: Node in node.get_children():
+ enforce_subtree(child)
+
+
+static func enforce_node(node: Node) -> void:
+ if node is CanvasItem:
+ (node as CanvasItem).texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ if node is SpriteBase3D:
+ (node as SpriteBase3D).texture_filter = (
+ BaseMaterial3D.TEXTURE_FILTER_NEAREST
+ )
+ if node is GeometryInstance3D:
+ var geometry := node as GeometryInstance3D
+ enforce_material(geometry.material_override)
+ enforce_material(geometry.material_overlay)
+ if node is MeshInstance3D:
+ enforce_mesh((node as MeshInstance3D).mesh)
+ if node is MultiMeshInstance3D:
+ var multimesh := (node as MultiMeshInstance3D).multimesh
+ if multimesh != null:
+ enforce_mesh(multimesh.mesh)
+ if node is GPUParticles3D:
+ var particles := node as GPUParticles3D
+ for pass_index: int in particles.draw_passes:
+ enforce_mesh(particles.get_draw_pass_mesh(pass_index))
+ if node is CPUParticles3D:
+ enforce_mesh((node as CPUParticles3D).mesh)
+
+
+static func enforce_mesh(mesh: Mesh) -> void:
+ if mesh == null:
+ return
+ for surface_index: int in mesh.get_surface_count():
+ enforce_material(mesh.surface_get_material(surface_index))
+
+
+static func enforce_material(material: Material) -> void:
+ if material is BaseMaterial3D:
+ (material as BaseMaterial3D).texture_filter = (
+ BaseMaterial3D.TEXTURE_FILTER_NEAREST
+ )
diff --git a/main/texture_sampling_policy.gd.uid b/main/texture_sampling_policy.gd.uid
new file mode 100644
index 0000000..820783e
--- /dev/null
+++ b/main/texture_sampling_policy.gd.uid
@@ -0,0 +1 @@
+uid://dwd4wfn8bwk5i
diff --git a/network/direct_enet_transport.gd b/network/direct_enet_transport.gd
index fdfa048..067b86c 100644
--- a/network/direct_enet_transport.gd
+++ b/network/direct_enet_transport.gd
@@ -40,3 +40,22 @@ func connect_to_route(route: ConnectionRoute) -> Error:
_peer = enet_peer
_route_description = endpoint.normalized_display
return OK
+
+
+func send_raw_packet(
+ destination_address: String,
+ destination_port: int,
+ packet: PackedByteArray,
+) -> bool:
+ var enet_peer := _peer as ENetMultiplayerPeer
+ if (
+ enet_peer == null
+ or enet_peer.host == null
+ or destination_address.is_empty()
+ or destination_port < 1
+ or destination_port > 65535
+ or packet.is_empty()
+ ):
+ return false
+ enet_peer.host.socket_send(destination_address, destination_port, packet)
+ return true
diff --git a/network/discovery_client.gd b/network/discovery_client.gd
new file mode 100644
index 0000000..bf15bbf
--- /dev/null
+++ b/network/discovery_client.gd
@@ -0,0 +1,1089 @@
+class_name DiscoveryClient
+extends Node
+
+signal rooms_updated(rooms: Array[Dictionary])
+signal browse_status_changed(message: String, is_error: bool)
+signal host_settings_changed(room_name: String, discoverable: bool)
+signal host_status_changed(message: String, is_error: bool)
+signal host_state_changed(state: int)
+signal public_join_prepared(endpoint: String)
+signal public_join_status_changed(message: String, is_error: bool)
+signal public_join_state_changed(state: int)
+
+const BASE_URL_SETTING: String = "network/discovery/base_url"
+const BASE_URL_ENVIRONMENT: String = "NETFISHING_DISCOVERY_URL"
+const SETTINGS_PATH: String = "user://network_discovery.cfg"
+const DEFAULT_ROOM_NAME: String = "Player's Server"
+const LEGACY_DEFAULT_ROOM_NAME: String = "NETfishing Room"
+const LEGACY_DEDICATED_DEFAULT_ROOM_NAME: String = (
+ "NETfishing Dedicated Server"
+)
+const ROOM_NAME_SUFFIX: String = "'s Server"
+const MAX_ROOM_NAME_LENGTH: int = 48
+const HEARTBEAT_INTERVAL_SECONDS: float = 15.0
+const REQUEST_TIMEOUT_SECONDS: float = 8.0
+const TRAVERSAL_POLL_INTERVAL_SECONDS: float = 1.0
+const JOIN_PROBE_INTERVAL_SECONDS: float = 0.35
+const TRAVERSAL_PACKET_PREFIX: String = "NETFISHING_TRAVERSAL_V1 "
+const UPNP_MAPPING_DURATION_SECONDS: int = 3600
+const UPNP_RENEW_INTERVAL_SECONDS: float = 2700.0
+const UPNP_RETRY_INTERVAL_SECONDS: float = 300.0
+
+enum HostState {
+ UNAVAILABLE,
+ CLOSED,
+ PRIVATE,
+ OPENING_PORT,
+ REGISTERING,
+ VERIFYING,
+ PUBLIC,
+ ERROR,
+}
+
+enum PublicJoinState {
+ IDLE,
+ REQUESTING_ROUTE,
+ CONNECTING,
+ ERROR,
+}
+
+enum HostRequestKind {
+ NONE,
+ CREATE,
+ UPDATE,
+ DELETE,
+}
+
+var _session: NetworkSession
+var _base_url: String = ""
+var _room_name: String = DEFAULT_ROOM_NAME
+var _room_name_uses_default: bool = true
+var _host_settings_persistence_enabled: bool = true
+var _discoverable: bool = false
+var _host_status_message: String = ""
+var _host_status_is_error: bool = false
+var _host_state: HostState = HostState.CLOSED
+var _public_join_state: PublicJoinState = PublicJoinState.IDLE
+var _lease_room_id: String = ""
+var _lease_token: String = ""
+var _host_request_kind: HostRequestKind = HostRequestKind.NONE
+var _host_request_in_flight: bool = false
+var _host_sync_queued: bool = false
+var _browse_request_in_flight: bool = false
+var _host_request: HTTPRequest
+var _browse_request: HTTPRequest
+var _heartbeat: Timer
+var _traversal_request: HTTPRequest
+var _join_request: HTTPRequest
+var _traversal_timer: Timer
+var _join_probe_timer: Timer
+var _host_verified: bool = false
+var _traversal_host: String = ""
+var _traversal_port: int = 0
+var _host_verification_token: String = ""
+var _join_request_in_flight: bool = false
+var _pending_join_endpoint: String = ""
+var _pending_join_token: String = ""
+var _pending_join_room_id: String = ""
+var _preserve_pending_join_on_inactive: bool = false
+var _upnp_thread: Thread
+var _upnp_mapping_in_progress: bool = false
+var _upnp_operation_is_renewal: bool = false
+var _upnp_renew_timer: Timer
+var _upnp: UPNP
+var _upnp_mapped_port: int = 0
+
+
+func _ready() -> void:
+ _host_request = HTTPRequest.new()
+ _host_request.name = "HostLeaseRequest"
+ _host_request.timeout = REQUEST_TIMEOUT_SECONDS
+ add_child(_host_request)
+ _host_request.request_completed.connect(_on_host_request_completed)
+
+ _browse_request = HTTPRequest.new()
+ _browse_request.name = "RoomBrowseRequest"
+ _browse_request.timeout = REQUEST_TIMEOUT_SECONDS
+ add_child(_browse_request)
+ _browse_request.request_completed.connect(_on_browse_request_completed)
+
+ _traversal_request = HTTPRequest.new()
+ _traversal_request.name = "HostTraversalRequest"
+ _traversal_request.timeout = REQUEST_TIMEOUT_SECONDS
+ add_child(_traversal_request)
+ _traversal_request.request_completed.connect(
+ _on_traversal_request_completed
+ )
+
+ _join_request = HTTPRequest.new()
+ _join_request.name = "PublicJoinPreparationRequest"
+ _join_request.timeout = REQUEST_TIMEOUT_SECONDS
+ add_child(_join_request)
+ _join_request.request_completed.connect(_on_join_request_completed)
+
+ _heartbeat = Timer.new()
+ _heartbeat.name = "HostLeaseHeartbeat"
+ _heartbeat.wait_time = HEARTBEAT_INTERVAL_SECONDS
+ _heartbeat.one_shot = false
+ add_child(_heartbeat)
+ _heartbeat.timeout.connect(_on_heartbeat_timeout)
+
+ _upnp_renew_timer = Timer.new()
+ _upnp_renew_timer.name = "HostUPnPRenewal"
+ _upnp_renew_timer.one_shot = true
+ add_child(_upnp_renew_timer)
+ _upnp_renew_timer.timeout.connect(_on_upnp_renew_timer_timeout)
+
+ _traversal_timer = Timer.new()
+ _traversal_timer.name = "HostTraversalPoll"
+ _traversal_timer.wait_time = TRAVERSAL_POLL_INTERVAL_SECONDS
+ _traversal_timer.one_shot = false
+ add_child(_traversal_timer)
+ _traversal_timer.timeout.connect(_on_traversal_timer_timeout)
+
+ _join_probe_timer = Timer.new()
+ _join_probe_timer.name = "PublicJoinTraversalProbe"
+ _join_probe_timer.wait_time = JOIN_PROBE_INTERVAL_SECONDS
+ _join_probe_timer.one_shot = false
+ add_child(_join_probe_timer)
+ _join_probe_timer.timeout.connect(_send_pending_join_probe)
+ _load_settings()
+ _base_url = _configured_base_url()
+
+
+func setup(session: NetworkSession) -> void:
+ _session = session
+ if _room_name_uses_default:
+ _room_name = _default_room_name(_session.get_local_display_name())
+ _save_settings()
+ _session.set_session_display_name(_room_name)
+ if not _session.state_changed.is_connected(_on_session_state_changed):
+ _session.state_changed.connect(_on_session_state_changed)
+ if not _session.peer_count_changed.is_connected(_on_peer_count_changed):
+ _session.peer_count_changed.connect(_on_peer_count_changed)
+ if not _session.host_openness_changed.is_connected(_on_host_openness_changed):
+ _session.host_openness_changed.connect(_on_host_openness_changed)
+ host_settings_changed.emit(_room_name, _discoverable)
+ if not is_configured():
+ _set_host_state(HostState.UNAVAILABLE)
+ _set_host_status("Room discovery is not configured in this build.", true)
+ elif _session.is_open_host():
+ _set_host_state(HostState.PRIVATE)
+ _set_host_status("Room is open but unlisted.", false)
+ else:
+ _set_host_state(HostState.CLOSED)
+ _set_host_status("Open the game before listing it publicly.", false)
+
+
+func is_configured() -> bool:
+ return not _base_url.is_empty()
+
+
+func get_base_url() -> String:
+ return _base_url
+
+
+func set_base_url_override(value: String) -> bool:
+ var normalized: String = value.strip_edges()
+ while normalized.ends_with("/"):
+ normalized = normalized.left(normalized.length() - 1)
+ if not normalized.is_empty() and not (
+ normalized.begins_with("https://")
+ or normalized.begins_with("http://")
+ ):
+ return false
+ _base_url = normalized
+ return true
+
+
+func get_room_name() -> String:
+ return _room_name
+
+
+func is_discoverable() -> bool:
+ return _discoverable
+
+
+func get_host_status_message() -> String:
+ return _host_status_message
+
+
+func host_status_is_error() -> bool:
+ return _host_status_is_error
+
+
+func get_host_state() -> HostState:
+ return _host_state
+
+
+func get_public_join_state() -> PublicJoinState:
+ return _public_join_state
+
+
+func configure_dedicated_runtime(room_name: String) -> bool:
+ _host_settings_persistence_enabled = false
+ return set_room_name(room_name)
+
+
+func set_room_name(value: String) -> bool:
+ var cleaned: String = _sanitize_room_name(value)
+ if cleaned.is_empty():
+ _set_host_state(HostState.ERROR)
+ _set_host_status("Room name cannot be empty.", true)
+ return false
+ if cleaned == _room_name:
+ if _room_name_uses_default:
+ _room_name_uses_default = false
+ _save_settings()
+ return true
+ _room_name = cleaned
+ _room_name_uses_default = false
+ _save_settings()
+ if _session != null:
+ _session.set_session_display_name(_room_name)
+ host_settings_changed.emit(_room_name, _discoverable)
+ if _discoverable:
+ _synchronize_host_lease()
+ return true
+
+
+func set_discoverable(enabled: bool) -> bool:
+ if enabled and (
+ _session == null
+ or not _session.is_open_host()
+ or not is_configured()
+ ):
+ _set_host_state(HostState.ERROR)
+ _set_host_status(
+ "Open the game before enabling discovery."
+ if is_configured()
+ else "Room discovery is not configured in this build.",
+ true,
+ )
+ return false
+ if _discoverable == enabled:
+ return true
+ _discoverable = enabled
+ host_settings_changed.emit(_room_name, _discoverable)
+ if enabled:
+ _heartbeat.start()
+ _set_host_state(
+ HostState.REGISTERING
+ if _session.is_dedicated_host()
+ else HostState.OPENING_PORT
+ )
+ _set_host_status("Opening public room…", false)
+ if _session.is_dedicated_host():
+ _synchronize_host_lease()
+ else:
+ _begin_upnp_mapping(_session.get_host_port())
+ else:
+ _heartbeat.stop()
+ _upnp_renew_timer.stop()
+ _traversal_timer.stop()
+ _remove_host_lease()
+ _begin_upnp_cleanup()
+ _set_host_state(HostState.PRIVATE)
+ _set_host_status("Room is open but unlisted.", false)
+ return true
+
+
+func is_public_join_preparing() -> bool:
+ return _join_request_in_flight
+
+
+func preserve_public_join_for_session_switch() -> bool:
+ _preserve_pending_join_on_inactive = not _pending_join_token.is_empty()
+ return _preserve_pending_join_on_inactive
+
+
+func cancel_pending_public_join() -> void:
+ _preserve_pending_join_on_inactive = false
+ _set_public_join_state(PublicJoinState.IDLE)
+ _clear_pending_join()
+
+
+func prepare_public_join(room: Dictionary) -> bool:
+ if _join_request_in_flight:
+ return false
+ if _session == null or not is_configured():
+ _set_public_join_state(PublicJoinState.ERROR)
+ return false
+ if is_own_room(room):
+ _set_public_join_state(PublicJoinState.ERROR)
+ public_join_status_changed.emit(
+ "You are already hosting this room.", true
+ )
+ return false
+ var endpoint: String = room_endpoint(room)
+ var room_id: String = str(room.get("room_id", "")).strip_edges()
+ if endpoint.is_empty() or room_id.is_empty():
+ _set_public_join_state(PublicJoinState.ERROR)
+ return false
+ _pending_join_endpoint = endpoint
+ _pending_join_room_id = room_id
+ _pending_join_token = ""
+ var url: String = "%s/v1/rooms/%s/join-attempts" % [
+ _base_url,
+ room_id.uri_encode(),
+ ]
+ var error: Error = _join_request.request(
+ url,
+ PackedStringArray(),
+ HTTPClient.METHOD_POST,
+ "",
+ )
+ if error != OK:
+ _set_public_join_state(PublicJoinState.ERROR)
+ _clear_pending_join()
+ return false
+ _join_request_in_flight = true
+ _set_public_join_state(PublicJoinState.REQUESTING_ROUTE)
+ public_join_status_changed.emit("Opening a route to the room…", false)
+ return true
+
+
+func request_rooms() -> bool:
+ if not is_configured():
+ rooms_updated.emit([])
+ browse_status_changed.emit(
+ "Public room discovery is not configured in this build.", true
+ )
+ return false
+ if _browse_request_in_flight:
+ return true
+ var game_version: String = str(
+ ProjectSettings.get_setting("application/config/version", "unknown")
+ )
+ var url: String = "%s/v1/rooms?game_version=%s&protocol_version=%d" % [
+ _base_url,
+ game_version.uri_encode(),
+ NetworkProtocol.PROTOCOL_VERSION,
+ ]
+ var error: Error = _browse_request.request(url)
+ if error != OK:
+ rooms_updated.emit([])
+ browse_status_changed.emit("Could not request public rooms.", true)
+ return false
+ _browse_request_in_flight = true
+ browse_status_changed.emit("Looking for public rooms…", false)
+ return true
+
+
+func room_endpoint(room: Dictionary) -> String:
+ var address: String = str(room.get("address", "")).strip_edges()
+ var port: int = int(room.get("port", 0))
+ if address.is_empty() or port < 1 or port > 65535:
+ return ""
+ if ":" in address and not address.begins_with("["):
+ address = "[%s]" % address
+ return "%s:%d" % [address, port]
+
+
+func is_own_room(room: Dictionary) -> bool:
+ return (
+ not _lease_room_id.is_empty()
+ and str(room.get("room_id", "")) == _lease_room_id
+ )
+
+
+func _configured_base_url() -> String:
+ var value: String = OS.get_environment(BASE_URL_ENVIRONMENT).strip_edges()
+ if value.is_empty():
+ value = str(ProjectSettings.get_setting(BASE_URL_SETTING, "")).strip_edges()
+ while value.ends_with("/"):
+ value = value.left(value.length() - 1)
+ if not value.is_empty() and not (
+ value.begins_with("https://") or value.begins_with("http://")
+ ):
+ push_warning("Ignored invalid NETfishing discovery URL.")
+ return ""
+ return value
+
+
+func _on_heartbeat_timeout() -> void:
+ _synchronize_host_lease()
+ # NAT bindings can change during a long host session. Re-sending the signed
+ # probe lets discovery refresh the authoritative public endpoint in place.
+ _send_host_verification_probe()
+
+
+func _synchronize_host_lease() -> void:
+ if not _should_advertise():
+ if not _lease_room_id.is_empty():
+ _remove_host_lease()
+ return
+ if _host_request_in_flight:
+ _host_sync_queued = true
+ return
+ var method: HTTPClient.Method = HTTPClient.METHOD_POST
+ var url: String = "%s/v1/rooms" % _base_url
+ var headers := PackedStringArray(["Content-Type: application/json"])
+ _host_request_kind = HostRequestKind.CREATE
+ if not _lease_room_id.is_empty():
+ method = HTTPClient.METHOD_PUT
+ url = "%s/v1/rooms/%s" % [_base_url, _lease_room_id.uri_encode()]
+ headers.append("Authorization: Bearer %s" % _lease_token)
+ _host_request_kind = HostRequestKind.UPDATE
+ elif _host_state != HostState.REGISTERING:
+ _set_host_state(HostState.REGISTERING)
+ _start_host_request(url, headers, method, JSON.stringify(_host_payload()))
+
+
+func _remove_host_lease() -> void:
+ if _lease_room_id.is_empty():
+ return
+ if _host_request_in_flight:
+ _host_sync_queued = true
+ return
+ var url: String = "%s/v1/rooms/%s" % [
+ _base_url, _lease_room_id.uri_encode()
+ ]
+ var headers := PackedStringArray([
+ "Authorization: Bearer %s" % _lease_token,
+ ])
+ _host_request_kind = HostRequestKind.DELETE
+ _start_host_request(url, headers, HTTPClient.METHOD_DELETE, "")
+
+
+func _start_host_request(
+ url: String,
+ headers: PackedStringArray,
+ method: HTTPClient.Method,
+ body: String,
+) -> void:
+ var error: Error = _host_request.request(url, headers, method, body)
+ if error != OK:
+ _host_request_kind = HostRequestKind.NONE
+ _set_host_state(HostState.ERROR)
+ _set_host_status("Could not contact room discovery.", true)
+ return
+ _host_request_in_flight = true
+
+
+func _host_payload() -> Dictionary:
+ return {
+ "room_name": _room_name,
+ "port": _session.get_host_port(),
+ "current_players": _session.get_player_count(),
+ "max_players": _session.get_session_max_players(),
+ "game_version": str(
+ ProjectSettings.get_setting("application/config/version", "unknown")
+ ),
+ "protocol_version": NetworkProtocol.PROTOCOL_VERSION,
+ }
+
+
+func _should_advertise() -> bool:
+ return (
+ _discoverable
+ and is_configured()
+ and _session != null
+ and _session.is_open_host()
+ and (
+ not _upnp_mapping_in_progress
+ or _upnp_operation_is_renewal
+ )
+ )
+
+
+func _on_host_request_completed(
+ result: int,
+ response_code: int,
+ _headers: PackedStringArray,
+ body: PackedByteArray,
+) -> void:
+ var completed_kind: HostRequestKind = _host_request_kind
+ _host_request_kind = HostRequestKind.NONE
+ _host_request_in_flight = false
+ var response: Dictionary = _parse_response_dictionary(body)
+ var transport_ok: bool = result == HTTPRequest.RESULT_SUCCESS
+ match completed_kind:
+ HostRequestKind.CREATE:
+ if transport_ok and response_code == HTTPClient.RESPONSE_CREATED:
+ var room: Dictionary = response.get("room", {})
+ _lease_room_id = str(room.get("room_id", ""))
+ _lease_token = str(response.get("lease_token", ""))
+ if _lease_room_id.is_empty() or _lease_token.is_empty():
+ _clear_lease()
+ _set_host_state(HostState.ERROR)
+ _set_host_status("Discovery returned an invalid lease.", true)
+ else:
+ _apply_traversal_response(response)
+ _host_verified = bool(room.get("verified", false))
+ _traversal_timer.start()
+ _send_host_verification_probe()
+ _set_host_state(
+ HostState.PUBLIC
+ if _host_verified
+ else HostState.VERIFYING
+ )
+ _set_host_status(
+ "Room is listed publicly."
+ if _host_verified
+ else "Checking the public route…",
+ false,
+ )
+ else:
+ _set_host_state(HostState.ERROR)
+ _set_host_status(_request_failure(response), true)
+ HostRequestKind.UPDATE:
+ if transport_ok and response_code == HTTPClient.RESPONSE_OK:
+ var room: Dictionary = response.get("room", {})
+ _host_verified = bool(room.get("verified", false))
+ _set_host_state(
+ HostState.PUBLIC
+ if _host_verified
+ else HostState.VERIFYING
+ )
+ _set_host_status(
+ "Room is listed publicly."
+ if _host_verified
+ else "Checking the public route…",
+ false,
+ )
+ elif response_code in [
+ HTTPClient.RESPONSE_UNAUTHORIZED,
+ HTTPClient.RESPONSE_NOT_FOUND,
+ ]:
+ _clear_lease()
+ _host_sync_queued = true
+ else:
+ _set_host_state(HostState.ERROR)
+ _set_host_status(_request_failure(response), true)
+ HostRequestKind.DELETE:
+ _clear_lease()
+ if not transport_ok or response_code not in [
+ HTTPClient.RESPONSE_NO_CONTENT,
+ HTTPClient.RESPONSE_NOT_FOUND,
+ ]:
+ _set_host_state(HostState.ERROR)
+ _set_host_status(_request_failure(response), true)
+ _:
+ pass
+ if not _should_advertise() and not _lease_room_id.is_empty():
+ _host_sync_queued = true
+ if _host_sync_queued:
+ _host_sync_queued = false
+ call_deferred("_synchronize_host_lease")
+
+
+func _on_join_request_completed(
+ result: int,
+ response_code: int,
+ _headers: PackedStringArray,
+ body: PackedByteArray,
+) -> void:
+ _join_request_in_flight = false
+ var response: Dictionary = _parse_response_dictionary(body)
+ if (
+ result != HTTPRequest.RESULT_SUCCESS
+ or response_code != HTTPClient.RESPONSE_CREATED
+ ):
+ _set_public_join_state(PublicJoinState.ERROR)
+ public_join_status_changed.emit(_request_failure(response), true)
+ _clear_pending_join()
+ return
+ _pending_join_token = str(response.get("join_token", ""))
+ _apply_traversal_response(response)
+ if (
+ _pending_join_token.is_empty()
+ or _traversal_host.is_empty()
+ or _traversal_port < 1
+ ):
+ _set_public_join_state(PublicJoinState.ERROR)
+ public_join_status_changed.emit(
+ "Discovery returned an invalid traversal route.", true
+ )
+ _clear_pending_join()
+ return
+ _set_public_join_state(PublicJoinState.CONNECTING)
+ public_join_status_changed.emit("Connecting…", false)
+ public_join_prepared.emit(_pending_join_endpoint)
+
+
+func _on_traversal_timer_timeout() -> void:
+ if not _should_advertise() or _lease_room_id.is_empty():
+ _traversal_timer.stop()
+ return
+ if not _host_verified:
+ _send_host_verification_probe()
+ _synchronize_host_lease()
+ return
+ if _traversal_request.get_http_client_status() != HTTPClient.STATUS_DISCONNECTED:
+ return
+ var url: String = "%s/v1/rooms/%s/join-attempts" % [
+ _base_url,
+ _lease_room_id.uri_encode(),
+ ]
+ var headers := PackedStringArray([
+ "Authorization: Bearer %s" % _lease_token,
+ ])
+ var error: Error = _traversal_request.request(url, headers)
+ if error != OK:
+ _set_host_state(HostState.ERROR)
+ _set_host_status("Could not check incoming public connections.", true)
+
+
+func _on_traversal_request_completed(
+ result: int,
+ response_code: int,
+ _headers: PackedStringArray,
+ body: PackedByteArray,
+) -> void:
+ if result != HTTPRequest.RESULT_SUCCESS or response_code != HTTPClient.RESPONSE_OK:
+ return
+ var response: Dictionary = _parse_response_dictionary(body)
+ var endpoints: Variant = response.get("endpoints", [])
+ if typeof(endpoints) != TYPE_ARRAY:
+ return
+ for value: Variant in endpoints:
+ if typeof(value) != TYPE_DICTIONARY:
+ continue
+ var endpoint: Dictionary = value
+ var address: String = str(endpoint.get("address", ""))
+ var port: int = int(endpoint.get("port", 0))
+ if address.is_empty() or port < 1 or port > 65535:
+ continue
+ var punch: PackedByteArray = "NETFISHING_PUNCH_V1".to_utf8_buffer()
+ for _attempt: int in 3:
+ _session.send_traversal_packet(address, port, punch)
+
+
+func _apply_traversal_response(response: Dictionary) -> void:
+ var traversal: Variant = response.get("traversal", {})
+ if typeof(traversal) != TYPE_DICTIONARY:
+ return
+ var details: Dictionary = traversal
+ _traversal_host = str(details.get("host", "")).strip_edges()
+ _traversal_port = int(details.get("port", 0))
+ _host_verification_token = str(
+ details.get("verification_token", "")
+ )
+
+
+func _send_host_verification_probe() -> void:
+ if (
+ _session == null
+ or _lease_room_id.is_empty()
+ or _host_verification_token.is_empty()
+ ):
+ return
+ _send_traversal_probe({
+ "kind": "host",
+ "room_id": _lease_room_id,
+ "token": _host_verification_token,
+ })
+
+
+func _send_pending_join_probe() -> void:
+ if (
+ _session == null
+ or _pending_join_token.is_empty()
+ or _session.state not in [
+ NetworkSession.State.CONNECTING,
+ NetworkSession.State.AUTHENTICATING,
+ ]
+ ):
+ _join_probe_timer.stop()
+ return
+ _send_traversal_probe({
+ "kind": "join",
+ "room_id": _pending_join_room_id,
+ "token": _pending_join_token,
+ })
+
+
+func _send_traversal_probe(payload: Dictionary) -> void:
+ if _traversal_host.is_empty() or _traversal_port < 1:
+ return
+ var packet: PackedByteArray = (
+ TRAVERSAL_PACKET_PREFIX + JSON.stringify(payload)
+ ).to_utf8_buffer()
+ _session.send_traversal_packet(_traversal_host, _traversal_port, packet)
+
+
+func _begin_upnp_mapping(port: int, is_renewal: bool = false) -> void:
+ if _upnp_mapping_in_progress or port < 1:
+ if not is_renewal:
+ _synchronize_host_lease()
+ return
+ _upnp_mapping_in_progress = true
+ _upnp_operation_is_renewal = is_renewal
+ _upnp_thread = Thread.new()
+ var error: Error = _upnp_thread.start(
+ _configure_upnp_mapping.bind(port)
+ )
+ if error != OK:
+ _upnp_thread = null
+ _upnp_mapping_in_progress = false
+ _upnp_operation_is_renewal = false
+ if is_renewal:
+ _schedule_upnp_renewal(UPNP_RETRY_INTERVAL_SECONDS)
+ _synchronize_host_lease()
+
+
+func _configure_upnp_mapping(port: int) -> Dictionary:
+ var upnp := UPNP.new()
+ var discovery_result: int = upnp.discover()
+ if discovery_result != UPNP.UPNP_RESULT_SUCCESS:
+ return {"success": false, "upnp": upnp, "port": port}
+ var mapping_result: int = upnp.add_port_mapping(
+ port,
+ port,
+ "NETfishing",
+ "UDP",
+ UPNP_MAPPING_DURATION_SECONDS,
+ )
+ if mapping_result == UPNP.UPNP_RESULT_ONLY_PERMANENT_LEASE_SUPPORTED:
+ mapping_result = upnp.add_port_mapping(
+ port, port, "NETfishing", "UDP", 0
+ )
+ return {
+ "success": mapping_result == UPNP.UPNP_RESULT_SUCCESS,
+ "upnp": upnp,
+ "port": port,
+ }
+
+
+func _process(_delta: float) -> void:
+ if _upnp_thread == null or _upnp_thread.is_alive():
+ return
+ var was_renewal: bool = _upnp_operation_is_renewal
+ var result: Variant = _upnp_thread.wait_to_finish()
+ _upnp_thread = null
+ _upnp_mapping_in_progress = false
+ _upnp_operation_is_renewal = false
+ var mapping_succeeded: bool = false
+ if typeof(result) == TYPE_DICTIONARY:
+ var details: Dictionary = result
+ if bool(details.get("success", false)):
+ _upnp = details.get("upnp") as UPNP
+ _upnp_mapped_port = int(details.get("port", 0))
+ mapping_succeeded = true
+ if not _discoverable:
+ _begin_upnp_cleanup()
+ return
+ if mapping_succeeded:
+ _schedule_upnp_renewal(UPNP_RENEW_INTERVAL_SECONDS)
+ elif was_renewal:
+ _schedule_upnp_renewal(UPNP_RETRY_INTERVAL_SECONDS)
+ _synchronize_host_lease()
+
+
+func _schedule_upnp_renewal(delay_seconds: float) -> void:
+ if (
+ _upnp_mapped_port < 1
+ or not _discoverable
+ or _session == null
+ or _session.is_dedicated_host()
+ ):
+ _upnp_renew_timer.stop()
+ return
+ _upnp_renew_timer.start(delay_seconds)
+
+
+func _on_upnp_renew_timer_timeout() -> void:
+ if (
+ not _discoverable
+ or _session == null
+ or not _session.is_open_host()
+ or _session.is_dedicated_host()
+ or _upnp_mapped_port < 1
+ ):
+ return
+ _begin_upnp_mapping(_upnp_mapped_port, true)
+
+
+func _begin_upnp_cleanup() -> void:
+ _upnp_renew_timer.stop()
+ if _upnp == null or _upnp_mapped_port < 1:
+ return
+ _upnp.delete_port_mapping(_upnp_mapped_port, "UDP")
+ _upnp = null
+ _upnp_mapped_port = 0
+
+
+func _on_browse_request_completed(
+ result: int,
+ response_code: int,
+ _headers: PackedStringArray,
+ body: PackedByteArray,
+) -> void:
+ _browse_request_in_flight = false
+ var response: Dictionary = _parse_response_dictionary(body)
+ if result != HTTPRequest.RESULT_SUCCESS or response_code != HTTPClient.RESPONSE_OK:
+ rooms_updated.emit([])
+ browse_status_changed.emit(_request_failure(response), true)
+ return
+ var raw_rooms: Variant = response.get("rooms", [])
+ if typeof(raw_rooms) != TYPE_ARRAY:
+ rooms_updated.emit([])
+ browse_status_changed.emit("Discovery returned an invalid room list.", true)
+ return
+ var rooms: Array[Dictionary] = []
+ for value: Variant in raw_rooms:
+ if typeof(value) != TYPE_DICTIONARY:
+ continue
+ var room: Dictionary = value
+ if _valid_public_room(room):
+ rooms.append(room.duplicate(true))
+ rooms_updated.emit(rooms)
+ browse_status_changed.emit(
+ "No public rooms are available."
+ if rooms.is_empty()
+ else "%d public room%s found." % [rooms.size(), "" if rooms.size() == 1 else "s"],
+ false,
+ )
+
+
+func _valid_public_room(room: Dictionary) -> bool:
+ var expected_version: String = str(
+ ProjectSettings.get_setting("application/config/version", "unknown")
+ )
+ return (
+ typeof(room.get("room_id")) == TYPE_STRING
+ and typeof(room.get("room_name")) == TYPE_STRING
+ and typeof(room.get("address")) == TYPE_STRING
+ and typeof(room.get("game_version")) == TYPE_STRING
+ and str(room.get("game_version")) == expected_version
+ and _valid_json_integer(room.get("port"), 1, 65535)
+ and _valid_json_integer(room.get("current_players"), 0, 128)
+ and _valid_json_integer(room.get("max_players"), 1, 128)
+ and int(room["current_players"]) <= int(room["max_players"])
+ and _valid_json_integer(
+ room.get("protocol_version"),
+ NetworkProtocol.PROTOCOL_VERSION,
+ NetworkProtocol.PROTOCOL_VERSION,
+ )
+ )
+
+
+func _valid_json_integer(value: Variant, minimum: int, maximum: int) -> bool:
+ if typeof(value) == TYPE_INT:
+ return int(value) >= minimum and int(value) <= maximum
+ if typeof(value) != TYPE_FLOAT:
+ return false
+ var number: float = float(value)
+ return (
+ is_finite(number)
+ and number == floor(number)
+ and number >= float(minimum)
+ and number <= float(maximum)
+ )
+
+
+func _parse_response_dictionary(body: PackedByteArray) -> Dictionary:
+ if body.is_empty():
+ return {}
+ var parsed: Variant = JSON.parse_string(body.get_string_from_utf8())
+ return parsed if typeof(parsed) == TYPE_DICTIONARY else {}
+
+
+func _request_failure(response: Dictionary) -> String:
+ var error: Variant = response.get("error", {})
+ if typeof(error) == TYPE_DICTIONARY:
+ var details := error as Dictionary
+ if str(details.get("code", "")) == "game_version_mismatch":
+ var required_version: String = str(
+ details.get("required_game_version", "")
+ ).strip_edges()
+ if not required_version.is_empty():
+ return _discovery_version_mismatch_message(required_version)
+ var message: String = str(details.get("message", "")).strip_edges()
+ if not message.is_empty():
+ return message
+ return "Room discovery is temporarily unavailable."
+
+
+func _discovery_version_mismatch_message(required_version: String) -> String:
+ var local_version: String = NetworkProtocol.game_version()
+ var rejection: NetworkProtocol.RejectionCode = (
+ NetworkProtocol.game_version_rejection(
+ local_version,
+ required_version,
+ )
+ )
+ match rejection:
+ NetworkProtocol.RejectionCode.CLIENT_OUTDATED:
+ return (
+ "Your NETfishing version is out of date. Update to %s to "
+ + "enable public discovery. This room will not be listed "
+ + "until you update."
+ ) % required_version
+ NetworkProtocol.RejectionCode.SERVER_OUTDATED:
+ return (
+ "Public discovery is still on NETfishing %s. This room "
+ + "will not be listed until discovery is updated for %s."
+ ) % [required_version, local_version]
+ _:
+ return (
+ "Public discovery requires NETfishing %s. This room will "
+ + "not be listed until both versions match."
+ ) % required_version
+
+
+func _on_session_state_changed(state: NetworkSession.State) -> void:
+ if state == NetworkSession.State.CONNECTING and not _pending_join_token.is_empty():
+ _preserve_pending_join_on_inactive = false
+ _set_public_join_state(PublicJoinState.CONNECTING)
+ _join_probe_timer.start()
+ call_deferred("_send_pending_join_probe")
+ elif state in [
+ NetworkSession.State.JOINED_CLIENT,
+ NetworkSession.State.SERVER_LOST,
+ ]:
+ _preserve_pending_join_on_inactive = false
+ _set_public_join_state(PublicJoinState.IDLE)
+ _join_probe_timer.stop()
+ _clear_pending_join()
+ elif state == NetworkSession.State.INACTIVE:
+ if (
+ _preserve_pending_join_on_inactive
+ and not _pending_join_token.is_empty()
+ ):
+ _preserve_pending_join_on_inactive = false
+ else:
+ _set_public_join_state(PublicJoinState.IDLE)
+ _join_probe_timer.stop()
+ _clear_pending_join()
+ elif state == NetworkSession.State.CONNECTION_FAILED:
+ _preserve_pending_join_on_inactive = false
+ _set_public_join_state(PublicJoinState.ERROR)
+ _join_probe_timer.stop()
+ _clear_pending_join()
+ if state == NetworkSession.State.OPEN_HOST:
+ if _discoverable:
+ _heartbeat.start()
+ _synchronize_host_lease()
+ else:
+ _set_host_state(HostState.PRIVATE)
+ _set_host_status("Room is open but unlisted.", false)
+ return
+ if state in [
+ NetworkSession.State.PRIVATE_HOST,
+ NetworkSession.State.INACTIVE,
+ NetworkSession.State.DISCONNECTING,
+ NetworkSession.State.CONNECTION_FAILED,
+ NetworkSession.State.SERVER_LOST,
+ ]:
+ if _discoverable:
+ _discoverable = false
+ host_settings_changed.emit(_room_name, false)
+ _heartbeat.stop()
+ _upnp_renew_timer.stop()
+ _remove_host_lease()
+ _begin_upnp_cleanup()
+ if state == NetworkSession.State.PRIVATE_HOST:
+ _set_host_state(HostState.CLOSED)
+ _set_host_status("Open the game before listing it publicly.", false)
+ else:
+ _set_host_state(HostState.CLOSED)
+
+
+func _on_host_openness_changed(is_open: bool) -> void:
+ if not is_open and _discoverable:
+ set_discoverable(false)
+
+
+func _on_peer_count_changed(_player_count: int, _max_players: int) -> void:
+ if _discoverable:
+ _synchronize_host_lease()
+
+
+func _clear_lease() -> void:
+ _lease_room_id = ""
+ _lease_token = ""
+ _host_verified = false
+ _host_verification_token = ""
+ _traversal_timer.stop()
+
+
+func _clear_pending_join() -> void:
+ _pending_join_endpoint = ""
+ _pending_join_token = ""
+ _pending_join_room_id = ""
+ _join_probe_timer.stop()
+
+
+func _exit_tree() -> void:
+ _upnp_renew_timer.stop()
+ if _upnp_thread != null:
+ var result: Variant = _upnp_thread.wait_to_finish()
+ _upnp_thread = null
+ if typeof(result) == TYPE_DICTIONARY:
+ var details: Dictionary = result
+ if bool(details.get("success", false)):
+ _upnp = details.get("upnp") as UPNP
+ _upnp_mapped_port = int(details.get("port", 0))
+ _begin_upnp_cleanup()
+
+
+func _set_host_status(message: String, is_error: bool) -> void:
+ _host_status_message = message
+ _host_status_is_error = is_error
+ host_status_changed.emit(message, is_error)
+
+
+func _set_host_state(state: HostState) -> void:
+ if _host_state == state:
+ return
+ _host_state = state
+ host_state_changed.emit(int(state))
+
+
+func _set_public_join_state(state: PublicJoinState) -> void:
+ if _public_join_state == state:
+ return
+ _public_join_state = state
+ public_join_state_changed.emit(int(state))
+
+
+func _sanitize_room_name(value: String) -> String:
+ var cleaned: String = value.strip_edges().replace("\n", " ").replace("\r", " ")
+ cleaned = cleaned.replace("\t", " ")
+ while " " in cleaned:
+ cleaned = cleaned.replace(" ", " ")
+ return cleaned.left(MAX_ROOM_NAME_LENGTH)
+
+
+func _default_room_name(player_name: String) -> String:
+ var cleaned_name: String = player_name.strip_edges()
+ if cleaned_name.is_empty():
+ return DEFAULT_ROOM_NAME
+ return "%s%s" % [
+ cleaned_name.left(MAX_ROOM_NAME_LENGTH - ROOM_NAME_SUFFIX.length()),
+ ROOM_NAME_SUFFIX,
+ ]
+
+
+func _load_settings() -> void:
+ var config := ConfigFile.new()
+ if config.load(SETTINGS_PATH) == OK:
+ var saved_name: String = _sanitize_room_name(
+ str(config.get_value("host", "room_name", DEFAULT_ROOM_NAME))
+ )
+ if not saved_name.is_empty():
+ _room_name = saved_name
+ _room_name_uses_default = bool(config.get_value(
+ "host",
+ "room_name_uses_default",
+ saved_name in [
+ DEFAULT_ROOM_NAME,
+ LEGACY_DEFAULT_ROOM_NAME,
+ LEGACY_DEDICATED_DEFAULT_ROOM_NAME,
+ ],
+ ))
+
+
+func _save_settings() -> void:
+ if not _host_settings_persistence_enabled:
+ return
+ var config := ConfigFile.new()
+ config.set_value("host", "room_name", _room_name)
+ config.set_value(
+ "host", "room_name_uses_default", _room_name_uses_default
+ )
+ var error: Error = config.save(SETTINGS_PATH)
+ if error != OK:
+ push_warning("Could not save the local NETfishing room name.")
diff --git a/network/discovery_client.gd.uid b/network/discovery_client.gd.uid
new file mode 100644
index 0000000..eebfd6a
--- /dev/null
+++ b/network/discovery_client.gd.uid
@@ -0,0 +1 @@
+uid://d0jv8n2nfqia0
diff --git a/network/local_signing_identity_store.gd b/network/local_signing_identity_store.gd
index 87fc4c6..a8ac7a0 100644
--- a/network/local_signing_identity_store.gd
+++ b/network/local_signing_identity_store.gd
@@ -9,11 +9,17 @@ var error_message: String = ""
var _private_key: CryptoKey
var _prefix: String = ""
var _allow_generation: bool = true
+var _storage_directory: String = ""
-func configure(prefix: String, allow_generation: bool = true) -> void:
+func configure(
+ prefix: String,
+ allow_generation: bool = true,
+ storage_directory: String = "",
+) -> void:
_prefix = prefix
_allow_generation = allow_generation
+ _storage_directory = storage_directory.strip_edges()
func load_or_create() -> bool:
@@ -225,7 +231,12 @@ func _write_atomic(path: String, content: String) -> bool:
func _path(extension: String) -> String:
- return "user://%s%s" % [_prefix, extension]
+ var filename: String = "%s%s" % [_prefix, extension]
+ return (
+ _storage_directory.path_join(filename)
+ if not _storage_directory.is_empty()
+ else "user://%s" % filename
+ )
func identity_type() -> String:
diff --git a/network/network_chat_service.gd b/network/network_chat_service.gd
index ebb65e9..50c47d3 100644
--- a/network/network_chat_service.gd
+++ b/network/network_chat_service.gd
@@ -4,24 +4,55 @@ extends Node
const BURST_COUNT: int = 3
const WINDOW_COUNT: int = 5
const WINDOW_SECONDS: float = 10.0
+const CALL_COOLDOWN_MILLISECONDS: int = 180
+const WORLD_COMMAND_COOLDOWN_MILLISECONDS: int = 500
+const CALL_PITCH_VARIANTS: Array[float] = [
+ 0.96,
+ 1.03,
+ 0.985,
+ 1.055,
+ 1.0,
+ 0.975,
+ 1.04,
+]
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
signal message_received(message: Dictionary)
signal local_message_confirmed(message: Dictionary)
signal send_rejected(message: String)
signal history_replaced(messages: Array[Dictionary])
+signal world_command_finished(success: bool, message: String)
+signal character_call_received(
+ peer_id: int,
+ call_id: String,
+ pitch_scale: float,
+)
var _session: NetworkSession
var _history: Array[Dictionary] = []
var _seen_messages: Dictionary[String, bool] = {}
var _request_ledgers: Dictionary[int, Dictionary] = {}
var _rate_times: Dictionary[int, Array] = {}
+var _last_call_msec: Dictionary[int, int] = {}
+var _call_variant_indices: Dictionary[int, int] = {}
+var _last_world_command_msec: Dictionary[int, int] = {}
var _sequence: int = 0
var _peer_names: Dictionary[int, String] = {}
var _relationships: PlayerRelationshipStore
+var _world_time: WorldTimeService
+var _world_weather: WorldWeatherService
-func setup(session: NetworkSession) -> void:
+func setup(
+ session: NetworkSession,
+ world_time: WorldTimeService,
+ world_weather: WorldWeatherService,
+) -> void:
_session = session
+ _world_time = world_time
+ _world_weather = world_weather
_session.peer_authenticated.connect(_on_peer_authenticated)
_session.peer_removed.connect(_on_peer_removed)
_session.state_changed.connect(_on_session_state_changed)
@@ -79,6 +110,331 @@ func send_local_message(body: String) -> bool:
return true
+func send_local_character_call(call_id: String) -> bool:
+ if (
+ _session == null
+ or not _session.is_gameplay_session_active()
+ or not VoiceProfilesType.is_valid_call(call_id)
+ or (
+ not _session.is_host()
+ and not _session.supports_server_capability(
+ NetworkChatProtocol.CAPABILITY
+ )
+ )
+ ):
+ return false
+ var request := {
+ "request_id": _new_id("character_call"),
+ "session_id": _session.get_session_id(),
+ "call_id": call_id,
+ "sender_fingerprint": _session.get_local_identity_fingerprint(),
+ }
+ request["sender_signature"] = _session.sign_local_action(
+ "character_call", _character_call_signature_fields(request)
+ )
+ if _session.is_host():
+ _handle_character_call(_session.get_local_peer_id(), request)
+ else:
+ submit_character_call.rpc_id(1, request)
+ return true
+
+
+@rpc("any_peer", "call_remote", "reliable", NetworkChatProtocol.RELIABLE_CHANNEL)
+func submit_character_call(data: Dictionary) -> void:
+ var sender_id := multiplayer.get_remote_sender_id()
+ if _session.is_host() and _session.is_authenticated_peer(sender_id):
+ _handle_character_call(sender_id, data)
+
+
+func _handle_character_call(peer_id: int, data: Dictionary) -> void:
+ if (
+ typeof(data.get("request_id")) != TYPE_STRING
+ or str(data["request_id"]).is_empty()
+ or str(data["request_id"]).length() > 64
+ or typeof(data.get("session_id")) != TYPE_STRING
+ or str(data["session_id"]) != _session.get_session_id()
+ or typeof(data.get("call_id")) != TYPE_STRING
+ or not VoiceProfilesType.is_valid_call(str(data["call_id"]))
+ or typeof(data.get("sender_fingerprint")) != TYPE_STRING
+ or typeof(data.get("sender_signature")) != TYPE_PACKED_BYTE_ARRAY
+ ):
+ return
+ var record := _session.get_peer_record(peer_id)
+ if (
+ record == null
+ or record.identity_fingerprint != str(data["sender_fingerprint"])
+ or not _session.verify_peer_action(
+ peer_id,
+ "character_call",
+ _character_call_signature_fields(data),
+ data["sender_signature"],
+ )
+ or not _consume_character_call_rate(peer_id)
+ ):
+ return
+ var pitch_scale: float = _next_character_call_pitch(peer_id)
+ _apply_character_call(peer_id, str(data["call_id"]), pitch_scale)
+ receive_character_call.rpc(
+ peer_id,
+ str(data["call_id"]),
+ pitch_scale,
+ )
+
+
+@rpc("authority", "call_remote", "reliable", NetworkChatProtocol.RELIABLE_CHANNEL)
+func receive_character_call(
+ peer_id: int,
+ call_id: String,
+ pitch_scale: float,
+) -> void:
+ _apply_character_call(peer_id, call_id, pitch_scale)
+
+
+func _apply_character_call(
+ peer_id: int,
+ call_id: String,
+ pitch_scale: float,
+) -> void:
+ if (
+ not VoiceProfilesType.is_valid_call(call_id)
+ or pitch_scale < 0.9
+ or pitch_scale > 1.1
+ or _session == null
+ or not _session.is_gameplay_session_active()
+ ):
+ return
+ var record := _session.get_peer_record(peer_id)
+ if record == null or is_sender_filtered(record.identity_fingerprint):
+ return
+ character_call_received.emit(peer_id, call_id, pitch_scale)
+
+
+func _next_character_call_pitch(peer_id: int) -> float:
+ var variant_index: int = _call_variant_indices.get(peer_id, 0)
+ var pitch_scale: float = CALL_PITCH_VARIANTS[
+ variant_index % CALL_PITCH_VARIANTS.size()
+ ]
+ _call_variant_indices[peer_id] = variant_index + 1
+ return pitch_scale
+
+
+func _consume_character_call_rate(peer_id: int) -> bool:
+ var now_msec: int = Time.get_ticks_msec()
+ var last_msec: int = _last_call_msec.get(
+ peer_id, now_msec - CALL_COOLDOWN_MILLISECONDS
+ )
+ if now_msec - last_msec < CALL_COOLDOWN_MILLISECONDS:
+ return false
+ _last_call_msec[peer_id] = now_msec
+ return true
+
+
+func _character_call_signature_fields(data: Dictionary) -> Array:
+ return [
+ str(data.get("session_id", "")),
+ str(data.get("request_id", "")),
+ str(data.get("sender_fingerprint", "")),
+ str(data.get("call_id", "")),
+ ]
+
+
+func broadcast_system_message(body: String) -> bool:
+ if _session == null or not _session.is_host():
+ return false
+ var clean := NetworkChatProtocol.sanitize_body(body)
+ if clean.is_empty():
+ return false
+ _broadcast(_make_message(
+ NetworkChatProtocol.Kind.SYSTEM,
+ 0,
+ "",
+ clean,
+ ))
+ return true
+
+
+func request_world_time_change(phase_name: String) -> bool:
+ var normalized: String = phase_name.strip_edges().to_lower()
+ if not _valid_time_phase(normalized) or _session == null:
+ return false
+ if _session.is_host():
+ return _apply_world_time_change(normalized)
+ if (
+ not _session.is_joined_client()
+ or not _session.is_local_operator()
+ or not _session.supports_server_capability(
+ NetworkProtocol.WORLD_TIME_CAPABILITY
+ )
+ ):
+ return false
+ submit_world_time_command.rpc_id(1, normalized)
+ return true
+
+
+func request_world_weather_change(weather_name: String) -> bool:
+ var normalized: String = _normalized_weather_name(weather_name)
+ if normalized.is_empty() or _session == null:
+ return false
+ if _session.is_host():
+ return _apply_world_weather_change(normalized)
+ if (
+ not _session.is_joined_client()
+ or not _session.is_local_operator()
+ or not _session.supports_server_capability(
+ NetworkProtocol.WORLD_WEATHER_CAPABILITY
+ )
+ ):
+ return false
+ submit_world_weather_command.rpc_id(1, normalized)
+ return true
+
+
+@rpc("any_peer", "call_remote", "reliable", NetworkChatProtocol.RELIABLE_CHANNEL)
+func submit_world_time_command(phase_name: String) -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if not _valid_world_command_sender(sender_id):
+ _send_world_command_result(
+ sender_id, false, "Only the host or an operator can change world time."
+ )
+ return
+ if not _consume_world_command_rate(sender_id):
+ _send_world_command_result(sender_id, false, "Slow down.")
+ return
+ var success: bool = _apply_world_time_change(
+ phase_name.strip_edges().to_lower()
+ )
+ _send_world_command_result(
+ sender_id,
+ success,
+ "" if success else "World time could not be changed.",
+ )
+
+
+@rpc("any_peer", "call_remote", "reliable", NetworkChatProtocol.RELIABLE_CHANNEL)
+func submit_world_weather_command(weather_name: String) -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if not _valid_world_command_sender(sender_id):
+ _send_world_command_result(
+ sender_id,
+ false,
+ "Only the host or an operator can change world weather.",
+ )
+ return
+ if not _consume_world_command_rate(sender_id):
+ _send_world_command_result(sender_id, false, "Slow down.")
+ return
+ var success: bool = _apply_world_weather_change(
+ _normalized_weather_name(weather_name)
+ )
+ _send_world_command_result(
+ sender_id,
+ success,
+ "" if success else "World weather could not be changed.",
+ )
+
+
+@rpc("authority", "call_remote", "reliable", NetworkChatProtocol.RELIABLE_CHANNEL)
+func receive_world_command_result(success: bool, message: String) -> void:
+ if _session == null or not _session.is_joined_client():
+ return
+ world_command_finished.emit(success, message.left(120))
+
+
+func _valid_world_command_sender(peer_id: int) -> bool:
+ return (
+ _session != null
+ and _session.is_host()
+ and peer_id > 1
+ and _session.is_authenticated_peer(peer_id)
+ and _session.is_peer_operator(peer_id)
+ )
+
+
+func _apply_world_time_change(phase_name: String) -> bool:
+ if _world_time == null or not _valid_time_phase(phase_name):
+ return false
+ var target_hour: float = _time_phase_hour(phase_name)
+ if not _world_time.set_authoritative_time(target_hour):
+ return false
+ broadcast_system_message(
+ "World time set to %s (%s)."
+ % [phase_name, _world_time.get_clock_text()]
+ )
+ return true
+
+
+func _apply_world_weather_change(weather_name: String) -> bool:
+ if _world_weather == null:
+ return false
+ var normalized: String = _normalized_weather_name(weather_name)
+ if normalized.is_empty():
+ return false
+ var target_weather: WorldWeatherService.Weather = (
+ _weather_for_name(normalized)
+ )
+ if not _world_weather.set_authoritative_weather(target_weather):
+ return false
+ broadcast_system_message("World weather set to %s." % normalized)
+ return true
+
+
+func _send_world_command_result(
+ peer_id: int,
+ success: bool,
+ message: String,
+) -> void:
+ if peer_id > 1 and _session.is_authenticated_peer(peer_id):
+ receive_world_command_result.rpc_id(peer_id, success, message.left(120))
+
+
+func _consume_world_command_rate(peer_id: int) -> bool:
+ var now_msec: int = Time.get_ticks_msec()
+ var last_msec: int = _last_world_command_msec.get(
+ peer_id, now_msec - WORLD_COMMAND_COOLDOWN_MILLISECONDS
+ )
+ if now_msec - last_msec < WORLD_COMMAND_COOLDOWN_MILLISECONDS:
+ return false
+ _last_world_command_msec[peer_id] = now_msec
+ return true
+
+
+static func _valid_time_phase(phase_name: String) -> bool:
+ return phase_name in ["dawn", "day", "dusk", "night"]
+
+
+static func _time_phase_hour(phase_name: String) -> float:
+ match phase_name:
+ "dawn":
+ return WorldTimeService.DAWN_START_HOUR
+ "day":
+ return WorldTimeService.DAWN_END_HOUR
+ "dusk":
+ return WorldTimeService.DUSK_START_HOUR
+ "night":
+ return WorldTimeService.DUSK_END_HOUR
+ return -1.0
+
+
+static func _normalized_weather_name(weather_name: String) -> String:
+ var normalized: String = weather_name.strip_edges().to_lower()
+ return "clear" if normalized == "sunny" else normalized if normalized in [
+ "clear", "cloudy", "rainy", "foggy"
+ ] else ""
+
+
+static func _weather_for_name(
+ weather_name: String,
+) -> WorldWeatherService.Weather:
+ match weather_name:
+ "cloudy":
+ return WorldWeatherService.Weather.CLOUDY
+ "rainy":
+ return WorldWeatherService.Weather.RAINY
+ "foggy":
+ return WorldWeatherService.Weather.FOGGY
+ return WorldWeatherService.Weather.SUNNY
+
+
func get_history() -> Array[Dictionary]:
var result: Array[Dictionary] = []
for message: Dictionary in _history:
@@ -257,6 +613,9 @@ func _on_peer_authenticated(peer_id: int, display_name: String) -> void:
func _on_peer_removed(peer_id: int) -> void:
_request_ledgers.erase(peer_id)
_rate_times.erase(peer_id)
+ _last_call_msec.erase(peer_id)
+ _call_variant_indices.erase(peer_id)
+ _last_world_command_msec.erase(peer_id)
if not _session.is_host():
return
var display_name: String = _peer_names.get(peer_id, "Player")
@@ -314,6 +673,9 @@ func _on_session_state_changed(state: NetworkSession.State) -> void:
_seen_messages.clear()
_request_ledgers.clear()
_rate_times.clear()
+ _last_call_msec.clear()
+ _call_variant_indices.clear()
+ _last_world_command_msec.clear()
_peer_names.clear()
_sequence = 0
history_replaced.emit([])
diff --git a/network/network_fish_showcase_service.gd b/network/network_fish_showcase_service.gd
index 4908e4f..068ee7d 100644
--- a/network/network_fish_showcase_service.gd
+++ b/network/network_fish_showcase_service.gd
@@ -39,6 +39,19 @@ func setup(
_local_hotbar.selected_assignment_changed.connect(
_on_selected_assignment_changed
)
+ var selected_kind: int = (
+ _local_hotbar.get_selected_assignment_kind()
+ )
+ var selected_identity: StringName = StringName()
+ if selected_kind == PlayerHotbarType.AssignmentKind.ITEM:
+ selected_identity = _local_hotbar.get_selected_item_id()
+ elif selected_kind == PlayerHotbarType.AssignmentKind.FISH:
+ selected_identity = _local_hotbar.get_selected_fish_catch_id()
+ _on_selected_assignment_changed(
+ _local_hotbar.get_selected_slot(),
+ selected_kind,
+ selected_identity,
+ )
func toggle_selected_fish() -> bool:
@@ -180,7 +193,7 @@ func _apply_state(data: Dictionary) -> void:
if avatar == null:
return
if not bool(data["visible"]):
- avatar.set_held_fish(null, 1.0, false)
+ avatar.set_held_fish(null, 1.0, false, true)
return
var fish: FishDataType = _fish_catalog.get_fish_by_id(
StringName(str(data["fish_id"]))
@@ -197,13 +210,16 @@ func _on_selected_assignment_changed(
kind: int,
identity: StringName,
) -> void:
- if (
- _local_visible
- and (
- kind != PlayerHotbarType.AssignmentKind.FISH
- or identity != _local_catch_id
- )
- ):
+ if kind == PlayerHotbarType.AssignmentKind.FISH:
+ if _local_visible and identity == _local_catch_id:
+ return
+ var fish_catch: FishCatchType = _local_inventory.get_catch_by_id(identity)
+ if fish_catch != null and fish_catch.is_valid():
+ _submit_local_state(fish_catch, true)
+ elif _local_visible:
+ _submit_local_state(null, false)
+ return
+ if _local_visible:
_submit_local_state(null, false)
diff --git a/network/network_fishing_attempt.gd b/network/network_fishing_attempt.gd
index 7ad71ae..3a1b1de 100644
--- a/network/network_fishing_attempt.gd
+++ b/network/network_fishing_attempt.gd
@@ -22,8 +22,10 @@ var target: Vector3
var bobber_position: Vector3
var fish_id: StringName
var bait_tags: Array[StringName] = []
+var lure_effects: Array[StringName] = []
var encounter_seed: int = 0
var bite_time_remaining: float = 0.0
+var bite_confirmation_pending: bool = false
var withdrawal_progress: float = 0.0
var reel_speed: float = 0.0
var barrier_damage: int = 1
diff --git a/network/network_fishing_protocol.gd b/network/network_fishing_protocol.gd
index 547b255..2e9a342 100644
--- a/network/network_fishing_protocol.gd
+++ b/network/network_fishing_protocol.gd
@@ -55,6 +55,8 @@ static func validate_cast_request(data: Variant) -> String:
return "Malformed fishing request."
if payload.has("bait_id") and typeof(payload["bait_id"]) not in [TYPE_STRING, TYPE_STRING_NAME]:
return "Malformed fishing request."
+ if payload.has("lure_id") and typeof(payload["lure_id"]) not in [TYPE_STRING, TYPE_STRING_NAME]:
+ return "Malformed fishing request."
var request_id: String = payload["request_id"]
var session_id: String = payload["session_id"]
var origin: Array = payload["origin"]
@@ -89,6 +91,7 @@ static func validate_cast_request(data: Variant) -> String:
or discovered.size() > MAX_EVIDENCE_FISH_IDS
or str(payload["rod_id"]).is_empty()
or str(payload["rod_id"]).length() > 96
+ or str(payload.get("lure_id", "")).length() > 96
):
return "Fishing request values are outside allowed limits."
for value: Variant in rarity:
diff --git a/network/network_fishing_service.gd b/network/network_fishing_service.gd
index a15b929..2015681 100644
--- a/network/network_fishing_service.gd
+++ b/network/network_fishing_service.gd
@@ -24,6 +24,7 @@ const MIN_CAST_INTERVAL: float = 0.25
signal local_cast_accepted(attempt_id: String, target: Vector3)
signal local_cast_rejected(message: String)
signal local_bite_started(attempt_id: String)
+signal local_bite_pending(attempt_id: String)
signal local_snapshot_received(snapshot: Dictionary)
signal local_catch_received(fish_catch: FishCatch)
signal local_attempt_ended(outcome: StringName, message: String)
@@ -32,6 +33,7 @@ var _session: NetworkSession
var _spawn_service: PlayerSpawnService
var _fishing_spot: FishingSpot
var _local_inventory: FishInventory
+var _local_bag: PlayerBag
var _local_collection: CollectionLog
var _local_capacity: PlayerCoolerCapacity
var _local_experience: PlayerExperienceType
@@ -46,6 +48,7 @@ var _result_acknowledgements: Dictionary[String, String] = {}
var _last_cast_time: Dictionary[int, float] = {}
var _last_input_time: Dictionary[int, float] = {}
var _remote_presentations: Dictionary[int, RemoteFishingPresentation] = {}
+var _pending_local_bait_by_request: Dictionary[String, StringName] = {}
var _snapshot_accumulator: float = 0.0
var _local_input_sequence: int = 0
@@ -55,6 +58,7 @@ func setup(
spawn_service: PlayerSpawnService,
fishing_spot: FishingSpot,
local_inventory: FishInventory,
+ local_bag: PlayerBag,
local_collection: CollectionLog,
local_capacity: PlayerCoolerCapacity,
local_experience: PlayerExperienceType,
@@ -67,6 +71,7 @@ func setup(
_spawn_service = spawn_service
_fishing_spot = fishing_spot
_local_inventory = local_inventory
+ _local_bag = local_bag
_local_collection = local_collection
_local_capacity = local_capacity
_local_experience = local_experience
@@ -96,6 +101,18 @@ func request_local_cast(
):
local_cast_rejected.emit("Fishing attempt ended.")
return ""
+ var bait_id := StringName(str(evidence.get("bait_id", "")))
+ if not bait_id.is_empty() and (
+ _local_bag == null or not _local_bag.owns_item(bait_id)
+ ):
+ local_cast_rejected.emit("No bait available.")
+ return ""
+ var lure_id := StringName(str(evidence.get("lure_id", "")))
+ if not lure_id.is_empty() and (
+ _local_bag == null or not _local_bag.owns_item(lure_id)
+ ):
+ local_cast_rejected.emit("Lure is unavailable.")
+ return ""
var request_id: String = _new_id("cast")
var data: Dictionary = {
"request_id": request_id,
@@ -110,11 +127,14 @@ func request_local_cast(
"rarity_multipliers": evidence.get("rarity_multipliers", []),
"discovered_fish_ids": evidence.get("discovered_fish_ids", []),
"capacity_available": bool(evidence.get("capacity_available", false)),
- "bait_id": str(evidence.get("bait_id", "")),
+ "bait_id": str(bait_id),
+ "lure_id": str(lure_id),
}
if _session.is_host():
_handle_cast_request(_session.get_local_peer_id(), data)
else:
+ if not bait_id.is_empty():
+ _pending_local_bait_by_request[request_id] = bait_id
submit_cast_request.rpc_id(1, data)
return request_id
@@ -176,12 +196,17 @@ func _process(delta: float) -> void:
continue
match attempt.phase:
NetworkFishingAttempt.Phase.WAITING_FOR_BITE:
+ if attempt.bite_confirmation_pending:
+ continue
_update_waiting_attempt(attempt, delta)
if not _attempts.has(peer_id):
continue
attempt.bite_time_remaining -= delta
if attempt.bite_time_remaining <= 0.0:
- _start_bite(attempt)
+ if &"deferred_fight" in attempt.lure_effects:
+ _set_bite_pending(attempt)
+ else:
+ _start_bite(attempt)
NetworkFishingAttempt.Phase.PENDING_CAPACITY:
if now >= attempt.capacity_deadline:
_cancel_attempt(peer_id, "Fishing attempt ended.")
@@ -296,7 +321,47 @@ func _handle_cast_request(peer_id: int, data: Dictionary) -> void:
return
var bait_id: StringName = StringName(str(data.get("bait_id", "")))
var avatar_bag: PlayerBag = avatar.bag
- if not bait_id.is_empty() and (avatar_bag == null or not avatar_bag.remove_item(bait_id, 1)):
+ var owns_authoritative_bag: bool = (
+ peer_id == _session.get_local_peer_id()
+ )
+ var bait: ItemDataType = (
+ _item_catalog.get_item_by_id(bait_id)
+ if not bait_id.is_empty() and _item_catalog != null
+ else null
+ )
+ var lure_id: StringName = StringName(str(data.get("lure_id", "")))
+ var lure: ItemDataType = (
+ _item_catalog.get_item_by_id(lure_id)
+ if not lure_id.is_empty() and _item_catalog != null
+ else null
+ )
+ if (
+ not lure_id.is_empty()
+ and (
+ lure == null
+ or not lure.is_lure()
+ or (
+ owns_authoritative_bag
+ and (
+ avatar_bag == null
+ or not avatar_bag.owns_item(lure_id)
+ )
+ )
+ )
+ ):
+ _record_and_reject(peer_id, request_id, "Lure is unavailable.")
+ return
+ if not bait_id.is_empty() and (
+ bait == null
+ or not bait.is_bait()
+ or (
+ owns_authoritative_bag
+ and (
+ avatar_bag == null
+ or not avatar_bag.remove_item(bait_id, 1)
+ )
+ )
+ ):
_record_and_reject(peer_id, request_id, "No bait available.")
return
var attempt := NetworkFishingAttempt.new()
@@ -310,6 +375,10 @@ func _handle_cast_request(peer_id: int, data: Dictionary) -> void:
attempt.bobber_position = authoritative_target
attempt.fish_id = selected_fish.id
attempt.bait_tags = _bait_tags_for_request(data)
+ attempt.lure_effects.clear()
+ if lure != null:
+ for effect_id: StringName in lure.lure_effects:
+ attempt.lure_effects.append(effect_id)
attempt.reel_speed = float(data["reel_speed"]) * (
effects.get_reel_multiplier() if effects != null else 1.0
)
@@ -437,6 +506,23 @@ func _bait_tags_for_request(data: Dictionary) -> Array[StringName]:
return bait.bait_tags.duplicate() if bait != null and bait.is_bait() else []
+func _set_bite_pending(attempt: NetworkFishingAttempt) -> void:
+ if (
+ attempt.phase != NetworkFishingAttempt.Phase.WAITING_FOR_BITE
+ or attempt.bite_confirmation_pending
+ ):
+ return
+ attempt.bite_confirmation_pending = true
+ attempt.bite_time_remaining = 0.0
+ attempt.input_held = false
+ var data: Dictionary = {
+ "attempt_id": attempt.attempt_id,
+ "owner_peer_id": attempt.owner_peer_id,
+ }
+ _apply_bite_pending(data)
+ receive_bite_pending.rpc(data)
+
+
func _start_bite(attempt: NetworkFishingAttempt) -> void:
if attempt.phase != NetworkFishingAttempt.Phase.WAITING_FOR_BITE:
return
@@ -444,6 +530,7 @@ func _start_bite(attempt: NetworkFishingAttempt) -> void:
if fish == null or fish.catch_profile == null:
_cancel_attempt(attempt.owner_peer_id, "Fishing attempt ended.")
return
+ attempt.bite_confirmation_pending = false
attempt.phase = NetworkFishingAttempt.Phase.FIGHTING
attempt.encounter_seed = _new_seed()
var selector := FishSelectorType.new()
@@ -461,8 +548,6 @@ func _start_bite(attempt: NetworkFishingAttempt) -> void:
attempt.barrier_damage,
attempt.encounter_seed,
fish_catch.quality,
- int(fish.rarity),
- fish.get_weight_percentile(fish_catch.weight_lb),
)
var data: Dictionary = {
"attempt_id": attempt.attempt_id,
@@ -496,6 +581,14 @@ func _handle_fishing_input(peer_id: int, data: Dictionary) -> void:
return
attempt.last_input_sequence = int(data["sequence"])
attempt.input_held = bool(data["held"])
+ if (
+ attempt.phase == NetworkFishingAttempt.Phase.WAITING_FOR_BITE
+ and attempt.bite_confirmation_pending
+ ):
+ if bool(data["pressed"]):
+ attempt.input_held = false
+ _start_bite(attempt)
+ return
if attempt.phase != NetworkFishingAttempt.Phase.FIGHTING:
return
attempt.controller.set_reel_input(attempt.input_held)
@@ -860,7 +953,7 @@ func _on_attempt_escaped(peer_id: int) -> void:
if attempt == null:
return
attempt.phase = NetworkFishingAttempt.Phase.ESCAPED
- _broadcast_public_outcome(attempt, &"escape", "The fish got away!")
+ _broadcast_public_outcome(attempt, &"escape", "")
_dispose_attempt(peer_id)
@@ -971,6 +1064,20 @@ func _apply_cast_accepted(data: Dictionary) -> void:
# On the host this replaces the same authoritative value with itself.
if not _session.is_host():
_attempts[peer_id] = attempt
+ var pending_bait_id: StringName = (
+ _pending_local_bait_by_request.get(
+ attempt.request_id,
+ StringName(),
+ )
+ )
+ _pending_local_bait_by_request.erase(attempt.request_id)
+ if not pending_bait_id.is_empty() and (
+ _local_bag == null
+ or not _local_bag.remove_item(pending_bait_id, 1)
+ ):
+ cancel_local_attempt("No bait available.")
+ local_cast_rejected.emit("No bait available.")
+ return
local_cast_accepted.emit(attempt.attempt_id, target)
else:
var presentation := _get_remote_presentation(peer_id)
@@ -978,6 +1085,21 @@ func _apply_cast_accepted(data: Dictionary) -> void:
presentation.show_cast(origin, target)
+@rpc("authority", "call_remote", "reliable", 0)
+func receive_bite_pending(data: Dictionary) -> void:
+ _apply_bite_pending(data)
+
+
+func _apply_bite_pending(data: Dictionary) -> void:
+ if (
+ typeof(data.get("attempt_id")) != TYPE_STRING
+ or typeof(data.get("owner_peer_id")) != TYPE_INT
+ ):
+ return
+ if int(data["owner_peer_id"]) == _session.get_local_peer_id():
+ local_bite_pending.emit(str(data["attempt_id"]))
+
+
@rpc("authority", "call_remote", "reliable", 0)
func receive_bite_started(data: Dictionary) -> void:
_apply_bite_started(data)
@@ -1024,7 +1146,8 @@ func _send_cast_rejected(
@rpc("authority", "call_remote", "reliable", 0)
-func receive_cast_rejected(_request_id: String, message: String) -> void:
+func receive_cast_rejected(request_id: String, message: String) -> void:
+ _pending_local_bait_by_request.erase(request_id)
local_cast_rejected.emit(message)
diff --git a/network/network_item_use_service.gd b/network/network_item_use_service.gd
index 654b45b..f39d198 100644
--- a/network/network_item_use_service.gd
+++ b/network/network_item_use_service.gd
@@ -50,9 +50,19 @@ func request_use(item_id: StringName) -> String:
if not _pending_local.is_empty():
local_item_use_finished.emit(false, "An item use is already pending.")
return ""
+ var consumed_item_id: StringName = _consumed_item_id(item_id)
+ if item_id == PlayerItemEffects.FISH_FINDER_ID and (
+ _local_bag == null
+ or not _local_bag.owns_item(item_id)
+ or _local_bag.get_quantity(consumed_item_id) < 1
+ ):
+ local_item_use_finished.emit(
+ false, PlayerItemEffects.FISH_FINDER_DEAD_MESSAGE
+ )
+ return ""
if (
_reservations != null
- and _reservations.get_available_item_quantity(item_id) < 1
+ and _reservations.get_available_item_quantity(consumed_item_id) < 1
):
local_item_use_finished.emit(false, "Reserved in a letter.")
return ""
@@ -73,7 +83,7 @@ func request_use(item_id: StringName) -> String:
"request_id": request_id,
"session_id": _session.get_session_id(),
"item_id": str(item_id),
- "quantity": _local_bag.get_quantity(item_id),
+ "quantity": _local_bag.get_quantity(consumed_item_id),
}
_pending_local = data.duplicate(true)
local_item_use_pending.emit(request_id)
@@ -109,14 +119,28 @@ func _handle_use_request(peer_id: int, data: Dictionary) -> void:
var item: ItemData = _catalog.get_item_by_id(item_id)
var avatar: Player = _spawn_service.get_avatar(peer_id)
var duration: float = 0.0
+ var is_fish_finder: bool = (
+ item_id == PlayerItemEffects.FISH_FINDER_ID
+ and item != null
+ and item.category == ItemData.Category.TOOL
+ and item.usable
+ and item.equippable
+ )
if error.is_empty() and (
item == null
- or item.category != ItemData.Category.CONSUMABLE
+ or (
+ item.category != ItemData.Category.CONSUMABLE
+ and not is_fish_finder
+ )
or not item.usable
):
error = "That item cannot be used now."
if error.is_empty() and int(data["quantity"]) < 1:
- error = "You do not have that item."
+ error = (
+ PlayerItemEffects.FISH_FINDER_DEAD_MESSAGE
+ if is_fish_finder
+ else "You do not have that item."
+ )
if error.is_empty() and (
avatar == null
or avatar.is_water_recovery_active()
@@ -180,9 +204,10 @@ func _apply_result(data: Dictionary) -> void:
_acknowledge(data, false, str(data["message"]))
return
var item_id := StringName(str(data["item_id"]))
+ var consumed_item_id: StringName = _consumed_item_id(item_id)
if (
_reservations != null
- and _reservations.get_available_item_quantity(item_id) < 1
+ and _reservations.get_available_item_quantity(consumed_item_id) < 1
):
_pending_local.clear()
local_item_use_finished.emit(false, "Reserved in a letter.")
@@ -190,8 +215,8 @@ func _apply_result(data: Dictionary) -> void:
return
var bag_snapshot := _local_bag.get_all_items()
if (
- _local_bag.get_quantity(item_id) < 1
- or not _local_bag.remove_item(item_id, 1)
+ _local_bag.get_quantity(consumed_item_id) < 1
+ or not _local_bag.remove_item(consumed_item_id, 1)
or not _save_manager.save_if_dirty()
):
_local_bag.replace_all_items(bag_snapshot)
@@ -328,7 +353,10 @@ func _apply_equipped(data: Dictionary) -> void:
if avatar != null:
var item_id := StringName(str(data["item_id"]))
var item: ItemData = _catalog.get_item_by_id(item_id)
- avatar.set_active_item_is_rod(int(data["category"]) == ItemData.Category.ROD)
+ avatar.set_active_item_is_rod(
+ int(data["category"]) == ItemData.Category.ROD,
+ true,
+ )
avatar.set_active_art_kit(
item.icon if item != null else null,
item_id == ArtShopStockType.ART_KIT_ITEM_ID and bool(data["owns_item"]),
@@ -409,3 +437,11 @@ func _new_id(prefix: String) -> String:
return "%s:%s" % [
prefix, Crypto.new().generate_random_bytes(16).hex_encode(),
]
+
+
+func _consumed_item_id(item_id: StringName) -> StringName:
+ return (
+ PlayerItemEffects.BATTERIES_ID
+ if item_id == PlayerItemEffects.FISH_FINDER_ID
+ else item_id
+ )
diff --git a/network/network_job_service.gd b/network/network_job_service.gd
index 7745903..ebf5a6e 100644
--- a/network/network_job_service.gd
+++ b/network/network_job_service.gd
@@ -2,11 +2,13 @@ class_name NetworkJobService
extends Node
const MAX_SESSION_ID_LENGTH: int = 96
+const BOARD_REQUEST_INTERVAL_SECONDS: float = 1.5
var _session: NetworkSession
var _jobs: PlayerJobService
var _sequence: int = 0
var _last_received_sequence: int = -1
+var _board_request_accumulator: float = 0.0
func setup(session: NetworkSession, jobs: PlayerJobService) -> void:
@@ -15,13 +17,36 @@ func setup(session: NetworkSession, jobs: PlayerJobService) -> void:
_session.state_changed.connect(_on_session_state_changed)
_session.peer_authenticated.connect(_on_peer_authenticated)
_jobs.board_changed.connect(_on_board_changed)
+ set_process(true)
+
+
+func _process(delta: float) -> void:
+ if (
+ _session == null
+ or _jobs == null
+ or not _session.is_joined_client()
+ or not _session.supports_server_capability(
+ NetworkProtocol.JOBS_CAPABILITY
+ )
+ or _jobs.has_active_board()
+ ):
+ _board_request_accumulator = 0.0
+ return
+ _board_request_accumulator += delta
+ if _board_request_accumulator < BOARD_REQUEST_INTERVAL_SECONDS:
+ return
+ _board_request_accumulator = 0.0
+ _request_remote_board()
func _on_session_state_changed(state: NetworkSession.State) -> void:
_sequence = 0
_last_received_sequence = -1
+ _board_request_accumulator = 0.0
if state == NetworkSession.State.JOINED_CLIENT:
- if not _session.supports_server_capability(NetworkProtocol.JOBS_CAPABILITY):
+ if _session.supports_server_capability(NetworkProtocol.JOBS_CAPABILITY):
+ _request_remote_board()
+ else:
_jobs.clear_remote_board()
elif state in [
NetworkSession.State.INACTIVE,
@@ -69,6 +94,33 @@ func _send_board(peer_id: int) -> void:
})
+func _request_remote_board() -> void:
+ if (
+ _session != null
+ and _session.is_joined_client()
+ and _session.supports_server_capability(
+ NetworkProtocol.JOBS_CAPABILITY
+ )
+ ):
+ request_job_board.rpc_id(1)
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_job_board() -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if (
+ _session == null
+ or not _session.is_host()
+ or sender_id <= 1
+ or not _session.is_authenticated_peer(sender_id)
+ or not _session.peer_supports_capability(
+ sender_id, NetworkProtocol.JOBS_CAPABILITY
+ )
+ ):
+ return
+ _send_board(sender_id)
+
+
@rpc("authority", "call_remote", "reliable", 0)
func receive_job_board(data: Dictionary) -> void:
if (
@@ -86,6 +138,7 @@ func receive_job_board(data: Dictionary) -> void:
var board: Dictionary = data.get("board", {})
if _jobs.apply_remote_board(board):
_last_received_sequence = sequence
+ _board_request_accumulator = 0.0
static func validate_snapshot(value: Variant) -> bool:
diff --git a/network/network_mail_service.gd b/network/network_mail_service.gd
index f63c7ce..eb9fe0f 100644
--- a/network/network_mail_service.gd
+++ b/network/network_mail_service.gd
@@ -992,6 +992,7 @@ func _capture_assets() -> Dictionary:
return {
"wallet": _wallet.get_balance(),
"bag": _bag.get_all_items(),
+ "unlocked_bait_ids": _bag.get_unlocked_bait_ids(),
"catches": _inventory.get_all_catches(),
"next_sequence": _inventory.get_next_catch_sequence(),
"discovered": _collection_log.get_discovered_ids(),
@@ -1002,6 +1003,7 @@ func _capture_assets() -> Dictionary:
func _restore_assets(snapshot: Dictionary) -> void:
_wallet.restore_balance(int(snapshot["wallet"]))
_bag.replace_all_items(snapshot["bag"])
+ _bag.replace_unlocked_bait_ids(snapshot["unlocked_bait_ids"])
_inventory.replace_all_catches(
snapshot["catches"], int(snapshot["next_sequence"])
)
diff --git a/network/network_player_animation_protocol.gd b/network/network_player_animation_protocol.gd
new file mode 100644
index 0000000..b27cb9d
--- /dev/null
+++ b/network/network_player_animation_protocol.gd
@@ -0,0 +1,94 @@
+class_name NetworkPlayerAnimationProtocol
+extends RefCounted
+
+const FORMAT_VERSION: int = 1
+const MAX_STATE_ID_LENGTH: int = 64
+const MAX_ACTION_SEQUENCE: int = 2147483647
+const MAX_ACTION_ELAPSED_SECONDS: float = 86400.0
+
+const LOCOMOTION_IDLE: StringName = &"idle"
+const LOCOMOTION_WALKING: StringName = &"walking"
+const LOCOMOTION_RUNNING: StringName = &"running"
+
+
+static func make_state(
+ locomotion_id: StringName,
+ grounded: bool,
+ action_id: StringName = &"",
+ action_sequence: int = 0,
+ action_elapsed: float = 0.0,
+) -> Dictionary:
+ return {
+ "format_version": FORMAT_VERSION,
+ "locomotion_id": String(locomotion_id),
+ "grounded": grounded,
+ "action": make_action_state(
+ action_id, action_sequence, action_elapsed
+ ),
+ }
+
+
+static func make_action_state(
+ action_id: StringName = &"",
+ action_sequence: int = 0,
+ action_elapsed: float = 0.0,
+) -> Dictionary:
+ return {
+ "id": String(action_id),
+ "sequence": action_sequence,
+ "elapsed": action_elapsed,
+ }
+
+
+static func validate_state(value: Variant) -> bool:
+ if typeof(value) != TYPE_DICTIONARY:
+ return false
+ var state: Dictionary = value
+ return (
+ typeof(state.get("format_version")) == TYPE_INT
+ and int(state["format_version"]) == FORMAT_VERSION
+ and valid_state_id(state.get("locomotion_id"), false)
+ and typeof(state.get("grounded")) == TYPE_BOOL
+ and validate_action_state(state.get("action"))
+ )
+
+
+static func validate_action_state(value: Variant) -> bool:
+ if typeof(value) != TYPE_DICTIONARY:
+ return false
+ var action: Dictionary = value
+ if (
+ not valid_state_id(action.get("id"), true)
+ or typeof(action.get("sequence")) != TYPE_INT
+ or typeof(action.get("elapsed")) not in [TYPE_FLOAT, TYPE_INT]
+ ):
+ return false
+ var sequence: int = int(action["sequence"])
+ var elapsed: float = float(action["elapsed"])
+ return (
+ sequence >= 0
+ and sequence <= MAX_ACTION_SEQUENCE
+ and is_finite(elapsed)
+ and elapsed >= 0.0
+ and elapsed <= MAX_ACTION_ELAPSED_SECONDS
+ )
+
+
+static func valid_state_id(value: Variant, allow_empty: bool) -> bool:
+ if typeof(value) not in [TYPE_STRING, TYPE_STRING_NAME]:
+ return false
+ var state_id: String = str(value)
+ if state_id.is_empty():
+ return allow_empty
+ if state_id.length() > MAX_STATE_ID_LENGTH:
+ return false
+ for index: int in state_id.length():
+ var codepoint: int = state_id.unicode_at(index)
+ var valid_character: bool = (
+ codepoint >= 97 and codepoint <= 122
+ or codepoint >= 48 and codepoint <= 57
+ or codepoint == 95
+ )
+ if not valid_character:
+ return false
+ return true
diff --git a/network/network_player_animation_protocol.gd.uid b/network/network_player_animation_protocol.gd.uid
new file mode 100644
index 0000000..466ad02
--- /dev/null
+++ b/network/network_player_animation_protocol.gd.uid
@@ -0,0 +1 @@
+uid://cmaaep4n3p2tq
diff --git a/network/network_player_list_service.gd b/network/network_player_list_service.gd
index 6f65e12..4742d14 100644
--- a/network/network_player_list_service.gd
+++ b/network/network_player_list_service.gd
@@ -15,6 +15,9 @@ var _surface_drawing: NetworkSurfaceDrawingService
var _revision := 0
var _host_block_pairs: Dictionary[String, bool] = {}
var _peer_fingerprints: Dictionary[int, String] = {}
+var _remote_bans: Array[Dictionary] = []
+var _ban_snapshot_requested: bool = false
+var _ban_snapshot_loaded: bool = false
func setup(
@@ -40,6 +43,7 @@ func setup(
func(_count: int, _maximum: int) -> void: _sync_authenticated_peers()
)
_session.state_changed.connect(_on_session_state_changed)
+ _session.operator_status_changed.connect(_on_operator_status_changed)
_relationships.relationship_changed.connect(_on_relationship_changed)
_bans.bans_changed.connect(_changed)
_chat.set_relationship_store(_relationships)
@@ -64,13 +68,24 @@ func get_entries() -> Array[PlayerListEntry]:
entry.compact_fingerprint = NetworkIdentityCrypto.compact_suffix(record.identity_fingerprint)
entry.display_name = record.display_name
entry.is_host = peer_id == 1
+ entry.is_operator = _session.is_peer_operator(peer_id)
entry.is_local_player = peer_id == local_id
entry.continuity_state = _known.identity_status(record.identity_fingerprint, record.display_name)
entry.ping_to_host_ms = _session.get_peer_rtt_ms(peer_id)
entry.muted = _relationships.is_muted(record.identity_fingerprint)
entry.blocked = blocked
- entry.can_kick = _session.is_host() and peer_id != local_id and peer_id != 1
+ entry.can_kick = (
+ _session.can_local_moderate()
+ and peer_id != local_id
+ and peer_id != 1
+ and (_session.is_host() or not entry.is_operator)
+ )
entry.can_ban = entry.can_kick
+ entry.can_manage_operator = (
+ _session.can_manage_operators()
+ and peer_id != local_id
+ and peer_id != 1
+ )
entry.revision = _revision
result.append(entry)
result.sort_custom(_entry_before)
@@ -89,12 +104,33 @@ func is_local_host() -> bool:
return _session.is_host()
+func is_local_moderator() -> bool:
+ return _session.can_local_moderate()
+
+
+func can_manage_operators() -> bool:
+ return _session.can_manage_operators()
+
+
+func is_open_host() -> bool:
+ return _session.is_open_host()
+
+
+func set_host_open(is_open: bool) -> bool:
+ return _session.set_host_open(is_open)
+
+
func get_relationships() -> Array[Dictionary]:
return _relationships.get_records()
func get_bans() -> Array[Dictionary]:
- return _bans.get_bans(_session.get_host_identity_fingerprint()) if _session.is_host() else []
+ if _session.is_host():
+ return _bans.get_bans(_session.get_host_identity_fingerprint())
+ if not _session.is_local_operator():
+ return []
+ _request_ban_snapshot()
+ return _remote_bans.duplicate(true)
func set_surface_drawing_service(
@@ -123,14 +159,12 @@ func get_session_artwork_counts() -> Vector2i:
func reset_session_artwork() -> bool:
- if not _session.is_host() or _surface_drawing == null:
+ if _session.is_host():
+ return _reset_session_artwork_on_host()
+ if not _session.is_local_operator():
return false
- var ok: bool = _surface_drawing.clear_session_artwork()
- moderation_finished.emit(
- ok,
- "Session artwork cleared." if ok else "Session artwork could not be cleared.",
- )
- return ok
+ request_reset_session_artwork.rpc_id(1)
+ return true
func set_muted(fingerprint: String, display_name: String, value: bool) -> bool:
@@ -146,12 +180,13 @@ func set_blocked(fingerprint: String, display_name: String, value: bool) -> bool
func kick(peer_id: int, fingerprint: String, revision: int) -> bool:
- if not _valid_moderation_target(peer_id, fingerprint, revision):
- moderation_finished.emit(false, "That player is no longer connected.")
+ if _session.is_host():
+ return _kick_on_host(peer_id, fingerprint, revision, true)
+ if not _session.is_local_operator():
+ moderation_finished.emit(false, "Only the host or an operator can remove players.")
return false
- var ok := _session.kick_authenticated_peer(peer_id, fingerprint)
- moderation_finished.emit(ok, "Player removed." if ok else "Player could not be removed.")
- return ok
+ request_kick.rpc_id(1, peer_id, fingerprint)
+ return true
func ban(
@@ -160,22 +195,158 @@ func ban(
display_name: String,
revision: int,
) -> bool:
- if not _valid_moderation_target(peer_id, fingerprint, revision):
- moderation_finished.emit(false, "That player is no longer connected.")
+ if _session.is_host():
+ return _ban_on_host(
+ peer_id, fingerprint, display_name, revision, true
+ )
+ if not _session.is_local_operator():
+ moderation_finished.emit(false, "Only the host or an operator can ban players.")
return false
- var host_fingerprint := _session.get_host_identity_fingerprint()
- if not _bans.ban(host_fingerprint, fingerprint, display_name):
- moderation_finished.emit(false, "Ban could not be saved.")
- return false
- var ok := _session.kick_authenticated_peer(peer_id, fingerprint, true)
- moderation_finished.emit(ok, "Player banned." if ok else "Ban saved.")
+ request_ban.rpc_id(1, peer_id, fingerprint)
return true
func unban(fingerprint: String) -> bool:
- if not _session.is_host():
+ if _session.is_host():
+ var ok: bool = _bans.unban(
+ _session.get_host_identity_fingerprint(), fingerprint
+ )
+ moderation_finished.emit(
+ ok, "Player unbanned." if ok else "Ban could not be removed."
+ )
+ return ok
+ if not _session.is_local_operator():
+ moderation_finished.emit(false, "Only the host or an operator can remove bans.")
return false
- return _bans.unban(_session.get_host_identity_fingerprint(), fingerprint)
+ request_unban.rpc_id(1, fingerprint)
+ return true
+
+
+func set_operator(
+ peer_id: int,
+ fingerprint: String,
+ enabled: bool,
+ revision: int,
+) -> bool:
+ if (
+ not _session.can_manage_operators()
+ or not _valid_moderation_target(
+ peer_id, fingerprint, revision, true, true
+ )
+ ):
+ moderation_finished.emit(false, "That player is no longer connected.")
+ return false
+ var ok: bool = _session.set_peer_operator(peer_id, fingerprint, enabled)
+ moderation_finished.emit(
+ ok,
+ ("Player is now an operator." if enabled else "Operator access removed.")
+ if ok
+ else "Operator access could not be changed.",
+ )
+ return ok
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_kick(peer_id: int, fingerprint: String) -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if not _valid_operator_sender(sender_id):
+ return
+ var ok: bool = _kick_on_host(peer_id, fingerprint, -1, false)
+ _send_moderation_result(
+ sender_id, ok, "Player removed." if ok else "Player could not be removed."
+ )
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_ban(peer_id: int, fingerprint: String) -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if not _valid_operator_sender(sender_id):
+ return
+ var record: PeerRegistry.PeerRecord = _session.get_peer_record(peer_id)
+ var display_name: String = record.display_name if record != null else "Player"
+ var ok: bool = _ban_on_host(
+ peer_id, fingerprint, display_name, -1, false
+ )
+ _send_moderation_result(
+ sender_id, ok, "Player banned." if ok else "Player could not be banned."
+ )
+ _send_ban_snapshot(sender_id)
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_unban(fingerprint: String) -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if (
+ not _valid_operator_sender(sender_id)
+ or not NetworkIdentityCrypto.valid_fingerprint(fingerprint)
+ ):
+ return
+ var ok: bool = _bans.unban(
+ _session.get_host_identity_fingerprint(), fingerprint
+ )
+ _send_moderation_result(
+ sender_id, ok, "Player unbanned." if ok else "Ban could not be removed."
+ )
+ _send_ban_snapshot(sender_id)
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_reset_session_artwork() -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if not _valid_operator_sender(sender_id):
+ return
+ var ok: bool = _reset_session_artwork_on_host(false)
+ _send_moderation_result(
+ sender_id,
+ ok,
+ "Session artwork cleared."
+ if ok
+ else "Session artwork could not be cleared.",
+ )
+
+
+@rpc("any_peer", "call_remote", "reliable", 0)
+func request_ban_snapshot() -> void:
+ var sender_id: int = multiplayer.get_remote_sender_id()
+ if _valid_operator_sender(sender_id):
+ _send_ban_snapshot(sender_id)
+
+
+@rpc("authority", "call_remote", "reliable", 0)
+func receive_moderation_result(success: bool, message: String) -> void:
+ if not _session.is_joined_client():
+ return
+ moderation_finished.emit(success, message.left(120))
+
+
+@rpc("authority", "call_remote", "reliable", 0)
+func receive_ban_snapshot(records: Array) -> void:
+ if not _session.is_local_operator() or records.size() > HostBanStore.MAX_BANS:
+ return
+ var sanitized: Array[Dictionary] = []
+ for value: Variant in records:
+ if typeof(value) != TYPE_DICTIONARY:
+ return
+ var record: Dictionary = value
+ var fingerprint: String = str(record.get("target_fingerprint", ""))
+ var display_name: String = str(
+ record.get("last_known_display_name", "Player")
+ ).strip_edges().left(NetworkProtocol.MAX_DISPLAY_NAME_LENGTH)
+ if (
+ not NetworkIdentityCrypto.valid_fingerprint(fingerprint)
+ or display_name.is_empty()
+ or typeof(record.get("banned_unix")) != TYPE_INT
+ ):
+ return
+ sanitized.append({
+ "target_fingerprint": fingerprint,
+ "last_known_display_name": display_name,
+ "banned_unix": int(record["banned_unix"]),
+ })
+ _remote_bans = sanitized
+ _ban_snapshot_requested = false
+ _ban_snapshot_loaded = true
+ _changed()
func is_locally_blocked(fingerprint: String) -> bool:
@@ -263,6 +434,22 @@ func _on_session_state_changed(state: NetworkSession.State) -> void:
]:
_host_block_pairs.clear()
_peer_fingerprints.clear()
+ _remote_bans.clear()
+ _ban_snapshot_requested = false
+ _ban_snapshot_loaded = false
+ elif state == NetworkSession.State.JOINED_CLIENT:
+ _request_ban_snapshot()
+ _changed()
+
+
+func _on_operator_status_changed(peer_id: int, enabled: bool) -> void:
+ if peer_id == _session.get_local_peer_id():
+ if enabled:
+ _request_ban_snapshot()
+ else:
+ _remote_bans.clear()
+ _ban_snapshot_requested = false
+ _ban_snapshot_loaded = false
_changed()
@@ -287,16 +474,137 @@ func _peer_for_fingerprint(fingerprint: String) -> int:
return 0
-func _valid_moderation_target(peer_id: int, fingerprint: String, revision: int) -> bool:
- if not _session.is_host() or revision != _revision or peer_id == 1:
+func _valid_moderation_target(
+ peer_id: int,
+ fingerprint: String,
+ revision: int,
+ require_revision: bool,
+ can_target_operator: bool,
+) -> bool:
+ if (
+ not _session.is_host()
+ or (require_revision and revision != _revision)
+ or peer_id == 1
+ or (not can_target_operator and _session.is_peer_operator(peer_id))
+ ):
return false
var record := _session.get_peer_record(peer_id)
return record != null and record.identity_fingerprint == fingerprint
+func _valid_operator_sender(peer_id: int) -> bool:
+ return (
+ _session.is_host()
+ and peer_id > 1
+ and _session.is_authenticated_peer(peer_id)
+ and _session.is_peer_operator(peer_id)
+ )
+
+
+func _kick_on_host(
+ peer_id: int,
+ fingerprint: String,
+ revision: int,
+ local_host_request: bool,
+) -> bool:
+ if not _valid_moderation_target(
+ peer_id,
+ fingerprint,
+ revision,
+ local_host_request,
+ local_host_request,
+ ):
+ if local_host_request:
+ moderation_finished.emit(false, "That player is no longer connected.")
+ return false
+ var ok: bool = _session.kick_authenticated_peer(peer_id, fingerprint)
+ if local_host_request:
+ moderation_finished.emit(
+ ok, "Player removed." if ok else "Player could not be removed."
+ )
+ return ok
+
+
+func _ban_on_host(
+ peer_id: int,
+ fingerprint: String,
+ display_name: String,
+ revision: int,
+ local_host_request: bool,
+) -> bool:
+ if not _valid_moderation_target(
+ peer_id,
+ fingerprint,
+ revision,
+ local_host_request,
+ local_host_request,
+ ):
+ if local_host_request:
+ moderation_finished.emit(false, "That player is no longer connected.")
+ return false
+ var record: PeerRegistry.PeerRecord = _session.get_peer_record(peer_id)
+ var trusted_display_name: String = (
+ record.display_name if record != null else display_name
+ )
+ var host_fingerprint: String = _session.get_host_identity_fingerprint()
+ if not _bans.ban(host_fingerprint, fingerprint, trusted_display_name):
+ if local_host_request:
+ moderation_finished.emit(false, "Ban could not be saved.")
+ return false
+ var ok: bool = _session.kick_authenticated_peer(peer_id, fingerprint, true)
+ if local_host_request:
+ moderation_finished.emit(ok, "Player banned." if ok else "Ban saved.")
+ return true
+
+
+func _reset_session_artwork_on_host(
+ emit_local_result: bool = true,
+) -> bool:
+ if not _session.is_host() or _surface_drawing == null:
+ return false
+ var ok: bool = _surface_drawing.clear_session_artwork()
+ if emit_local_result:
+ moderation_finished.emit(
+ ok,
+ "Session artwork cleared."
+ if ok
+ else "Session artwork could not be cleared.",
+ )
+ return ok
+
+
+func _send_moderation_result(
+ peer_id: int,
+ success: bool,
+ message: String,
+) -> void:
+ receive_moderation_result.rpc_id(peer_id, success, message.left(120))
+
+
+func _send_ban_snapshot(peer_id: int) -> void:
+ if not _valid_operator_sender(peer_id):
+ return
+ receive_ban_snapshot.rpc_id(
+ peer_id,
+ _bans.get_bans(_session.get_host_identity_fingerprint()),
+ )
+
+
+func _request_ban_snapshot() -> void:
+ if (
+ _session.is_local_operator()
+ and not _ban_snapshot_requested
+ and not _ban_snapshot_loaded
+ ):
+ _ban_snapshot_requested = true
+ request_ban_snapshot.rpc_id(1)
+
+
func _entry_before(a: PlayerListEntry, b: PlayerListEntry) -> bool:
if a.is_host != b.is_host:
return a.is_host
+ if a.is_operator != b.is_operator:
+ return a.is_operator
if a.is_local_player != b.is_local_player:
return a.is_local_player
var compared := a.display_name.naturalnocasecmp_to(b.display_name)
diff --git a/network/network_profile_preferences.gd b/network/network_profile_preferences.gd
index c90cd7d..5ecb6fd 100644
--- a/network/network_profile_preferences.gd
+++ b/network/network_profile_preferences.gd
@@ -2,8 +2,14 @@ class_name NetworkProfilePreferences
extends Node
const FORMAT_VERSION: int = 1
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
var profile_id: String = ""
var display_name: String = "Player"
+var voice_id: String = VoiceProfilesType.DEFAULT_ID
+var speech_speed_id: String = VoiceProfilesType.DEFAULT_SPEED_ID
+var call_id: String = VoiceProfilesType.DEFAULT_CALL_ID
var created_at_unix: int = 0
var _profile_path := ""
var _expected_hash := ""
@@ -48,19 +54,45 @@ func load_or_create() -> bool:
Time.get_ticks_usec(),
]
display_name = "Player"
+ voice_id = VoiceProfilesType.DEFAULT_ID
+ speech_speed_id = VoiceProfilesType.DEFAULT_SPEED_ID
+ call_id = VoiceProfilesType.DEFAULT_CALL_ID
created_at_unix = int(Time.get_unix_time_from_system())
return _save_atomic()
func set_display_name(value: String) -> bool:
+ return set_profile_identity(value, voice_id, speech_speed_id, call_id)
+
+
+func set_profile_identity(
+ value: String,
+ selected_voice_id: String,
+ selected_speech_speed_id: String,
+ selected_call_id: String,
+) -> bool:
var clean_name: String = value.strip_edges()
- if not is_valid_display_name(clean_name):
+ if (
+ not is_valid_display_name(clean_name)
+ or not VoiceProfilesType.is_valid(selected_voice_id)
+ or not VoiceProfilesType.is_valid_speed(selected_speech_speed_id)
+ or not VoiceProfilesType.is_valid_call(selected_call_id)
+ ):
return false
- var previous: String = display_name
+ var previous_name: String = display_name
+ var previous_voice_id: String = voice_id
+ var previous_speech_speed_id: String = speech_speed_id
+ var previous_call_id: String = call_id
display_name = clean_name
+ voice_id = selected_voice_id
+ speech_speed_id = selected_speech_speed_id
+ call_id = selected_call_id
if _save_atomic():
return true
- display_name = previous
+ display_name = previous_name
+ voice_id = previous_voice_id
+ speech_speed_id = previous_speech_speed_id
+ call_id = previous_call_id
return false
@@ -109,6 +141,15 @@ func _load_existing() -> bool:
return false
profile_id = loaded_id
display_name = loaded_name
+ voice_id = VoiceProfilesType.sanitized_id(
+ str(data.get("voice_id", VoiceProfilesType.DEFAULT_ID))
+ )
+ speech_speed_id = VoiceProfilesType.sanitized_speed_id(
+ str(data.get("speech_speed_id", VoiceProfilesType.DEFAULT_SPEED_ID))
+ )
+ call_id = VoiceProfilesType.sanitized_call_id(
+ str(data.get("call_id", VoiceProfilesType.DEFAULT_CALL_ID))
+ )
created_at_unix = int(data["created_at_unix"])
return true
@@ -118,6 +159,9 @@ func _save_atomic() -> bool:
"format_version": FORMAT_VERSION,
"profile_id": profile_id,
"display_name": display_name,
+ "voice_id": voice_id,
+ "speech_speed_id": speech_speed_id,
+ "call_id": call_id,
"created_at_unix": created_at_unix,
}
var result := PortableFileGuard.write_guarded(
diff --git a/network/network_profile_protocol.gd b/network/network_profile_protocol.gd
index b4c2d3a..32c44b6 100644
--- a/network/network_profile_protocol.gd
+++ b/network/network_profile_protocol.gd
@@ -56,6 +56,10 @@ static func signature_fields(data: Dictionary) -> Array:
)
),
str(appearance.get("fur_pattern", "")),
+ str(appearance.get("fur_style", "")),
+ str(appearance.get("fur_color_2", "")),
+ str(appearance.get("fur_color_3", "")),
+ str(appearance.get("fur_color_4", "")),
str(appearance.get("ears", "")),
str(appearance.get("eyes", "")),
str(appearance.get("nose", "")),
diff --git a/network/network_profile_service.gd b/network/network_profile_service.gd
index 2666d26..86b1be1 100644
--- a/network/network_profile_service.gd
+++ b/network/network_profile_service.gd
@@ -1,6 +1,10 @@
class_name NetworkProfileService
extends Node
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
+
signal conflict_result(
request_id: String,
has_conflict: bool,
@@ -18,6 +22,9 @@ var _preferences: NetworkProfilePreferences
var _appearance_store: PlayerAppearanceStore
var _spawn_service: PlayerSpawnService
var _pending_apply: Dictionary[String, Dictionary] = {}
+var _pending_voice_ids: Dictionary[String, String] = {}
+var _pending_speech_speed_ids: Dictionary[String, String] = {}
+var _pending_call_ids: Dictionary[String, String] = {}
var _host_pending_apply: Dictionary[String, Dictionary] = {}
var _latest_check_id: String = ""
var _latest_check_name: String = ""
@@ -40,6 +47,7 @@ func setup(
_session.join_authenticated.connect(_on_join_authenticated)
_session.state_changed.connect(_on_session_state_changed)
_apply_to_avatar(1, _appearance_store.get_snapshot())
+ _apply_local_voice_to_avatar()
func get_persisted_name() -> String:
@@ -50,6 +58,18 @@ func get_persisted_appearance() -> Dictionary:
return _appearance_store.get_snapshot()
+func get_persisted_voice_id() -> String:
+ return _preferences.voice_id
+
+
+func get_persisted_speech_speed_id() -> String:
+ return _preferences.speech_speed_id
+
+
+func get_persisted_call_id() -> String:
+ return _preferences.call_id
+
+
func get_identity_fingerprint() -> String:
return (
_session.get_local_identity_fingerprint()
@@ -87,11 +107,17 @@ func apply_profile(
display_name: String,
appearance: Dictionary,
use_anyway: bool,
+ voice_id: String = VoiceProfilesType.DEFAULT_ID,
+ speech_speed_id: String = VoiceProfilesType.DEFAULT_SPEED_ID,
+ call_id: String = VoiceProfilesType.DEFAULT_CALL_ID,
) -> bool:
var clean_name := display_name.strip_edges()
if (
not NetworkProfilePreferences.is_valid_display_name(clean_name)
or not CharacterCustomizationCatalog.validate_snapshot(appearance)
+ or not VoiceProfilesType.is_valid(voice_id)
+ or not VoiceProfilesType.is_valid_speed(speech_speed_id)
+ or not VoiceProfilesType.is_valid_call(call_id)
):
apply_finished.emit(false, "Check the player name and appearance choices.")
return false
@@ -108,6 +134,9 @@ func apply_profile(
"profile_update", NetworkProfileProtocol.signature_fields(request)
)
_pending_apply[request_id] = request
+ _pending_voice_ids[request_id] = voice_id
+ _pending_speech_speed_ids[request_id] = speech_speed_id
+ _pending_call_ids[request_id] = call_id
if _session == null or not _session.is_gameplay_session_active():
_apply_local_result(request_id, true, "", false, PackedStringArray())
elif _session.is_host():
@@ -264,20 +293,57 @@ func _apply_local_result(
return
if not accepted:
_pending_apply.erase(request_id)
+ _pending_voice_ids.erase(request_id)
+ _pending_speech_speed_ids.erase(request_id)
+ _pending_call_ids.erase(request_id)
conflict_result.emit(request_id, conflict, suggestions)
apply_finished.emit(false, message)
return
var previous_name := _preferences.display_name
- if not _preferences.set_display_name(str(request["display_name"])):
+ var previous_voice_id := _preferences.voice_id
+ var previous_speech_speed_id := _preferences.speech_speed_id
+ var previous_call_id := _preferences.call_id
+ var requested_voice_id: String = _pending_voice_ids.get(
+ request_id,
+ VoiceProfilesType.DEFAULT_ID,
+ )
+ var requested_speech_speed_id: String = _pending_speech_speed_ids.get(
+ request_id,
+ VoiceProfilesType.DEFAULT_SPEED_ID,
+ )
+ var requested_call_id: String = _pending_call_ids.get(
+ request_id,
+ VoiceProfilesType.DEFAULT_CALL_ID,
+ )
+ if not _preferences.set_profile_identity(
+ str(request["display_name"]),
+ requested_voice_id,
+ requested_speech_speed_id,
+ requested_call_id,
+ ):
_pending_apply.erase(request_id)
+ _pending_voice_ids.erase(request_id)
+ _pending_speech_speed_ids.erase(request_id)
+ _pending_call_ids.erase(request_id)
apply_finished.emit(false, "Profile could not be saved.")
return
if not _appearance_store.save_snapshot(request["appearance"]):
- _preferences.set_display_name(previous_name)
+ _preferences.set_profile_identity(
+ previous_name,
+ previous_voice_id,
+ previous_speech_speed_id,
+ previous_call_id,
+ )
_pending_apply.erase(request_id)
+ _pending_voice_ids.erase(request_id)
+ _pending_speech_speed_ids.erase(request_id)
+ _pending_call_ids.erase(request_id)
apply_finished.emit(false, "Profile could not be saved.")
return
_pending_apply.erase(request_id)
+ _pending_voice_ids.erase(request_id)
+ _pending_speech_speed_ids.erase(request_id)
+ _pending_call_ids.erase(request_id)
if _session != null and _session.is_gameplay_session_active():
if _session.is_host():
_session.apply_canonical_profile(
@@ -304,6 +370,7 @@ func _apply_local_result(
_session.get_local_peer_id() if _session != null else 1,
_appearance_store.get_snapshot(),
)
+ _apply_local_voice_to_avatar()
apply_finished.emit(true, "Profile saved.")
@@ -361,6 +428,7 @@ func _on_join_authenticated() -> void:
_apply_to_avatar(
_session.get_local_peer_id(), _appearance_store.get_snapshot()
)
+ _apply_local_voice_to_avatar()
func _on_peer_removed(_peer_id: int) -> void:
@@ -400,6 +468,9 @@ func _refresh_latest_check() -> void:
func _on_session_state_changed(state: NetworkSession.State) -> void:
if state == NetworkSession.State.INACTIVE:
_pending_apply.clear()
+ _pending_voice_ids.clear()
+ _pending_speech_speed_ids.clear()
+ _pending_call_ids.clear()
_host_pending_apply.clear()
_latest_check_id = ""
_latest_check_name = ""
@@ -465,5 +536,16 @@ func _apply_to_avatar(peer_id: int, appearance: Dictionary) -> void:
avatar.apply_appearance_snapshot(appearance)
+func _apply_local_voice_to_avatar() -> void:
+ if _spawn_service == null:
+ return
+ var local_peer_id := (
+ _session.get_local_peer_id() if _session != null else 1
+ )
+ var avatar := _spawn_service.get_avatar(local_peer_id)
+ if avatar != null:
+ avatar.apply_animalese_voice_id(_preferences.voice_id)
+
+
func _new_id() -> String:
return Crypto.new().generate_random_bytes(16).hex_encode()
diff --git a/network/network_protocol.gd b/network/network_protocol.gd
index 23b80b6..7250fba 100644
--- a/network/network_protocol.gd
+++ b/network/network_protocol.gd
@@ -1,8 +1,9 @@
class_name NetworkProtocol
extends RefCounted
-const PROTOCOL_VERSION: int = 3
+const PROTOCOL_VERSION: int = 4
const GAME_BUILD: String = "prealpha"
+const MAX_GAME_VERSION_LENGTH: int = 64
const MAX_DISPLAY_NAME_LENGTH: int = 24
const MAX_PROFILE_ID_LENGTH: int = 96
const MAX_NONCE_LENGTH: int = 96
@@ -37,9 +38,80 @@ enum RejectionCode {
SERVER_SHUTTING_DOWN,
UNSUPPORTED_CLIENT,
BANNED,
+ CLIENT_OUTDATED,
+ SERVER_OUTDATED,
+ VERSION_MISMATCH,
}
+static func game_version() -> String:
+ return str(ProjectSettings.get_setting(
+ "application/config/version", "unknown"
+ )).strip_edges()
+
+
+static func game_version_rejection(
+ client_version: String,
+ server_version: String,
+) -> RejectionCode:
+ if client_version == server_version:
+ return RejectionCode.NONE
+ var comparison: int = _compare_game_versions(
+ client_version, server_version
+ )
+ if comparison < 0:
+ return RejectionCode.CLIENT_OUTDATED
+ if comparison > 0:
+ return RejectionCode.SERVER_OUTDATED
+ return RejectionCode.VERSION_MISMATCH
+
+
+static func _compare_game_versions(first: String, second: String) -> int:
+ var first_parts: PackedStringArray = first.split("-", true, 1)
+ var second_parts: PackedStringArray = second.split("-", true, 1)
+ var first_core: PackedStringArray = first_parts[0].split(".")
+ var second_core: PackedStringArray = second_parts[0].split(".")
+ for index: int in maxi(first_core.size(), second_core.size()):
+ var first_number: int = (
+ int(first_core[index])
+ if index < first_core.size() and first_core[index].is_valid_int()
+ else 0
+ )
+ var second_number: int = (
+ int(second_core[index])
+ if index < second_core.size() and second_core[index].is_valid_int()
+ else 0
+ )
+ if first_number != second_number:
+ return -1 if first_number < second_number else 1
+ var first_rank: int = _prerelease_rank(
+ first_parts[1] if first_parts.size() > 1 else ""
+ )
+ var second_rank: int = _prerelease_rank(
+ second_parts[1] if second_parts.size() > 1 else ""
+ )
+ if first_rank != second_rank:
+ return -1 if first_rank < second_rank else 1
+ return 0
+
+
+static func _prerelease_rank(label: String) -> int:
+ var normalized: String = label.to_lower()
+ if normalized.is_empty():
+ return 5
+ if normalized.begins_with("dev"):
+ return 0
+ if normalized.begins_with("prealpha"):
+ return 1
+ if normalized.begins_with("alpha"):
+ return 2
+ if normalized.begins_with("beta"):
+ return 3
+ if normalized.begins_with("rc"):
+ return 4
+ return 2
+
+
static func make_identity_hello(
public_key: String,
fingerprint: String,
@@ -48,6 +120,7 @@ static func make_identity_hello(
) -> Dictionary:
return {
"protocol_version": PROTOCOL_VERSION,
+ "game_version": game_version(),
"public_key": public_key,
"fingerprint": fingerprint,
"client_nonce": client_nonce,
@@ -62,6 +135,9 @@ static func validate_identity_hello(data: Variant) -> bool:
var value: Dictionary = data
return (
typeof(value.get("protocol_version")) == TYPE_INT
+ and typeof(value.get("game_version")) == TYPE_STRING
+ and not str(value["game_version"]).is_empty()
+ and str(value["game_version"]).length() <= MAX_GAME_VERSION_LENGTH
and typeof(value.get("public_key")) == TYPE_STRING
and str(value["public_key"]).to_utf8_buffer().size() <= MAX_PUBLIC_KEY_LENGTH
and NetworkIdentityCrypto.valid_fingerprint(value.get("fingerprint"))
@@ -85,6 +161,7 @@ static func make_client_hello(
) -> Dictionary:
return {
"protocol_version": PROTOCOL_VERSION,
+ "game_version": game_version(),
"game_build": GAME_BUILD,
"local_profile_id": profile_id,
"display_name": display_name,
@@ -108,6 +185,7 @@ static func validate_client_hello(data: Variant) -> String:
var payload: Dictionary = data
for key: String in [
"protocol_version",
+ "game_version",
"game_build",
"local_profile_id",
"display_name",
@@ -121,6 +199,12 @@ static func validate_client_hello(data: Variant) -> String:
return "Handshake is missing %s." % key
if typeof(payload["protocol_version"]) != TYPE_INT:
return "Protocol version is invalid."
+ if (
+ typeof(payload["game_version"]) != TYPE_STRING
+ or str(payload["game_version"]).is_empty()
+ or str(payload["game_version"]).length() > MAX_GAME_VERSION_LENGTH
+ ):
+ return "Game version is invalid."
if typeof(payload["game_build"]) != TYPE_STRING:
return "Game build is invalid."
if typeof(payload["local_profile_id"]) != TYPE_STRING:
@@ -171,6 +255,7 @@ static func validate_client_hello(data: Variant) -> String:
static func client_profile_fields(data: Dictionary) -> Array:
var appearance: Dictionary = data.get("cosmetic_snapshot", {})
return [
+ str(data.get("game_version", "")),
str(data.get("client_nonce", "")),
str(data.get("identity_fingerprint", "")),
str(data.get("local_profile_id", "")),
@@ -183,6 +268,10 @@ static func client_profile_fields(data: Dictionary) -> Array:
)
),
str(appearance.get("fur_pattern", "")),
+ str(appearance.get("fur_style", "")),
+ str(appearance.get("fur_color_2", "")),
+ str(appearance.get("fur_color_3", "")),
+ str(appearance.get("fur_color_4", "")),
str(appearance.get("ears", "")),
str(appearance.get("eyes", "")),
str(appearance.get("nose", "")),
@@ -198,14 +287,16 @@ static func make_server_hello(
assigned_peer_id: int,
player_count: int,
max_players: int,
+ server_display_name: String = "NETfishing",
) -> Dictionary:
return {
"accepted": accepted,
"rejection_code": int(rejection_code),
"protocol_version": PROTOCOL_VERSION,
+ "game_version": game_version(),
"session_id": session_id,
"assigned_peer_id": assigned_peer_id,
- "server_display_name": "NETfishing",
+ "server_display_name": server_display_name,
"player_count": player_count,
"max_players": max_players,
"capability_flags": PackedStringArray([
@@ -250,5 +341,20 @@ static func rejection_text(code: int) -> String:
return "This game build is not supported by the server."
RejectionCode.BANNED:
return "You are not permitted to join this server."
+ RejectionCode.CLIENT_OUTDATED:
+ return (
+ "Your NETfishing version is out of date. "
+ + "Update the game to join this server."
+ )
+ RejectionCode.SERVER_OUTDATED:
+ return (
+ "This server is out of date. "
+ + "The host needs to update NETfishing."
+ )
+ RejectionCode.VERSION_MISMATCH:
+ return (
+ "This game and server use different NETfishing versions. "
+ + "Update both to the latest release."
+ )
_:
return "The server rejected the connection."
diff --git a/network/network_session.gd b/network/network_session.gd
index 27b599f..076acc5 100644
--- a/network/network_session.gd
+++ b/network/network_session.gd
@@ -8,7 +8,8 @@ const DEFAULT_TRANSPORT_MAX_CLIENTS: int = 31
const CONNECTION_TIMEOUT_SECONDS: float = 10.0
const AUTHENTICATION_TIMEOUT_SECONDS: float = 60.0
const INPUT_INTERVAL: float = 1.0 / 30.0
-const SNAPSHOT_INTERVAL: float = 1.0 / 20.0
+const SNAPSHOT_INTERVAL: float = 1.0 / 30.0
+const MAX_MOVEMENT_INPUT_SEQUENCE: int = 2147483647
signal state_changed(state: State)
signal status_message_changed(message: String)
@@ -16,6 +17,7 @@ signal connection_error(message: String)
signal peer_authenticated(peer_id: int, display_name: String)
signal peer_removed(peer_id: int)
signal host_openness_changed(is_open: bool)
+signal session_display_name_changed(display_name: String)
signal peer_count_changed(player_count: int, max_players: int)
signal peer_display_name_changed(peer_id: int, display_name: String)
signal peer_profile_changed(
@@ -31,7 +33,8 @@ signal server_trust_required(
is_changed: bool,
)
signal peer_identity_observed(peer_id: int, status: String)
-signal server_lost
+signal operator_status_changed(peer_id: int, is_operator: bool)
+signal server_lost(message: String)
signal remote_recovery_requested(peer_id: int, entry_position: Vector3)
signal remote_recovery_presentation_changed(
peer_id: int,
@@ -99,6 +102,12 @@ var _local_appearance_snapshot: Dictionary = (
)
var _moderation_disconnect_message := ""
var _host_port: int = 0
+var _session_display_name: String = "NETfishing Room"
+var _dedicated_host: bool = false
+var _configured_operator_fingerprints: Dictionary[String, bool] = {}
+var _session_operator_fingerprints: Dictionary[String, bool] = {}
+var _operator_peer_ids: Dictionary[int, bool] = {}
+var _local_operator: bool = false
func _ready() -> void:
@@ -118,6 +127,7 @@ func setup(
known_players: KnownPlayerStore,
server_trust: ServerTrustStore,
host_bans: HostBanStore,
+ dedicated: bool = false,
) -> void:
_profile = profile
_saved_servers = saved_servers
@@ -127,12 +137,26 @@ func setup(
_known_players = known_players
_server_trust = server_trust
_host_bans = host_bans
- if _profile != null:
+ if not dedicated and _profile != null:
_profile_ready = _profile.load_or_create()
- if _player_identity != null:
+ if not dedicated and _player_identity != null:
_profile_ready = _profile_ready and _player_identity.load_or_create()
+func configure_dedicated_operators(
+ fingerprints: PackedStringArray,
+) -> bool:
+ if state != State.INACTIVE:
+ return false
+ var configured: Dictionary[String, bool] = {}
+ for fingerprint: String in fingerprints:
+ if not NetworkIdentityCrypto.valid_fingerprint(fingerprint):
+ return false
+ configured[fingerprint] = true
+ _configured_operator_fingerprints = configured
+ return true
+
+
func start_private_host(
port: int = DEFAULT_PORT,
port_attempts: int = 1,
@@ -145,6 +169,34 @@ func start_private_host(
or _host_identity == null
):
return false
+ return _start_host(port, port_attempts, false)
+
+
+func start_dedicated_host(
+ port: int = DEFAULT_PORT,
+ max_players: int = DEFAULT_SESSION_MAX_PLAYERS,
+ bind_address: String = "*",
+) -> bool:
+ if (
+ state != State.INACTIVE
+ or _spawn_service == null
+ or _host_identity == null
+ or max_players < 1
+ or max_players > 128
+ or bind_address.is_empty()
+ ):
+ return false
+ session_max_players = max_players
+ transport_max_clients = maxi(transport_max_clients, max_players)
+ return _start_host(port, 1, true, bind_address)
+
+
+func _start_host(
+ port: int,
+ port_attempts: int,
+ dedicated: bool,
+ bind_address: String = "*",
+) -> bool:
if not _host_identity.load_or_create():
_fail(_host_identity.error_message)
return false
@@ -152,16 +204,20 @@ func start_private_host(
_fail("The hosting port must be from 1 to 65535.")
return false
_operation_generation += 1
- _set_state(State.STARTING_PRIVATE_HOST, "Starting private game...")
+ _set_state(
+ State.STARTING_PRIVATE_HOST,
+ "Starting dedicated server..." if dedicated else "Starting private game...",
+ )
var selected_port: int = 0
var final_port: int = mini(port + port_attempts - 1, 65535)
for candidate_port: int in range(port, final_port + 1):
- if not _can_bind_udp_port(candidate_port):
+ if not _can_bind_udp_port(candidate_port, bind_address):
continue
_replace_transport()
var error: Error = _transport.start_host(
candidate_port,
transport_max_clients,
+ bind_address,
)
if error == OK:
selected_port = candidate_port
@@ -173,11 +229,31 @@ func start_private_host(
)
return false
_host_port = selected_port
+ _dedicated_host = dedicated
var peer: MultiplayerPeer = _transport.get_multiplayer_peer()
peer.refuse_new_connections = true
multiplayer.multiplayer_peer = peer
_session_id = Crypto.new().generate_random_bytes(16).hex_encode()
_registry.clear()
+ _session_operator_fingerprints.clear()
+ _operator_peer_ids.clear()
+ _local_operator = false
+ _spawn_service.clear_remote_players()
+ if not dedicated:
+ _register_player_host()
+ _set_state(
+ State.PRIVATE_HOST,
+ (
+ "Dedicated server • UDP %d"
+ if dedicated else "Private game • UDP %d"
+ ) % selected_port,
+ )
+ host_openness_changed.emit(false)
+ _emit_peer_count()
+ return true
+
+
+func _register_player_host() -> void:
_registry.add_peer(
1,
_profile.profile_id,
@@ -213,24 +289,100 @@ func start_private_host(
"client_nonce": host_profile_hello["client_nonce"],
}
_archive_authenticated_identity(host_record)
- _spawn_service.clear_remote_players()
_spawn_service.register_local_player(1)
var host_avatar := _spawn_service.get_avatar(1)
if host_avatar != null:
host_avatar.apply_appearance_snapshot(_local_appearance_snapshot)
- _set_state(State.PRIVATE_HOST, "Private game • UDP %d" % selected_port)
- host_openness_changed.emit(false)
- _emit_peer_count()
- return true
func get_host_port() -> int:
return _host_port if is_host() else 0
-static func _can_bind_udp_port(port: int) -> bool:
+func send_traversal_packet(
+ destination_address: String,
+ destination_port: int,
+ packet: PackedByteArray,
+) -> bool:
+ return (
+ _transport != null
+ and state in [
+ State.PRIVATE_HOST,
+ State.OPEN_HOST,
+ State.CONNECTING,
+ State.AUTHENTICATING,
+ ]
+ and _transport.send_raw_packet(
+ destination_address,
+ destination_port,
+ packet,
+ )
+ )
+
+
+func is_dedicated_host() -> bool:
+ return is_host() and _dedicated_host
+
+
+func is_local_operator() -> bool:
+ return state == State.JOINED_CLIENT and _local_operator
+
+
+func can_local_moderate() -> bool:
+ return is_host() or is_local_operator()
+
+
+func can_manage_operators() -> bool:
+ return is_host() and not _dedicated_host
+
+
+func is_peer_operator(peer_id: int) -> bool:
+ return bool(_operator_peer_ids.get(peer_id, false))
+
+
+func set_peer_operator(
+ peer_id: int,
+ fingerprint: String,
+ enabled: bool,
+) -> bool:
+ if not can_manage_operators() or peer_id <= 1:
+ return false
+ var record: PeerRegistry.PeerRecord = _registry.get_peer(peer_id)
+ if (
+ record == null
+ or not record.identity_authenticated
+ or record.identity_fingerprint != fingerprint
+ ):
+ return false
+ if enabled:
+ _session_operator_fingerprints[fingerprint] = true
+ else:
+ _session_operator_fingerprints.erase(fingerprint)
+ _set_operator_status(peer_id, enabled)
+ return true
+
+
+func set_session_display_name(value: String) -> void:
+ var cleaned: String = value.strip_edges().left(48)
+ if cleaned.is_empty():
+ cleaned = "NETfishing Room"
+ if cleaned == _session_display_name:
+ return
+ _session_display_name = cleaned
+ session_display_name_changed.emit(_session_display_name)
+
+
+func get_session_display_name() -> String:
+ return _session_display_name
+
+
+func get_local_display_name() -> String:
+ return _profile.display_name if _profile != null else ""
+
+
+static func _can_bind_udp_port(port: int, bind_address: String = "*") -> bool:
var probe := PacketPeerUDP.new()
- var error: Error = probe.bind(port)
+ var error: Error = probe.bind(port, bind_address)
probe.close()
return error == OK
@@ -312,7 +464,9 @@ func set_host_open(is_open: bool) -> bool:
_set_state(
State.OPEN_HOST if is_open else State.PRIVATE_HOST,
(
- "Open game • UDP %d • %d / %d players"
+ "Dedicated server • UDP %d • %d / %d players"
+ if _dedicated_host
+ else "Open game • UDP %d • %d / %d players"
if is_open
else "Private game • UDP %d • %d / %d players"
) % [_host_port, _registry.size(), session_max_players]
@@ -574,9 +728,13 @@ func apply_canonical_profile(
var appearance_changed := _registry.update_appearance(peer_id, appearance)
if name_changed:
peer_display_name_changed.emit(peer_id, display_name)
- if name_changed and appearance_changed:
+ if appearance_changed:
+ var avatar: Player = _spawn_service.get_avatar(peer_id)
+ if avatar != null:
+ avatar.apply_appearance_snapshot(appearance)
+ if name_changed or appearance_changed:
peer_profile_changed.emit(peer_id, display_name, appearance.duplicate(true))
- return name_changed and appearance_changed
+ return name_changed or appearance_changed
@rpc("any_peer", "call_remote", "reliable", 0)
@@ -603,6 +761,8 @@ func _apply_display_name(peer_id: int, value: String) -> void:
func get_local_peer_id() -> int:
+ if is_dedicated_host():
+ return 0
return multiplayer.get_unique_id() if is_gameplay_session_active() else 0
@@ -715,7 +875,7 @@ func _on_server_disconnected() -> void:
)
_moderation_disconnect_message = ""
_set_state(State.SERVER_LOST, message)
- server_lost.emit()
+ server_lost.emit(message)
connection_error.emit(message)
@@ -723,6 +883,7 @@ func _on_peer_disconnected(peer_id: int) -> void:
_pending_authentication.erase(peer_id)
_pending_identity_challenges.erase(peer_id)
_authenticated_identity_cache.erase(peer_id)
+ _operator_peer_ids.erase(peer_id)
var recovery_attempt: String = _recovery_attempts.get(peer_id, "")
if not recovery_attempt.is_empty():
_recovery_attempts.erase(peer_id)
@@ -743,6 +904,16 @@ func submit_identity_hello(data: Dictionary) -> void:
var sender_id: int = multiplayer.get_remote_sender_id()
if not is_host() or sender_id <= 1 or not _pending_authentication.has(sender_id):
return
+ var client_game_version: String = str(data.get("game_version", ""))
+ var version_rejection: NetworkProtocol.RejectionCode = (
+ NetworkProtocol.game_version_rejection(
+ client_game_version,
+ NetworkProtocol.game_version(),
+ )
+ )
+ if version_rejection != NetworkProtocol.RejectionCode.NONE:
+ _reject_peer(sender_id, version_rejection)
+ return
if (
not NetworkProtocol.validate_identity_hello(data)
or int(data["protocol_version"]) != NetworkProtocol.PROTOCOL_VERSION
@@ -773,8 +944,10 @@ func submit_identity_hello(data: Dictionary) -> void:
"client_nonce": str(data["client_nonce"]),
"client_fingerprint": fingerprint,
"client_public_key": public_pem,
+ "client_game_version": client_game_version,
"server_nonce": server_nonce,
"server_fingerprint": _host_identity.fingerprint,
+ "server_game_version": NetworkProtocol.game_version(),
"session_id": _session_id,
"generation": _operation_generation,
"expires_at_msec": Time.get_ticks_msec() + 60000,
@@ -791,7 +964,25 @@ func submit_identity_hello(data: Dictionary) -> void:
@rpc("authority", "call_remote", "reliable", 0)
func receive_server_identity_proof(data: Dictionary) -> void:
- if state != State.AUTHENTICATING or not _valid_server_proof_shape(data):
+ if state != State.AUTHENTICATING:
+ return
+ var server_game_version: String = str(data.get("server_game_version", ""))
+ if server_game_version.is_empty():
+ _fail_identity(NetworkProtocol.rejection_text(
+ NetworkProtocol.RejectionCode.SERVER_OUTDATED
+ ))
+ return
+ var version_rejection: NetworkProtocol.RejectionCode = (
+ NetworkProtocol.game_version_rejection(
+ NetworkProtocol.game_version(),
+ server_game_version,
+ )
+ )
+ if version_rejection != NetworkProtocol.RejectionCode.NONE:
+ _fail_identity(NetworkProtocol.rejection_text(version_rejection))
+ return
+ if not _valid_server_proof_shape(data):
+ _fail_identity("The server sent an invalid identity proof.")
return
if (
str(data["attempt_id"]) != str(_client_identity_attempt.get("attempt_id", ""))
@@ -900,6 +1091,7 @@ func submit_client_identity_proof(data: Dictionary) -> void:
_authenticated_identity_cache[sender_id] = {
"fingerprint": challenge["client_fingerprint"],
"public_key": challenge["client_public_key"],
+ "game_version": challenge["client_game_version"],
}
if (
_host_bans != null
@@ -916,7 +1108,6 @@ func submit_client_identity_proof(data: Dictionary) -> void:
@rpc("authority", "call_remote", "reliable", 0)
func receive_moderation_disconnect(message: String) -> void:
_moderation_disconnect_message = message.left(120)
- connection_error.emit(_moderation_disconnect_message)
@rpc("authority", "call_remote", "reliable", 0)
@@ -946,6 +1137,16 @@ func submit_client_hello(data: Dictionary) -> void:
if not validation_error.is_empty():
_reject_peer(sender_id, NetworkProtocol.RejectionCode.MALFORMED_HANDSHAKE)
return
+ var client_game_version: String = str(data.get("game_version", ""))
+ var version_rejection: NetworkProtocol.RejectionCode = (
+ NetworkProtocol.game_version_rejection(
+ client_game_version,
+ NetworkProtocol.game_version(),
+ )
+ )
+ if version_rejection != NetworkProtocol.RejectionCode.NONE:
+ _reject_peer(sender_id, version_rejection)
+ return
var client_capabilities: PackedStringArray = _sanitized_capabilities(
data.get("capability_flags", [])
)
@@ -961,6 +1162,7 @@ func submit_client_hello(data: Dictionary) -> void:
return
if (
data["identity_fingerprint"] != identity["fingerprint"]
+ or client_game_version != str(identity.get("game_version", ""))
or not NetworkIdentityCrypto.verify_fields(
NetworkIdentityCrypto.load_public_key(identity["public_key"]),
"handshake_client_profile",
@@ -995,6 +1197,11 @@ func submit_client_hello(data: Dictionary) -> void:
NetworkProtocol.RejectionCode.MALFORMED_HANDSHAKE
)
return
+ var operator_enabled: bool = _operator_for_fingerprint(
+ str(identity["fingerprint"])
+ )
+ if operator_enabled:
+ _operator_peer_ids[sender_id] = true
var submitted_appearance := CharacterCustomizationCatalog.sanitized_snapshot(
data["cosmetic_snapshot"]
)
@@ -1018,6 +1225,14 @@ func submit_client_hello(data: Dictionary) -> void:
_spawn_service.get_spawn_transform_for_index(spawn_index)
)
_spawn_service.spawn_remote_player(sender_id, spawn_transform, true)
+ var spawned_avatar: Player = _spawn_service.get_avatar(sender_id)
+ if spawned_avatar != null:
+ spawned_avatar.apply_appearance_snapshot(submitted_appearance)
+ peer_profile_changed.emit(
+ sender_id,
+ display_name,
+ submitted_appearance.duplicate(true),
+ )
receive_server_hello.rpc_id(
sender_id,
NetworkProtocol.make_server_hello(
@@ -1026,13 +1241,17 @@ func submit_client_hello(data: Dictionary) -> void:
_session_id,
sender_id,
_registry.size(),
- session_max_players
+ session_max_players,
+ _session_display_name,
)
)
receive_spawn_list.rpc_id(sender_id, _build_spawn_list())
+ receive_operator_snapshot.rpc_id(sender_id, _operator_peer_id_snapshot())
receive_peer_spawn.rpc(
_make_spawn_entry(sender_id, display_name, spawn_transform)
)
+ if operator_enabled:
+ receive_operator_status.rpc(sender_id, true)
peer_authenticated.emit(sender_id, display_name)
_emit_peer_count()
@@ -1075,6 +1294,7 @@ func receive_server_hello(data: Dictionary) -> void:
if (
typeof(data.get("accepted")) != TYPE_BOOL
or typeof(data.get("protocol_version")) != TYPE_INT
+ or typeof(data.get("game_version")) != TYPE_STRING
or typeof(data.get("rejection_code")) != TYPE_INT
):
_teardown_peer()
@@ -1087,6 +1307,16 @@ func receive_server_hello(data: Dictionary) -> void:
_teardown_peer()
_fail(message)
return
+ var version_rejection: NetworkProtocol.RejectionCode = (
+ NetworkProtocol.game_version_rejection(
+ NetworkProtocol.game_version(),
+ str(data["game_version"]),
+ )
+ )
+ if version_rejection != NetworkProtocol.RejectionCode.NONE:
+ _teardown_peer()
+ _fail(NetworkProtocol.rejection_text(version_rejection))
+ return
if int(data["protocol_version"]) != NetworkProtocol.PROTOCOL_VERSION:
_teardown_peer()
_fail("The server uses a different network protocol.")
@@ -1173,12 +1403,41 @@ func receive_peer_spawn(entry: Dictionary) -> void:
func receive_peer_despawn(peer_id: int) -> void:
if state != State.JOINED_CLIENT:
return
+ _operator_peer_ids.erase(peer_id)
_registry.remove_peer(peer_id)
_spawn_service.remove_peer(peer_id)
peer_removed.emit(peer_id)
_emit_peer_count()
+@rpc("authority", "call_remote", "reliable", 0)
+func receive_operator_snapshot(peer_ids: PackedInt32Array) -> void:
+ if (
+ state != State.JOINED_CLIENT
+ or peer_ids.size() > get_session_max_players()
+ ):
+ return
+ _operator_peer_ids.clear()
+ for peer_id: int in peer_ids:
+ if peer_id > 1:
+ _operator_peer_ids[peer_id] = true
+ _update_local_operator()
+ for peer_id: int in _operator_peer_ids:
+ operator_status_changed.emit(peer_id, true)
+
+
+@rpc("authority", "call_remote", "reliable", 0)
+func receive_operator_status(peer_id: int, enabled: bool) -> void:
+ if state != State.JOINED_CLIENT or peer_id <= 1:
+ return
+ if enabled:
+ _operator_peer_ids[peer_id] = true
+ else:
+ _operator_peer_ids.erase(peer_id)
+ _update_local_operator()
+ operator_status_changed.emit(peer_id, enabled)
+
+
func _apply_spawn_entry(entry: Dictionary) -> void:
if (
typeof(entry.get("peer_id")) != TYPE_INT
@@ -1309,6 +1568,36 @@ func _sanitized_capabilities(value: Variant) -> PackedStringArray:
return result
+func _operator_for_fingerprint(fingerprint: String) -> bool:
+ return bool((
+ _configured_operator_fingerprints
+ if _dedicated_host
+ else _session_operator_fingerprints
+ ).get(fingerprint, false))
+
+
+func _operator_peer_id_snapshot() -> PackedInt32Array:
+ var result: PackedInt32Array = PackedInt32Array()
+ for peer_id: int in _operator_peer_ids:
+ result.append(peer_id)
+ result.sort()
+ return result
+
+
+func _set_operator_status(peer_id: int, enabled: bool) -> void:
+ if enabled:
+ _operator_peer_ids[peer_id] = true
+ else:
+ _operator_peer_ids.erase(peer_id)
+ operator_status_changed.emit(peer_id, enabled)
+ receive_operator_status.rpc(peer_id, enabled)
+
+
+func _update_local_operator() -> void:
+ var local_peer_id: int = multiplayer.get_unique_id()
+ _local_operator = bool(_operator_peer_ids.get(local_peer_id, false))
+
+
func _verify_spawn_identity(entry: Dictionary) -> bool:
var fingerprint := str(entry.get("identity_fingerprint", ""))
var public_pem := NetworkIdentityCrypto.normalize_public_pem(
@@ -1353,6 +1642,8 @@ func _verify_spawn_identity(entry: Dictionary) -> bool:
func _identity_proof_fields(data: Dictionary) -> Array:
return [
NetworkProtocol.PROTOCOL_VERSION,
+ str(data.get("client_game_version", "")),
+ str(data.get("server_game_version", "")),
str(data.get("attempt_id", "")),
str(data.get("client_fingerprint", "")),
str(data.get("client_nonce", "")),
@@ -1393,6 +1684,10 @@ func _valid_server_proof_shape(data: Variant) -> bool:
and str(value["server_nonce"]).length() == 64
and NetworkIdentityCrypto.valid_fingerprint(value.get("client_fingerprint"))
and NetworkIdentityCrypto.valid_fingerprint(value.get("server_fingerprint"))
+ and typeof(value.get("client_game_version")) == TYPE_STRING
+ and str(value["client_game_version"]) == NetworkProtocol.game_version()
+ and typeof(value.get("server_game_version")) == TYPE_STRING
+ and str(value["server_game_version"]) == NetworkProtocol.game_version()
and typeof(value.get("server_public_key")) == TYPE_STRING
and str(value["server_public_key"]).to_utf8_buffer().size()
<= NetworkProtocol.MAX_PUBLIC_KEY_LENGTH
@@ -1446,9 +1741,10 @@ func _is_valid_movement_input(data: Dictionary) -> bool:
or typeof(data.get("sprint")) != TYPE_BOOL
or typeof(data.get("sneak")) != TYPE_BOOL
or typeof(data.get("slow_walk")) != TYPE_BOOL
- or (
- data.has("sitting")
- and typeof(data.get("sitting")) != TYPE_BOOL
+ or typeof(data.get("sitting")) != TYPE_BOOL
+ or typeof(data.get("casting")) != TYPE_BOOL
+ or not NetworkPlayerAnimationProtocol.validate_action_state(
+ data.get("animation_action")
)
or typeof(data.get("camera_yaw")) not in [TYPE_FLOAT, TYPE_INT]
):
@@ -1456,11 +1752,18 @@ func _is_valid_movement_input(data: Dictionary) -> bool:
var axis: Array = data["axis"]
if axis.size() != 2:
return false
+ if (
+ typeof(axis[0]) not in [TYPE_FLOAT, TYPE_INT]
+ or typeof(axis[1]) not in [TYPE_FLOAT, TYPE_INT]
+ ):
+ return false
var x: float = float(axis[0])
var y: float = float(axis[1])
var camera_yaw: float = float(data["camera_yaw"])
return (
- is_finite(x)
+ int(data["sequence"]) > 0
+ and int(data["sequence"]) <= MAX_MOVEMENT_INPUT_SEQUENCE
+ and is_finite(x)
and is_finite(y)
and is_finite(camera_yaw)
and absf(x) <= 1.01
@@ -1762,4 +2065,8 @@ func _teardown_peer() -> void:
_server_identity_fingerprint = ""
_server_identity_public_key = ""
_session_identity_keys.clear()
+ _session_operator_fingerprints.clear()
+ _operator_peer_ids.clear()
+ _local_operator = false
_host_port = 0
+ _dedicated_host = false
diff --git a/network/network_shop_protocol.gd b/network/network_shop_protocol.gd
index 65a0395..11900e9 100644
--- a/network/network_shop_protocol.gd
+++ b/network/network_shop_protocol.gd
@@ -56,6 +56,11 @@ static func validate_request(data: Variant) -> String:
var quantity: int = payload["quantity"]
var wallet_balance: int = payload["wallet_balance"]
var current_state: int = payload["current_state"]
+ if (
+ payload.has("bait_unlocked")
+ and typeof(payload["bait_unlocked"]) != TYPE_BOOL
+ ):
+ return "Purchase could not be completed."
if (
request_id.is_empty()
or request_id.length() > MAX_ID_LENGTH
diff --git a/network/network_shop_service.gd b/network/network_shop_service.gd
index 88b821d..4dd0f98 100644
--- a/network/network_shop_service.gd
+++ b/network/network_shop_service.gd
@@ -109,7 +109,15 @@ func is_local_purchase_pending() -> bool:
func request_supply(item_id: StringName) -> String:
var owned: int = _bag.get_quantity(item_id) if _bag != null else 0
- var quantity: int = FishingShopStockType.get_purchase_quantity(item_id, owned)
+ var item: ItemDataType = (
+ _item_catalog.get_item_by_id(item_id)
+ if _item_catalog != null else null
+ )
+ var quantity: int = FishingShopStockType.get_purchase_quantity(
+ item_id,
+ owned,
+ item.max_stack if item != null else FishingShopStockType.WORM_MAX_STACK,
+ )
return _request_purchase(
item_id,
NetworkShopProtocol.ProductCategory.SUPPLY,
@@ -223,6 +231,13 @@ func _request_purchase(
"wallet_balance": _wallet.get_balance() if _wallet != null else 0,
"current_state": current_state,
}
+ if (
+ category == NetworkShopProtocol.ProductCategory.SUPPLY
+ and FishingShopStockType.is_bait_topoff(product_id)
+ ):
+ request["bait_unlocked"] = (
+ _bag != null and _bag.is_bait_unlocked(product_id)
+ )
_pending_local_request = request.duplicate(true)
local_purchase_pending.emit(request_id)
if _session.is_host():
@@ -317,16 +332,32 @@ func _build_authoritative_result(
var item: ItemDataType = _item_catalog.get_item_by_id(
product_id
) if _item_catalog != null else null
- cost = FishingShopStockType.get_price(product_id)
+ var bait_topoff: bool = (
+ FishingShopStockType.is_bait_topoff(product_id)
+ )
+ var permanent_unlock: bool = (
+ FishingShopStockType.is_permanent_unlock(product_id, item)
+ )
if (
item == null
or not item.is_valid()
or product_id not in (
FishingShopStockType.get_stock_item_ids()
)
- or (item.category != ItemDataType.Category.CONSUMABLE and not FishingShopStockType.is_bait_topoff(product_id))
- or not item.stackable
- or (not item.usable and not FishingShopStockType.is_bait_topoff(product_id))
+ or (
+ item.category != ItemDataType.Category.CONSUMABLE
+ and not bait_topoff
+ and not permanent_unlock
+ )
+ or (not item.stackable and not permanent_unlock)
+ or (
+ not item.usable
+ and not bait_topoff
+ and not permanent_unlock
+ and not FishingShopStockType.is_passive_supply(
+ product_id
+ )
+ )
or current_state >= item.max_stack
or current_state + quantity > item.max_stack
):
@@ -336,10 +367,21 @@ func _build_authoritative_result(
else "Purchase could not be completed."
)
else:
- if not FishingShopStockType.is_bait_topoff(product_id) and quantity != 1:
+ var expected_quantity: int = (
+ FishingShopStockType.get_purchase_quantity(
+ product_id, current_state, item.max_stack
+ )
+ )
+ if quantity != expected_quantity:
rejection = "Purchase could not be completed."
else:
- cost *= quantity
+ cost = FishingShopStockType.get_purchase_cost(
+ product_id,
+ quantity,
+ bool(request.get("bait_unlocked", true)),
+ )
+ if cost < 0:
+ rejection = "Purchase could not be completed."
resulting_state = current_state + quantity
NetworkShopProtocol.ProductCategory.ROD:
rejection = "This item is not sold here."
@@ -422,7 +464,7 @@ func _build_authoritative_result(
current_state, product_id
)
if rejection.is_empty() and (cost < 0 or wallet_balance < cost):
- rejection = "Not enough fish coin."
+ rejection = "Insufficient funds."
if not rejection.is_empty():
return _rejected_result(request, rejection)
return {
@@ -532,6 +574,9 @@ func _apply_purchase_result(data: Dictionary) -> void:
return
var wallet_snapshot: int = _wallet.get_balance()
var bag_snapshot: Array[OwnedItemType] = _bag.get_all_items()
+ var bait_unlock_snapshot: Array[StringName] = (
+ _bag.get_unlocked_bait_ids()
+ )
var reel_snapshot: int = _upgrades.get_reel_speed_level()
var barrier_snapshot: int = _upgrades.get_barrier_power_level()
var cooler_snapshot: int = _cooler_capacity.get_level()
@@ -539,6 +584,7 @@ func _apply_purchase_result(data: Dictionary) -> void:
var applied: bool = _apply_local_product(data)
if not applied or not _save_manager.save_if_dirty():
_bag.replace_all_items(bag_snapshot)
+ _bag.replace_unlocked_bait_ids(bait_unlock_snapshot)
_upgrades.restore_levels(reel_snapshot, barrier_snapshot)
_cooler_capacity.restore_level(cooler_snapshot)
_art_unlocks.restore_mask(art_snapshot)
@@ -587,12 +633,25 @@ func _validate_local_result(data: Dictionary) -> String:
):
return "Purchase could not be completed."
if not _wallet.can_afford(cost):
- return "Not enough fish coin."
+ return "Insufficient funds."
match category:
NetworkShopProtocol.ProductCategory.SUPPLY:
- if _bag.get_quantity(product_id) != expected_state:
+ var item: ItemDataType = (
+ _item_catalog.get_item_by_id(product_id)
+ if _item_catalog != null else null
+ )
+ var bait_unlocked: bool = _bag.is_bait_unlocked(product_id)
+ if (
+ item == null
+ or _bag.get_quantity(product_id) != expected_state
+ or int(data["quantity"]) != FishingShopStockType.get_purchase_quantity(
+ product_id, expected_state, item.max_stack
+ )
+ ):
return "Purchase could not be completed."
- if cost != FishingShopStockType.get_price(product_id) * int(data["quantity"]):
+ if cost != FishingShopStockType.get_purchase_cost(
+ product_id, int(data["quantity"]), bait_unlocked
+ ):
return "Purchase could not be completed."
if not _bag.can_add_item(product_id, data["quantity"]):
return "Your Bag is full."
diff --git a/network/network_surface_drawing_service.gd b/network/network_surface_drawing_service.gd
index 5065acd..e42519c 100644
--- a/network/network_surface_drawing_service.gd
+++ b/network/network_surface_drawing_service.gd
@@ -41,6 +41,7 @@ var _spawn_service: PlayerSpawnService
var _relationships: PlayerRelationshipStore
var _local_player: Player
var _bag: PlayerBag
+var _hotbar: PlayerHotbar
var _art_unlocks: PlayerArtUnlocks
var _drawing_root: Node3D
var _canvas_states: Dictionary[String, Dictionary] = {}
@@ -87,6 +88,7 @@ func setup(
local_player: Player,
drawing_root: Node3D,
bag: PlayerBag,
+ hotbar: PlayerHotbar,
art_unlocks: PlayerArtUnlocks,
) -> void:
_session = session
@@ -95,6 +97,7 @@ func setup(
_local_player = local_player
_drawing_root = drawing_root
_bag = bag
+ _hotbar = hotbar
_art_unlocks = art_unlocks
_refresh_local_unlocks()
if _session != null:
@@ -123,20 +126,6 @@ func handle_input(
can_open: bool,
pointer_screen_position: Vector2 = INVALID_POINTER_SCREEN_POSITION,
) -> bool:
- if event is InputEventKey:
- var key_event := event as InputEventKey
- if (
- key_event.pressed
- and not key_event.echo
- and key_event.physical_keycode == KEY_P
- ):
- if _active:
- deactivate()
- return true
- if can_open and can_activate():
- activate(pointer_screen_position)
- return true
- return false
if not _active:
return false
if not can_open:
@@ -149,8 +138,7 @@ func handle_input(
if _placing_grid:
_set_placement_mode(false)
return true
- deactivate()
- return true
+ return false
if event is InputEventKey:
var key_event := event as InputEventKey
if not key_event.pressed or key_event.echo:
@@ -172,28 +160,19 @@ func handle_input(
return true
if event is InputEventMouseButton:
var mouse_event := event as InputEventMouseButton
+ # Ordinary wheel input always belongs to Hotbar selection. Brush size is
+ # selected explicitly in the Art Kit toolbar.
+ if mouse_event.button_index in [
+ MOUSE_BUTTON_WHEEL_UP,
+ MOUSE_BUTTON_WHEEL_DOWN,
+ ]:
+ return false
_set_pointer_from_input(
mouse_event.position,
pointer_screen_position,
)
_update_aim()
- if (
- mouse_event.shift_pressed
- and mouse_event.button_index in [
- MOUSE_BUTTON_WHEEL_UP,
- MOUSE_BUTTON_WHEEL_DOWN,
- ]
- ):
- return false
match mouse_event.button_index:
- MOUSE_BUTTON_WHEEL_UP:
- if mouse_event.pressed and not _placing_grid:
- _set_brush_size(_brush_size + 1)
- return true
- MOUSE_BUTTON_WHEEL_DOWN:
- if mouse_event.pressed and not _placing_grid:
- _set_brush_size(_brush_size - 1)
- return true
MOUSE_BUTTON_LEFT:
if _placing_grid:
if mouse_event.pressed:
@@ -241,7 +220,7 @@ func activate(
if _active or not can_activate():
return
_active = true
- _placing_grid = true
+ _placing_grid = false
_eraser_mode = false
_clear_armed_guide_action(false)
_refresh_local_unlocks()
@@ -257,9 +236,7 @@ func activate(
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
_update_aim()
_refresh_stencil_visibility()
- _emit_hud_state(
- "click to place a shared grid"
- )
+ _emit_hud_state("marker selected")
func deactivate() -> void:
@@ -288,7 +265,11 @@ func is_placement_mode() -> bool:
func can_activate() -> bool:
- return _drawing_available() and _owns_art_kit()
+ return (
+ _drawing_available()
+ and _owns_art_kit()
+ and _art_kit_is_selected()
+ )
func set_placement_mode(enabled: bool) -> void:
@@ -344,7 +325,7 @@ func arm_guide_action(action: int) -> bool:
_selected_canvas_id = ""
_update_aim()
_refresh_stencil_visibility()
- _emit_hud_state("click a grid to %s it" % _guide_action_verb(action))
+ _emit_hud_state(_guide_action_status(action))
return true
@@ -415,6 +396,15 @@ func _owns_art_kit() -> bool:
return _bag != null and _bag.owns_item(ArtShopStockType.ART_KIT_ITEM_ID)
+func _art_kit_is_selected() -> bool:
+ return (
+ _hotbar != null
+ and _hotbar.get_selected_assignment_kind()
+ == PlayerHotbar.AssignmentKind.ITEM
+ and _hotbar.get_selected_item_id() == ArtShopStockType.ART_KIT_ITEM_ID
+ )
+
+
func _local_entitlement() -> Dictionary:
return {
"has_kit": _owns_art_kit(),
@@ -550,8 +540,7 @@ func request_canvas_at_surface(
tangent: Vector3,
) -> bool:
if (
- not _drawing_available()
- or not _owns_art_kit()
+ not can_activate()
or _art_unlocks == null
or not _art_unlocks.is_grid_size_unlocked(_grid_size)
or normal.is_zero_approx()
@@ -581,8 +570,7 @@ func request_cell_edits(
stroke_id: String = "",
) -> bool:
if (
- not _drawing_available()
- or not _owns_art_kit()
+ not can_activate()
or canvas_id.is_empty()
or edits.is_empty()
):
@@ -613,7 +601,7 @@ func request_guide_visibility(
should_be_visible: bool,
should_finalize: bool = false,
) -> bool:
- if not _drawing_available() or not _owns_art_kit() or canvas_id.is_empty():
+ if not can_activate() or canvas_id.is_empty():
return false
var data: Dictionary = {
"request_id": _new_request_id("guide"),
@@ -633,8 +621,7 @@ func request_guide_visibility(
func request_undo_last_stroke() -> bool:
if (
- not _drawing_available()
- or not _owns_art_kit()
+ not can_activate()
or _last_local_stroke_id.is_empty()
):
_emit_hud_state("nothing to undo")
@@ -698,6 +685,9 @@ func get_canvas_state(canvas_id: String) -> Dictionary:
func _process(_delta: float) -> void:
if not _active:
return
+ if not can_activate():
+ deactivate()
+ return
_update_aim()
if _placing_grid:
return
@@ -752,7 +742,7 @@ func _update_aim() -> void:
func _raycast_from_pointer() -> Dictionary:
if _local_player == null or not is_instance_valid(_local_player):
return {}
- var camera: Camera3D = _local_player.get_gameplay_camera()
+ var camera: Camera3D = _local_player.get_active_gameplay_camera()
if camera == null or not camera.current:
return {}
var from: Vector3 = camera.project_ray_origin(_pointer_screen_position)
@@ -1684,7 +1674,9 @@ func _is_static_surface(value: Variant) -> bool:
func _surface_tangent(normal: Vector3) -> Vector3:
var camera: Camera3D = (
- _local_player.get_gameplay_camera() if _local_player != null else null
+ _local_player.get_active_gameplay_camera()
+ if _local_player != null
+ else null
)
var candidate: Vector3 = (
camera.global_basis.x if camera != null else Vector3.RIGHT
@@ -1872,8 +1864,10 @@ func _execute_armed_guide_action() -> void:
_restore_selected_guide()
GuideAction.FINALIZE:
_finalize_selected_guide()
- _clear_armed_guide_action(true)
- _emit_hud_state("")
+ # Guide actions are persistent modes. Keep the selected action armed so
+ # multiple grids can be handled without returning to the toolbar after
+ # every click; selecting the active toggle again explicitly exits it.
+ _emit_hud_state(_guide_action_status(action))
func _cancel_armed_guide_action() -> void:
@@ -1902,12 +1896,18 @@ func _guide_action_verb(action: int) -> String:
GuideAction.HIDE:
return "hide"
GuideAction.RESTORE:
- return "restore"
+ return "show"
GuideAction.FINALIZE:
return "finish"
return "use"
+func _guide_action_status(action: int) -> String:
+ return "%s grid mode • click grids • toggle again to exit" % (
+ _guide_action_verb(action).capitalize()
+ )
+
+
func _remove_selected_guide() -> void:
if _selected_canvas_id.is_empty():
_emit_hud_state("aim at a placed grid before removing its guide")
@@ -2161,7 +2161,7 @@ func _on_peer_removed(peer_id: int) -> void:
func _on_local_art_entitlement_changed() -> void:
- if _active and not _owns_art_kit():
+ if _active and not can_activate():
deactivate()
_publish_local_entitlement()
diff --git a/network/network_transport.gd b/network/network_transport.gd
index 8b0cd05..ce68172 100644
--- a/network/network_transport.gd
+++ b/network/network_transport.gd
@@ -1,6 +1,7 @@
class_name NetworkTransport
extends Node
+@warning_ignore("unused_signal")
signal transport_error(message: String)
var _peer: MultiplayerPeer
diff --git a/network/network_world_time_service.gd b/network/network_world_time_service.gd
index 91b4060..246af77 100644
--- a/network/network_world_time_service.gd
+++ b/network/network_world_time_service.gd
@@ -17,6 +17,12 @@ func setup(session: NetworkSession, world_time: WorldTimeService) -> void:
_world_time = world_time
_session.state_changed.connect(_on_session_state_changed)
_session.peer_authenticated.connect(_on_peer_authenticated)
+ if not _world_time.authoritative_time_set.is_connected(
+ _on_authoritative_time_set
+ ):
+ _world_time.authoritative_time_set.connect(
+ _on_authoritative_time_set
+ )
set_process(true)
@@ -82,6 +88,13 @@ func _on_peer_authenticated(peer_id: int, _display_name: String) -> void:
_send_snapshot(peer_id)
+func _on_authoritative_time_set(_time_hours: float) -> void:
+ if _session == null or not _session.is_host():
+ return
+ _sync_elapsed = 0.0
+ _broadcast_snapshot()
+
+
func _broadcast_snapshot() -> void:
if _session == null or not _session.is_host():
return
diff --git a/network/player_data_root.gd b/network/player_data_root.gd
index ba831f4..525c545 100644
--- a/network/player_data_root.gd
+++ b/network/player_data_root.gd
@@ -169,6 +169,13 @@ func use_existing_root(path: String) -> bool:
return true
+func activate_process_root(path: String) -> bool:
+ _load_bootstrap_identity()
+ override_active = true
+ mode = Mode.COMMAND_LINE_OVERRIDE
+ return _activate_existing(path, "", false)
+
+
func path_for(store_owner: StringName) -> String:
var relative: String = {
&"player_save": "player/player_save.json",
diff --git a/network/player_list_entry.gd b/network/player_list_entry.gd
index fbe0d8f..f401da6 100644
--- a/network/player_list_entry.gd
+++ b/network/player_list_entry.gd
@@ -6,6 +6,7 @@ var full_fingerprint := ""
var compact_fingerprint := ""
var display_name := ""
var is_host := false
+var is_operator := false
var is_local_player := false
var continuity_state := ""
var ping_to_host_ms := -1
@@ -13,4 +14,5 @@ var muted := false
var blocked := false
var can_kick := false
var can_ban := false
+var can_manage_operator := false
var revision := 0
diff --git a/player/animalese_voice_profiles.gd b/player/animalese_voice_profiles.gd
new file mode 100644
index 0000000..2ea6cab
--- /dev/null
+++ b/player/animalese_voice_profiles.gd
@@ -0,0 +1,81 @@
+class_name AnimaleseVoiceProfiles
+extends RefCounted
+
+const DEFAULT_ID: String = "natural"
+const DEFAULT_SPEED_ID: String = "normal"
+const DEFAULT_CALL_ID: String = "meow"
+const CALL_AUDIO_DIRECTORY: String = "res://sound/dialogue/calls"
+const OPTIONS: Array[Dictionary] = [
+ {"id": "tiny", "label": "tiny", "pitch": 1.24},
+ {"id": "bright", "label": "bright", "pitch": 1.10},
+ {"id": "natural", "label": "natural", "pitch": 1.0},
+ {"id": "mellow", "label": "mellow", "pitch": 0.89},
+ {"id": "deep", "label": "deep", "pitch": 0.77},
+]
+const SPEED_OPTIONS: Array[Dictionary] = [
+ {"id": "slow", "label": "slow", "characters_per_second": 20.0},
+ {"id": "relaxed", "label": "relaxed", "characters_per_second": 24.0},
+ {"id": "normal", "label": "normal", "characters_per_second": 28.0},
+ {"id": "quick", "label": "quick", "characters_per_second": 34.0},
+ {"id": "rapid", "label": "rapid", "characters_per_second": 40.0},
+]
+const CALL_OPTIONS: Array[Dictionary] = [
+ {"id": "meow", "label": "meow"},
+ {"id": "bark", "label": "bark"},
+]
+
+
+static func is_valid(voice_id: String) -> bool:
+ for option: Dictionary in OPTIONS:
+ if str(option.get("id", "")) == voice_id:
+ return true
+ return false
+
+
+static func sanitized_id(voice_id: String) -> String:
+ return voice_id if is_valid(voice_id) else DEFAULT_ID
+
+
+static func pitch_for(voice_id: String) -> float:
+ var resolved_id := sanitized_id(voice_id)
+ for option: Dictionary in OPTIONS:
+ if str(option.get("id", "")) == resolved_id:
+ return float(option.get("pitch", 1.0))
+ return 1.0
+
+
+static func is_valid_speed(speed_id: String) -> bool:
+ for option: Dictionary in SPEED_OPTIONS:
+ if str(option.get("id", "")) == speed_id:
+ return true
+ return false
+
+
+static func sanitized_speed_id(speed_id: String) -> String:
+ return speed_id if is_valid_speed(speed_id) else DEFAULT_SPEED_ID
+
+
+static func speed_for(speed_id: String) -> float:
+ var resolved_id := sanitized_speed_id(speed_id)
+ for option: Dictionary in SPEED_OPTIONS:
+ if str(option.get("id", "")) == resolved_id:
+ return float(option.get("characters_per_second", 28.0))
+ return 28.0
+
+
+static func is_valid_call(call_id: String) -> bool:
+ for option: Dictionary in CALL_OPTIONS:
+ if str(option.get("id", "")) == call_id:
+ return true
+ return false
+
+
+static func sanitized_call_id(call_id: String) -> String:
+ return call_id if is_valid_call(call_id) else DEFAULT_CALL_ID
+
+
+static func call_audio_path(call_id: String) -> String:
+ return "%s/%s.wav" % [
+ CALL_AUDIO_DIRECTORY,
+ sanitized_call_id(call_id),
+ ]
diff --git a/player/animalese_voice_profiles.gd.uid b/player/animalese_voice_profiles.gd.uid
new file mode 100644
index 0000000..1817007
--- /dev/null
+++ b/player/animalese_voice_profiles.gd.uid
@@ -0,0 +1 @@
+uid://dlut32tq2v66j
diff --git a/player/fishing_rod_attachment.tscn b/player/fishing_rod_attachment.tscn
index af895f5..46da419 100644
--- a/player/fishing_rod_attachment.tscn
+++ b/player/fishing_rod_attachment.tscn
@@ -10,15 +10,14 @@ albedo_color = Color(0.22, 0.12, 0.06, 1)
roughness = 0.8
[node name="FishingRodAttachment" type="BoneAttachment3D"]
-bone_name = "hand.R"
+bone_name = "rod_socket"
[node name="FishingRod" type="Node3D" parent="."]
-rotation_degrees = Vector3(322.6, -31.2, 248.9)
[node name="RodMesh" type="MeshInstance3D" parent="FishingRod"]
-position = Vector3(0, 0.42, 0)
+position = Vector3(0, 0.5, 0)
mesh = SubResource("FishingRodMesh")
material_override = SubResource("FishingRodMaterial")
[node name="FishingRodTip" type="Marker3D" parent="FishingRod"]
-position = Vector3(0, 0.95, 0)
+position = Vector3(0, 1.1, 0)
diff --git a/player/fur_pattern.gdshader b/player/fur_pattern.gdshader
new file mode 100644
index 0000000..aad013f
--- /dev/null
+++ b/player/fur_pattern.gdshader
@@ -0,0 +1,27 @@
+shader_type spatial;
+render_mode unshaded, cull_back;
+
+// Pattern PNGs are data maps rather than colored artwork. Black selects the
+// base color and the red, green, and blue channels select the three authored
+// accent colors. Alpha is intentionally ignored so artists may leave unused
+// UV space transparent.
+uniform sampler2D pattern_texture : filter_nearest, repeat_disable;
+uniform vec4 base_color : source_color = vec4(1.0);
+uniform vec4 red_zone_color : source_color = vec4(0.9, 0.8, 0.6, 1.0);
+uniform vec4 green_zone_color : source_color = vec4(0.4, 0.2, 0.1, 1.0);
+uniform vec4 blue_zone_color : source_color = vec4(0.7, 0.2, 0.15, 1.0);
+
+void fragment() {
+ vec3 zone_weights = max(texture(pattern_texture, UV).rgb, vec3(0.0));
+ float zone_total = zone_weights.r + zone_weights.g + zone_weights.b;
+ // Filtering between two authored zone colors can produce a sum near one.
+ // Normalize only an overfull sample, retaining smooth black-to-zone edges.
+ zone_weights /= max(zone_total, 1.0);
+ float base_weight = 1.0 - min(zone_total, 1.0);
+ ALBEDO = (
+ base_color.rgb * base_weight
+ + red_zone_color.rgb * zone_weights.r
+ + green_zone_color.rgb * zone_weights.g
+ + blue_zone_color.rgb * zone_weights.b
+ );
+}
diff --git a/player/fur_pattern.gdshader.uid b/player/fur_pattern.gdshader.uid
new file mode 100644
index 0000000..e16692e
--- /dev/null
+++ b/player/fur_pattern.gdshader.uid
@@ -0,0 +1 @@
+uid://eoeegcj00qy8
diff --git a/player/held_item_attachment.tscn b/player/held_item_attachment.tscn
index 05eff4b..66b3b7c 100644
--- a/player/held_item_attachment.tscn
+++ b/player/held_item_attachment.tscn
@@ -23,10 +23,12 @@ visible = false
[node name="HeldArtKitSprite" type="Sprite3D" parent="HeldArtKitDisplay"]
unique_name_in_owner = true
+rotation = Vector3(0, 0, 4.71239)
pixel_size = 0.008
+flip_h = true
shaded = false
double_sided = true
-texture_filter = 1
+texture_filter = 0
[node name="CatchDisplay" type="Node3D" parent="."]
unique_name_in_owner = true
diff --git a/player/player.gd b/player/player.gd
index 4686df5..6284873 100644
--- a/player/player.gd
+++ b/player/player.gd
@@ -34,6 +34,9 @@ const FishingRodAttachmentScene = preload(
const HeldItemAttachmentScene = preload(
"res://player/held_item_attachment.tscn"
)
+const SprintDustTrailType = preload("res://player/sprint_dust_trail.gd")
+
+signal retract_visual_finished
const CHARACTER_IDLE_ANIMATION: StringName = &"idle"
const CHARACTER_IDLE_SHOW_ANIMATION: StringName = &"idle_show"
@@ -41,7 +44,64 @@ const CHARACTER_IDLE_SIT_ANIMATION: StringName = &"idle_sit"
const CHARACTER_IDLE_SIT_SHOW_ANIMATION: StringName = &"idle_sit_show"
const CHARACTER_WALKING_ANIMATION: StringName = &"walking"
const CHARACTER_WALKING_SHOW_ANIMATION: StringName = &"walking_show"
+const CHARACTER_RUNNING_ANIMATION: StringName = &"running"
+const CHARACTER_RUNNING_SHOW_ANIMATION: StringName = &"running_show"
+const CHARACTER_CASTING_ANIMATION: StringName = &"casting"
+const CHARACTER_CASTING_SIT_ANIMATION: StringName = &"casting_sit"
+const CHARACTER_RELEASE_ANIMATION: StringName = &"release"
+const CHARACTER_RELEASE_SIT_ANIMATION: StringName = &"release_sit"
+const CHARACTER_RETRACT_ANIMATION: StringName = &"retract"
+const CHARACTER_RETRACT_SIT_ANIMATION: StringName = &"retract_sit"
+const CHARACTER_POCKET_IDLE_IDLE_ANIMATION: StringName = &"pocket_idle_idle"
+const CHARACTER_POCKET_IDLE_SHOW_ANIMATION: StringName = &"pocket_idle_show"
+const CHARACTER_POCKET_SHOW_SHOW_ANIMATION: StringName = &"pocket_show_show"
+const CHARACTER_POCKET_SHOW_IDLE_ANIMATION: StringName = &"pocket_show_idle"
+const CHARACTER_POCKET_SIT_IDLE_IDLE_ANIMATION: StringName = &"pocket_sit_idle_idle"
+const CHARACTER_POCKET_SIT_IDLE_SHOW_ANIMATION: StringName = &"pocket_sit_idle_show"
+const CHARACTER_POCKET_SIT_SHOW_SHOW_ANIMATION: StringName = &"pocket_sit_show_show"
+const CHARACTER_POCKET_SIT_SHOW_IDLE_ANIMATION: StringName = &"pocket_sit_show_idle"
+const CHARACTER_POCKET_WALKING_IDLE_IDLE_ANIMATION: StringName = &"pocket_walking_idle_idle"
+const CHARACTER_POCKET_WALKING_IDLE_SHOW_ANIMATION: StringName = &"pocket_walking_idle_show"
+const CHARACTER_POCKET_WALKING_SHOW_SHOW_ANIMATION: StringName = &"pocket_walking_show_show"
+const CHARACTER_POCKET_WALKING_SHOW_IDLE_ANIMATION: StringName = &"pocket_walking_show_idle"
+const CHARACTER_FISHING_ANIMATION: StringName = &"fishing"
+const CHARACTER_FISHING_SIT_ANIMATION: StringName = &"fishing_sit"
+const CHARACTER_FIGHTING_ANIMATION: StringName = &"fighting"
+const CHARACTER_FIGHTING_SIT_ANIMATION: StringName = &"fighting_sit"
+# Add future networked emote animation IDs here. The protocol accepts unknown
+# safe IDs so newer clients can extend it, but Player only presents actions
+# explicitly approved by this catalog.
+const NETWORK_ANIMATION_ACTION_IDS: Array[StringName] = []
+
+enum FishingVisualPhase {
+ NONE,
+ CASTING,
+ RELEASE,
+ RETRACT,
+ FISHING,
+}
+
+enum PocketVisualTarget {
+ NONE,
+ IDLE_ITEM,
+ HELD_FISH,
+ ART_KIT,
+ CATCH_SHOWCASE,
+}
+
+enum LocomotionState {
+ IDLE,
+ WALKING,
+ RUNNING,
+}
+const FIGHTING_EYES_ID: String = "alligator_eyes"
+const BLINK_EYES_ID: String = "closed"
+const BLINK_INTERVAL_SECONDS := Vector2(2.8, 7.5)
+const BLINK_DURATION_SECONDS: float = 0.11
+const CHARACTER_CALL_MOUTH_ID: String = "open_ah"
+const CHARACTER_CALL_MOUTH_DURATION_SECONDS: float = 0.16
const BASE_REEL_SPEED: float = 0.16
+const LANDING_DUST_MIN_FALL_SPEED: float = 2.5
# The target Android handheld exposes its physical right trigger through
# Godot's left-trigger axis. Keep the role named here so the platform mapping
# remains isolated from camera behavior.
@@ -50,8 +110,11 @@ const CONTROLLER_ZOOM_TRIGGER_AXIS: JoyAxis = JOY_AXIS_TRIGGER_LEFT
var appearance_snapshot: Dictionary = (
CharacterCustomizationCatalog.default_snapshot()
)
+var animalese_voice_id: String = "natural"
var active_bait_id: StringName = StringName()
+var active_lure_id: StringName = StringName()
signal active_bait_changed(item_id: StringName)
+signal active_lure_changed(item_id: StringName)
func equip_bait(item: ItemDataType) -> bool:
@@ -71,10 +134,145 @@ func unequip_bait() -> void:
active_bait_changed.emit(active_bait_id)
+func equip_lure(item: ItemDataType) -> bool:
+ if item == null or not item.is_lure() or bag == null:
+ return false
+ if not bag.owns_item(item.item_id):
+ return false
+ active_lure_id = item.item_id
+ active_lure_changed.emit(active_lure_id)
+ return true
+
+
+func unequip_lure() -> void:
+ if active_lure_id.is_empty():
+ return
+ active_lure_id = StringName()
+ active_lure_changed.emit(active_lure_id)
+
+
func apply_appearance_snapshot(snapshot: Dictionary) -> void:
if CharacterCustomizationCatalog.validate_snapshot(snapshot):
appearance_snapshot = snapshot.duplicate(true)
- PlayerVisualPresenter.apply_appearance(_visuals, appearance_snapshot)
+ _apply_presented_appearance()
+
+
+func get_character_visual_scale() -> float:
+ return CharacterCustomizationCatalog.character_scale(
+ appearance_snapshot.get(
+ CharacterCustomizationCatalog.SCALE_CATEGORY_ID,
+ CharacterCustomizationCatalog.DEFAULT_CHARACTER_SCALE,
+ )
+ )
+
+
+func set_fighting_visual(active: bool) -> void:
+ if _fighting_visual_active == active:
+ return
+ _fighting_visual_active = active
+ if active:
+ _blink_visual_active = false
+ _schedule_next_blink()
+ _apply_presented_appearance()
+ _character_animation_name = &""
+ _update_character_animation()
+
+
+func play_character_call_visual() -> void:
+ _character_call_visual_generation += 1
+ var generation: int = _character_call_visual_generation
+ _character_call_mouth_active = true
+ _apply_presented_appearance()
+ await get_tree().create_timer(
+ CHARACTER_CALL_MOUTH_DURATION_SECONDS
+ ).timeout
+ if generation != _character_call_visual_generation:
+ return
+ _character_call_mouth_active = false
+ _apply_presented_appearance()
+
+
+func set_fishing_visual(active: bool) -> void:
+ if (
+ active
+ and _fishing_visual_phase == FishingVisualPhase.RELEASE
+ and _character_animation_name in [
+ CHARACTER_RELEASE_ANIMATION,
+ CHARACTER_RELEASE_SIT_ANIMATION,
+ ]
+ and _character_animation_player != null
+ and _character_animation_player.is_playing()
+ ):
+ _fishing_after_release_pending = true
+ return
+ _set_fishing_visual_phase(
+ FishingVisualPhase.FISHING if active else FishingVisualPhase.NONE
+ )
+
+
+func set_casting_visual() -> void:
+ _set_fishing_visual_phase(FishingVisualPhase.CASTING)
+
+
+func set_release_visual() -> void:
+ _set_fishing_visual_phase(FishingVisualPhase.RELEASE)
+
+
+func set_retract_visual() -> void:
+ _retract_animation_completed = false
+ _set_fishing_visual_phase(FishingVisualPhase.RETRACT)
+ if (
+ _character_animation_player == null
+ or _character_animation_name not in [
+ CHARACTER_RETRACT_ANIMATION,
+ CHARACTER_RETRACT_SIT_ANIMATION,
+ ]
+ or not _character_animation_player.is_playing()
+ ):
+ _complete_retract_animation()
+
+
+func _set_fishing_visual_phase(phase: FishingVisualPhase) -> void:
+ if phase != FishingVisualPhase.NONE and _pocket_visual_active:
+ _complete_pocket_visual()
+ if _fishing_visual_phase == phase:
+ return
+ if (
+ _fishing_visual_phase == FishingVisualPhase.RETRACT
+ and phase != FishingVisualPhase.RETRACT
+ ):
+ _complete_retract_animation()
+ if phase != FishingVisualPhase.RELEASE:
+ _fishing_after_release_pending = false
+ _fishing_visual_phase = phase
+ _fishing_visual_active = phase != FishingVisualPhase.NONE
+ _character_animation_name = &""
+ _update_character_animation()
+
+
+func _apply_presented_appearance() -> void:
+ if not is_node_ready() or _visuals == null:
+ return
+ var presented_appearance := appearance_snapshot
+ if _blink_visual_active and not _fighting_visual_active:
+ presented_appearance = appearance_snapshot.duplicate(true)
+ presented_appearance["eyes"] = BLINK_EYES_ID
+ if _fighting_visual_active:
+ presented_appearance = appearance_snapshot.duplicate(true)
+ presented_appearance["eyes"] = FIGHTING_EYES_ID
+ if _character_call_mouth_active:
+ if presented_appearance == appearance_snapshot:
+ presented_appearance = appearance_snapshot.duplicate(true)
+ presented_appearance["mouth"] = CHARACTER_CALL_MOUTH_ID
+ PlayerVisualPresenter.apply_appearance(_visuals, presented_appearance)
+
+
+func apply_animalese_voice_id(voice_id: String) -> void:
+ animalese_voice_id = voice_id
+
+
+func get_animalese_voice_id() -> String:
+ return animalese_voice_id
class ShowcaseCameraSnapshot:
extends RefCounted
@@ -90,8 +288,8 @@ class ShowcaseCameraSnapshot:
@export_category("Movement")
@export var walk_speed: float = 2.25
-@export var sprint_speed: float = 7.2
-@export var sneak_speed: float = 1.8
+@export var sprint_speed: float = 4.5
+@export var sneak_speed: float = 1.125
@export var slow_walk_speed: float = 2.9
@export_range(0.1, 20.0, 0.1) var jump_velocity: float = 4.6
@export_range(0.1, 5.0, 0.05) var upward_gravity_multiplier: float = 1.35
@@ -129,6 +327,8 @@ class ShowcaseCameraSnapshot:
@export var zoom_smoothing: float = 12.0
@export_range(0.1, 12.0, 0.1) var controller_zoom_speed: float = 4.0
@export_range(0.0, 1.0, 0.01) var controller_trigger_threshold: float = 0.55
+@export_range(1.0, 40.0, 0.5) var free_camera_speed: float = 10.0
+@export_range(1.0, 10.0, 0.5) var free_camera_sprint_multiplier: float = 3.0
@onready var _visuals: Node3D = %Visuals
@onready var _character_rig: Node3D = get_node_or_null(
@@ -141,6 +341,7 @@ class ShowcaseCameraSnapshot:
@onready var _camera_pitch: Node3D = %CameraPitch
@onready var _spring_arm: SpringArm3D = %SpringArm3D
@onready var _camera: Camera3D = %Camera3D
+@onready var _player_collision_shape: CollisionShape3D = $CollisionShape3D
@onready var inventory: FishInventoryType = %Inventory
@onready var collection_log: CollectionLogType = %CollectionLog
@onready var wallet: PlayerWalletType = %Wallet
@@ -159,13 +360,21 @@ var _held_item_attachment: BoneAttachment3D
var _held_fish_display: Node3D
var _held_fish_attachment_offset: Vector3 = Vector3(0.0, 0.08, 0.04)
var _held_fish_sprite: Sprite3D
+var _held_art_kit_display: Node3D
var _held_art_kit_sprite: Sprite3D
var _catch_attachment_offset: Vector3 = Vector3(0.0, 0.08, 0.04)
var _gravity: float = float(ProjectSettings.get_setting("physics/3d/default_gravity"))
var _camera_dragging: bool = false
var _camera_input_enabled: bool = true
+var _camera_drag_prior_mouse_mode: Input.MouseMode = Input.MOUSE_MODE_VISIBLE
+var _free_camera_active: bool = false
+var _free_camera_body: CharacterBody3D
+var _free_camera: Camera3D
+var _free_camera_yaw: float = 0.0
+var _free_camera_pitch: float = 0.0
var _movement_enabled: bool = true
+var _local_input_suppressors: Dictionary[StringName, bool] = {}
var _water_recovery_active: bool = false
var _remote_recovery_presentation_active: bool = false
var _remote_recovery_visual_origin: Vector3
@@ -194,18 +403,72 @@ var _last_network_input_sequence: int = 0
var _network_target_position: Vector3
var _network_target_velocity: Vector3
var _network_target_visual_yaw: float = 0.0
+var _network_target_grounded: bool = false
+var _network_target_locomotion_state: LocomotionState = LocomotionState.IDLE
+var _network_target_animation_action_id: StringName = &""
+var _network_target_animation_action_sequence: int = 0
+var _network_target_animation_action_elapsed: float = 0.0
var _network_snapshot_ready: bool = false
+var _network_snapshot_age: float = 0.0
+var _animation_action_id: StringName = &""
+var _animation_action_sequence: int = 0
+var _animation_action_elapsed: float = 0.0
+var _presented_animation_action_id: StringName = &""
+var _presented_animation_action_sequence: int = -1
var _character_animation_name: StringName = &""
var _sitting: bool = false
+var _sit_after_landing: bool = false
+var _sitting_intent_pending: bool = false
+var _sitting_intent_sequence: int = -1
var _held_fish_visible: bool = false
+var _pending_held_fish_texture: Texture2D
+var _pending_held_fish_scale: Vector3 = Vector3.ONE
+var _held_art_kit_visible: bool = false
var _showcase_animation_active: bool = false
+var _pocket_visual_active: bool = false
+var _pocket_visual_target: PocketVisualTarget = PocketVisualTarget.NONE
+var _pocket_visual_animation: StringName = &""
+var _pocket_visual_finished_callback: Callable
+var _pocket_visual_callback_runs_on_interrupt: bool = true
+var _pocket_visual_midpoint_callback: Callable
+var _pocket_visual_midpoint_called: bool = false
+var _pocket_visual_generation: int = 0
+var _fighting_visual_active: bool = false
+var _blink_visual_active: bool = false
+var _blink_seconds_remaining: float = 0.0
+var _blink_rng := RandomNumberGenerator.new()
+var _character_call_mouth_active: bool = false
+var _character_call_visual_generation: int = 0
+var _fishing_visual_active: bool = false
+var _fishing_visual_phase: FishingVisualPhase = FishingVisualPhase.NONE
+var _fishing_after_release_pending: bool = false
+var _retract_animation_completed: bool = true
var _fishing_rod: Node3D
var _fishing_rod_tip: Marker3D
+var _active_item_is_rod: bool = false
var _controller_mapping_manager: ControllerMappingManagerType
+var _sprint_dust_landing_ready: bool = false
+var _sprint_dust_airborne: bool = false
+var _sprint_dust_fall_speed: float = 0.0
+
+@onready var _sprint_dust: SprintDustTrailType = %SprintDust
func _ready() -> void:
- PlayerVisualPresenter.apply_appearance(_visuals, appearance_snapshot)
+ _blink_rng.randomize()
+ _schedule_next_blink()
+ if (
+ _character_animation_player != null
+ and not _character_animation_player.animation_finished.is_connected(
+ _on_character_animation_finished
+ )
+ ):
+ _character_animation_player.animation_finished.connect(
+ _on_character_animation_finished
+ )
+ if not bag.contents_changed.is_connected(_on_bag_contents_changed):
+ bag.contents_changed.connect(_on_bag_contents_changed)
+ _apply_presented_appearance()
_initialize_fishing_rod()
_target_zoom = clampf(_spring_arm.spring_length, minimum_zoom, maximum_zoom)
_spring_arm.spring_length = _target_zoom
@@ -213,12 +476,91 @@ func _ready() -> void:
_initialize_held_item_attachment()
+func _on_bag_contents_changed() -> void:
+ if (
+ not active_bait_id.is_empty()
+ and bag.get_quantity(active_bait_id) <= 0
+ ):
+ unequip_bait()
+ if (
+ not active_lure_id.is_empty()
+ and not bag.owns_item(active_lure_id)
+ ):
+ unequip_lure()
+
+
func set_controller_mapping_manager(
mapping_manager: ControllerMappingManagerType,
) -> void:
_controller_mapping_manager = mapping_manager
+func begin_animation_action(
+ action_id: StringName,
+ elapsed_seconds: float = 0.0,
+) -> bool:
+ if (
+ action_id.is_empty()
+ or not supports_network_animation_action(action_id)
+ or _character_animation_player == null
+ or not _character_animation_player.has_animation(action_id)
+ ):
+ return false
+ var next_sequence: int = (
+ 1
+ if _animation_action_sequence
+ >= NetworkPlayerAnimationProtocol.MAX_ACTION_SEQUENCE
+ else _animation_action_sequence + 1
+ )
+ var action_state: Dictionary = (
+ NetworkPlayerAnimationProtocol.make_action_state(
+ action_id, next_sequence, elapsed_seconds
+ )
+ )
+ if not NetworkPlayerAnimationProtocol.validate_action_state(action_state):
+ return false
+ _apply_animation_action_state(action_state)
+ return true
+
+
+func end_animation_action() -> void:
+ if _animation_action_id.is_empty():
+ return
+ var next_sequence: int = (
+ 1
+ if _animation_action_sequence
+ >= NetworkPlayerAnimationProtocol.MAX_ACTION_SEQUENCE
+ else _animation_action_sequence + 1
+ )
+ _apply_animation_action_state(
+ NetworkPlayerAnimationProtocol.make_action_state(
+ &"", next_sequence, 0.0
+ )
+ )
+
+
+func _apply_animation_action_state(action_state: Dictionary) -> void:
+ if not NetworkPlayerAnimationProtocol.validate_action_state(action_state):
+ return
+ var action_id := StringName(str(action_state["id"]))
+ if (
+ not action_id.is_empty()
+ and not supports_network_animation_action(action_id)
+ ):
+ action_id = &""
+ var action_sequence: int = int(action_state["sequence"])
+ var action_changed: bool = (
+ action_id != _animation_action_id
+ or action_sequence != _animation_action_sequence
+ )
+ _animation_action_id = action_id
+ _animation_action_sequence = action_sequence
+ _animation_action_elapsed = float(action_state["elapsed"])
+ if action_changed:
+ _character_animation_name = &""
+ _update_character_animation()
+
+
func _initialize_fishing_rod() -> void:
var skeleton := get_node_or_null(
"Visuals/CharacterRig/CharacterRig/Skeleton3D"
@@ -255,6 +597,7 @@ func _initialize_held_item_attachment() -> void:
_held_fish_sprite = attachment.get_node(
"HeldFishDisplay/HeldFishSprite"
) as Sprite3D
+ _held_art_kit_display = attachment.get_node("HeldArtKitDisplay") as Node3D
_held_art_kit_sprite = attachment.get_node(
"HeldArtKitDisplay/HeldArtKitSprite"
) as Sprite3D
@@ -267,16 +610,29 @@ func _physics_process(delta: float) -> void:
if _network_interpolation_enabled:
_update_network_interpolation(delta)
return
+ if local_control_enabled and _free_camera_active:
+ _update_free_camera_physics()
+ velocity.x = 0.0
+ velocity.z = 0.0
+ if not is_on_floor():
+ velocity.y -= _gravity * fall_gravity_multiplier * delta
+ move_and_slide()
+ _network_jump_pending = false
+ return
var jump_requested: bool = (
- _movement_enabled
+ _is_movement_input_enabled()
+ and not _free_camera_active
and (
(local_control_enabled and Input.is_action_just_pressed("jump"))
or (_network_authoritative_simulation and _network_jump_pending)
)
)
+ if _sit_after_landing and is_on_floor():
+ _sit_after_landing = false
+ _set_sitting(true, local_control_enabled)
if _sitting:
if jump_requested:
- _set_sitting(false)
+ _set_sitting(false, local_control_enabled)
else:
velocity = Vector3.ZERO
_network_jump_pending = false
@@ -297,7 +653,7 @@ func _physics_process(delta: float) -> void:
velocity.y = jump_velocity
_network_jump_pending = false
- if not _movement_enabled:
+ if not _is_movement_input_enabled():
velocity.x = 0.0
velocity.z = 0.0
move_and_slide()
@@ -343,7 +699,14 @@ func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
+ if not _animation_action_id.is_empty():
+ _animation_action_elapsed = minf(
+ _animation_action_elapsed + delta,
+ NetworkPlayerAnimationProtocol.MAX_ACTION_ELAPSED_SECONDS,
+ )
+ _update_blink(delta)
_update_character_animation()
+ _update_sprint_dust(delta)
# The hand bone supplies the attachment position, but its animated wrist
# rotation should not turn the flat fish/catch artwork edge-on. Keep each
# display aligned with the character's facing while it follows the hand.
@@ -370,15 +733,13 @@ func _process(delta: float) -> void:
)
if not local_control_enabled:
return
+ if _free_camera_active:
+ return
- if (
- _camera_input_enabled
- and _camera_dragging
- and not Input.is_action_pressed("camera_drag")
- ):
- _camera_dragging = false
+ if _camera_dragging and not Input.is_action_pressed("camera_drag"):
+ _set_camera_dragging(false)
- if _camera_input_enabled:
+ if _is_camera_input_enabled():
var stick: Vector2 = _get_controller_camera_stick()
if stick.length() > controller_camera_deadzone:
if (
@@ -410,6 +771,70 @@ func _process(delta: float) -> void:
)
+func _update_blink(delta: float) -> void:
+ if _fighting_visual_active:
+ return
+ _blink_seconds_remaining -= delta
+ if _blink_seconds_remaining > 0.0:
+ return
+ _blink_visual_active = not _blink_visual_active
+ if _blink_visual_active:
+ _blink_seconds_remaining = BLINK_DURATION_SECONDS
+ else:
+ _schedule_next_blink()
+ _apply_presented_appearance()
+
+
+func _schedule_next_blink() -> void:
+ _blink_seconds_remaining = _blink_rng.randf_range(
+ BLINK_INTERVAL_SECONDS.x,
+ BLINK_INTERVAL_SECONDS.y,
+ )
+
+
+func _update_sprint_dust(delta: float) -> void:
+ if _sprint_dust == null:
+ return
+ var horizontal_velocity := Vector3(velocity.x, 0.0, velocity.z)
+ var grounded: bool = _get_presented_grounded()
+ if _water_recovery_active:
+ _sprint_dust_airborne = false
+ _sprint_dust_fall_speed = 0.0
+ elif not _sprint_dust_landing_ready:
+ # Establish a real ground contact before arming landing effects. This
+ # prevents the player's initial placement from looking like a fall.
+ _sprint_dust_landing_ready = grounded
+ elif not grounded:
+ _sprint_dust_airborne = true
+ _sprint_dust_fall_speed = maxf(
+ _sprint_dust_fall_speed,
+ maxf(-velocity.y, 0.0),
+ )
+ elif _sprint_dust_airborne:
+ if _sprint_dust_fall_speed >= LANDING_DUST_MIN_FALL_SPEED:
+ var landing_facing: Vector3 = horizontal_velocity.normalized()
+ if landing_facing.is_zero_approx() and _visuals != null:
+ landing_facing = -_visuals.global_basis.z
+ _sprint_dust.emit_landing_burst(
+ global_position,
+ landing_facing,
+ )
+ _sprint_dust_airborne = false
+ _sprint_dust_fall_speed = 0.0
+ var should_emit: bool = (
+ grounded
+ and not _sitting
+ and not _water_recovery_active
+ and _get_presented_locomotion_state() == LocomotionState.RUNNING
+ )
+ _sprint_dust.update_trail(
+ delta,
+ global_position,
+ horizontal_velocity,
+ should_emit,
+ )
+
+
func _get_controller_camera_stick() -> Vector2:
if _controller_mapping_manager != null:
return Vector2(
@@ -437,12 +862,25 @@ func _get_controller_zoom_strength() -> float:
func _update_character_animation() -> void:
if _character_animation_player == null:
return
- var horizontal_speed_squared: float = (
- velocity.x * velocity.x + velocity.z * velocity.z
+ var locomotion_state: LocomotionState = (
+ _get_presented_locomotion_state()
+ )
+ var is_walking: bool = locomotion_state != LocomotionState.IDLE
+ var is_running: bool = locomotion_state == LocomotionState.RUNNING
+ var animation_action: Dictionary = _get_presented_animation_action()
+ var animation_action_id := StringName(str(animation_action.get("id", "")))
+ var animation_action_available: bool = (
+ not animation_action_id.is_empty()
+ and supports_network_animation_action(animation_action_id)
+ and _character_animation_player.has_animation(animation_action_id)
+ )
+ var held_show_item_visible: bool = (
+ _held_fish_visible or _held_art_kit_visible
)
- var is_walking: bool = horizontal_speed_squared > 0.0025
var requested_animation: Array[StringName] = []
- if _showcase_animation_active:
+ if _pocket_visual_active:
+ requested_animation = [_pocket_visual_animation]
+ elif _showcase_animation_active:
if _sitting:
requested_animation = [
CHARACTER_IDLE_SIT_SHOW_ANIMATION,
@@ -458,8 +896,75 @@ func _update_character_animation() -> void:
&"show",
&"show_loop",
]
+ elif _fighting_visual_active:
+ if _sitting:
+ requested_animation = [
+ CHARACTER_FIGHTING_SIT_ANIMATION,
+ CHARACTER_IDLE_SIT_ANIMATION,
+ &"idle_sit_loop",
+ ]
+ else:
+ requested_animation = [
+ CHARACTER_FIGHTING_ANIMATION,
+ CHARACTER_IDLE_ANIMATION,
+ ]
+ elif _fishing_visual_active:
+ if _sitting:
+ match _fishing_visual_phase:
+ FishingVisualPhase.CASTING:
+ requested_animation = [
+ CHARACTER_CASTING_SIT_ANIMATION,
+ CHARACTER_FISHING_SIT_ANIMATION,
+ CHARACTER_IDLE_SIT_ANIMATION,
+ ]
+ FishingVisualPhase.RELEASE:
+ requested_animation = [
+ CHARACTER_RELEASE_SIT_ANIMATION,
+ CHARACTER_FISHING_SIT_ANIMATION,
+ CHARACTER_IDLE_SIT_ANIMATION,
+ ]
+ FishingVisualPhase.RETRACT:
+ requested_animation = [
+ CHARACTER_RETRACT_SIT_ANIMATION,
+ CHARACTER_RETRACT_ANIMATION,
+ CHARACTER_FISHING_SIT_ANIMATION,
+ CHARACTER_IDLE_SIT_ANIMATION,
+ ]
+ _:
+ requested_animation = [
+ CHARACTER_FISHING_SIT_ANIMATION,
+ CHARACTER_IDLE_SIT_ANIMATION,
+ &"idle_sit_loop",
+ ]
+ else:
+ match _fishing_visual_phase:
+ FishingVisualPhase.CASTING:
+ requested_animation = [
+ CHARACTER_CASTING_ANIMATION,
+ CHARACTER_FISHING_ANIMATION,
+ CHARACTER_IDLE_ANIMATION,
+ ]
+ FishingVisualPhase.RELEASE:
+ requested_animation = [
+ CHARACTER_RELEASE_ANIMATION,
+ CHARACTER_FISHING_ANIMATION,
+ CHARACTER_IDLE_ANIMATION,
+ ]
+ FishingVisualPhase.RETRACT:
+ requested_animation = [
+ CHARACTER_RETRACT_ANIMATION,
+ CHARACTER_FISHING_ANIMATION,
+ CHARACTER_IDLE_ANIMATION,
+ ]
+ _:
+ requested_animation = [
+ CHARACTER_FISHING_ANIMATION,
+ CHARACTER_IDLE_ANIMATION,
+ ]
+ elif animation_action_available:
+ requested_animation = [animation_action_id]
elif _sitting:
- if _held_fish_visible:
+ if held_show_item_visible:
requested_animation = [
CHARACTER_IDLE_SIT_SHOW_ANIMATION,
&"idle_sit_show_loop",
@@ -474,12 +979,26 @@ func _update_character_animation() -> void:
&"sitting",
&"idle_loop_sit",
]
- elif is_walking and _held_fish_visible:
+ elif is_running and held_show_item_visible:
+ requested_animation = [
+ CHARACTER_RUNNING_SHOW_ANIMATION,
+ &"running_show_loop",
+ CHARACTER_WALKING_SHOW_ANIMATION,
+ &"walking_show_loop",
+ ]
+ elif is_running:
+ requested_animation = [
+ CHARACTER_RUNNING_ANIMATION,
+ &"running_loop",
+ CHARACTER_WALKING_ANIMATION,
+ &"walking_loop",
+ ]
+ elif is_walking and held_show_item_visible:
requested_animation = [
CHARACTER_WALKING_SHOW_ANIMATION,
&"walking_show_loop",
]
- elif _held_fish_visible:
+ elif held_show_item_visible:
requested_animation = [
CHARACTER_IDLE_SHOW_ANIMATION,
&"idle_show_loop",
@@ -500,13 +1019,95 @@ func _update_character_animation() -> void:
break
if next_animation.is_empty():
return
- if _character_animation_name == next_animation:
+ var action_selected: bool = (
+ animation_action_available and next_animation == animation_action_id
+ )
+ var action_sequence: int = int(animation_action.get("sequence", 0))
+ var action_changed: bool = (
+ action_selected
+ and (
+ animation_action_id != _presented_animation_action_id
+ or action_sequence != _presented_animation_action_sequence
+ )
+ )
+ if not action_selected:
+ _presented_animation_action_id = &""
+ _presented_animation_action_sequence = -1
+ if _character_animation_name == next_animation and not action_changed:
return
_character_animation_player.play(next_animation)
_character_animation_name = next_animation
+ if action_selected:
+ _presented_animation_action_id = animation_action_id
+ _presented_animation_action_sequence = action_sequence
+ var elapsed: float = float(animation_action.get("elapsed", 0.0))
+ var animation: Animation = _character_animation_player.get_animation(
+ next_animation
+ )
+ if elapsed > 0.0 and animation != null and animation.length > 0.0:
+ _character_animation_player.seek(
+ fposmod(elapsed, animation.length), true
+ )
+
+
+func _on_character_animation_finished(animation_name: StringName) -> void:
+ if (
+ local_control_enabled
+ and not _animation_action_id.is_empty()
+ and animation_name == _animation_action_id
+ ):
+ end_animation_action()
+ return
+ if animation_name in [
+ CHARACTER_POCKET_IDLE_IDLE_ANIMATION,
+ CHARACTER_POCKET_IDLE_SHOW_ANIMATION,
+ CHARACTER_POCKET_SHOW_SHOW_ANIMATION,
+ CHARACTER_POCKET_SHOW_IDLE_ANIMATION,
+ CHARACTER_POCKET_SIT_IDLE_IDLE_ANIMATION,
+ CHARACTER_POCKET_SIT_IDLE_SHOW_ANIMATION,
+ CHARACTER_POCKET_SIT_SHOW_SHOW_ANIMATION,
+ CHARACTER_POCKET_SIT_SHOW_IDLE_ANIMATION,
+ CHARACTER_POCKET_WALKING_IDLE_IDLE_ANIMATION,
+ CHARACTER_POCKET_WALKING_IDLE_SHOW_ANIMATION,
+ CHARACTER_POCKET_WALKING_SHOW_SHOW_ANIMATION,
+ CHARACTER_POCKET_WALKING_SHOW_IDLE_ANIMATION,
+ ]:
+ if _pocket_visual_active:
+ _complete_pocket_visual()
+ return
+ if animation_name in [
+ CHARACTER_RETRACT_ANIMATION,
+ CHARACTER_RETRACT_SIT_ANIMATION,
+ ]:
+ _complete_retract_animation()
+ return
+ if (
+ not _fishing_after_release_pending
+ or animation_name not in [
+ CHARACTER_RELEASE_ANIMATION,
+ CHARACTER_RELEASE_SIT_ANIMATION,
+ ]
+ ):
+ return
+ _fishing_after_release_pending = false
+ _set_fishing_visual_phase(FishingVisualPhase.FISHING)
+
+
+func is_retract_visual_complete() -> bool:
+ return _retract_animation_completed
+
+
+func _complete_retract_animation() -> void:
+ if _retract_animation_completed:
+ return
+ _retract_animation_completed = true
+ retract_visual_finished.emit()
func toggle_sitting() -> void:
+ if _sit_after_landing:
+ _sit_after_landing = false
+ return
var should_sit: bool = not _sitting
if should_sit:
if (
@@ -519,7 +1120,10 @@ func toggle_sitting() -> void:
])
):
return
- _set_sitting(should_sit)
+ if not is_on_floor():
+ _sit_after_landing = true
+ return
+ _set_sitting(should_sit, local_control_enabled)
func _has_any_character_animation(candidates: Array[StringName]) -> bool:
@@ -531,10 +1135,16 @@ func _has_any_character_animation(candidates: Array[StringName]) -> bool:
return false
-func _set_sitting(should_sit: bool) -> void:
+func _set_sitting(
+ should_sit: bool,
+ is_local_intent: bool = false,
+) -> void:
if _sitting == should_sit:
return
_sitting = should_sit
+ if is_local_intent:
+ _sitting_intent_pending = true
+ _sitting_intent_sequence = -1
if _sitting:
velocity = Vector3.ZERO
_character_animation_name = &""
@@ -546,18 +1156,27 @@ func is_sitting() -> bool:
func _unhandled_input(event: InputEvent) -> void:
- if not local_control_enabled or not _camera_input_enabled:
+ if not local_control_enabled or not _is_camera_input_enabled():
+ return
+ if event.is_action_pressed("toggle_free_camera"):
+ toggle_free_camera()
+ get_viewport().set_input_as_handled()
return
if event.is_action("camera_drag"):
- _camera_dragging = event.is_pressed()
+ _set_camera_dragging(event.is_pressed())
get_viewport().set_input_as_handled()
return
if event is InputEventMouseMotion and _camera_dragging:
- _rotate_camera(event.relative * mouse_sensitivity)
+ if _free_camera_active:
+ _rotate_free_camera(event.relative * mouse_sensitivity)
+ else:
+ _rotate_camera(event.relative * mouse_sensitivity)
get_viewport().set_input_as_handled()
return
+ if _free_camera_active:
+ return
var mouse_zoom_in: bool = (
event is InputEventMouseButton
@@ -595,6 +1214,17 @@ func _get_current_speed() -> float:
return walk_speed
+func _set_camera_dragging(active: bool) -> void:
+ if _camera_dragging == active:
+ return
+ _camera_dragging = active
+ if active:
+ _camera_drag_prior_mouse_mode = Input.mouse_mode
+ Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
+ elif Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
+ Input.mouse_mode = _camera_drag_prior_mouse_mode
+
+
func _get_network_aware_speed() -> float:
if local_control_enabled:
return _get_current_speed()
@@ -617,6 +1247,115 @@ func _rotate_camera(delta_rotation: Vector2) -> void:
)
+func _set_free_camera_active(active: bool) -> void:
+ if _free_camera_active == active:
+ return
+ if active:
+ var camera_transform: Transform3D = _camera.global_transform
+ var duplicated_camera := _camera.duplicate() as Camera3D
+ if duplicated_camera == null:
+ return
+ var camera_body := CharacterBody3D.new()
+ camera_body.name = "FreeCameraBody"
+ camera_body.collision_layer = 0
+ camera_body.collision_mask = collision_mask
+ camera_body.motion_mode = CharacterBody3D.MOTION_MODE_FLOATING
+ add_child(camera_body)
+ camera_body.top_level = true
+ camera_body.global_position = camera_transform.origin
+ var camera_collision := CollisionShape3D.new()
+ camera_collision.name = "FreeCameraCollision"
+ camera_collision.shape = _player_collision_shape.shape
+ camera_body.add_child(camera_collision)
+ duplicated_camera.name = "FreeCamera"
+ duplicated_camera.unique_name_in_owner = false
+ camera_body.add_child(duplicated_camera)
+ duplicated_camera.transform = Transform3D(
+ camera_transform.basis,
+ Vector3.ZERO,
+ )
+ _free_camera_body = camera_body
+ _free_camera = duplicated_camera
+ var camera_rotation: Vector3 = _free_camera.global_rotation
+ _free_camera_yaw = camera_rotation.y
+ _free_camera_pitch = camera_rotation.x
+ _camera.current = false
+ _free_camera.current = true
+ _free_camera_active = true
+ return
+ _free_camera_active = false
+ _set_camera_dragging(false)
+ if _free_camera != null:
+ _free_camera.current = false
+ _free_camera = null
+ if _free_camera_body != null:
+ _free_camera_body.queue_free()
+ _free_camera_body = null
+ _camera.current = local_control_enabled
+
+
+func toggle_free_camera() -> void:
+ if not local_control_enabled:
+ return
+ _set_free_camera_active(not _free_camera_active)
+
+
+func is_free_camera_active() -> bool:
+ return _free_camera_active
+
+
+func _update_free_camera_physics() -> void:
+ if _free_camera == null or _free_camera_body == null:
+ _set_free_camera_active(false)
+ return
+ var input_vector: Vector2 = Input.get_vector(
+ "move_left",
+ "move_right",
+ "move_forward",
+ "move_backward",
+ )
+ var vertical_input: float = (
+ Input.get_action_strength("jump")
+ - Input.get_action_strength("sneak")
+ )
+ var yaw_basis := Basis(Vector3.UP, _free_camera_yaw)
+ var movement: Vector3 = (
+ yaw_basis.x * input_vector.x
+ + yaw_basis.z * input_vector.y
+ + Vector3.UP * vertical_input
+ )
+ if movement.length_squared() > 1.0:
+ movement = movement.normalized()
+ var movement_speed: float = free_camera_speed
+ if Input.is_action_pressed("sprint"):
+ movement_speed *= free_camera_sprint_multiplier
+ _free_camera_body.velocity = movement * movement_speed
+ _free_camera_body.move_and_slide()
+
+
+func _rotate_free_camera(delta_rotation: Vector2) -> void:
+ if _free_camera == null:
+ return
+ _free_camera_yaw -= delta_rotation.x
+ var vertical_direction: float = -1.0 if invert_camera_y else 1.0
+ _free_camera_pitch = clampf(
+ _free_camera_pitch - delta_rotation.y * vertical_direction,
+ deg_to_rad(-90.0),
+ deg_to_rad(90.0),
+ )
+ _free_camera.global_rotation = Vector3(
+ _free_camera_pitch,
+ _free_camera_yaw,
+ 0.0,
+ )
+
+
+func get_active_gameplay_camera() -> Camera3D:
+ if _free_camera_active and _free_camera != null:
+ return _free_camera
+ return _camera
+
+
func _set_target_zoom(value: float) -> void:
_target_zoom = clampf(value, minimum_zoom, maximum_zoom)
@@ -633,11 +1372,13 @@ func _apply_axis_deadzone(value: float) -> float:
func set_local_control(enabled: bool) -> void:
+ if not enabled and _free_camera_active:
+ _set_free_camera_active(false)
local_control_enabled = enabled
if is_node_ready():
_camera.current = enabled
if not enabled:
- _camera_dragging = false
+ _set_camera_dragging(false)
func set_network_peer_id(peer_id: int) -> void:
@@ -653,11 +1394,23 @@ func configure_network_remote(authoritative_simulation: bool) -> void:
_network_authoritative_simulation = authoritative_simulation
_network_interpolation_enabled = not authoritative_simulation
_network_snapshot_ready = false
+ _network_snapshot_age = 0.0
+ _network_target_grounded = false
+ _network_target_locomotion_state = LocomotionState.IDLE
+ _network_target_animation_action_id = &""
+ _network_target_animation_action_sequence = 0
+ _network_target_animation_action_elapsed = 0.0
_camera.current = false
func capture_network_input(sequence: int) -> Dictionary:
- if not _movement_enabled or _water_recovery_active:
+ if _sitting_intent_pending and _sitting_intent_sequence < 0:
+ _sitting_intent_sequence = sequence
+ if (
+ not _is_movement_input_enabled()
+ or _water_recovery_active
+ or _free_camera_active
+ ):
return {
"sequence": sequence,
"axis": [0.0, 0.0],
@@ -667,6 +1420,10 @@ func capture_network_input(sequence: int) -> Dictionary:
"sneak": false,
"slow_walk": false,
"sitting": _sitting,
+ "casting": (
+ _fishing_visual_phase == FishingVisualPhase.CASTING
+ ),
+ "animation_action": _make_animation_action_state(),
}
var axis: Vector2 = Input.get_vector(
"move_left",
@@ -683,6 +1440,8 @@ func capture_network_input(sequence: int) -> Dictionary:
"sneak": Input.is_action_pressed("sneak"),
"slow_walk": Input.is_action_pressed("slow_walk"),
"sitting": _sitting,
+ "casting": _fishing_visual_phase == FishingVisualPhase.CASTING,
+ "animation_action": _make_animation_action_state(),
}
@@ -700,7 +1459,15 @@ func apply_authoritative_network_input(data: Dictionary) -> void:
_network_sprint = bool(data.get("sprint", false))
_network_sneak = bool(data.get("sneak", false))
_network_slow_walk = bool(data.get("slow_walk", false))
- _set_sitting(bool(data.get("sitting", false)))
+ _apply_animation_action_state(data.get("animation_action", {}))
+ _apply_network_casting(bool(data.get("casting", false)))
+ var sitting_requested: bool = bool(data.get("sitting", false))
+ if sitting_requested and not is_on_floor():
+ _sit_after_landing = true
+ _set_sitting(false)
+ else:
+ _sit_after_landing = false
+ _set_sitting(sitting_requested)
func make_network_snapshot(peer_id: int) -> Dictionary:
@@ -710,8 +1477,15 @@ func make_network_snapshot(peer_id: int) -> Dictionary:
"position": [global_position.x, global_position.y, global_position.z],
"velocity": [velocity.x, velocity.y, velocity.z],
"visual_yaw": _visuals.rotation.y,
- "grounded": is_on_floor(),
+ "animation_state": NetworkPlayerAnimationProtocol.make_state(
+ _get_authoritative_locomotion_id(),
+ is_on_floor(),
+ _animation_action_id,
+ _animation_action_sequence,
+ _animation_action_elapsed,
+ ),
"sitting": _sitting,
+ "casting": _fishing_visual_phase == FishingVisualPhase.CASTING,
}
@@ -722,6 +1496,9 @@ func push_network_snapshot(snapshot: Dictionary) -> void:
_network_target_position = parsed["position"]
_network_target_velocity = parsed["velocity"]
_network_target_visual_yaw = parsed["visual_yaw"]
+ _apply_network_target_animation_state(parsed["animation_state"])
+ _network_snapshot_age = 0.0
+ _apply_network_casting(bool(parsed["casting"]))
_set_sitting(bool(parsed["sitting"]))
if not _network_snapshot_ready:
global_position = _network_target_position
@@ -734,7 +1511,17 @@ func apply_local_prediction_correction(snapshot: Dictionary) -> void:
var parsed: Dictionary = _parse_network_snapshot(snapshot)
if parsed.is_empty():
return
- _set_sitting(bool(parsed["sitting"]))
+ var acknowledged_input: int = parsed["acknowledged_input"]
+ var sitting_intent_acknowledged: bool = (
+ _sitting_intent_pending
+ and _sitting_intent_sequence >= 0
+ and acknowledged_input >= _sitting_intent_sequence
+ )
+ if sitting_intent_acknowledged:
+ _sitting_intent_pending = false
+ _sitting_intent_sequence = -1
+ if not _sitting_intent_pending:
+ _set_sitting(bool(parsed["sitting"]))
var authoritative_position: Vector3 = parsed["position"]
var error_distance: float = global_position.distance_to(
authoritative_position
@@ -752,10 +1539,13 @@ func apply_network_teleport(snapshot: Dictionary) -> void:
global_position = parsed["position"]
velocity = parsed["velocity"]
_visuals.rotation.y = parsed["visual_yaw"]
+ _apply_network_casting(bool(parsed["casting"]))
_set_sitting(bool(parsed["sitting"]))
_network_target_position = global_position
_network_target_velocity = velocity
_network_target_visual_yaw = _visuals.rotation.y
+ _apply_network_target_animation_state(parsed["animation_state"])
+ _network_snapshot_age = 0.0
_network_snapshot_ready = true
@@ -780,9 +1570,29 @@ func _parse_network_snapshot(snapshot: Dictionary) -> Dictionary:
float(network_velocity[2])
)
var visual_yaw: float = float(snapshot.get("visual_yaw", 0.0))
+ var animation_state_value: Variant = snapshot.get("animation_state")
+ if not NetworkPlayerAnimationProtocol.validate_state(animation_state_value):
+ return {}
+ var animation_state: Dictionary = (
+ animation_state_value as Dictionary
+ ).duplicate(true)
+ if (
+ snapshot.has("acknowledged_input")
+ and (
+ typeof(snapshot.get("acknowledged_input")) != TYPE_INT
+ or int(snapshot.get("acknowledged_input")) < 0
+ )
+ ):
+ return {}
+ var acknowledged_input: int = int(
+ snapshot.get("acknowledged_input", 0)
+ )
if snapshot.has("sitting") and typeof(snapshot.get("sitting")) != TYPE_BOOL:
return {}
var sitting: bool = bool(snapshot.get("sitting", false))
+ if snapshot.has("casting") and typeof(snapshot.get("casting")) != TYPE_BOOL:
+ return {}
+ var casting: bool = bool(snapshot.get("casting", false))
if (
not parsed_position.is_finite()
or not parsed_velocity.is_finite()
@@ -793,18 +1603,145 @@ func _parse_network_snapshot(snapshot: Dictionary) -> Dictionary:
"position": parsed_position,
"velocity": parsed_velocity,
"visual_yaw": visual_yaw,
+ "animation_state": animation_state,
+ "acknowledged_input": acknowledged_input,
"sitting": sitting,
+ "casting": casting,
}
+func _make_animation_action_state() -> Dictionary:
+ return NetworkPlayerAnimationProtocol.make_action_state(
+ _animation_action_id,
+ _animation_action_sequence,
+ _animation_action_elapsed,
+ )
+
+
+func _apply_network_target_animation_state(state: Dictionary) -> void:
+ if not NetworkPlayerAnimationProtocol.validate_state(state):
+ return
+ _network_target_grounded = bool(state["grounded"])
+ _network_target_locomotion_state = _locomotion_state_from_id(
+ StringName(str(state["locomotion_id"]))
+ )
+ var action: Dictionary = state["action"]
+ _network_target_animation_action_id = StringName(str(action["id"]))
+ _network_target_animation_action_sequence = int(action["sequence"])
+ _network_target_animation_action_elapsed = float(action["elapsed"])
+
+
+func _get_authoritative_locomotion_state() -> LocomotionState:
+ if (
+ _network_authoritative_simulation
+ and _is_movement_input_enabled()
+ and not _water_recovery_active
+ and not _sitting
+ and _network_axis.length_squared() > 0.0025
+ ):
+ return (
+ LocomotionState.RUNNING
+ if _network_sprint
+ else LocomotionState.WALKING
+ )
+ return _locomotion_state_from_velocity()
+
+
+func _get_authoritative_locomotion_id() -> StringName:
+ return _locomotion_id_from_state(_get_authoritative_locomotion_state())
+
+
+func _get_presented_locomotion_state() -> LocomotionState:
+ if _network_interpolation_enabled and _network_snapshot_ready:
+ return _network_target_locomotion_state
+ return _locomotion_state_from_velocity()
+
+
+func _get_presented_animation_action() -> Dictionary:
+ if _network_interpolation_enabled and _network_snapshot_ready:
+ return NetworkPlayerAnimationProtocol.make_action_state(
+ _network_target_animation_action_id,
+ _network_target_animation_action_sequence,
+ minf(
+ _network_target_animation_action_elapsed + _network_snapshot_age,
+ NetworkPlayerAnimationProtocol.MAX_ACTION_ELAPSED_SECONDS,
+ ),
+ )
+ return _make_animation_action_state()
+
+
+func _locomotion_id_from_state(state: LocomotionState) -> StringName:
+ match state:
+ LocomotionState.WALKING:
+ return NetworkPlayerAnimationProtocol.LOCOMOTION_WALKING
+ LocomotionState.RUNNING:
+ return NetworkPlayerAnimationProtocol.LOCOMOTION_RUNNING
+ _:
+ return NetworkPlayerAnimationProtocol.LOCOMOTION_IDLE
+
+
+func _locomotion_state_from_id(state_id: StringName) -> LocomotionState:
+ match state_id:
+ NetworkPlayerAnimationProtocol.LOCOMOTION_WALKING:
+ return LocomotionState.WALKING
+ NetworkPlayerAnimationProtocol.LOCOMOTION_RUNNING:
+ return LocomotionState.RUNNING
+ _:
+ return LocomotionState.IDLE
+
+
+static func supports_network_animation_action(action_id: StringName) -> bool:
+ return action_id in NETWORK_ANIMATION_ACTION_IDS
+
+
+func _locomotion_state_from_velocity() -> LocomotionState:
+ var horizontal_speed_squared: float = (
+ velocity.x * velocity.x + velocity.z * velocity.z
+ )
+ if horizontal_speed_squared <= 0.0025:
+ return LocomotionState.IDLE
+ var fastest_non_sprint_speed := maxf(
+ walk_speed,
+ maxf(sneak_speed, slow_walk_speed)
+ )
+ var running_threshold := fastest_non_sprint_speed + 0.5
+ if horizontal_speed_squared > running_threshold * running_threshold:
+ return LocomotionState.RUNNING
+ return LocomotionState.WALKING
+
+
+func _get_presented_grounded() -> bool:
+ if _network_interpolation_enabled and _network_snapshot_ready:
+ return _network_target_grounded
+ return is_on_floor()
+
+
+func _apply_network_casting(casting: bool) -> void:
+ if casting:
+ if _fishing_visual_phase == FishingVisualPhase.NONE:
+ set_casting_visual()
+ elif _fishing_visual_phase == FishingVisualPhase.CASTING:
+ set_fishing_visual(false)
+
+
func _update_network_interpolation(delta: float) -> void:
if not _network_snapshot_ready:
return
- var position_weight: float = 1.0 - exp(-12.0 * delta)
- global_position = global_position.lerp(
- _network_target_position,
- position_weight
+ _network_snapshot_age = minf(_network_snapshot_age + delta, 0.1)
+ var predicted_position: Vector3 = (
+ _network_target_position
+ + _network_target_velocity * _network_snapshot_age
)
+ var projected_position: Vector3 = (
+ global_position + _network_target_velocity * delta
+ )
+ if projected_position.distance_to(predicted_position) > 2.0:
+ global_position = predicted_position
+ else:
+ global_position = projected_position.lerp(
+ predicted_position,
+ 1.0 - exp(-10.0 * delta)
+ )
velocity = _network_target_velocity
_visuals.rotation.y = lerp_angle(
_visuals.rotation.y,
@@ -828,14 +1765,37 @@ func is_movement_enabled() -> bool:
return _movement_enabled
+func set_local_input_suppressed(owner: StringName, suppressed: bool) -> void:
+ if owner.is_empty():
+ return
+ if suppressed:
+ _local_input_suppressors[owner] = true
+ velocity.x = 0.0
+ velocity.z = 0.0
+ _set_camera_dragging(false)
+ else:
+ _local_input_suppressors.erase(owner)
+
+
+func _is_movement_input_enabled() -> bool:
+ return _movement_enabled and _local_input_suppressors.is_empty()
+
+
+func _is_camera_input_enabled() -> bool:
+ return _camera_input_enabled and _local_input_suppressors.is_empty()
+
+
func set_camera_input_enabled(enabled: bool) -> void:
_camera_input_enabled = enabled
if not enabled:
- _camera_dragging = false
+ _set_camera_dragging(false)
func set_camera_active(active: bool) -> void:
- _camera.current = active
+ if _free_camera_active and _free_camera != null:
+ _free_camera.current = active
+ else:
+ _camera.current = active
func apply_camera_settings(
@@ -942,41 +1902,316 @@ func get_fishing_rod() -> Node3D:
return _fishing_rod
-func set_active_item_is_rod(active_is_rod: bool) -> void:
+func set_active_item_is_rod(
+ active_is_rod: bool,
+ animate_transition: bool = false,
+) -> void:
+ _active_item_is_rod = active_is_rod
if _showcase_rod_state_stored:
_showcase_rod_visibility = active_is_rod
- else:
+ return
+ var visibility_changed: bool = _fishing_rod.visible != active_is_rod
+ if not animate_transition or not visibility_changed:
_fishing_rod.visible = active_is_rod
+ return
+ if _has_held_show_item() or _showcase_animation_active:
+ if not active_is_rod:
+ _fishing_rod.visible = false
+ return
+ if active_is_rod:
+ _fishing_rod.visible = false
+ _begin_pocket_visual(
+ PocketVisualTarget.IDLE_ITEM,
+ false,
+ false,
+ _apply_active_rod_visibility,
+ )
+
+
+func _apply_active_rod_visibility() -> void:
+ if _showcase_rod_state_stored:
+ _showcase_rod_visibility = _active_item_is_rod
+ return
+ _fishing_rod.visible = _active_item_is_rod
func set_active_art_kit(icon: Texture2D, should_show: bool) -> void:
- _held_art_kit_sprite.texture = icon if should_show else null
- _held_art_kit_sprite.visible = should_show and icon != null
+ var new_visible: bool = should_show and icon != null
+ if not new_visible:
+ if _held_art_kit_visible:
+ _begin_pocket_visual(
+ PocketVisualTarget.ART_KIT,
+ true,
+ _held_fish_visible,
+ _clear_active_art_kit,
+ true,
+ _apply_pending_held_fish,
+ )
+ else:
+ _clear_active_art_kit()
+ return
+ var previous_show_pose: bool = _has_held_show_item()
+ var item_changed: bool = (
+ not _held_art_kit_visible
+ or _held_art_kit_sprite.texture != icon
+ )
+ _held_art_kit_visible = true
+ _held_art_kit_sprite.texture = icon
+ _held_art_kit_sprite.visible = true
+ if not previous_show_pose:
+ _held_art_kit_display.visible = false
+ _fishing_rod.visible = false
+ if item_changed:
+ _begin_pocket_visual(
+ PocketVisualTarget.ART_KIT,
+ previous_show_pose,
+ true,
+ Callable(),
+ false,
+ _apply_active_art_kit_visual,
+ )
+ else:
+ _apply_active_art_kit_visual()
+ _update_character_animation()
func set_held_fish(
fish: FishDataType,
display_scale: float,
should_show: bool,
+ animate_put_away: bool = false,
) -> void:
if not should_show or fish == null or fish.display_texture == null:
- _held_fish_visible = false
- _held_fish_display.visible = false
- _held_fish_display.scale = Vector3.ONE
- _held_fish_sprite.texture = null
- _update_character_animation()
+ if animate_put_away and _held_fish_visible:
+ _begin_pocket_visual(
+ PocketVisualTarget.HELD_FISH,
+ true,
+ _held_art_kit_visible,
+ _clear_held_fish,
+ )
+ else:
+ if _pocket_visual_target == PocketVisualTarget.HELD_FISH:
+ _cancel_pocket_visual()
+ _clear_held_fish()
return
+ var previous_show_pose: bool = _has_held_show_item()
+ var item_changed: bool = (
+ not _held_fish_visible
+ or _held_fish_sprite.texture != fish.display_texture
+ )
_held_fish_visible = true
- _held_fish_sprite.texture = fish.display_texture
- _held_fish_display.scale = (
+ _pending_held_fish_texture = fish.display_texture
+ _pending_held_fish_scale = (
Vector3.ONE
* maxf(display_scale, 0.01)
* catch_presentation_base_scale
)
- _held_fish_display.visible = true
+ if not previous_show_pose:
+ _held_fish_display.visible = false
+ _fishing_rod.visible = false
+ if item_changed:
+ _begin_pocket_visual(
+ PocketVisualTarget.HELD_FISH,
+ previous_show_pose,
+ true,
+ Callable(),
+ false,
+ _apply_pending_held_fish,
+ )
+ else:
+ _apply_pending_held_fish()
+ _update_character_animation()
+
+
+func _has_held_show_item() -> bool:
+ return _held_fish_visible or _held_art_kit_visible
+
+
+func _clear_held_fish() -> void:
+ var was_visible: bool = _held_fish_visible
+ _held_fish_visible = false
+ _pending_held_fish_texture = null
+ _pending_held_fish_scale = Vector3.ONE
+ _held_fish_display.visible = false
+ _held_fish_display.scale = Vector3.ONE
+ _held_fish_sprite.texture = null
+ if was_visible:
+ _apply_active_rod_visibility()
_update_character_animation()
+func _apply_pending_held_fish() -> void:
+ if not _held_fish_visible or _pending_held_fish_texture == null:
+ return
+ _held_fish_sprite.texture = _pending_held_fish_texture
+ _held_fish_display.scale = _pending_held_fish_scale
+ _held_fish_display.visible = true
+
+
+func _clear_active_art_kit() -> void:
+ var was_visible: bool = _held_art_kit_visible
+ _held_art_kit_visible = false
+ _held_art_kit_display.visible = false
+ _held_art_kit_sprite.texture = null
+ _held_art_kit_sprite.visible = false
+ if was_visible:
+ _apply_active_rod_visibility()
+ if _held_fish_visible:
+ _apply_pending_held_fish()
+ _update_character_animation()
+
+
+func _apply_active_art_kit_visual() -> void:
+ if not _held_art_kit_visible or _held_art_kit_sprite.texture == null:
+ return
+ _held_art_kit_display.visible = true
+
+
+func _begin_pocket_visual(
+ target: PocketVisualTarget,
+ starts_in_show_pose: bool,
+ ends_in_show_pose: bool,
+ finished_callback: Callable,
+ callback_runs_on_interrupt: bool = true,
+ midpoint_callback: Callable = Callable(),
+) -> void:
+ var animation_name: StringName
+ if _sitting:
+ if starts_in_show_pose:
+ animation_name = (
+ CHARACTER_POCKET_SIT_SHOW_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_SIT_SHOW_IDLE_ANIMATION
+ )
+ else:
+ animation_name = (
+ CHARACTER_POCKET_SIT_IDLE_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_SIT_IDLE_IDLE_ANIMATION
+ )
+ elif _is_moving_for_pocket_visual():
+ if starts_in_show_pose:
+ animation_name = (
+ CHARACTER_POCKET_WALKING_SHOW_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_WALKING_SHOW_IDLE_ANIMATION
+ )
+ else:
+ animation_name = (
+ CHARACTER_POCKET_WALKING_IDLE_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_WALKING_IDLE_IDLE_ANIMATION
+ )
+ elif starts_in_show_pose:
+ animation_name = (
+ CHARACTER_POCKET_SHOW_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_SHOW_IDLE_ANIMATION
+ )
+ else:
+ animation_name = (
+ CHARACTER_POCKET_IDLE_SHOW_ANIMATION
+ if ends_in_show_pose
+ else CHARACTER_POCKET_IDLE_IDLE_ANIMATION
+ )
+ if _pocket_visual_active:
+ if (
+ _pocket_visual_target == target
+ and _pocket_visual_animation == animation_name
+ ):
+ return
+ if _pocket_visual_callback_runs_on_interrupt:
+ _complete_pocket_visual()
+ else:
+ _cancel_pocket_visual()
+ if (
+ animation_name.is_empty()
+ or _character_animation_player == null
+ or not _character_animation_player.has_animation(animation_name)
+ ):
+ if midpoint_callback.is_valid():
+ midpoint_callback.call()
+ if finished_callback.is_valid():
+ finished_callback.call()
+ _update_character_animation()
+ return
+ _pocket_visual_active = true
+ _pocket_visual_target = target
+ _pocket_visual_animation = animation_name
+ _pocket_visual_finished_callback = finished_callback
+ _pocket_visual_callback_runs_on_interrupt = callback_runs_on_interrupt
+ _pocket_visual_midpoint_callback = midpoint_callback
+ _pocket_visual_midpoint_called = false
+ _pocket_visual_generation += 1
+ var midpoint_generation: int = _pocket_visual_generation
+ _update_character_animation()
+ _schedule_pocket_visual_midpoint(midpoint_generation, animation_name)
+
+
+func _is_moving_for_pocket_visual() -> bool:
+ var horizontal_velocity := Vector2(velocity.x, velocity.z)
+ return horizontal_velocity.length_squared() > 0.0025
+
+
+func _schedule_pocket_visual_midpoint(
+ generation: int,
+ animation_name: StringName,
+) -> void:
+ if not _pocket_visual_midpoint_callback.is_valid():
+ return
+ var animation: Animation = _character_animation_player.get_animation(
+ animation_name
+ )
+ var midpoint_seconds: float = maxf(animation.length * 0.5, 0.0)
+ if midpoint_seconds > 0.0:
+ await get_tree().create_timer(midpoint_seconds, false).timeout
+ if (
+ generation != _pocket_visual_generation
+ or not _pocket_visual_active
+ or _pocket_visual_animation != animation_name
+ ):
+ return
+ _apply_pocket_visual_midpoint()
+
+
+func _apply_pocket_visual_midpoint() -> void:
+ if _pocket_visual_midpoint_called:
+ return
+ _pocket_visual_midpoint_called = true
+ var midpoint_callback: Callable = _pocket_visual_midpoint_callback
+ _pocket_visual_midpoint_callback = Callable()
+ if midpoint_callback.is_valid():
+ midpoint_callback.call()
+
+
+func _complete_pocket_visual() -> void:
+ if not _pocket_visual_active:
+ return
+ var finished_callback: Callable = _pocket_visual_finished_callback
+ _pocket_visual_active = false
+ _pocket_visual_target = PocketVisualTarget.NONE
+ _pocket_visual_animation = &""
+ _pocket_visual_finished_callback = Callable()
+ _pocket_visual_callback_runs_on_interrupt = true
+ _pocket_visual_midpoint_callback = Callable()
+ _pocket_visual_midpoint_called = false
+ _pocket_visual_generation += 1
+ if finished_callback.is_valid():
+ finished_callback.call()
+ _update_character_animation()
+
+
+func _cancel_pocket_visual() -> void:
+ _pocket_visual_active = false
+ _pocket_visual_target = PocketVisualTarget.NONE
+ _pocket_visual_animation = &""
+ _pocket_visual_finished_callback = Callable()
+ _pocket_visual_callback_runs_on_interrupt = true
+ _pocket_visual_midpoint_callback = Callable()
+ _pocket_visual_midpoint_called = false
+ _pocket_visual_generation += 1
+
+
func get_cast_origin_position() -> Vector3:
return _cast_origin.global_position
@@ -984,8 +2219,10 @@ func get_cast_origin_position() -> Vector3:
func begin_catch_showcase(fish_catch: FishCatchType) -> void:
if fish_catch == null or not fish_catch.is_valid():
return
+ if _pocket_visual_target == PocketVisualTarget.CATCH_SHOWCASE:
+ _cancel_pocket_visual()
_showcase_animation_active = true
- _update_character_animation()
+ set_fishing_visual(false)
_kill_showcase_camera_tween()
_kill_showcase_restore_tween()
_capture_showcase_camera_snapshot()
@@ -1005,6 +2242,7 @@ func begin_catch_showcase(fish_catch: FishCatchType) -> void:
* catch_presentation_base_scale
)
_catch_display.visible = _catch_sprite.texture != null
+ _update_character_animation()
func begin_remote_catch_showcase(fish_catch: FishCatchType) -> void:
@@ -1012,7 +2250,7 @@ func begin_remote_catch_showcase(fish_catch: FishCatchType) -> void:
return
end_catch_showcase(Callable(), true)
_showcase_animation_active = true
- _update_character_animation()
+ set_fishing_visual(false)
_showcase_rod_visibility = _fishing_rod.visible
_showcase_rod_state_stored = true
_fishing_rod.visible = false
@@ -1023,12 +2261,28 @@ func begin_remote_catch_showcase(fish_catch: FishCatchType) -> void:
* catch_presentation_base_scale
)
_catch_display.visible = _catch_sprite.texture != null
+ _update_character_animation()
func end_catch_showcase(
restored_callback: Callable = Callable(),
immediate: bool = false,
+ pocket_completed: bool = false,
) -> void:
+ if immediate and _pocket_visual_target == PocketVisualTarget.CATCH_SHOWCASE:
+ _cancel_pocket_visual()
+ elif (
+ not pocket_completed
+ and _showcase_animation_active
+ and _catch_display.visible
+ ):
+ _begin_pocket_visual(
+ PocketVisualTarget.CATCH_SHOWCASE,
+ true,
+ false,
+ end_catch_showcase.bind(restored_callback, false, true),
+ )
+ return
_showcase_animation_active = false
_update_character_animation()
_kill_showcase_turn_tween()
@@ -1201,7 +2455,10 @@ func _complete_showcase_restore(
_camera_input_enabled = (
_showcase_camera_snapshot.camera_input_enabled
)
- _camera_dragging = _showcase_camera_snapshot.camera_dragging
+ _set_camera_dragging(
+ _showcase_camera_snapshot.camera_dragging
+ and Input.is_action_pressed("camera_drag")
+ )
_showcase_camera_snapshot = null
if restored_callback.is_valid():
restored_callback.call()
@@ -1219,7 +2476,7 @@ func _capture_showcase_camera_snapshot() -> void:
_showcase_camera_snapshot.camera_input_enabled = _camera_input_enabled
_showcase_camera_snapshot.camera_dragging = _camera_dragging
_camera_input_enabled = false
- _camera_dragging = false
+ _set_camera_dragging(false)
func _begin_showcase_camera_transition() -> Vector3:
diff --git a/player/player.tscn b/player/player.tscn
index 2cda4eb..43ab900 100644
--- a/player/player.tscn
+++ b/player/player.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=18 format=3]
+[gd_scene load_steps=22 format=3]
[ext_resource type="Script" path="res://player/player.gd" id="1_script"]
[ext_resource type="Script" path="res://inventory/fish_inventory.gd" id="2_inventory"]
@@ -15,6 +15,7 @@
[ext_resource type="PackedScene" path="res://art/exported/characters/base/netfishing_base_character.glb" id="13_character"]
[ext_resource type="Script" path="res://progression/player_art_unlocks.gd" id="14_art_unlocks"]
[ext_resource type="Script" path="res://progression/player_experience.gd" id="15_experience"]
+[ext_resource type="Script" path="res://player/sprint_dust_trail.gd" id="16_sprint_dust"]
[sub_resource type="CapsuleShape3D" id="PlayerShape"]
radius = 0.45
@@ -24,6 +25,17 @@ height = 1.8
material = ExtResource("12_blob_shadow")
size = Vector2(1.15, 0.72)
+[sub_resource type="Shader" id="SprintDustShader"]
+code = "shader_type spatial;\nrender_mode blend_mix, depth_draw_never, cull_disabled, unshaded, shadows_disabled;\n\nuniform vec3 dust_color : source_color = vec3(0.61, 0.57, 0.53);\nvarying flat float puff_phase;\nvarying flat float puff_alpha;\n\nvoid vertex() {\n\tpuff_phase = INSTANCE_CUSTOM.x;\n\tpuff_alpha = INSTANCE_CUSTOM.w;\n\tVERTEX.xy *= INSTANCE_CUSTOM.yz;\n\tfloat puff_rotation = puff_phase * 6.28318530718;\n\tfloat rotation_sine = sin(puff_rotation);\n\tfloat rotation_cosine = cos(puff_rotation);\n\tVERTEX.xy = mat2(\n\t\tvec2(rotation_cosine, -rotation_sine),\n\t\tvec2(rotation_sine, rotation_cosine)\n\t) * VERTEX.xy;\n\tMODELVIEW_MATRIX = VIEW_MATRIX * mat4(\n\t\tINV_VIEW_MATRIX[0],\n\t\tINV_VIEW_MATRIX[1],\n\t\tINV_VIEW_MATRIX[2],\n\t\tMODEL_MATRIX[3]\n\t);\n}\n\nvoid fragment() {\n\tvec2 centered_uv = UV * 2.0 - 1.0;\n\tfloat angle = atan(centered_uv.y, centered_uv.x);\n\tfloat edge_wobble =\n\t\tsin(angle * 5.0 + puff_phase * 8.0) * 0.07\n\t\t+ sin(angle * 3.0 - puff_phase * 5.0) * 0.025;\n\tfloat radius = length(centered_uv);\n\tif (radius > 0.82 + edge_wobble) {\n\t\tdiscard;\n\t}\n\tALBEDO = dust_color;\n\tALPHA = puff_alpha;\n}\n"
+
+[sub_resource type="ShaderMaterial" id="SprintDustMaterial"]
+render_priority = 1
+shader = SubResource("SprintDustShader")
+
+[sub_resource type="QuadMesh" id="SprintDustMesh"]
+material = SubResource("SprintDustMaterial")
+size = Vector2(1, 1)
+
[node name="Player" type="CharacterBody3D"]
collision_layer = 2
collision_mask = 1
@@ -55,6 +67,12 @@ rotation_degrees = Vector3(-90, 0, 0)
cast_shadow = 0
mesh = SubResource("GroundShadowMesh")
+[node name="SprintDust" type="MultiMeshInstance3D" parent="."]
+unique_name_in_owner = true
+cast_shadow = 0
+script = ExtResource("16_sprint_dust")
+puff_mesh = SubResource("SprintDustMesh")
+
[node name="CharacterRig" parent="Visuals" instance=ExtResource("13_character")]
rotation_degrees = Vector3(0, 180, 0)
diff --git a/player/player_ground_shadow.gd b/player/player_ground_shadow.gd
index 9a4bb6f..0efa948 100644
--- a/player/player_ground_shadow.gd
+++ b/player/player_ground_shadow.gd
@@ -54,7 +54,7 @@ func _physics_process(delta: float) -> void:
_visual.transparency = 1.0 - _opacity
-func _place_on_surface(position: Vector3, normal: Vector3) -> void:
+func _place_on_surface(surface_position: Vector3, normal: Vector3) -> void:
var tangent := Vector3.RIGHT - normal * Vector3.RIGHT.dot(normal)
if tangent.length_squared() < 0.001:
tangent = Vector3.FORWARD - normal * Vector3.FORWARD.dot(normal)
@@ -62,5 +62,5 @@ func _place_on_surface(position: Vector3, normal: Vector3) -> void:
var bitangent := tangent.cross(normal).normalized()
_placement.global_transform = Transform3D(
Basis(tangent, normal, bitangent),
- position + normal * surface_offset,
+ surface_position + normal * surface_offset,
)
diff --git a/player/player_visual_presenter.gd b/player/player_visual_presenter.gd
index 8dd9f93..7a1ae1c 100644
--- a/player/player_visual_presenter.gd
+++ b/player/player_visual_presenter.gd
@@ -2,7 +2,27 @@ class_name PlayerVisualPresenter
extends RefCounted
const PlayerScene: PackedScene = preload("res://player/player.tscn")
+const FurPatternShader: Shader = preload("res://player/fur_pattern.gdshader")
const RUNTIME_MATERIAL_META: StringName = &"netfishing_runtime_material"
+const RUNTIME_FUR_PATTERN_MATERIAL_META: StringName = (
+ &"netfishing_runtime_fur_pattern_material"
+)
+const EAR_MESH_NAMES: Array[String] = [
+ "ears_antlers_round",
+ "ears_bear",
+ "ears_bunny",
+ "ears_pointy_long",
+ "ears_pointy_short",
+ "ears_pointy_wide",
+]
+const TAIL_MESH_NAMES: Array[String] = [
+ "tails_bear",
+ "tails_bunny",
+ "tails_cat",
+ "tails_fox",
+ "tails_gator",
+ "tails_pointy",
+]
static var _feature_uv_aspects: Dictionary = {}
@@ -113,25 +133,32 @@ static func apply_appearance(
var selected_ears: String = CharacterCustomizationCatalog.canonical_option_id(
"ears", str(snapshot.get("ears", "none"))
)
- var ear_names: Array[String] = [
- "ears_pointy_long",
- "ears_pointy_short",
- "ears_pointy_wide",
- ]
- for ear_name: String in ear_names:
+ for ear_name: String in EAR_MESH_NAMES:
var ears: Node3D = skeleton.get_node_or_null(ear_name) as Node3D
if ears != null:
ears.visible = selected_ears == ear_name.trim_prefix("ears_")
+ var selected_tail: String = CharacterCustomizationCatalog.canonical_option_id(
+ "tail", str(snapshot.get("tail", "none"))
+ )
+ for tail_name: String in TAIL_MESH_NAMES:
+ var tail: Node3D = skeleton.get_node_or_null(tail_name) as Node3D
+ if tail != null:
+ tail.visible = selected_tail == tail_name.trim_prefix("tails_")
var fur_color: Color = CharacterCustomizationCatalog.option_color(
"fur_pattern", str(snapshot.get("fur_pattern", "white"))
)
- _set_mesh_color(skeleton, "body_arms", fur_color)
- _set_mesh_color(skeleton, "body_main", fur_color)
- _set_mesh_color(skeleton, "head_pointy", fur_color)
- _set_mesh_color(skeleton, "head_round", fur_color)
- for ear_name: String in ear_names:
- _set_mesh_color(skeleton, ear_name, fur_color)
+ for fur_mesh_name: String in [
+ "body_main",
+ "body_arms",
+ "head_pointy",
+ "head_round",
+ ]:
+ _set_fur_mesh(skeleton, fur_mesh_name, snapshot, fur_color)
+ for ear_name: String in EAR_MESH_NAMES:
+ _set_fur_mesh(skeleton, ear_name, snapshot, fur_color)
+ for tail_name: String in TAIL_MESH_NAMES:
+ _set_fur_mesh(skeleton, tail_name, snapshot, fur_color)
var eye_id: String = CharacterCustomizationCatalog.canonical_option_id(
"eyes", str(snapshot.get("eyes", "simple_shine"))
@@ -182,17 +209,60 @@ static func _set_feature_texture(
material.albedo_texture = texture
-static func _set_mesh_color(
+static func _set_fur_mesh(
skeleton: Skeleton3D,
mesh_name: String,
- color: Color,
+ snapshot: Dictionary,
+ base_color: Color,
) -> void:
- var mesh_instance: MeshInstance3D = skeleton.get_node_or_null(
- mesh_name
- ) as MeshInstance3D
- var material: StandardMaterial3D = _runtime_material(mesh_instance)
- if material != null:
- material.albedo_color = color
+ var mesh_instance := skeleton.get_node_or_null(mesh_name) as MeshInstance3D
+ if mesh_instance == null:
+ return
+ var style_id := CharacterCustomizationCatalog.canonical_option_id(
+ CharacterCustomizationCatalog.FUR_STYLE_ID,
+ str(snapshot.get(
+ CharacterCustomizationCatalog.FUR_STYLE_ID,
+ CharacterCustomizationCatalog.DEFAULT_FUR_STYLE,
+ )),
+ )
+ var pattern_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ style_id,
+ mesh_name,
+ )
+ if pattern_texture == null:
+ var solid_material := _runtime_material(mesh_instance)
+ if solid_material != null:
+ solid_material.albedo_color = base_color
+ mesh_instance.material_override = solid_material
+ return
+
+ var pattern_material := _runtime_fur_pattern_material(mesh_instance)
+ pattern_material.set_shader_parameter("pattern_texture", pattern_texture)
+ pattern_material.set_shader_parameter("base_color", base_color)
+ pattern_material.set_shader_parameter(
+ "red_zone_color",
+ _fur_snapshot_color(snapshot, "fur_color_2", "cream"),
+ )
+ pattern_material.set_shader_parameter(
+ "green_zone_color",
+ _fur_snapshot_color(snapshot, "fur_color_3", "brown"),
+ )
+ pattern_material.set_shader_parameter(
+ "blue_zone_color",
+ _fur_snapshot_color(snapshot, "fur_color_4", "red"),
+ )
+ mesh_instance.material_override = pattern_material
+
+
+static func _fur_snapshot_color(
+ snapshot: Dictionary,
+ category_id: String,
+ default_id: String,
+) -> Color:
+ return CharacterCustomizationCatalog.option_color(
+ category_id,
+ str(snapshot.get(category_id, default_id)),
+ )
static func _runtime_material(
@@ -201,7 +271,9 @@ static func _runtime_material(
if mesh_instance == null or mesh_instance.mesh == null:
return null
if mesh_instance.has_meta(RUNTIME_MATERIAL_META):
- var runtime := mesh_instance.material_override as StandardMaterial3D
+ var runtime := mesh_instance.get_meta(
+ RUNTIME_MATERIAL_META
+ ) as StandardMaterial3D
_configure_matte_material(runtime)
return runtime
var source: StandardMaterial3D = mesh_instance.mesh.surface_get_material(
@@ -212,13 +284,27 @@ static func _runtime_material(
var material: StandardMaterial3D = source.duplicate() as StandardMaterial3D
_configure_matte_material(material)
mesh_instance.material_override = material
- mesh_instance.set_meta(RUNTIME_MATERIAL_META, true)
+ mesh_instance.set_meta(RUNTIME_MATERIAL_META, material)
+ return material
+
+
+static func _runtime_fur_pattern_material(
+ mesh_instance: MeshInstance3D,
+) -> ShaderMaterial:
+ if mesh_instance.has_meta(RUNTIME_FUR_PATTERN_MATERIAL_META):
+ return mesh_instance.get_meta(
+ RUNTIME_FUR_PATTERN_MATERIAL_META
+ ) as ShaderMaterial
+ var material := ShaderMaterial.new()
+ material.shader = FurPatternShader
+ mesh_instance.set_meta(RUNTIME_FUR_PATTERN_MATERIAL_META, material)
return material
static func _configure_matte_material(material: StandardMaterial3D) -> void:
if material == null:
return
+ material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_NEAREST
# Character artwork is deliberately graphic and flat. Unshaded rendering
# keeps the authored fur and facial colors invariant across world weather,
# time of day, and the isolated Profile preview.
diff --git a/player/sprint_dust_trail.gd b/player/sprint_dust_trail.gd
new file mode 100644
index 0000000..124b6ae
--- /dev/null
+++ b/player/sprint_dust_trail.gd
@@ -0,0 +1,249 @@
+class_name SprintDustTrail
+extends MultiMeshInstance3D
+
+const PUFF_COUNT: int = 12
+const PUFF_SPACING: float = 0.46
+const PUFF_LIFETIME: float = 0.62
+const PUFF_GROW_TIME: float = 0.16
+const PUFF_FADE_TIME: float = 0.22
+const PUFF_BACK_OFFSET: float = 0.14
+const PUFF_SIDE_OFFSET: float = 0.11
+const PUFF_HEIGHT: float = 0.08
+const PUFF_MIN_SCALE: float = 0.22
+
+@export var puff_mesh: Mesh
+
+var _puff_positions: Array[Vector3] = []
+var _puff_ages := PackedFloat32Array()
+var _puff_widths := PackedFloat32Array()
+var _puff_heights := PackedFloat32Array()
+var _puff_phases := PackedFloat32Array()
+var _next_puff: int = 0
+var _spawn_serial: int = 0
+var _foot_side: float = -1.0
+var _tracking_run: bool = false
+var _previous_source_position: Vector3
+var _distance_since_puff: float = 0.0
+
+
+func _ready() -> void:
+ top_level = true
+ global_transform = Transform3D.IDENTITY
+ _initialize_pool()
+
+
+func update_trail(
+ delta: float,
+ source_position: Vector3,
+ movement_velocity: Vector3,
+ is_running: bool,
+) -> void:
+ _update_existing_puffs(delta)
+ custom_aabb = AABB(
+ source_position - Vector3(5.0, 2.0, 5.0),
+ Vector3(10.0, 5.0, 10.0),
+ )
+ if not is_running:
+ _tracking_run = false
+ _distance_since_puff = 0.0
+ return
+
+ var flat_source := Vector3(
+ source_position.x,
+ source_position.y,
+ source_position.z,
+ )
+ if not _tracking_run:
+ _tracking_run = true
+ _previous_source_position = flat_source
+ _distance_since_puff = 0.0
+ return
+
+ var segment := flat_source - _previous_source_position
+ segment.y = 0.0
+ var remaining_distance: float = segment.length()
+ if remaining_distance <= 0.0001:
+ _previous_source_position = flat_source
+ return
+
+ var segment_direction: Vector3 = segment / remaining_distance
+ var movement_direction := Vector3(
+ movement_velocity.x,
+ 0.0,
+ movement_velocity.z,
+ ).normalized()
+ if movement_direction.is_zero_approx():
+ movement_direction = segment_direction
+ var cursor: Vector3 = _previous_source_position
+ var distance_to_next: float = PUFF_SPACING - _distance_since_puff
+ while remaining_distance >= distance_to_next:
+ cursor += segment_direction * distance_to_next
+ _spawn_puff(cursor, movement_direction)
+ remaining_distance -= distance_to_next
+ _distance_since_puff = 0.0
+ distance_to_next = PUFF_SPACING
+ _distance_since_puff += remaining_distance
+ _previous_source_position = flat_source
+
+
+func clear_trail() -> void:
+ _tracking_run = false
+ _distance_since_puff = 0.0
+ for index: int in PUFF_COUNT:
+ _puff_ages[index] = PUFF_LIFETIME
+ _write_inactive_puff(index)
+
+
+func emit_landing_burst(
+ source_position: Vector3,
+ facing_direction: Vector3,
+) -> void:
+ var direction := Vector3(
+ facing_direction.x,
+ 0.0,
+ facing_direction.z,
+ ).normalized()
+ if direction.is_zero_approx():
+ direction = Vector3.FORWARD
+ var first_direction: Vector3 = -direction
+ for puff_index: int in 5:
+ var spread_direction := first_direction.rotated(
+ Vector3.UP,
+ TAU * float(puff_index) / 5.0,
+ )
+ var radius: float = lerpf(
+ 0.38,
+ 0.46,
+ _stable_variation(_spawn_serial + puff_index + 81),
+ )
+ _spawn_puff_at(
+ source_position
+ + spread_direction * radius
+ + Vector3.UP * PUFF_HEIGHT,
+ 0.95,
+ )
+
+
+func get_active_puff_count() -> int:
+ var active_count: int = 0
+ for age: float in _puff_ages:
+ if age < PUFF_LIFETIME:
+ active_count += 1
+ return active_count
+
+
+func get_first_active_puff_position() -> Vector3:
+ for index: int in PUFF_COUNT:
+ if _puff_ages[index] < PUFF_LIFETIME:
+ return _puff_positions[index]
+ return Vector3.INF
+
+
+func _initialize_pool() -> void:
+ var pool := MultiMesh.new()
+ pool.transform_format = MultiMesh.TRANSFORM_3D
+ pool.use_custom_data = true
+ pool.instance_count = PUFF_COUNT
+ pool.mesh = puff_mesh
+ multimesh = pool
+ _puff_positions.resize(PUFF_COUNT)
+ _puff_ages.resize(PUFF_COUNT)
+ _puff_widths.resize(PUFF_COUNT)
+ _puff_heights.resize(PUFF_COUNT)
+ _puff_phases.resize(PUFF_COUNT)
+ clear_trail()
+
+
+func _spawn_puff(source_position: Vector3, direction: Vector3) -> void:
+ var lateral := Vector3(-direction.z, 0.0, direction.x)
+ var position := (
+ source_position
+ - direction * PUFF_BACK_OFFSET
+ + lateral * PUFF_SIDE_OFFSET * _foot_side
+ + Vector3.UP * PUFF_HEIGHT
+ )
+ _spawn_puff_at(position)
+ _foot_side *= -1.0
+
+
+func _spawn_puff_at(
+ position: Vector3,
+ size_multiplier: float = 1.0,
+) -> void:
+ var variation: float = _stable_variation(_spawn_serial)
+ var second_variation: float = _stable_variation(_spawn_serial + 37)
+ var index: int = _next_puff
+ _puff_positions[index] = position
+ _puff_ages[index] = 0.0
+ _puff_widths[index] = (
+ lerpf(0.34, 0.43, variation) * size_multiplier
+ )
+ _puff_heights[index] = (
+ lerpf(0.23, 0.30, second_variation) * size_multiplier
+ )
+ _puff_phases[index] = variation
+ _write_puff(index, PUFF_MIN_SCALE, 1.0)
+ _next_puff = (_next_puff + 1) % PUFF_COUNT
+ _spawn_serial += 1
+
+
+func _update_existing_puffs(delta: float) -> void:
+ if multimesh == null:
+ return
+ for index: int in PUFF_COUNT:
+ var age: float = _puff_ages[index]
+ if age >= PUFF_LIFETIME:
+ continue
+ age += delta
+ _puff_ages[index] = age
+ if age >= PUFF_LIFETIME:
+ _write_inactive_puff(index)
+ continue
+ var visual_scale: float = 1.0
+ if age < PUFF_GROW_TIME:
+ var grow_weight: float = smoothstep(
+ 0.0,
+ 1.0,
+ age / PUFF_GROW_TIME,
+ )
+ visual_scale = lerpf(PUFF_MIN_SCALE, 1.0, grow_weight)
+ var visual_alpha: float = 1.0
+ if age > PUFF_LIFETIME - PUFF_FADE_TIME:
+ var fade_weight: float = smoothstep(
+ 0.0,
+ 1.0,
+ (age - (PUFF_LIFETIME - PUFF_FADE_TIME))
+ / PUFF_FADE_TIME,
+ )
+ visual_alpha = 1.0 - fade_weight
+ _write_puff(index, visual_scale, visual_alpha)
+
+
+func _write_puff(
+ index: int,
+ visual_scale: float,
+ visual_alpha: float,
+) -> void:
+ var puff_transform := Transform3D.IDENTITY
+ puff_transform.origin = _puff_positions[index]
+ multimesh.set_instance_transform(index, puff_transform)
+ multimesh.set_instance_custom_data(
+ index,
+ Color(
+ _puff_phases[index],
+ _puff_widths[index] * visual_scale,
+ _puff_heights[index] * visual_scale,
+ visual_alpha,
+ ),
+ )
+
+
+func _write_inactive_puff(index: int) -> void:
+ var inactive_transform := Transform3D.IDENTITY
+ inactive_transform.origin = _puff_positions[index]
+ multimesh.set_instance_transform(index, inactive_transform)
+ multimesh.set_instance_custom_data(index, Color(0.0, 0.0, 0.0, 0.0))
+
+
+func _stable_variation(serial: int) -> float:
+ return fposmod(sin(float(serial + 1) * 12.9898) * 43758.5453, 1.0)
diff --git a/player/sprint_dust_trail.gd.uid b/player/sprint_dust_trail.gd.uid
new file mode 100644
index 0000000..c40239c
--- /dev/null
+++ b/player/sprint_dust_trail.gd.uid
@@ -0,0 +1 @@
+uid://o2gi5oqunsp8
diff --git a/progression/character_customization_catalog.gd b/progression/character_customization_catalog.gd
index ddcf0b3..609f593 100644
--- a/progression/character_customization_catalog.gd
+++ b/progression/character_customization_catalog.gd
@@ -12,10 +12,28 @@ const CATEGORY_IDS: PackedStringArray = [
"tail",
]
+# CATEGORY_IDS controls the visible Profile navigation. The additional fur
+# fields are edited together on the existing fur page, but remain explicit in
+# saves and signed multiplayer appearance snapshots.
+const SNAPSHOT_IDS: PackedStringArray = [
+ "species",
+ "scale",
+ "fur_pattern",
+ "fur_style",
+ "fur_color_2",
+ "fur_color_3",
+ "fur_color_4",
+ "ears",
+ "eyes",
+ "nose",
+ "mouth",
+ "tail",
+]
+
const CATEGORY_LABELS: Dictionary = {
"species": "head",
"scale": "size",
- "fur_pattern": "fur color",
+ "fur_pattern": "fur",
"ears": "ears",
"eyes": "eyes",
"nose": "nose",
@@ -24,10 +42,24 @@ const CATEGORY_LABELS: Dictionary = {
}
const SCALE_CATEGORY_ID: String = "scale"
-const MIN_CHARACTER_SCALE: float = 0.75
-const MAX_CHARACTER_SCALE: float = 1.25
+const MIN_CHARACTER_SCALE: float = 0.5
+const MAX_CHARACTER_SCALE: float = 1.5
const DEFAULT_CHARACTER_SCALE: float = 1.0
const CHARACTER_SCALE_STEP: float = 0.05
+const FUR_STYLE_ID: String = "fur_style"
+const FUR_COLOR_IDS: PackedStringArray = [
+ "fur_pattern",
+ "fur_color_2",
+ "fur_color_3",
+ "fur_color_4",
+]
+const FUR_COLOR_LABELS: Dictionary = {
+ "fur_pattern": "primary",
+ "fur_color_2": "secondary",
+ "fur_color_3": "accent",
+ "fur_color_4": "detail",
+}
+const DEFAULT_FUR_STYLE: String = "solid"
const FEATURE_CATEGORIES: PackedStringArray = ["eyes", "nose", "mouth"]
const FEATURE_ASSET_ROOTS: Dictionary = {
@@ -41,26 +73,101 @@ const FEATURE_LABEL_OVERRIDES: Dictionary = {
"dog_round": "round",
"three": "three",
}
+const FUR_COLOR_OPTIONS: Array = [
+ {"id": "white", "label": "white", "color": Color("f2f0e8")},
+ {"id": "ivory", "label": "ivory", "color": Color("f0e2c2")},
+ {"id": "cream", "label": "cream", "color": Color("e6d39b")},
+ {"id": "sand", "label": "sand", "color": Color("c6a66f")},
+ {"id": "tan", "label": "tan", "color": Color("ad7c55")},
+ {"id": "taupe", "label": "taupe", "color": Color("89756a")},
+ {"id": "silver", "label": "silver", "color": Color("b8c3c1")},
+ {"id": "gray", "label": "gray", "color": Color("819398")},
+ {"id": "slate", "label": "slate", "color": Color("58686c")},
+ {"id": "charcoal", "label": "charcoal", "color": Color("34444a")},
+ {"id": "black", "label": "black", "color": Color("192126")},
+ {"id": "dark_brown", "label": "dark brown", "color": Color("432a25")},
+ {"id": "chocolate", "label": "chocolate", "color": Color("603b2c")},
+ {"id": "brown", "label": "brown", "color": Color("7b4a32")},
+ {"id": "chestnut", "label": "chestnut", "color": Color("98513d")},
+ {"id": "ginger", "label": "ginger", "color": Color("d28742")},
+ {"id": "orange", "label": "orange", "color": Color("c86c36")},
+ {"id": "red", "label": "red", "color": Color("a9433f")},
+ {"id": "pink", "label": "pink", "color": Color("d8899e")},
+ {"id": "yellow", "label": "yellow", "color": Color("d8c545")},
+ {"id": "gold", "label": "gold", "color": Color("c29a3d")},
+ {"id": "sage", "label": "sage", "color": Color("8fa16b")},
+ {"id": "green", "label": "green", "color": Color("6f913c")},
+ {"id": "forest", "label": "forest", "color": Color("3f6945")},
+ {"id": "aqua", "label": "aqua", "color": Color("69aeb0")},
+ {"id": "teal", "label": "teal", "color": Color("3a8790")},
+ {"id": "blue", "label": "blue", "color": Color("4d76a8")},
+ {"id": "navy", "label": "navy", "color": Color("344b78")},
+ {"id": "lavender", "label": "lavender", "color": Color("9a7eaa")},
+ {"id": "purple", "label": "purple", "color": Color("76558f")},
+]
const OPTIONS: Dictionary = {
"species": [
{"id": "round", "label": "round"},
{"id": "pointy", "label": "pointy"},
],
- # The serialized field remains `fur_pattern` for save and network
- # compatibility. It holds the initial solid fur-color selection until the
- # authored pattern layer is ready.
- "fur_pattern": [
- {"id": "white", "label": "white", "color": Color("f2f0e8")},
- {"id": "gray", "label": "gray", "color": Color("819398")},
- {"id": "charcoal", "label": "charcoal", "color": Color("34444a")},
- {"id": "brown", "label": "brown", "color": Color("7b4a32")},
- {"id": "orange", "label": "orange", "color": Color("c86c36")},
- {"id": "yellow", "label": "yellow", "color": Color("d8c545")},
- {"id": "green", "label": "green", "color": Color("6f913c")},
- {"id": "teal", "label": "teal", "color": Color("3a8790")},
+ # `fur_pattern` remains the primary color key for compatibility with
+ # existing appearance saves. The actual authored pattern has its own field.
+ "fur_pattern": FUR_COLOR_OPTIONS,
+ "fur_color_2": FUR_COLOR_OPTIONS,
+ "fur_color_3": FUR_COLOR_OPTIONS,
+ "fur_color_4": FUR_COLOR_OPTIONS,
+ "fur_style": [
+ {"id": "solid", "label": "solid"},
+ {
+ "id": "spots_bengal",
+ "label": "bengal spots",
+ "textures": {
+ "body_main": (
+ "res://art/exported/characters/patterns/"
+ + "bengal/body_main_bengal.png"
+ ),
+ "body_arms": (
+ "res://art/exported/characters/patterns/"
+ + "bengal/body_arms_bengal.png"
+ ),
+ "head_round": (
+ "res://art/exported/characters/patterns/"
+ + "bengal/head_round_bengal.png"
+ ),
+ },
+ },
+ {
+ "id": "fox",
+ "label": "fox",
+ "textures": {
+ "body_main": (
+ "res://art/exported/characters/patterns/"
+ + "fox/body_main_fox.png"
+ ),
+ "body_arms": (
+ "res://art/exported/characters/patterns/"
+ + "fox/body_arms_fox.png"
+ ),
+ "head_pointy": (
+ "res://art/exported/characters/patterns/"
+ + "fox/head_pointy_fox.png"
+ ),
+ "head_round": (
+ "res://art/exported/characters/patterns/"
+ + "fox/head_round_fox.png"
+ ),
+ "tails_fox": (
+ "res://art/exported/characters/patterns/"
+ + "fox/tails_fox_fox.png"
+ ),
+ },
+ },
],
"ears": [
{"id": "none", "label": "none"},
+ {"id": "antlers_round", "label": "antlers"},
+ {"id": "bear", "label": "bear"},
+ {"id": "bunny", "label": "bunny"},
{"id": "pointy_long", "label": "long"},
{"id": "pointy_short", "label": "short"},
{"id": "pointy_wide", "label": "wide"},
@@ -74,13 +181,23 @@ const OPTIONS: Dictionary = {
],
"nose": [{"id": "dog_round", "label": "round"}],
"mouth": [{"id": "three", "label": "three"}],
- "tail": [{"id": "none", "label": "none"}],
+ "tail": [
+ {"id": "none", "label": "none"},
+ {"id": "bear", "label": "bear"},
+ {"id": "bunny", "label": "bunny"},
+ {"id": "cat", "label": "cat"},
+ {"id": "fox", "label": "fox"},
+ {"id": "gator", "label": "gator"},
+ {"id": "pointy", "label": "pointy"},
+ ],
}
const LEGACY_OPTION_ALIASES: Dictionary = {
"species": {"default": "round"},
"fur_pattern": {"solid": "white"},
+ "fur_style": {"bengal": "spots_bengal"},
"ears": {"default": "none"},
+ "tail": {"default": "none"},
"eyes": {"default": "simple_shine"},
"nose": {"default": "dog_round"},
"mouth": {"default": "three"},
@@ -89,6 +206,7 @@ const LEGACY_OPTION_ALIASES: Dictionary = {
static var _feature_assets_ready: bool = false
static var _feature_options: Dictionary = {}
static var _feature_textures: Dictionary = {}
+static var _fur_pattern_textures: Dictionary = {}
static func default_snapshot() -> Dictionary:
@@ -97,6 +215,10 @@ static func default_snapshot() -> Dictionary:
"species": "round",
"scale": DEFAULT_CHARACTER_SCALE,
"fur_pattern": "white",
+ "fur_style": DEFAULT_FUR_STYLE,
+ "fur_color_2": "cream",
+ "fur_color_3": "brown",
+ "fur_color_4": "red",
"ears": "none",
"eyes": _default_feature_option("eyes", "simple_shine"),
"nose": _default_feature_option("nose", "dog_round"),
@@ -127,6 +249,82 @@ static func options_for(category_id: String) -> Array:
return OPTIONS.get(category_id, [])
+static func feature_option_groups(category_id: String) -> Array:
+ if category_id not in FEATURE_CATEGORIES:
+ return []
+ var options: Array = options_for(category_id)
+ var option_ids: Array[String] = []
+ for option: Dictionary in options:
+ option_ids.append(str(option.get("id", "")))
+ var grouped_options: Dictionary = {}
+ var group_order: Array[String] = []
+ for option: Dictionary in options:
+ var option_id := str(option.get("id", ""))
+ var group_id := _feature_variant_root(option_id, option_ids)
+ if not grouped_options.has(group_id):
+ grouped_options[group_id] = []
+ group_order.append(group_id)
+ var group: Array = grouped_options[group_id] as Array
+ group.append(option)
+ grouped_options[group_id] = group
+ var result: Array = []
+ for group_id: String in group_order:
+ result.append({
+ "id": group_id,
+ "options": grouped_options[group_id],
+ })
+ return result
+
+
+static func _feature_variant_root(
+ option_id: String,
+ option_ids: Array[String],
+) -> String:
+ if option_id == "none":
+ return option_id
+ # Prefer the shortest authored base option. This keeps nested names such as
+ # `beady_extra_shine` in the `beady` drawer rather than creating drawers
+ # inside drawers.
+ var authored_root := ""
+ for candidate_id: String in option_ids:
+ if candidate_id == "none":
+ continue
+ if (
+ option_id != candidate_id
+ and not option_id.begins_with(candidate_id + "_")
+ ):
+ continue
+ var has_descendant := false
+ for descendant_id: String in option_ids:
+ if descendant_id.begins_with(candidate_id + "_"):
+ has_descendant = true
+ break
+ if (
+ has_descendant
+ and (
+ authored_root.is_empty()
+ or candidate_id.length() < authored_root.length()
+ )
+ ):
+ authored_root = candidate_id
+ if not authored_root.is_empty():
+ return authored_root
+
+ # Some families have no unqualified base asset. Group those siblings by
+ # their leading name segment, making the sorted first asset representative.
+ var separator_index := option_id.find("_")
+ if separator_index <= 0:
+ return option_id
+ var leading_segment := option_id.substr(0, separator_index)
+ var sibling_count := 0
+ for candidate_id: String in option_ids:
+ if candidate_id.begins_with(leading_segment + "_"):
+ sibling_count += 1
+ if sibling_count >= 2:
+ return leading_segment
+ return option_id
+
+
static func texture_for(category_id: String, option_id: String) -> Texture2D:
if category_id not in FEATURE_CATEGORIES:
return null
@@ -250,13 +448,41 @@ static func option_color(category_id: String, option_id: String) -> Color:
return Color.WHITE
+static func fur_color_label(category_id: String) -> String:
+ return str(FUR_COLOR_LABELS.get(category_id, category_id))
+
+
+static func fur_pattern_texture(
+ option_id: String,
+ component_id: String = "body_main",
+) -> Texture2D:
+ var canonical_id := canonical_option_id(FUR_STYLE_ID, option_id)
+ if canonical_id == DEFAULT_FUR_STYLE:
+ return null
+ var cache_id := "%s:%s" % [canonical_id, component_id]
+ if _fur_pattern_textures.has(cache_id):
+ return _fur_pattern_textures[cache_id] as Texture2D
+ for option: Dictionary in options_for(FUR_STYLE_ID):
+ if str(option.get("id", "")) != canonical_id:
+ continue
+ var textures := option.get("textures", {}) as Dictionary
+ var resource_path := str(textures.get(component_id, ""))
+ if resource_path.is_empty():
+ return null
+ var texture := ResourceLoader.load(resource_path) as Texture2D
+ if texture != null:
+ _fur_pattern_textures[cache_id] = texture
+ return texture
+ return null
+
+
static func validate_snapshot(value: Variant) -> bool:
if typeof(value) != TYPE_DICTIONARY:
return false
var snapshot: Dictionary = value
- if snapshot.size() != CATEGORY_IDS.size():
+ if snapshot.size() != SNAPSHOT_IDS.size():
return false
- for category_id: String in CATEGORY_IDS:
+ for category_id: String in SNAPSHOT_IDS:
if category_id == SCALE_CATEGORY_ID:
if not is_valid_character_scale(snapshot.get(category_id)):
return false
@@ -274,7 +500,7 @@ static func sanitized_snapshot(value: Variant) -> Dictionary:
if typeof(value) != TYPE_DICTIONARY:
return result
var snapshot: Dictionary = value
- for category_id: String in CATEGORY_IDS:
+ for category_id: String in SNAPSHOT_IDS:
if category_id == SCALE_CATEGORY_ID:
result[category_id] = character_scale(
snapshot.get(category_id, DEFAULT_CHARACTER_SCALE)
diff --git a/progression/player_item_effects.gd b/progression/player_item_effects.gd
index d7542fc..1a73c43 100644
--- a/progression/player_item_effects.gd
+++ b/progression/player_item_effects.gd
@@ -10,6 +10,8 @@ const COFFEE_ID: StringName = &"coffee"
const ENERGY_DRINK_ID: StringName = &"energy_drink"
const SNACK_ID: StringName = &"snack"
const FISH_FINDER_ID: StringName = &"fish_finder"
+const BATTERIES_ID: StringName = &"batteries"
+const FISH_FINDER_DEAD_MESSAGE: String = "hmm... batteries are dead..."
const COFFEE_DURATION: float = 90.0
const ENERGY_DRINK_DURATION: float = 90.0
const SNACK_DURATION: float = 60.0
@@ -45,16 +47,35 @@ func use_consumable(
item: ItemDataType,
bag: PlayerBagType,
) -> bool:
+ return use_item(item, bag)
+
+
+func use_item(
+ item: ItemDataType,
+ bag: PlayerBagType,
+) -> bool:
+ var is_fish_finder: bool = (
+ item != null
+ and item.item_id == FISH_FINDER_ID
+ and item.category == ItemDataType.Category.TOOL
+ and item.equippable
+ )
if (
item == null
or bag == null
- or item.category != ItemDataType.Category.CONSUMABLE
+ or (
+ item.category != ItemDataType.Category.CONSUMABLE
+ and not is_fish_finder
+ )
or not item.usable
or not _remaining.has(item.item_id)
or not bag.owns_item(item.item_id)
):
return false
- if not bag.remove_item(item.item_id, 1):
+ var consumed_item_id: StringName = (
+ BATTERIES_ID if is_fish_finder else item.item_id
+ )
+ if not bag.remove_item(consumed_item_id, 1):
return false
_remaining[item.item_id] = _get_duration(item.item_id)
effects_changed.emit()
diff --git a/project.godot b/project.godot
index 080c9f8..1745ecc 100644
--- a/project.godot
+++ b/project.godot
@@ -11,15 +11,23 @@ config_version=5
[application]
config/name="NETFISHING"
-config/version="0.5.1-prealpha"
+config/version="0.7.1-alpha"
run/main_scene="res://main/main.tscn"
config/features=PackedStringArray("4.7", "GL Compatibility")
-config/icon="res://icon.svg"
+config/icon="res://art/exported/system_icons/netfishing_256.png"
+
+[autoload]
+
+TextureSamplingPolicy="*res://main/texture_sampling_policy.gd"
[display]
window/stretch/aspect="expand"
+[editor_plugins]
+
+enabled=PackedStringArray("res://addons/netfishing_shoreline_baker/plugin.cfg")
+
[gui]
theme/custom="res://ui/game_theme.tres"
@@ -185,6 +193,11 @@ open_emotes={
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
]
}
+character_call={
+"deadzone": 0.2,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":71,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
+]
+}
open_quick_actions={
"deadzone": 0.2,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
@@ -236,6 +249,10 @@ alternate_fishing={
]
}
+[network]
+
+discovery/base_url="https://discovery.netfishing.org"
+
[physics]
3d/physics_engine="Jolt Physics"
diff --git a/save/player_save_manager.gd b/save/player_save_manager.gd
index 9a9a3be..57e355d 100644
--- a/save/player_save_manager.gd
+++ b/save/player_save_manager.gd
@@ -43,6 +43,7 @@ class LoadSnapshot:
var wallet_balance: int = 0
var next_catch_sequence: int = 1
var bag_items: Array[OwnedItemType] = []
+ var unlocked_bait_ids: Array[StringName] = []
var hotbar_slots: Array[StringName] = []
var fish_hotbar_slots: Array[StringName] = []
var selected_hotbar_slot: int = 0
@@ -258,7 +259,10 @@ func load_player_data() -> bool:
var wallet_restored: bool = _wallet.restore_balance(
snapshot.wallet_balance
)
- var bag_restored: bool = _bag.replace_all_items(snapshot.bag_items)
+ var bag_restored: bool = (
+ _bag.replace_all_items(snapshot.bag_items)
+ and _bag.replace_unlocked_bait_ids(snapshot.unlocked_bait_ids)
+ )
var hotbar_restored: bool = _hotbar.replace_state(
snapshot.hotbar_slots,
snapshot.selected_hotbar_slot,
@@ -492,6 +496,12 @@ func _build_save_dictionary() -> Dictionary:
if owned == null or not owned.is_valid():
return {}
serialized_items.append(owned.to_save_dict())
+ var serialized_unlocked_baits: Array[String] = []
+ for item_id: StringName in _bag.get_unlocked_bait_ids():
+ var item_data = _item_catalog.get_item_by_id(item_id)
+ if item_data == null or not item_data.is_valid() or not item_data.is_bait():
+ return {}
+ serialized_unlocked_baits.append(String(item_id))
var serialized_slots: Array[String] = []
for item_id: StringName in _hotbar.get_slots():
serialized_slots.append(String(item_id))
@@ -524,6 +534,7 @@ func _build_save_dictionary() -> Dictionary:
},
"bag": {
"items": serialized_items,
+ "unlocked_bait_ids": serialized_unlocked_baits,
},
"hotbar": {
"selected_slot": _hotbar.get_selected_slot(),
@@ -589,6 +600,10 @@ func _build_load_snapshot(save_data: Dictionary) -> LoadSnapshot:
or typeof(inventory_data.get("catches")) != TYPE_ARRAY
or not inventory_data.has("next_catch_sequence")
or typeof(bag_data.get("items")) != TYPE_ARRAY
+ or (
+ bag_data.has("unlocked_bait_ids")
+ and typeof(bag_data.get("unlocked_bait_ids")) != TYPE_ARRAY
+ )
or typeof(hotbar_data.get("slots")) != TYPE_ARRAY
or not hotbar_data.has("selected_slot")
or not experience_data.has("total_experience")
@@ -781,6 +796,34 @@ func _build_load_snapshot(save_data: Dictionary) -> LoadSnapshot:
seen_items[item_id] = true
snapshot.bag_items.append(owned)
+ var seen_unlocked_baits: Dictionary[StringName, bool] = {}
+ if bag_data.has("unlocked_bait_ids"):
+ var unlocked_bait_values: Array = bag_data["unlocked_bait_ids"]
+ for value: Variant in unlocked_bait_values:
+ if typeof(value) not in [TYPE_STRING, TYPE_STRING_NAME]:
+ continue
+ var bait_id: StringName = StringName(str(value))
+ var bait_data = _item_catalog.get_item_by_id(bait_id)
+ if (
+ bait_id.is_empty()
+ or seen_unlocked_baits.has(bait_id)
+ or bait_data == null
+ or not bait_data.is_valid()
+ or not bait_data.is_bait()
+ ):
+ continue
+ seen_unlocked_baits[bait_id] = true
+ snapshot.unlocked_bait_ids.append(bait_id)
+ for owned: OwnedItemType in snapshot.bag_items:
+ var owned_item_data = _item_catalog.get_item_by_id(owned.item_id)
+ if (
+ owned_item_data != null
+ and owned_item_data.is_bait()
+ and not seen_unlocked_baits.has(owned.item_id)
+ ):
+ seen_unlocked_baits[owned.item_id] = true
+ snapshot.unlocked_bait_ids.append(owned.item_id)
+
var slot_values: Array = hotbar_data["slots"]
snapshot.hotbar_slots.resize(PlayerHotbarType.SLOT_COUNT)
snapshot.hotbar_slots.fill(StringName())
@@ -1098,6 +1141,8 @@ func _restore_defaults() -> void:
)
_wallet.restore_balance(0)
_bag.replace_all_items(default_items)
+ var default_unlocked_baits: Array[StringName] = []
+ _bag.replace_unlocked_bait_ids(default_unlocked_baits)
_hotbar.replace_state(default_slots, 0)
_fishing_upgrades.reset_to_defaults()
_cooler_capacity.reset_to_defaults()
diff --git a/scripts/build_playtest.sh b/scripts/build_playtest.sh
index e984de3..7749b3d 100755
--- a/scripts/build_playtest.sh
+++ b/scripts/build_playtest.sh
@@ -4,12 +4,14 @@ set -euo pipefail
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
-readonly BUILD_ROOT="${PROJECT_ROOT}/builds/v0.5.1-prealpha"
+readonly BUILD_ROOT="${PROJECT_ROOT}/builds/v0.7.1-alpha"
readonly WINDOWS_DIR="${BUILD_ROOT}/windows-x86_64"
readonly LINUX_DIR="${BUILD_ROOT}/linux-x86_64"
-readonly README_SOURCE="${PROJECT_ROOT}/playtest/README-PLAYTEST.txt"
-readonly WINDOWS_ZIP="${BUILD_ROOT}/NETfishing-v0.5.1-prealpha-windows-x86_64.zip"
-readonly LINUX_ZIP="${BUILD_ROOT}/NETfishing-v0.5.1-prealpha-linux-x86_64.zip"
+readonly README_SOURCE="${PROJECT_ROOT}/docs/README-PLAYTEST.txt"
+readonly SOURCE_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse HEAD)"
+readonly SOURCE_URL="https://forge.makearmy.io/woofmeow/netfishing"
+readonly WINDOWS_ZIP="${BUILD_ROOT}/NETfishing-v0.7.1-alpha-windows-x86_64.zip"
+readonly LINUX_ZIP="${BUILD_ROOT}/NETfishing-v0.7.1-alpha-linux-x86_64.zip"
readonly GODOT_BIN="${GODOT_BIN:-godot}"
if [[ ! -f "${PROJECT_ROOT}/project.godot" ]]; then
@@ -52,6 +54,38 @@ chmod +x -- "${LINUX_DIR}/NETfishing.x86_64"
cp -- "${README_SOURCE}" "${WINDOWS_DIR}/README-PLAYTEST.txt"
cp -- "${README_SOURCE}" "${LINUX_DIR}/README-PLAYTEST.txt"
+stage_licenses() {
+ local destination="$1/licenses"
+ mkdir -p -- "${destination}"
+ install -m 0644 "${PROJECT_ROOT}/LICENSE" \
+ "${destination}/GPL-3.0-or-later.txt"
+ install -m 0644 "${PROJECT_ROOT}/ASSET-LICENSE.md" \
+ "${destination}/NETFISHING-ASSET-LICENSE.md"
+ install -m 0644 "${PROJECT_ROOT}/docs/ATTRIBUTION.md" \
+ "${destination}/ATTRIBUTION.md"
+ install -m 0644 "${PROJECT_ROOT}/TRADEMARKS.md" \
+ "${destination}/TRADEMARKS.md"
+ install -m 0644 "${PROJECT_ROOT}/ui/fonts/Tuffy-LICENSE.txt" \
+ "${destination}/Tuffy-LICENSE.txt"
+ install -m 0644 "${PROJECT_ROOT}/ui/fonts/Seattle-Avenue-LICENSE.txt" \
+ "${destination}/Seattle-Avenue-LICENSE.txt"
+ cat >"${destination}/SOURCE-CODE.md" <&2
+ exit 2
+fi
+
+readonly PROJECT_VERSION="$(
+ sed -n 's/^config\/version="\([^"]*\)"/\1/p' "${PROJECT_ROOT}/project.godot"
+)"
+if [[ -z "${PROJECT_VERSION}" ]]; then
+ echo "Could not read application/config/version from project.godot." >&2
+ exit 1
+fi
+
+readonly RELEASE_TAG="v${PROJECT_VERSION}"
+readonly RELEASE_ROOT="${PROJECT_ROOT}/builds/${RELEASE_TAG}"
+readonly ARM64_ROOT="${RELEASE_ROOT}/linux-arm64"
+readonly ARM64_EXECUTABLE="${ARM64_ROOT}/NETfishing.arm64"
+readonly ARM64_PCK="${ARM64_ROOT}/NETfishing.pck"
+readonly STAGE_ROOT="${RELEASE_ROOT}/portmaster-stage"
+readonly GAME_ROOT="${STAGE_ROOT}/netfishing"
+readonly ARCHIVE="${RELEASE_ROOT}/netfishing.zip"
+readonly LEGACY_ARCHIVE="${RELEASE_ROOT}/netfishing-${RELEASE_TAG}-portmaster-arm64.zip"
+
+readonly HEAD_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse HEAD)"
+readonly TAG_COMMIT="$(git -C "${PROJECT_ROOT}" rev-parse "${RELEASE_TAG}^{commit}")"
+if [[ "${HEAD_COMMIT}" != "${TAG_COMMIT}" ]]; then
+ echo "HEAD does not match ${RELEASE_TAG}. Refusing to package mutable source." >&2
+ exit 1
+fi
+if [[ "${NETFISHING_ALLOW_DIRTY_RELEASE:-0}" != "1" ]]; then
+ dirty_tree=0
+ git -C "${PROJECT_ROOT}" diff --quiet || dirty_tree=1
+ git -C "${PROJECT_ROOT}" diff --cached --quiet || dirty_tree=1
+ if [[ -n "$(git -C "${PROJECT_ROOT}" status --porcelain --untracked-files=normal)" ]]; then
+ dirty_tree=1
+ fi
+ if [[ ${dirty_tree} -ne 0 ]]; then
+ echo "The repository is not clean. Refusing to build a release package." >&2
+ exit 1
+ fi
+fi
+
+for command_name in git file zip unzip sha256sum; do
+ command -v "${command_name}" >/dev/null 2>&1 || {
+ echo "Required command not found: ${command_name}" >&2
+ exit 1
+ }
+done
+
+mkdir -p -- "${ARM64_ROOT}" "${RELEASE_ROOT}"
+if [[ ${PACKAGE_ONLY} -eq 0 ]]; then
+ rm -f -- "${ARM64_EXECUTABLE}" "${ARM64_PCK}"
+ "${GODOT_BIN}" \
+ --headless \
+ --path "${PROJECT_ROOT}" \
+ --export-release "Linux ARM64"
+fi
+
+test -s "${ARM64_EXECUTABLE}"
+test -s "${ARM64_PCK}"
+file "${ARM64_EXECUTABLE}" | grep -q "ARM aarch64"
+
+rm -rf -- "${STAGE_ROOT}"
+rm -f -- "${ARCHIVE}" "${LEGACY_ARCHIVE}"
+mkdir -p -- "${GAME_ROOT}/licenses"
+
+install -m 0755 "${TEMPLATE_ROOT}/NETfishing.sh" "${STAGE_ROOT}/NETfishing.sh"
+install -m 0644 "${TEMPLATE_ROOT}/port.json" "${STAGE_ROOT}/port.json"
+install -m 0755 "${ARM64_EXECUTABLE}" "${GAME_ROOT}/NETfishing.aarch64"
+install -m 0644 "${ARM64_PCK}" "${GAME_ROOT}/NETfishing.pck"
+install -m 0644 "${TEMPLATE_ROOT}/gameinfo.xml" "${GAME_ROOT}/gameinfo.xml"
+install -m 0644 "${TEMPLATE_ROOT}/screenshot.png" "${GAME_ROOT}/screenshot.png"
+install -m 0644 \
+ "${PROJECT_ROOT}/docs/ATTRIBUTION.md" \
+ "${GAME_ROOT}/licenses/ATTRIBUTION.md"
+install -m 0644 \
+ "${PROJECT_ROOT}/LICENSE" \
+ "${GAME_ROOT}/licenses/GPL-3.0-or-later.txt"
+install -m 0644 \
+ "${PROJECT_ROOT}/ASSET-LICENSE.md" \
+ "${GAME_ROOT}/licenses/NETFISHING-ASSET-LICENSE.md"
+install -m 0644 \
+ "${PROJECT_ROOT}/TRADEMARKS.md" \
+ "${GAME_ROOT}/licenses/TRADEMARKS.md"
+install -m 0644 \
+ "${PROJECT_ROOT}/ui/fonts/Tuffy-LICENSE.txt" \
+ "${GAME_ROOT}/licenses/Tuffy-LICENSE.txt"
+install -m 0644 \
+ "${PROJECT_ROOT}/ui/fonts/Seattle-Avenue-LICENSE.txt" \
+ "${GAME_ROOT}/licenses/Seattle-Avenue-LICENSE.txt"
+
+cat >"${GAME_ROOT}/BUILD-INFO.txt" <"${GAME_ROOT}/licenses/SOURCE-CODE.md" <"${GAME_ROOT}/README.md" </dev/null
+readonly TOP_LEVELS="$(
+ unzip -Z1 "${ARCHIVE}" | cut -d/ -f1 | sort -u
+)"
+readonly EXPECTED_TOP_LEVELS="$(printf '%s\n' NETfishing.sh netfishing port.json)"
+if [[ "${TOP_LEVELS}" != "${EXPECTED_TOP_LEVELS}" ]]; then
+ echo "Unexpected PortMaster archive roots:" >&2
+ printf '%s\n' "${TOP_LEVELS}" >&2
+ exit 1
+fi
+grep -q '"version": 4' "${STAGE_ROOT}/port.json"
+grep -q '"name": "netfishing.zip"' "${STAGE_ROOT}/port.json"
+grep -q '^# PORTMASTER: netfishing.zip, NETfishing.sh$' \
+ "${STAGE_ROOT}/NETfishing.sh"
+if grep -q 'GPTOKEYB' "${STAGE_ROOT}/NETfishing.sh"; then
+ echo "GPTOKEYB must not be enabled for NETfishing." >&2
+ exit 1
+fi
+if unzip -Z1 "${ARCHIVE}" | grep -E \
+ '(^|/)(conf|\.git|\.godot|logs?|saves?|identities?)(/|$)|\.(gd|tscn|blend)$' \
+ >/dev/null; then
+ echo "The PortMaster archive contains prohibited release content." >&2
+ exit 1
+fi
+
+sha256sum "${ARCHIVE}"
+echo "PortMaster package created at ${ARCHIVE}"
diff --git a/scripts/generate_placeholder_animalese.gd b/scripts/generate_placeholder_animalese.gd
new file mode 100644
index 0000000..8119fd3
--- /dev/null
+++ b/scripts/generate_placeholder_animalese.gd
@@ -0,0 +1,71 @@
+extends SceneTree
+
+const OUTPUT_DIRECTORY := "res://sound/dialogue/animalese/placeholder"
+const SAMPLE_RATE: int = 22050
+const SAMPLE_SECONDS: float = 0.055
+const CHARACTERS := "abcdefghijklmnopqrstuvwxyz"
+const VOWELS := "aeiou"
+
+
+func _initialize() -> void:
+ var absolute_directory := ProjectSettings.globalize_path(OUTPUT_DIRECTORY)
+ var directory_error: Error = DirAccess.make_dir_recursive_absolute(
+ absolute_directory
+ )
+ if directory_error != OK:
+ push_error("Could not create animalese sample directory.")
+ quit(1)
+ return
+ for character_index: int in range(CHARACTERS.length()):
+ var character := CHARACTERS.substr(character_index, 1)
+ _save_sample(character, character_index)
+ _save_sample("fallback", CHARACTERS.length())
+ quit()
+
+
+func _save_sample(sample_name: String, sample_index: int) -> void:
+ var stream := _build_sample(sample_name, sample_index)
+ var output_path := "%s/%s" % [OUTPUT_DIRECTORY, sample_name]
+ var save_error: Error = stream.save_to_wav(output_path)
+ if save_error != OK:
+ push_error("Could not save animalese sample: %s" % sample_name)
+
+
+func _build_sample(sample_name: String, sample_index: int) -> AudioStreamWAV:
+ var frame_count := roundi(SAMPLE_RATE * SAMPLE_SECONDS)
+ var pcm := PackedByteArray()
+ pcm.resize(frame_count * 2)
+ var base_frequency := 245.0 + float(sample_index % 7) * 18.0
+ var formant_one := 620.0 + float(sample_index % 5) * 85.0
+ var formant_two := 1320.0 + float(sample_index % 6) * 115.0
+ var is_vowel := VOWELS.contains(sample_name)
+ var noise_seed := sample_index * 7919 + 104729
+ for frame_index: int in range(frame_count):
+ var time := float(frame_index) / SAMPLE_RATE
+ var attack := minf(time / 0.004, 1.0)
+ var release := minf((SAMPLE_SECONDS - time) / 0.014, 1.0)
+ var envelope := maxf(minf(attack, release), 0.0)
+ noise_seed = int(
+ (noise_seed * 1103515245 + 12345) & 0x7fffffff
+ )
+ var noise := float(noise_seed % 65536) / 32767.5 - 1.0
+ var voiced := (
+ sin(TAU * base_frequency * time) * 0.42
+ + sin(TAU * base_frequency * 2.0 * time) * 0.16
+ )
+ var formants := (
+ sin(TAU * formant_one * time) * 0.18
+ + sin(TAU * formant_two * time) * 0.10
+ )
+ var consonant_noise := noise * (0.08 if is_vowel else 0.24)
+ var value := envelope * (voiced + formants + consonant_noise) * 0.72
+ var signed_sample := clampi(roundi(value * 32767.0), -32768, 32767)
+ var encoded_sample := signed_sample if signed_sample >= 0 else signed_sample + 65536
+ pcm[frame_index * 2] = encoded_sample & 0xff
+ pcm[frame_index * 2 + 1] = (encoded_sample >> 8) & 0xff
+ var stream := AudioStreamWAV.new()
+ stream.set("format", AudioStreamWAV.FORMAT_16_BITS)
+ stream.mix_rate = SAMPLE_RATE
+ stream.stereo = false
+ stream.data = pcm
+ return stream
diff --git a/scripts/generate_placeholder_animalese.gd.uid b/scripts/generate_placeholder_animalese.gd.uid
new file mode 100644
index 0000000..9399a64
--- /dev/null
+++ b/scripts/generate_placeholder_animalese.gd.uid
@@ -0,0 +1 @@
+uid://cwqm75icgcr4u
diff --git a/scripts/normalize_texture_imports.gd b/scripts/normalize_texture_imports.gd
new file mode 100644
index 0000000..ae36fa0
--- /dev/null
+++ b/scripts/normalize_texture_imports.gd
@@ -0,0 +1,204 @@
+extends SceneTree
+
+const DEFAULT_PROFILE: Dictionary = {
+ "params": {
+ "compress/mode": 2,
+ "compress/high_quality": false,
+ "compress/lossy_quality": 0.7,
+ "compress/uastc_level": 0,
+ "compress/rdo_quality_loss": 0.0,
+ "compress/hdr_compression": 1,
+ "compress/normal_map": 0,
+ "compress/channel_pack": 0,
+ "mipmaps/generate": false,
+ "mipmaps/limit": -1,
+ "roughness/mode": 0,
+ "roughness/src_normal": "",
+ "process/channel_remap/red": 0,
+ "process/channel_remap/green": 1,
+ "process/channel_remap/blue": 2,
+ "process/channel_remap/alpha": 3,
+ "process/fix_alpha_border": true,
+ "process/premult_alpha": false,
+ "process/normal_map_invert_y": false,
+ "process/hdr_as_srgb": false,
+ "process/hdr_clamp_exposure": false,
+ "process/size_limit": 0,
+ "detect_3d/compress_to": 0,
+ },
+}
+
+var apply_changes: bool = false
+var verbose: bool = false
+var roots: PackedStringArray = PackedStringArray()
+var should_exit: bool = false
+
+var errors: int = 0
+var skipped_non_texture: int = 0
+var updated: int = 0
+var unchanged: int = 0
+
+func _initialize() -> void:
+ _parse_args()
+ if should_exit:
+ return
+ if roots.is_empty():
+ printerr("At least one --root path is required.")
+ quit(2)
+ return
+
+ for root: String in roots:
+ var normalized_root := root
+ if not normalized_root.ends_with("/"):
+ normalized_root += "/"
+ if not normalized_root.begins_with("res://") and not normalized_root.is_absolute_path():
+ if normalized_root.begins_with("./"):
+ normalized_root = "res://%s" % normalized_root.trim_prefix("./")
+ else:
+ normalized_root = "res://%s" % normalized_root
+ _print("Scanning %s" % normalized_root)
+ _scan_directory(normalized_root)
+
+ print_summary()
+ quit(1 if errors > 0 else 0)
+
+
+func _parse_args() -> void:
+ var args := OS.get_cmdline_user_args()
+ var i := 0
+ while i < args.size():
+ var arg := args[i]
+ if arg == "--help" or arg == "-h":
+ _print_usage()
+ should_exit = true
+ quit(0)
+ return
+ elif arg == "--apply":
+ apply_changes = true
+ i += 1
+ elif arg == "--verbose" or arg == "-v":
+ verbose = true
+ i += 1
+ elif arg == "--root":
+ if i + 1 >= args.size():
+ printerr("--root requires a path value")
+ should_exit = true
+ quit(1)
+ return
+ i += 1
+ roots.append(args[i])
+ i += 1
+ elif arg.begins_with("--root="):
+ roots.append(arg.trim_prefix("--root="))
+ i += 1
+ else:
+ printerr("Unknown argument: ", arg)
+ should_exit = true
+ quit(2)
+ return
+
+
+func _scan_directory(path: String) -> void:
+ var dir := DirAccess.open(path)
+ if dir == null:
+ printerr("Failed to open root: ", path)
+ errors += 1
+ return
+
+ dir.list_dir_begin()
+ while true:
+ var name := dir.get_next()
+ if name.is_empty():
+ break
+ if name == "." or name == "..":
+ continue
+ if name == ".godot":
+ continue
+
+ var candidate := path.path_join(name)
+ if dir.current_is_dir():
+ _scan_directory(candidate)
+ continue
+
+ if name.get_extension().to_lower() != "import":
+ continue
+
+ _handle_import_file(candidate)
+
+
+func _handle_import_file(import_path: String) -> void:
+ var cfg := ConfigFile.new()
+ var err := cfg.load(import_path)
+ if err != OK:
+ printerr("Could not load import settings: ", import_path, " (", err, ")")
+ errors += 1
+ return
+
+ if not cfg.has_section("remap") or not cfg.has_section_key("remap", "importer"):
+ skipped_non_texture += 1
+ return
+
+ if str(cfg.get_value("remap", "importer")) != "texture":
+ skipped_non_texture += 1
+ return
+
+ var changed := false
+ for section_name: String in DEFAULT_PROFILE.keys():
+ var section_data: Dictionary = DEFAULT_PROFILE[section_name]
+ for section_key: String in section_data.keys():
+ var desired: Variant = section_data[section_key]
+ var existing: Variant = null
+ if cfg.has_section(section_name) and cfg.has_section_key(section_name, section_key):
+ existing = cfg.get_value(section_name, section_key)
+ if existing != desired:
+ cfg.set_value(section_name, section_key, desired)
+ changed = true
+
+ if not changed:
+ unchanged += 1
+ if verbose:
+ _print("Unchanged: %s" % import_path)
+ return
+
+ if apply_changes:
+ err = cfg.save(import_path)
+ if err != OK:
+ printerr("Could not save import settings: ", import_path, " (", err, ")")
+ errors += 1
+ return
+ if verbose:
+ _print("Updated: %s" % import_path)
+ else:
+ _print("Would update: %s" % import_path)
+
+ updated += 1
+
+
+func print_summary() -> void:
+ if apply_changes:
+ _print(
+ "Texture import normalization complete: "
+ + "updated=%d unchanged=%d skipped_non_texture=%d errors=%d"
+ % [updated, unchanged, skipped_non_texture, errors]
+ )
+ else:
+ _print(
+ "Dry-run complete: "
+ + "would-update=%d unchanged=%d skipped_non_texture=%d errors=%d"
+ % [updated, unchanged, skipped_non_texture, errors]
+ )
+ _print("Pass --apply to write normalized settings into .import files.")
+
+
+func _print(msg: String) -> void:
+ print(msg)
+
+
+func _print_usage() -> void:
+ print("Usage:")
+ print(" godot --headless --path . --script scripts/normalize_texture_imports.gd [--apply] [--verbose] [--root ] [--root=] [--help]")
+ print()
+ print("Defaults:")
+ print("- Dry-run only unless --apply is provided")
+ print("- Requires at least one explicit --root path")
+ print("- Skips .godot")
diff --git a/scripts/normalize_texture_imports.gd.uid b/scripts/normalize_texture_imports.gd.uid
new file mode 100644
index 0000000..d2006e5
--- /dev/null
+++ b/scripts/normalize_texture_imports.gd.uid
@@ -0,0 +1 @@
+uid://b24mlapvqxj5a
diff --git a/scripts/normalize_texture_profiles.sh b/scripts/normalize_texture_profiles.sh
new file mode 100755
index 0000000..1483a61
--- /dev/null
+++ b/scripts/normalize_texture_profiles.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
+readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
+readonly GODOT_BIN="${GODOT_BIN:-godot}"
+
+if [[ $# -ne 1 ]]; then
+ echo "usage: scripts/normalize_texture_profiles.sh res://path/to/textures" >&2
+ exit 2
+fi
+
+readonly ROOT_PATH="$1"
+
+readonly WORK_ROOT="$(mktemp -d -t netfishing-godot-data.XXXXXX)"
+trap 'rm -rf -- "${WORK_ROOT}"' EXIT
+
+cd "${PROJECT_ROOT}"
+
+export XDG_DATA_HOME="${WORK_ROOT}/data"
+export XDG_CONFIG_HOME="${WORK_ROOT}/config"
+export XDG_CACHE_HOME="${WORK_ROOT}/cache"
+
+"${GODOT_BIN}" --headless --path . \
+ --script scripts/normalize_texture_imports.gd -- --apply --root "${ROOT_PATH}"
+
+# Synchronize Godot-generated remap and destination metadata with the updated
+# import parameters before the caller reviews or commits the sidecars.
+"${GODOT_BIN}" --headless --path . --import
diff --git a/scripts/portmaster/NETfishing.sh b/scripts/portmaster/NETfishing.sh
new file mode 100755
index 0000000..58fbfbd
--- /dev/null
+++ b/scripts/portmaster/NETfishing.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+# PORTMASTER: netfishing.zip, NETfishing.sh
+
+XDG_DATA_HOME=${XDG_DATA_HOME:-$HOME/.local/share}
+
+if [ -d "/opt/system/Tools/PortMaster/" ]; then
+ controlfolder="/opt/system/Tools/PortMaster"
+elif [ -d "/opt/tools/PortMaster/" ]; then
+ controlfolder="/opt/tools/PortMaster"
+elif [ -d "$XDG_DATA_HOME/PortMaster/" ]; then
+ controlfolder="$XDG_DATA_HOME/PortMaster"
+else
+ controlfolder="/roms/ports/PortMaster"
+fi
+
+if [ ! -f "$controlfolder/control.txt" ]; then
+ echo "PortMaster control.txt was not found at $controlfolder" >&2
+ exit 1
+fi
+
+source "$controlfolder/control.txt"
+[ -f "${controlfolder}/mod_${CFW_NAME}.txt" ] && source "${controlfolder}/mod_${CFW_NAME}.txt"
+get_controls
+
+GAMEDIR="/${directory}/ports/netfishing"
+if [ ! -d "$GAMEDIR" ] && [ -d "/mnt/mmc/ports/netfishing" ]; then
+ GAMEDIR="/mnt/mmc/ports/netfishing"
+fi
+
+CONFDIR="$GAMEDIR/conf"
+GAME_EXECUTABLE="$GAMEDIR/NETfishing.aarch64"
+WESTON_DIR="/tmp/netfishing-weston"
+WESTON_RUNTIME="weston_pkg_0.2"
+HARBOURMASTER="$controlfolder/harbourmaster"
+if [ ! -x "$HARBOURMASTER" ] && [ -x "/mnt/mmc/MUOS/PortMaster/harbourmaster" ]; then
+ HARBOURMASTER="/mnt/mmc/MUOS/PortMaster/harbourmaster"
+fi
+
+mkdir -p "$CONFDIR/data" "$CONFDIR/config" "$CONFDIR/cache" "$WESTON_DIR"
+chmod +x "$GAME_EXECUTABLE"
+
+> "$GAMEDIR/log.txt" && exec > >(tee "$GAMEDIR/log.txt") 2>&1
+
+if [ ! -f "$controlfolder/libs/${WESTON_RUNTIME}.squashfs" ]; then
+ if [ ! -x "$HARBOURMASTER" ]; then
+ pm_message "NETfishing requires the latest PortMaster and WestonPack runtime."
+ sleep 5
+ exit 1
+ fi
+ $ESUDO "$HARBOURMASTER" --quiet --no-check runtime_check "${WESTON_RUNTIME}.squashfs"
+fi
+
+if [ ! -f "$controlfolder/libs/${WESTON_RUNTIME}.squashfs" ]; then
+ pm_message "WestonPack could not be installed. Check the network connection and PortMaster runtime manager."
+ sleep 5
+ exit 1
+fi
+
+if [[ "$PM_CAN_MOUNT" != "N" ]]; then
+ $ESUDO umount "$WESTON_DIR" 2>/dev/null
+fi
+$ESUDO mount "$controlfolder/libs/${WESTON_RUNTIME}.squashfs" "$WESTON_DIR"
+
+cd "$GAMEDIR" || exit 1
+
+# Godot 4.7 identifies the muOS H700 virtual controller with a CRC-bearing
+# GUID and numbers its buttons without the volume keys exposed by SDL2. The
+# PortMaster SDL2 database entry therefore cannot drive Godot's gamepad layer.
+GODOT_MUOS_MAPPING="19004ca6010000000100000000010000,muOS-Keys,a:b0,b:b1,x:b3,y:b2,leftshoulder:b4,rightshoulder:b5,lefttrigger:b10,righttrigger:b11,guide:b8,start:b7,back:b6,dpup:h0.1,dpleft:h0.8,dpright:h0.2,dpdown:h0.4,leftx:a0,lefty:a1,leftstick:b9,rightx:a2,righty:a3,rightstick:b12,platform:Linux,"
+MUOS_SDL2_GUID="19000000010000000100000000010000"
+if [[ "$sdl_controllerconfig" == "${MUOS_SDL2_GUID},"* ]]; then
+ netfishing_controllerconfig="$GODOT_MUOS_MAPPING"
+elif [ -n "$sdl_controllerconfig" ]; then
+ netfishing_controllerconfig="$sdl_controllerconfig"
+else
+ netfishing_controllerconfig="$GODOT_MUOS_MAPPING"
+fi
+
+NETFISHING_GODOT_OPTIONS=()
+NETFISHING_GAME_ENVIRONMENT=()
+DEVICE_COMPATIBILITY=""
+if [[ -r /proc/device-tree/compatible ]]; then
+ DEVICE_COMPATIBILITY="$(tr '\0' ' ' /dev/null
+fi
+pm_finish
diff --git a/scripts/portmaster/gameinfo.xml b/scripts/portmaster/gameinfo.xml
new file mode 100755
index 0000000..ef608bd
--- /dev/null
+++ b/scripts/portmaster/gameinfo.xml
@@ -0,0 +1,13 @@
+
+
+
+ ./NETfishing.sh
+ NETfishing
+ A relaxed multiplayer fishing game about exploring a small island, catching and collecting fish, customizing your character, and spending time by the water.
+ 20260804T000000
+ NETfishing project
+ Independent
+ adventure, simulation
+ ./netfishing/screenshot.png
+
+
diff --git a/scripts/portmaster/port.json b/scripts/portmaster/port.json
new file mode 100644
index 0000000..98df160
--- /dev/null
+++ b/scripts/portmaster/port.json
@@ -0,0 +1,38 @@
+{
+ "version": 4,
+ "name": "netfishing.zip",
+ "items": [
+ "NETfishing.sh",
+ "netfishing/"
+ ],
+ "items_opt": null,
+ "attr": {
+ "title": "NETfishing",
+ "porter": [
+ "Voyager"
+ ],
+ "desc": "A relaxed multiplayer fishing game about exploring a small island, catching and collecting fish, customizing your character, and spending time by the water.",
+ "desc_md": null,
+ "inst": "Ready to run on supported ARM64 PortMaster devices. This alpha package requires two analog sticks.",
+ "inst_md": null,
+ "genres": [
+ "adventure",
+ "simulation"
+ ],
+ "image": {},
+ "rtr": false,
+ "exp": false,
+ "runtime": [
+ "weston_pkg_0.2.squashfs"
+ ],
+ "store": [],
+ "availability": "full",
+ "reqs": [
+ "analog_2"
+ ],
+ "arch": [
+ "aarch64"
+ ],
+ "min_glibc": "2.28"
+ }
+}
diff --git a/scripts/portmaster/screenshot.png b/scripts/portmaster/screenshot.png
new file mode 100755
index 0000000..4fe8f2e
Binary files /dev/null and b/scripts/portmaster/screenshot.png differ
diff --git a/scripts/portmaster/screenshot.png.import b/scripts/portmaster/screenshot.png.import
new file mode 100644
index 0000000..3aa5f2d
--- /dev/null
+++ b/scripts/portmaster/screenshot.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ww0w8iubiwsf"
+path="res://.godot/imported/screenshot.png-6eed5589b80ced9ab24aed11cadf34f5.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://scripts/portmaster/screenshot.png"
+dest_files=["res://.godot/imported/screenshot.png-6eed5589b80ced9ab24aed11cadf34f5.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/scripts/run_validations.sh b/scripts/run_validations.sh
index 1fa7312..7ae8929 100755
--- a/scripts/run_validations.sh
+++ b/scripts/run_validations.sh
@@ -10,15 +10,19 @@ readonly RUN_ROOT="$(mktemp -d -t netfishing-validations.XXXXXX)"
readonly -a QUICK_TESTS=(
"tests/android_readiness_validation.gd"
+ "tests/dedicated_server_config_validation.gd"
"tests/fish_catalog_content_validation.gd"
"tests/fish_quality_validation.gd"
"tests/fishing_audio_validation.gd"
"tests/fishing_surface_validation.gd"
+ "tests/fur_pattern_validation.gd"
"tests/logbook_validation.gd"
+ "tests/network_player_animation_protocol_validation.gd"
"tests/player_experience_validation.gd"
"tests/shoreline_ambience_validation.gd"
"tests/surface_drawing_validation.gd"
- "tests/terrain_projection_validation.gd"
+ "tests/terrain_blender_material_validation.gd"
+ "tests/texture_sampling_validation.gd"
"tests/world_time_validation.gd"
"tests/world_weather_validation.gd"
)
@@ -27,11 +31,13 @@ readonly -a RUNTIME_TESTS=(
"tests/inventory_notepad_art_validation.gd"
"tests/logbook_runtime_validation.gd"
"tests/player_experience_ui_validation.gd"
+ "tests/title_credits_validation.gd"
"tests/ui_scaling_runtime_validation.gd"
)
readonly -a HOST_TESTS=(
"tests/art_tools_validation.gd"
+ "tests/dedicated_host_session_validation.gd"
"tests/economy_regression_validation.gd"
"tests/fish_hotbar_showcase_validation.gd"
"tests/fishing_authority_validation.gd"
@@ -44,6 +50,8 @@ readonly -a NETWORK_TESTS=(
"tests/fish_showcase_multiplayer_validation.gd"
"tests/fishing_multiplayer_validation.gd"
"tests/job_multiplayer_validation.gd"
+ "tests/movement_multiplayer_validation.gd"
+ "tests/operator_multiplayer_validation.gd"
"tests/surface_drawing_multiplayer_validation.gd"
"tests/world_time_multiplayer_validation.gd"
)
@@ -78,6 +86,37 @@ run_test() {
--headless --path "${PROJECT_ROOT}" --script "${script}"
}
+
+wait_for_network_host() {
+ local script="$1"
+ local host_pid="$2"
+ local test_port="7777"
+ local declared_port
+ declared_port="$(
+ sed -n -E \
+ 's/^const TEST_PORT(: int)? = ([0-9]+)$/\2/p' \
+ "${PROJECT_ROOT}/${script}"
+ )"
+ if [[ -n "${declared_port}" ]]; then
+ test_port="${declared_port}"
+ fi
+ if ! command -v ss >/dev/null 2>&1; then
+ sleep 2
+ return 0
+ fi
+ for _attempt in {1..100}; do
+ if ! kill -0 "${host_pid}" 2>/dev/null; then
+ return 1
+ fi
+ if ss -H -lun "sport = :${test_port}" | grep -q .; then
+ return 0
+ fi
+ sleep 0.1
+ done
+ return 1
+}
+
+
run_network_test() {
local script="$1"
local name="${script#tests/}"
@@ -93,7 +132,17 @@ run_network_test() {
--headless --path "${PROJECT_ROOT}" --script "${script}" -- host \
>"${host_root}/output.log" 2>&1 &
host_pid=$!
- sleep 0.75
+ if ! wait_for_network_host "${script}" "${host_pid}"; then
+ set +e
+ wait "${host_pid}"
+ host_status=$?
+ set -e
+ printf '%s\n' '-- host output --'
+ sed -n '1,240p' "${host_root}/output.log"
+ printf 'error: host did not become ready (exit %d)\n' \
+ "${host_status}" >&2
+ return 1
+ fi
set +e
XDG_DATA_HOME="${client_root}/data" \
XDG_CONFIG_HOME="${client_root}/config" \
diff --git a/scripts/setup_android_build.sh b/scripts/setup_android_build.sh
new file mode 100755
index 0000000..c1cebdc
--- /dev/null
+++ b/scripts/setup_android_build.sh
@@ -0,0 +1,394 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ANDROID_HOME="${ANDROID_HOME:-${HOME}/Android/Sdk}"
+JAVA_HOME="${JAVA_HOME:-}"
+INSTALL=0
+AUTO=0
+CMDLINE_TOOLS_ZIP="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip"
+SDK_VERSION="33"
+BUILDTOOLS_VERSION="34.0.0"
+
+usage() {
+ cat <&2
+ usage
+ exit 2 ;;
+ esac
+done
+
+PROJECT_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
+GODOT="${GODOT_BIN:-godot}"
+PROJECT_VERSION="$(
+ sed -n 's/^config\/version="\([^"]*\)"/\1/p' "${PROJECT_ROOT}/project.godot"
+)"
+MISSING=0
+
+print_status() { printf '%s %s\n' "[$1]" "$2"; }
+
+check_dir() {
+ local path="$1" label="$2"
+ if [[ -d "$path" ]]; then
+ print_status OK "${label}: ${path}"
+ else
+ print_status ERR "Missing ${label}: ${path}"
+ MISSING=$((MISSING+1))
+ fi
+}
+
+check_file() {
+ local path="$1" label="$2"
+ if [[ -x "$path" ]]; then
+ print_status OK "${label}: ${path}"
+ else
+ print_status ERR "Missing ${label}: ${path}"
+ MISSING=$((MISSING+1))
+ fi
+}
+
+resolve_java_home() {
+ local candidate=""
+ if [[ -n "$JAVA_HOME" && -x "$JAVA_HOME/bin/java" ]]; then
+ return 0
+ fi
+
+ if command -v java >/dev/null 2>&1; then
+ candidate="$(readlink -f "$(command -v java)")"
+ candidate="$(dirname "$(dirname "$candidate")")"
+ if [[ -x "$candidate/bin/java" ]]; then
+ JAVA_HOME="$candidate"
+ return 0
+ fi
+ fi
+
+ # Common Ubuntu/Debian/JDK locations
+ for p in \
+ /usr/lib/jvm/default-java \
+ /usr/lib/jvm/java-17-openjdk-amd64 \
+ /usr/lib/jvm/java-17-openjdk \
+ /usr/lib/jvm/jdk-17* \
+ /usr/lib/jvm/temurin-17*;
+ do
+ if [[ -e $p && -x "$p/bin/java" ]]; then
+ JAVA_HOME="$p"
+ return 0
+ fi
+ done
+ return 1
+}
+
+check_java() {
+ if resolve_java_home && [[ -x "$JAVA_HOME/bin/java" ]]; then
+ print_status OK "Java binary: $JAVA_HOME/bin/java"
+ check_file "$JAVA_HOME/bin/javac" "javac binary"
+ check_file "$JAVA_HOME/bin/keytool" "keytool binary"
+ "$JAVA_HOME/bin/java" -version 2>&1 | sed -n '1,2p'
+ local java_ver
+ java_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | sed -n '1p')
+ if [[ "$java_ver" =~ \"([0-9]+)\\. ]]; then
+ local java_major="${BASH_REMATCH[1]}"
+ if [[ "$java_major" != "17" ]]; then
+ print_status WARN "Detected Java $java_major. Godot Android export is commonly validated with JDK 17."
+ fi
+ fi
+ else
+ print_status ERR "Java not found. Set JAVA_HOME to a JDK 17+ home or install one."
+ MISSING=$((MISSING+1))
+ JAVA_HOME=""
+ fi
+}
+
+find_sdkmanager() {
+ if [[ -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]]; then
+ echo "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager"
+ return
+ fi
+ if [[ -x "$ANDROID_HOME/cmdline-tools/bin/sdkmanager" ]]; then
+ echo "$ANDROID_HOME/cmdline-tools/bin/sdkmanager"; return
+ fi
+ if [[ -x "$ANDROID_HOME/tools/bin/sdkmanager" ]]; then
+ echo "$ANDROID_HOME/tools/bin/sdkmanager"; return
+ fi
+ if command -v sdkmanager >/dev/null 2>&1; then
+ command -v sdkmanager
+ return
+ fi
+ echo ""
+}
+
+sdkmanager_path="$(find_sdkmanager)"
+TMP_CMDLINE_TOOLS_DIR=""
+
+cleanup_tmpdir() {
+ [[ -n "${TMP_CMDLINE_TOOLS_DIR:-}" && -d "$TMP_CMDLINE_TOOLS_DIR" ]] && rm -rf "$TMP_CMDLINE_TOOLS_DIR"
+ TMP_CMDLINE_TOOLS_DIR=""
+}
+
+check_sdk_paths() {
+ print_status INFO "ANDROID_HOME: ${ANDROID_HOME}"
+ check_dir "$ANDROID_HOME" "Android SDK root"
+ check_dir "$ANDROID_HOME/platform-tools" "platform-tools"
+ check_file "$ANDROID_HOME/platform-tools/adb" "adb binary"
+
+ if [[ -d "$ANDROID_HOME/build-tools/$BUILDTOOLS_VERSION" ]]; then
+ print_status OK "build-tools ${BUILDTOOLS_VERSION}: present"
+ check_file \
+ "$ANDROID_HOME/build-tools/$BUILDTOOLS_VERSION/apksigner" \
+ "apksigner"
+ else
+ print_status ERR "Missing build-tools version: ${BUILDTOOLS_VERSION}"
+ MISSING=$((MISSING+1))
+ fi
+
+ if [[ -d "$ANDROID_HOME/platforms" ]]; then
+ if ls "$ANDROID_HOME/platforms/android-${SDK_VERSION}" >/dev/null 2>&1; then
+ print_status OK "platform ${SDK_VERSION}: present"
+ else
+ print_status ERR "Missing Android platform: android-${SDK_VERSION}"
+ MISSING=$((MISSING+1))
+ fi
+ else
+ print_status ERR "Missing platforms directory: $ANDROID_HOME/platforms"
+ MISSING=$((MISSING+1))
+ fi
+
+ if [[ -x "$sdkmanager_path" ]]; then
+ print_status OK "sdkmanager: ${sdkmanager_path}"
+ else
+ print_status ERR "sdkmanager not found in SDK or PATH"
+ MISSING=$((MISSING+1))
+ fi
+}
+
+install_jdk_hint() {
+ local pm=0
+ local -a elevate=()
+ echo "Attempting automatic JDK install..."
+ if command -v apt-get >/dev/null 2>&1; then
+ pm="apt-get"
+ elif command -v dnf >/dev/null 2>&1; then
+ pm="dnf"
+ elif command -v pacman >/dev/null 2>&1; then
+ pm="pacman"
+ else
+ echo "No supported package manager found (apt-get/dnf/pacman)."
+ echo "Install JDK 17 manually, then rerun with --java-home set."
+ return 1
+ fi
+
+ if [[ $EUID -ne 0 ]]; then
+ if ! command -v sudo >/dev/null 2>&1; then
+ echo "sudo not found; please run with root privileges for package install."
+ return 1
+ fi
+ elevate=(sudo)
+ fi
+
+ if [[ "$pm" == "apt-get" ]]; then
+ echo "apt-get install -y openjdk-17-jdk"
+ if [[ $AUTO -eq 1 ]]; then
+ "${elevate[@]}" apt-get update
+ "${elevate[@]}" apt-get install -y openjdk-17-jdk
+ else
+ echo "Run as manual step first: sudo apt-get update && sudo apt-get install -y openjdk-17-jdk"
+ return 1
+ fi
+ elif [[ "$pm" == "dnf" ]]; then
+ echo "dnf install -y java-17-openjdk-devel"
+ if [[ $AUTO -eq 1 ]]; then
+ "${elevate[@]}" dnf install -y java-17-openjdk-devel
+ else
+ return 1
+ fi
+ else
+ echo "pacman -S --noconfirm jdk17-openjdk"
+ if [[ $AUTO -eq 1 ]]; then
+ "${elevate[@]}" pacman -S --noconfirm jdk17-openjdk
+ else
+ return 1
+ fi
+ fi
+}
+
+install_cmdline_tools() {
+ if [[ -x "$sdkmanager_path" ]]; then
+ return 0
+ fi
+
+ echo "Downloading Android cmdline-tools to bootstrap sdkmanager..."
+ TMP_CMDLINE_TOOLS_DIR=""
+ TMP_CMDLINE_TOOLS_DIR="$(mktemp -d)"
+ if [[ -z "$TMP_CMDLINE_TOOLS_DIR" ]]; then
+ echo "Failed to create temporary directory."
+ return 1
+ fi
+ trap cleanup_tmpdir RETURN
+
+ if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then
+ echo "curl/wget required to download cmdline-tools. Install one and rerun."
+ return 1
+ fi
+
+ local zipfile="${TMP_CMDLINE_TOOLS_DIR}/cmdline-tools.zip"
+ if command -v curl >/dev/null 2>&1; then
+ if ! curl -fL "$CMDLINE_TOOLS_ZIP" -o "$zipfile"; then
+ echo "Failed to download cmdline-tools from $CMDLINE_TOOLS_ZIP"
+ return 1
+ fi
+ else
+ if ! wget -q "$CMDLINE_TOOLS_ZIP" -O "$zipfile"; then
+ echo "Failed to download cmdline-tools from $CMDLINE_TOOLS_ZIP"
+ return 1
+ fi
+ fi
+
+ if [[ ! -s "$zipfile" ]]; then
+ echo "Downloaded cmdline-tools archive is empty."
+ return 1
+ fi
+ unzip -q "$zipfile" -d "$TMP_CMDLINE_TOOLS_DIR"
+ if [[ ! -d "$TMP_CMDLINE_TOOLS_DIR/cmdline-tools" ]]; then
+ echo "Downloaded archive did not contain expected cmdline-tools payload."
+ return 1
+ fi
+ mkdir -p "$ANDROID_HOME" || {
+ echo "Cannot create Android SDK root: $ANDROID_HOME"
+ return 1
+ }
+ mkdir -p "$ANDROID_HOME/cmdline-tools"
+ rm -rf "$ANDROID_HOME/cmdline-tools/latest"
+ mkdir -p "$ANDROID_HOME/cmdline-tools/latest"
+ mv "$TMP_CMDLINE_TOOLS_DIR/cmdline-tools"/* "$ANDROID_HOME/cmdline-tools/latest/"
+ echo "Installed SDK cmdline-tools to $ANDROID_HOME/cmdline-tools/latest"
+ sdkmanager_path="$(find_sdkmanager)"
+ return 0
+}
+
+install_sdk_components() {
+ if [[ -z "$sdkmanager_path" ]]; then
+ echo "Cannot install SDK packages without sdkmanager."
+ return 1
+ fi
+ "$sdkmanager_path" --sdk_root="${ANDROID_HOME}" --list | sed -n '1,40p'
+ echo "Installing required SDK components: platform-tools, platform-android-${SDK_VERSION}, build-tools-${BUILDTOOLS_VERSION}"
+ if [[ $AUTO -eq 1 ]]; then
+ yes | "$sdkmanager_path" --sdk_root="${ANDROID_HOME}" --install "platform-tools" "platforms;android-${SDK_VERSION}" "build-tools;${BUILDTOOLS_VERSION}"
+ else
+ echo "Run this manually after accepting licenses:"
+ echo " yes | \"${sdkmanager_path}\" --sdk_root=\"${ANDROID_HOME}\" --install \"platform-tools\" \"platforms;android-${SDK_VERSION}\" \"build-tools;${BUILDTOOLS_VERSION}\""
+ return 1
+ fi
+}
+
+check_editor_settings() {
+ local editor_settings="$HOME/.config/godot/editor_settings-4.7.tres"
+ print_status INFO "Checking editor settings: $editor_settings"
+ if [[ -f "$editor_settings" ]]; then
+ if rg -n 'export/android/android_sdk_path|export/android/java_sdk_path' "$editor_settings" >/dev/null 2>&1; then
+ rg -n 'export/android/android_sdk_path|export/android/java_sdk_path' "$editor_settings"
+ else
+ print_status WARN "Editor export settings entries are missing for Android in this file"
+ echo " Set in editor: Export > Presets > Android:"
+ echo " android_sdk_path = ${ANDROID_HOME}"
+ echo " java_sdk_path = ${JAVA_HOME}"
+ fi
+ else
+ print_status WARN "No editor settings file found at expected path: $editor_settings"
+ fi
+}
+
+run_export_hint() {
+ echo
+ echo "Example export commands:"
+ echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-release \"Android\" builds/${PROJECT_VERSION}/android/NETfishing.apk"
+ echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-debug \"Android\" builds/android/NETfishing-debug.apk"
+}
+
+print_status INFO "Starting Android dependency preflight..."
+check_java
+check_sdk_paths
+check_editor_settings
+
+if [[ $MISSING -eq 0 ]]; then
+ print_status OK "Dependency check passed."
+ run_export_hint
+ exit 0
+fi
+
+if [[ $INSTALL -eq 1 ]]; then
+ echo
+ print_status INFO "Attempting dependency install path..."
+ if [[ \
+ -z "$JAVA_HOME" \
+ || ! -x "$JAVA_HOME/bin/java" \
+ || ! -x "$JAVA_HOME/bin/javac" \
+ || ! -x "$JAVA_HOME/bin/keytool" \
+ ]]; then
+ install_jdk_hint || true
+ fi
+
+ resolve_java_home || true
+ check_java
+
+ install_cmdline_tools || true
+ sdkmanager_path="$(find_sdkmanager)"
+ install_sdk_components || true
+
+ MISSING=0
+ check_java
+ check_sdk_paths
+ if [[ $MISSING -eq 0 ]]; then
+ echo
+ print_status OK "Dependencies fixed."
+ run_export_hint
+ exit 0
+ fi
+fi
+
+print_status ERR "Dependency check failed with ${MISSING} issue(s)."
+cat < DedicatedServerConfig:
+ var result := DedicatedServerConfig.new()
+ result.data_directory = ProjectSettings.globalize_path(
+ "user://dedicated-server-data"
+ )
+ result.discovery_url = str(ProjectSettings.get_setting(
+ "network/discovery/base_url", ""
+ )).strip_edges()
+ var config_path: String = OS.get_environment(
+ "NETFISHING_SERVER_CONFIG"
+ ).strip_edges()
+ for argument: String in OS.get_cmdline_user_args():
+ if argument.begins_with("--config="):
+ config_path = argument.trim_prefix("--config=").strip_edges()
+ if not config_path.is_empty() and not result._load_file(config_path):
+ return result
+ result._apply_environment()
+ result._apply_arguments(OS.get_cmdline_user_args())
+ result._validate()
+ return result
+
+
+func is_valid() -> bool:
+ return error_message.is_empty()
+
+
+func _load_file(path: String) -> bool:
+ var file := ConfigFile.new()
+ var error: Error = file.load(path)
+ if error != OK:
+ error_message = "Could not load server configuration: %s" % path
+ return false
+ server_name = str(file.get_value("server", "name", server_name))
+ bind_address = str(file.get_value(
+ "server", "bind_address", bind_address
+ ))
+ port = int(file.get_value("server", "port", port))
+ max_players = int(file.get_value(
+ "server", "max_players", max_players
+ ))
+ public_listing = bool(file.get_value(
+ "server", "public", public_listing
+ ))
+ data_directory = str(file.get_value(
+ "server", "data_directory", data_directory
+ ))
+ discovery_url = str(file.get_value(
+ "discovery", "url", discovery_url
+ ))
+ operator_fingerprints = _parse_fingerprint_list(file.get_value(
+ "moderation", "operators", operator_fingerprints
+ ))
+ return true
+
+
+func _apply_environment() -> void:
+ server_name = _environment_string(
+ "NETFISHING_SERVER_NAME", server_name
+ )
+ bind_address = _environment_string(
+ "NETFISHING_SERVER_BIND", bind_address
+ )
+ port = _environment_int("NETFISHING_SERVER_PORT", port)
+ max_players = _environment_int(
+ "NETFISHING_SERVER_MAX_PLAYERS", max_players
+ )
+ public_listing = _environment_bool(
+ "NETFISHING_SERVER_PUBLIC", public_listing
+ )
+ discovery_url = _environment_string(
+ "NETFISHING_DISCOVERY_URL", discovery_url
+ )
+ data_directory = _environment_string(
+ "NETFISHING_DATA_DIR", data_directory
+ )
+ if OS.has_environment("NETFISHING_SERVER_OPERATORS"):
+ operator_fingerprints = _parse_fingerprint_list(
+ OS.get_environment("NETFISHING_SERVER_OPERATORS")
+ )
+
+
+func _apply_arguments(arguments: PackedStringArray) -> void:
+ for argument: String in arguments:
+ if argument.begins_with("--name="):
+ server_name = argument.trim_prefix("--name=")
+ elif argument.begins_with("--bind="):
+ bind_address = argument.trim_prefix("--bind=")
+ elif argument.begins_with("--port="):
+ port = _parse_int(argument.trim_prefix("--port="), port)
+ elif argument.begins_with("--max-players="):
+ max_players = _parse_int(
+ argument.trim_prefix("--max-players="), max_players
+ )
+ elif argument.begins_with("--data-dir="):
+ data_directory = argument.trim_prefix("--data-dir=")
+ elif argument.begins_with("--discovery-url="):
+ discovery_url = argument.trim_prefix("--discovery-url=")
+ elif argument.begins_with("--operators="):
+ operator_fingerprints = _parse_fingerprint_list(
+ argument.trim_prefix("--operators=")
+ )
+ elif argument == "--public":
+ public_listing = true
+ elif argument == "--private":
+ public_listing = false
+
+
+func _validate() -> void:
+ server_name = server_name.strip_edges().left(48)
+ bind_address = bind_address.strip_edges()
+ discovery_url = discovery_url.strip_edges().trim_suffix("/")
+ data_directory = data_directory.strip_edges()
+ operator_fingerprints = _normalized_fingerprints(operator_fingerprints)
+ if server_name.is_empty():
+ error_message = "Server name cannot be empty."
+ elif not _safe_text(server_name):
+ error_message = "Server name contains unsupported characters."
+ elif bind_address.is_empty():
+ error_message = "Bind address cannot be empty."
+ elif port < 1 or port > 65535:
+ error_message = "Server port must be between 1 and 65535."
+ elif max_players < 1 or max_players > 128:
+ error_message = "Maximum players must be between 1 and 128."
+ elif not data_directory.is_empty() and not data_directory.is_absolute_path():
+ error_message = "Server data directory must be an absolute path."
+ elif public_listing and not (
+ discovery_url.begins_with("https://")
+ or discovery_url.begins_with("http://")
+ ):
+ error_message = "A public server requires a discovery URL."
+ elif operator_fingerprints.size() > MAX_OPERATORS:
+ error_message = "A server may configure at most %d operators." % (
+ MAX_OPERATORS
+ )
+ else:
+ for fingerprint: String in operator_fingerprints:
+ if not NetworkIdentityCrypto.valid_fingerprint(fingerprint):
+ error_message = (
+ "Server operator fingerprints must be 64 lowercase hex characters."
+ )
+ break
+
+
+static func _safe_text(value: String) -> bool:
+ for index: int in value.length():
+ var codepoint: int = value.unicode_at(index)
+ if codepoint < 32 or codepoint == 127:
+ return false
+ return true
+
+
+static func _environment_string(name: String, fallback: String) -> String:
+ return OS.get_environment(name) if OS.has_environment(name) else fallback
+
+
+static func _environment_int(name: String, fallback: int) -> int:
+ return (
+ _parse_int(OS.get_environment(name), fallback)
+ if OS.has_environment(name) else fallback
+ )
+
+
+static func _environment_bool(name: String, fallback: bool) -> bool:
+ if not OS.has_environment(name):
+ return fallback
+ var value: String = OS.get_environment(name).strip_edges().to_lower()
+ return value in ["1", "true", "yes", "on"]
+
+
+static func _parse_int(value: String, fallback: int) -> int:
+ return int(value) if value.strip_edges().is_valid_int() else fallback
+
+
+static func _parse_fingerprint_list(value: Variant) -> PackedStringArray:
+ var values: PackedStringArray = PackedStringArray()
+ if typeof(value) == TYPE_STRING:
+ var text: String = str(value)
+ for separator: String in [";", "\n", "\r", "\t", " "]:
+ text = text.replace(separator, ",")
+ values = text.split(",", false)
+ elif typeof(value) in [TYPE_ARRAY, TYPE_PACKED_STRING_ARRAY]:
+ for entry: Variant in value:
+ if typeof(entry) in [TYPE_STRING, TYPE_STRING_NAME]:
+ values.append(str(entry))
+ return _normalized_fingerprints(values)
+
+
+static func _normalized_fingerprints(
+ values: PackedStringArray,
+) -> PackedStringArray:
+ var result: PackedStringArray = PackedStringArray()
+ for value: String in values:
+ var fingerprint: String = value.strip_edges().to_lower()
+ if not fingerprint.is_empty() and fingerprint not in result:
+ result.append(fingerprint)
+ result.sort()
+ return result
diff --git a/server/dedicated_server_config.gd.uid b/server/dedicated_server_config.gd.uid
new file mode 100644
index 0000000..720cccc
--- /dev/null
+++ b/server/dedicated_server_config.gd.uid
@@ -0,0 +1 @@
+uid://nmg477qkcbhe
diff --git a/settings/controller_mapping_manager.gd b/settings/controller_mapping_manager.gd
index acff476..1690963 100644
--- a/settings/controller_mapping_manager.gd
+++ b/settings/controller_mapping_manager.gd
@@ -13,19 +13,19 @@ const MAX_PROFILE_BYTES: int = 1024 * 1024
const CAPTURE_AXIS_THRESHOLD: float = 0.55
const CAPTURE_AXIS_RELEASE_THRESHOLD: float = 0.30
const ACTIVE_DEVICE_AXIS_THRESHOLD: float = 0.35
-const MUOS_MAPPING_REVISION: String = "muos-v2"
+const MUOS_MAPPING_REVISION: String = "muos-v4"
const MUOS_CONTROLLER_NAMES: Array[String] = [
"muOS-Keys",
"Deeplay-keys",
]
const MUOS_MAPPING_BINDINGS: String = (
- "a:b2,b:b0,x:b1,y:b3,"
- + "leftshoulder:b6,rightshoulder:b7,"
- + "lefttrigger:b8,righttrigger:b9,"
- + "guide:b12,start:b11,back:b10,"
+ "a:b0,b:b1,x:b3,y:b2,"
+ + "leftshoulder:b4,rightshoulder:b5,"
+ + "lefttrigger:b10,righttrigger:b11,"
+ + "guide:b8,start:b7,back:b6,"
+ "dpup:h0.1,dpleft:h0.8,dpright:h0.2,dpdown:h0.4,"
- + "leftx:a0,lefty:a1,leftstick:b4,"
- + "rightx:a2,righty:a3,rightstick:b5,platform:Linux,"
+ + "leftx:a0,lefty:a1,leftstick:b9,"
+ + "rightx:a2,righty:a3,rightstick:b12,platform:Linux,"
)
const ROLE_A: StringName = &"a"
const ROLE_B: StringName = &"b"
@@ -739,8 +739,8 @@ static func should_install_muos_compatibility_mapping(
controller_name: String,
is_known: bool,
) -> bool:
- # Current SDL databases should remain authoritative. This fallback exists
- # only for legacy muOS virtual controllers that SDL cannot identify.
+ # Never update an already-recognized virtual controller at runtime. Godot
+ # can stop delivering its standardized input events after that replacement.
return is_muos_controller_name(controller_name) and not is_known
@@ -913,7 +913,7 @@ func _add_button_action_binding(action: StringName, value: Variant) -> void:
return
var event := InputEventJoypadButton.new()
event.device = _active_device_id
- event.button_index = int(binding.get("button", -1))
+ event.button_index = int(binding.get("button", -1)) as JoyButton
InputMap.action_add_event(action, event)
@@ -932,7 +932,7 @@ func _add_axis_action_binding(
)
var event := InputEventJoypadMotion.new()
event.device = _active_device_id
- event.axis = int(binding.get("axis", -1))
+ event.axis = int(binding.get("axis", -1)) as JoyAxis
event.axis_value = logical_direction * -captured_negative_direction
InputMap.action_add_event(action, event)
diff --git a/settings/player_settings.gd b/settings/player_settings.gd
index 2a8697b..a20a3e1 100644
--- a/settings/player_settings.gd
+++ b/settings/player_settings.gd
@@ -7,6 +7,8 @@ const MIN_MOUSE_SENSITIVITY: float = 0.001
const MAX_MOUSE_SENSITIVITY: float = 0.012
const MIN_CONTROLLER_SENSITIVITY: float = 0.5
const MAX_CONTROLLER_SENSITIVITY: float = 5.0
+const MIN_AUDIO_VOLUME: float = 0.0
+const MAX_AUDIO_VOLUME: float = 1.0
const MIN_WORLD_PIXEL_SIZE: int = 1
const MAX_WORLD_PIXEL_SIZE: int = 5
const DEFAULT_WORLD_PIXEL_SIZE: int = 3
@@ -27,11 +29,17 @@ const UI_COMPACT_RENDER_HEIGHTS: Array[int] = [0, 408, 336, 264, 192]
@export_range(0.001, 0.012, 0.0005) var mouse_camera_sensitivity: float = 0.005
@export_range(0.5, 5.0, 0.1) var controller_camera_sensitivity: float = 2.5
@export var invert_camera_y: bool = false
+@export var on_screen_keyboard_enabled: bool = false
@export var chat_draft: String = ""
@export var chat_collapsed: bool = false
@export var chat_dock_right: bool = false
@export var chat_mobile_mode: bool = false
@export var paint_dock_right: bool = true
+@export var fullscreen_enabled: bool = false
+@export_range(0.0, 1.0, 0.01) var master_volume: float = 1.0
+@export_range(0.0, 1.0, 0.01) var music_volume: float = 1.0
+@export_range(0.0, 1.0, 0.01) var effects_volume: float = 1.0
+@export_range(0.0, 1.0, 0.01) var environment_volume: float = 1.0
@export_range(1, 5, 1) var world_pixel_size: int = DEFAULT_WORLD_PIXEL_SIZE
@export_range(1, 5, 1) var ui_pixel_size: int = DEFAULT_UI_PIXEL_SIZE
@@ -47,6 +55,10 @@ func is_valid() -> bool:
and is_finite(controller_camera_sensitivity)
and controller_camera_sensitivity >= MIN_CONTROLLER_SENSITIVITY
and controller_camera_sensitivity <= MAX_CONTROLLER_SENSITIVITY
+ and _is_valid_audio_volume(master_volume)
+ and _is_valid_audio_volume(music_volume)
+ and _is_valid_audio_volume(effects_volume)
+ and _is_valid_audio_volume(environment_volume)
and chat_draft.length() <= MAX_CHAT_DRAFT_CHARACTERS
and world_pixel_size >= MIN_WORLD_PIXEL_SIZE
and world_pixel_size <= MAX_WORLD_PIXEL_SIZE
@@ -63,16 +75,30 @@ func copy() -> PlayerSettings:
result.mouse_camera_sensitivity = mouse_camera_sensitivity
result.controller_camera_sensitivity = controller_camera_sensitivity
result.invert_camera_y = invert_camera_y
+ result.on_screen_keyboard_enabled = on_screen_keyboard_enabled
result.chat_draft = chat_draft
result.chat_collapsed = chat_collapsed
result.chat_dock_right = chat_dock_right
result.chat_mobile_mode = chat_mobile_mode
result.paint_dock_right = paint_dock_right
+ result.fullscreen_enabled = fullscreen_enabled
+ result.master_volume = master_volume
+ result.music_volume = music_volume
+ result.effects_volume = effects_volume
+ result.environment_volume = environment_volume
result.world_pixel_size = world_pixel_size
result.ui_pixel_size = ui_pixel_size
return result
+static func _is_valid_audio_volume(value: float) -> bool:
+ return (
+ is_finite(value)
+ and value >= MIN_AUDIO_VOLUME
+ and value <= MAX_AUDIO_VOLUME
+ )
+
+
static func get_world_grid_height(
pixel_size: int,
displayed_height: int,
diff --git a/settings/player_settings_manager.gd b/settings/player_settings_manager.gd
index 7597c82..84b3f44 100644
--- a/settings/player_settings_manager.gd
+++ b/settings/player_settings_manager.gd
@@ -5,6 +5,7 @@ const SETTINGS_VERSION: int = 1
const SETTINGS_PATH: String = "user://player_settings.json"
const TEMP_PATH: String = "user://player_settings.json.tmp"
const BACKUP_PATH: String = "user://player_settings.json.backup"
+const SILENT_VOLUME_DB: float = -80.0
signal settings_changed(settings: PlayerSettings)
@@ -16,12 +17,14 @@ func load_settings() -> bool:
_recover_interrupted_write()
if not FileAccess.file_exists(SETTINGS_PATH):
current_settings = PlayerSettings.new()
+ _apply_audio_settings(current_settings)
emit_signal("settings_changed", current_settings)
return true
var file := FileAccess.open(SETTINGS_PATH, FileAccess.READ)
if file == null:
push_warning("Unable to open player settings; using defaults.")
current_settings = PlayerSettings.new()
+ _apply_audio_settings(current_settings)
emit_signal("settings_changed", current_settings)
return false
var json := JSON.new()
@@ -42,9 +45,16 @@ func load_settings() -> bool:
var presentation: Dictionary = {}
if typeof(data.get("presentation")) == TYPE_DICTIONARY:
presentation = data["presentation"]
+ var audio: Dictionary = {}
+ if typeof(data.get("audio")) == TYPE_DICTIONARY:
+ audio = data["audio"]
if (
typeof(accessibility.get("auto_click_enabled")) != TYPE_BOOL
or typeof(camera.get("invert_vertical")) != TYPE_BOOL
+ or (
+ accessibility.has("on_screen_keyboard_enabled")
+ and typeof(accessibility["on_screen_keyboard_enabled"]) != TYPE_BOOL
+ )
or (
accessibility.has("use_readable_interface_font")
and typeof(accessibility["use_readable_interface_font"]) != TYPE_BOOL
@@ -69,6 +79,10 @@ func load_settings() -> bool:
presentation.has("paint_dock_right")
and typeof(presentation["paint_dock_right"]) != TYPE_BOOL
)
+ or (
+ presentation.has("fullscreen_enabled")
+ and typeof(presentation["fullscreen_enabled"]) != TYPE_BOOL
+ )
):
return _use_defaults_after_corruption("Player settings values are invalid.")
var loaded := PlayerSettings.new()
@@ -88,6 +102,9 @@ func load_settings() -> bool:
-1.0
)
loaded.invert_camera_y = camera["invert_vertical"]
+ loaded.on_screen_keyboard_enabled = bool(
+ accessibility.get("on_screen_keyboard_enabled", false)
+ )
loaded.world_pixel_size = _read_clamped_integer(
presentation.get(
"world_pixel_size",
@@ -115,10 +132,20 @@ func load_settings() -> bool:
presentation.get("chat_mobile_mode", false)
)
loaded.paint_dock_right = bool(presentation.get("paint_dock_right", true))
+ loaded.fullscreen_enabled = bool(
+ presentation.get("fullscreen_enabled", false)
+ )
+ loaded.master_volume = _read_float(audio.get("master", 1.0), 1.0)
+ loaded.music_volume = _read_float(audio.get("music", 1.0), 1.0)
+ loaded.effects_volume = _read_float(audio.get("effects", 1.0), 1.0)
+ loaded.environment_volume = _read_float(
+ audio.get("environment", 1.0), 1.0
+ )
if not loaded.is_valid():
return _use_defaults_after_corruption("Player settings values are invalid.")
current_settings = loaded
_is_dirty = false
+ _apply_audio_settings(current_settings)
emit_signal("settings_changed", current_settings)
return true
@@ -131,7 +158,9 @@ func apply_settings(settings: PlayerSettings) -> bool:
_is_dirty = true
if not save_now():
current_settings = previous
+ _apply_audio_settings(current_settings)
return false
+ _apply_audio_settings(current_settings)
emit_signal("settings_changed", current_settings)
return true
@@ -176,12 +205,21 @@ func save_now() -> bool:
"auto_click_enabled": current_settings.auto_click_enabled,
"auto_click_interval": current_settings.auto_click_interval,
"use_readable_interface_font": true,
+ "on_screen_keyboard_enabled": (
+ current_settings.on_screen_keyboard_enabled
+ ),
},
"camera": {
"mouse_sensitivity": current_settings.mouse_camera_sensitivity,
"controller_sensitivity": current_settings.controller_camera_sensitivity,
"invert_vertical": current_settings.invert_camera_y,
},
+ "audio": {
+ "master": current_settings.master_volume,
+ "music": current_settings.music_volume,
+ "effects": current_settings.effects_volume,
+ "environment": current_settings.environment_volume,
+ },
"presentation": {
"world_pixel_size": current_settings.world_pixel_size,
"ui_pixel_size": current_settings.ui_pixel_size,
@@ -190,6 +228,7 @@ func save_now() -> bool:
"chat_dock_right": current_settings.chat_dock_right,
"chat_mobile_mode": current_settings.chat_mobile_mode,
"paint_dock_right": current_settings.paint_dock_right,
+ "fullscreen_enabled": current_settings.fullscreen_enabled,
},
}
if current_settings.chat_draft.is_empty():
@@ -222,6 +261,22 @@ func save_if_dirty() -> bool:
return not _is_dirty or save_now()
+func preview_audio_levels(
+ master: float,
+ music: float,
+ effects: float,
+ environment: float,
+) -> void:
+ _set_bus_volume(&"Master", master)
+ _set_bus_volume(&"Music", music)
+ _set_bus_volume(&"SFX", effects)
+ _set_bus_volume(&"Environment", environment)
+
+
+func restore_audio_levels() -> void:
+ _apply_audio_settings(current_settings)
+
+
func _exit_tree() -> void:
save_if_dirty()
@@ -230,10 +285,38 @@ func _use_defaults_after_corruption(message: String) -> bool:
push_warning(message)
current_settings = PlayerSettings.new()
_is_dirty = false
+ _apply_audio_settings(current_settings)
emit_signal("settings_changed", current_settings)
return false
+func _apply_audio_settings(settings: PlayerSettings) -> void:
+ preview_audio_levels(
+ settings.master_volume,
+ settings.music_volume,
+ settings.effects_volume,
+ settings.environment_volume,
+ )
+
+
+func _set_bus_volume(bus_name: StringName, linear_volume: float) -> void:
+ var bus_index: int = AudioServer.get_bus_index(bus_name)
+ if bus_index < 0:
+ return
+ var resolved_volume: float = clampf(
+ linear_volume,
+ PlayerSettings.MIN_AUDIO_VOLUME,
+ PlayerSettings.MAX_AUDIO_VOLUME,
+ )
+ AudioServer.set_bus_mute(bus_index, resolved_volume <= 0.0)
+ AudioServer.set_bus_volume_db(
+ bus_index,
+ SILENT_VOLUME_DB
+ if resolved_volume <= 0.0
+ else linear_to_db(resolved_volume),
+ )
+
+
func _recover_interrupted_write() -> void:
if FileAccess.file_exists(SETTINGS_PATH):
_remove_if_present(TEMP_PATH)
diff --git a/sound/dialogue/animalese/placeholder/a.wav b/sound/dialogue/animalese/placeholder/a.wav
new file mode 100644
index 0000000..ca652d4
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/a.wav differ
diff --git a/sound/dialogue/animalese/placeholder/a.wav.import b/sound/dialogue/animalese/placeholder/a.wav.import
new file mode 100644
index 0000000..86de7ca
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/a.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dvajjy4bwadio"
+path="res://.godot/imported/a.wav-9ab4b1a9a555e6fcf07951f399769b30.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/a.wav"
+dest_files=["res://.godot/imported/a.wav-9ab4b1a9a555e6fcf07951f399769b30.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/b.wav b/sound/dialogue/animalese/placeholder/b.wav
new file mode 100644
index 0000000..71ceb88
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/b.wav differ
diff --git a/sound/dialogue/animalese/placeholder/b.wav.import b/sound/dialogue/animalese/placeholder/b.wav.import
new file mode 100644
index 0000000..4aea49c
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/b.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://cs30tdyuo6wtc"
+path="res://.godot/imported/b.wav-eed860af2033bda258bd172899061b45.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/b.wav"
+dest_files=["res://.godot/imported/b.wav-eed860af2033bda258bd172899061b45.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/c.wav b/sound/dialogue/animalese/placeholder/c.wav
new file mode 100644
index 0000000..8b5eb64
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/c.wav differ
diff --git a/sound/dialogue/animalese/placeholder/c.wav.import b/sound/dialogue/animalese/placeholder/c.wav.import
new file mode 100644
index 0000000..bbd8074
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/c.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://2inox7x31xam"
+path="res://.godot/imported/c.wav-61dc49533634805d70c71d509b63e37b.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/c.wav"
+dest_files=["res://.godot/imported/c.wav-61dc49533634805d70c71d509b63e37b.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/d.wav b/sound/dialogue/animalese/placeholder/d.wav
new file mode 100644
index 0000000..978009a
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/d.wav differ
diff --git a/sound/dialogue/animalese/placeholder/d.wav.import b/sound/dialogue/animalese/placeholder/d.wav.import
new file mode 100644
index 0000000..ffc5bb9
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/d.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://yvha8eukw6l7"
+path="res://.godot/imported/d.wav-910bc02bc42bdb1b37561959a317c28a.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/d.wav"
+dest_files=["res://.godot/imported/d.wav-910bc02bc42bdb1b37561959a317c28a.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/e.wav b/sound/dialogue/animalese/placeholder/e.wav
new file mode 100644
index 0000000..76f7b8c
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/e.wav differ
diff --git a/sound/dialogue/animalese/placeholder/e.wav.import b/sound/dialogue/animalese/placeholder/e.wav.import
new file mode 100644
index 0000000..49de309
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/e.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://8ujopf8aqs83"
+path="res://.godot/imported/e.wav-7da5f8fcd017bf931de2bd49dc00f652.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/e.wav"
+dest_files=["res://.godot/imported/e.wav-7da5f8fcd017bf931de2bd49dc00f652.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/f.wav b/sound/dialogue/animalese/placeholder/f.wav
new file mode 100644
index 0000000..bec92c1
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/f.wav differ
diff --git a/sound/dialogue/animalese/placeholder/f.wav.import b/sound/dialogue/animalese/placeholder/f.wav.import
new file mode 100644
index 0000000..dc85ee3
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/f.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://c0gv4cphnfcxf"
+path="res://.godot/imported/f.wav-8eb31f2de6240647a0d6d2520aadcd6a.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/f.wav"
+dest_files=["res://.godot/imported/f.wav-8eb31f2de6240647a0d6d2520aadcd6a.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/fallback.wav b/sound/dialogue/animalese/placeholder/fallback.wav
new file mode 100644
index 0000000..63a759e
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/fallback.wav differ
diff --git a/sound/dialogue/animalese/placeholder/fallback.wav.import b/sound/dialogue/animalese/placeholder/fallback.wav.import
new file mode 100644
index 0000000..e116a3c
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/fallback.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bw0pod4tmexm0"
+path="res://.godot/imported/fallback.wav-7a40516b188f10028ac39bdc24fb52e5.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/fallback.wav"
+dest_files=["res://.godot/imported/fallback.wav-7a40516b188f10028ac39bdc24fb52e5.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/g.wav b/sound/dialogue/animalese/placeholder/g.wav
new file mode 100644
index 0000000..39dccf1
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/g.wav differ
diff --git a/sound/dialogue/animalese/placeholder/g.wav.import b/sound/dialogue/animalese/placeholder/g.wav.import
new file mode 100644
index 0000000..1709852
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/g.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://c7706p0fc8y7c"
+path="res://.godot/imported/g.wav-45b2cbd9653a31477e3f00c9432d560c.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/g.wav"
+dest_files=["res://.godot/imported/g.wav-45b2cbd9653a31477e3f00c9432d560c.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/h.wav b/sound/dialogue/animalese/placeholder/h.wav
new file mode 100644
index 0000000..acebfed
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/h.wav differ
diff --git a/sound/dialogue/animalese/placeholder/h.wav.import b/sound/dialogue/animalese/placeholder/h.wav.import
new file mode 100644
index 0000000..96b2359
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/h.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://cl66wka105xmo"
+path="res://.godot/imported/h.wav-2da53a6638eebb75f0867eaf75dc24ba.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/h.wav"
+dest_files=["res://.godot/imported/h.wav-2da53a6638eebb75f0867eaf75dc24ba.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/i.wav b/sound/dialogue/animalese/placeholder/i.wav
new file mode 100644
index 0000000..fbd10e1
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/i.wav differ
diff --git a/sound/dialogue/animalese/placeholder/i.wav.import b/sound/dialogue/animalese/placeholder/i.wav.import
new file mode 100644
index 0000000..0c11fd6
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/i.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://jicgdbnyt6bm"
+path="res://.godot/imported/i.wav-1e8d7f13980a6f2f61d73f65a2efc91c.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/i.wav"
+dest_files=["res://.godot/imported/i.wav-1e8d7f13980a6f2f61d73f65a2efc91c.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/j.wav b/sound/dialogue/animalese/placeholder/j.wav
new file mode 100644
index 0000000..0087db5
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/j.wav differ
diff --git a/sound/dialogue/animalese/placeholder/j.wav.import b/sound/dialogue/animalese/placeholder/j.wav.import
new file mode 100644
index 0000000..46a0baf
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/j.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://cji2evr0u3m6c"
+path="res://.godot/imported/j.wav-2f355374ffcea77f8dc630ee45879444.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/j.wav"
+dest_files=["res://.godot/imported/j.wav-2f355374ffcea77f8dc630ee45879444.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/k.wav b/sound/dialogue/animalese/placeholder/k.wav
new file mode 100644
index 0000000..c1b5e69
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/k.wav differ
diff --git a/sound/dialogue/animalese/placeholder/k.wav.import b/sound/dialogue/animalese/placeholder/k.wav.import
new file mode 100644
index 0000000..4af149c
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/k.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://eypaqf1iaq5"
+path="res://.godot/imported/k.wav-b85d045dc022b9055c25a650b2e3af2a.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/k.wav"
+dest_files=["res://.godot/imported/k.wav-b85d045dc022b9055c25a650b2e3af2a.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/l.wav b/sound/dialogue/animalese/placeholder/l.wav
new file mode 100644
index 0000000..fe2624b
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/l.wav differ
diff --git a/sound/dialogue/animalese/placeholder/l.wav.import b/sound/dialogue/animalese/placeholder/l.wav.import
new file mode 100644
index 0000000..8193ecf
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/l.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bixgnaq4idkhj"
+path="res://.godot/imported/l.wav-b21006c3b048e0c797d6baf19ab0f663.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/l.wav"
+dest_files=["res://.godot/imported/l.wav-b21006c3b048e0c797d6baf19ab0f663.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/m.wav b/sound/dialogue/animalese/placeholder/m.wav
new file mode 100644
index 0000000..4660d96
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/m.wav differ
diff --git a/sound/dialogue/animalese/placeholder/m.wav.import b/sound/dialogue/animalese/placeholder/m.wav.import
new file mode 100644
index 0000000..2a2439b
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/m.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dan4o17oreugv"
+path="res://.godot/imported/m.wav-aa394c4b1d5309d859ce73a368754264.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/m.wav"
+dest_files=["res://.godot/imported/m.wav-aa394c4b1d5309d859ce73a368754264.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/n.wav b/sound/dialogue/animalese/placeholder/n.wav
new file mode 100644
index 0000000..97e5457
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/n.wav differ
diff --git a/sound/dialogue/animalese/placeholder/n.wav.import b/sound/dialogue/animalese/placeholder/n.wav.import
new file mode 100644
index 0000000..f5e432c
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/n.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dxup6pw80km61"
+path="res://.godot/imported/n.wav-84e9a6fa6664222868d647187a09f374.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/n.wav"
+dest_files=["res://.godot/imported/n.wav-84e9a6fa6664222868d647187a09f374.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/o.wav b/sound/dialogue/animalese/placeholder/o.wav
new file mode 100644
index 0000000..bee6bc1
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/o.wav differ
diff --git a/sound/dialogue/animalese/placeholder/o.wav.import b/sound/dialogue/animalese/placeholder/o.wav.import
new file mode 100644
index 0000000..b094a9f
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/o.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://lntkug4avr2k"
+path="res://.godot/imported/o.wav-6c18faa9701875d7753d91afcd1b09e6.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/o.wav"
+dest_files=["res://.godot/imported/o.wav-6c18faa9701875d7753d91afcd1b09e6.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/p.wav b/sound/dialogue/animalese/placeholder/p.wav
new file mode 100644
index 0000000..29fdd60
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/p.wav differ
diff --git a/sound/dialogue/animalese/placeholder/p.wav.import b/sound/dialogue/animalese/placeholder/p.wav.import
new file mode 100644
index 0000000..a431c1f
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/p.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://crubsdrd220eh"
+path="res://.godot/imported/p.wav-c32b759c822f258d8d947827adf8127a.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/p.wav"
+dest_files=["res://.godot/imported/p.wav-c32b759c822f258d8d947827adf8127a.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/q.wav b/sound/dialogue/animalese/placeholder/q.wav
new file mode 100644
index 0000000..df184ca
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/q.wav differ
diff --git a/sound/dialogue/animalese/placeholder/q.wav.import b/sound/dialogue/animalese/placeholder/q.wav.import
new file mode 100644
index 0000000..574c906
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/q.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://ct0decr76agoq"
+path="res://.godot/imported/q.wav-d494b927c6f2b8bfbaa44d1f81887731.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/q.wav"
+dest_files=["res://.godot/imported/q.wav-d494b927c6f2b8bfbaa44d1f81887731.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/r.wav b/sound/dialogue/animalese/placeholder/r.wav
new file mode 100644
index 0000000..41fda60
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/r.wav differ
diff --git a/sound/dialogue/animalese/placeholder/r.wav.import b/sound/dialogue/animalese/placeholder/r.wav.import
new file mode 100644
index 0000000..1f196b1
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/r.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dpq7rin4pr1n3"
+path="res://.godot/imported/r.wav-d1d419e3246c0e918ff51a9dd662a742.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/r.wav"
+dest_files=["res://.godot/imported/r.wav-d1d419e3246c0e918ff51a9dd662a742.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/s.wav b/sound/dialogue/animalese/placeholder/s.wav
new file mode 100644
index 0000000..f9c542a
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/s.wav differ
diff --git a/sound/dialogue/animalese/placeholder/s.wav.import b/sound/dialogue/animalese/placeholder/s.wav.import
new file mode 100644
index 0000000..a794fdf
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/s.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://c00meumj2blfa"
+path="res://.godot/imported/s.wav-15abb20075aacc8d5fe95cd206ae25ce.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/s.wav"
+dest_files=["res://.godot/imported/s.wav-15abb20075aacc8d5fe95cd206ae25ce.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/t.wav b/sound/dialogue/animalese/placeholder/t.wav
new file mode 100644
index 0000000..76e0948
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/t.wav differ
diff --git a/sound/dialogue/animalese/placeholder/t.wav.import b/sound/dialogue/animalese/placeholder/t.wav.import
new file mode 100644
index 0000000..ce35ba2
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/t.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://dr0dp5v8fdb8r"
+path="res://.godot/imported/t.wav-3a26c5be0f8e3007adf1daa05a6a1ea2.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/t.wav"
+dest_files=["res://.godot/imported/t.wav-3a26c5be0f8e3007adf1daa05a6a1ea2.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/u.wav b/sound/dialogue/animalese/placeholder/u.wav
new file mode 100644
index 0000000..81ebbe5
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/u.wav differ
diff --git a/sound/dialogue/animalese/placeholder/u.wav.import b/sound/dialogue/animalese/placeholder/u.wav.import
new file mode 100644
index 0000000..8ccd096
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/u.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://bln1bkdu20muo"
+path="res://.godot/imported/u.wav-06e44c423f3d1cd6cdd34b54270211bb.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/u.wav"
+dest_files=["res://.godot/imported/u.wav-06e44c423f3d1cd6cdd34b54270211bb.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/v.wav b/sound/dialogue/animalese/placeholder/v.wav
new file mode 100644
index 0000000..d5c0d12
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/v.wav differ
diff --git a/sound/dialogue/animalese/placeholder/v.wav.import b/sound/dialogue/animalese/placeholder/v.wav.import
new file mode 100644
index 0000000..ff876a8
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/v.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://y3g1s3pw3bn0"
+path="res://.godot/imported/v.wav-5a9986e91dbdd0da4f0583b35a986b1c.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/v.wav"
+dest_files=["res://.godot/imported/v.wav-5a9986e91dbdd0da4f0583b35a986b1c.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/w.wav b/sound/dialogue/animalese/placeholder/w.wav
new file mode 100644
index 0000000..5122f9c
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/w.wav differ
diff --git a/sound/dialogue/animalese/placeholder/w.wav.import b/sound/dialogue/animalese/placeholder/w.wav.import
new file mode 100644
index 0000000..36f4e0f
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/w.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://5ml2iuf8cpgt"
+path="res://.godot/imported/w.wav-d3e9035a1fc5e7946be782a0d4f95e64.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/w.wav"
+dest_files=["res://.godot/imported/w.wav-d3e9035a1fc5e7946be782a0d4f95e64.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/x.wav b/sound/dialogue/animalese/placeholder/x.wav
new file mode 100644
index 0000000..e00f085
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/x.wav differ
diff --git a/sound/dialogue/animalese/placeholder/x.wav.import b/sound/dialogue/animalese/placeholder/x.wav.import
new file mode 100644
index 0000000..c91ffb4
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/x.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://b5al0m4de1m5x"
+path="res://.godot/imported/x.wav-b1beaddcc7d6663882ddd8b86e65db56.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/x.wav"
+dest_files=["res://.godot/imported/x.wav-b1beaddcc7d6663882ddd8b86e65db56.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/y.wav b/sound/dialogue/animalese/placeholder/y.wav
new file mode 100644
index 0000000..07b45ef
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/y.wav differ
diff --git a/sound/dialogue/animalese/placeholder/y.wav.import b/sound/dialogue/animalese/placeholder/y.wav.import
new file mode 100644
index 0000000..2c7d8d3
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/y.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://c6hust77yamoe"
+path="res://.godot/imported/y.wav-5ef178912b2921bb7c790b12e2e82337.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/y.wav"
+dest_files=["res://.godot/imported/y.wav-5ef178912b2921bb7c790b12e2e82337.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/animalese/placeholder/z.wav b/sound/dialogue/animalese/placeholder/z.wav
new file mode 100644
index 0000000..8f94654
Binary files /dev/null and b/sound/dialogue/animalese/placeholder/z.wav differ
diff --git a/sound/dialogue/animalese/placeholder/z.wav.import b/sound/dialogue/animalese/placeholder/z.wav.import
new file mode 100644
index 0000000..12b1b54
--- /dev/null
+++ b/sound/dialogue/animalese/placeholder/z.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://djvv63b0jlll"
+path="res://.godot/imported/z.wav-3e6ff24f53b1014b381cc80ee9fb1a84.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/animalese/placeholder/z.wav"
+dest_files=["res://.godot/imported/z.wav-3e6ff24f53b1014b381cc80ee9fb1a84.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/calls/bark.wav b/sound/dialogue/calls/bark.wav
new file mode 100644
index 0000000..2629fe7
Binary files /dev/null and b/sound/dialogue/calls/bark.wav differ
diff --git a/sound/dialogue/calls/bark.wav.import b/sound/dialogue/calls/bark.wav.import
new file mode 100644
index 0000000..702904d
--- /dev/null
+++ b/sound/dialogue/calls/bark.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://c8x46srpghnil"
+path="res://.godot/imported/bark.wav-9da6fd5d720375f4a64b26e364fcd74c.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/calls/bark.wav"
+dest_files=["res://.godot/imported/bark.wav-9da6fd5d720375f4a64b26e364fcd74c.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/sound/dialogue/calls/meow.wav b/sound/dialogue/calls/meow.wav
new file mode 100644
index 0000000..662b416
Binary files /dev/null and b/sound/dialogue/calls/meow.wav differ
diff --git a/sound/dialogue/calls/meow.wav.import b/sound/dialogue/calls/meow.wav.import
new file mode 100644
index 0000000..058b09a
--- /dev/null
+++ b/sound/dialogue/calls/meow.wav.import
@@ -0,0 +1,24 @@
+[remap]
+
+importer="wav"
+type="AudioStreamWAV"
+uid="uid://y86nskf7ewrg"
+path="res://.godot/imported/meow.wav-eb7bd4377946745ae1566c72ca026fae.sample"
+
+[deps]
+
+source_file="res://sound/dialogue/calls/meow.wav"
+dest_files=["res://.godot/imported/meow.wav-eb7bd4377946745ae1566c72ca026fae.sample"]
+
+[params]
+
+force/8_bit=false
+force/mono=false
+force/max_rate=false
+force/max_rate_hz=44100
+edit/trim=false
+edit/normalize=false
+edit/loop_mode=0
+edit/loop_begin=0
+edit/loop_end=-1
+compress/mode=2
diff --git a/tests/art_tools_validation.gd b/tests/art_tools_validation.gd
index 6cab7f7..14e19e7 100644
--- a/tests/art_tools_validation.gd
+++ b/tests/art_tools_validation.gd
@@ -27,6 +27,55 @@ func _run() -> void:
await physics_frame
var player := main.get("_player") as Player
+ var sprint_dust := player.get_node("%SprintDust") as SprintDustTrail
+ assert(sprint_dust != null)
+ assert(sprint_dust.get_active_puff_count() == 0)
+ sprint_dust.update_trail(
+ 0.016,
+ Vector3.ZERO,
+ Vector3(4.5, 0.0, 0.0),
+ true,
+ )
+ assert(sprint_dust.get_active_puff_count() == 0)
+ sprint_dust.update_trail(
+ 0.016,
+ Vector3(0.5, 0.0, 0.0),
+ Vector3(4.5, 0.0, 0.0),
+ true,
+ )
+ assert(sprint_dust.get_active_puff_count() == 1)
+ var planted_puff_position: Vector3 = (
+ sprint_dust.get_first_active_puff_position()
+ )
+ sprint_dust.update_trail(
+ 0.08,
+ Vector3(0.75, 0.0, 0.0),
+ Vector3(4.5, 0.0, 0.0),
+ true,
+ )
+ assert(
+ sprint_dust.get_first_active_puff_position()
+ == planted_puff_position
+ )
+ sprint_dust.update_trail(
+ 0.08,
+ Vector3(0.75, 0.0, 0.0),
+ Vector3.ZERO,
+ false,
+ )
+ assert(sprint_dust.get_active_puff_count() == 1)
+ sprint_dust.clear_trail()
+ assert(sprint_dust.get_active_puff_count() == 0)
+ sprint_dust.emit_landing_burst(Vector3.ZERO, Vector3.FORWARD)
+ assert(sprint_dust.get_active_puff_count() == 5)
+ sprint_dust.update_trail(
+ 0.08,
+ Vector3.ZERO,
+ Vector3.ZERO,
+ false,
+ )
+ assert(sprint_dust.get_active_puff_count() == 5)
+ sprint_dust.clear_trail()
var service := main.get_node(
"%NetworkSurfaceDrawingService"
) as NetworkSurfaceDrawingService
@@ -85,6 +134,14 @@ func _run() -> void:
assert(not toolbar.is_docked_right())
var chat_panel := chat_ui.get_node("ChatPanel") as PanelContainer
var chat_height_button := chat_ui.get_node("ChatHeightButton") as Button
+ var chat_status := chat_ui.find_child(
+ "ChatStatus", true, false
+ ) as Label
+ assert(chat_status != null)
+ assert(
+ chat_status.autowrap_mode
+ == TextServer.AUTOWRAP_WORD_SMART
+ )
assert(is_zero_approx(chat_panel.position.y))
assert(is_equal_approx(chat_panel.size.x, ChatUI.MOBILE_COMPACT_WIDTH))
assert(not chat_height_button.visible)
@@ -101,6 +158,17 @@ func _run() -> void:
default_docks.paint_dock_right = true
assert(settings_manager.apply_settings(default_docks))
await process_frame
+ chat_ui.call(
+ "_set_status",
+ (
+ "Unknown command: /this-command-name-is-intentionally-long-"
+ + "enough-to-require-smart-character-wrapping"
+ ),
+ )
+ await process_frame
+ assert(is_equal_approx(chat_panel.size.x, ChatUI.PANEL_WIDTH))
+ assert(chat_status.size.x <= ChatUI.PANEL_WIDTH)
+ chat_ui.call("_set_status", "")
assert(not chat_ui.is_docked_right())
assert(not chat_ui.is_mobile_mode())
assert(toolbar.is_docked_right())
@@ -109,6 +177,7 @@ func _run() -> void:
select_button.button_index = JOY_BUTTON_BACK
select_button.pressed = true
assert(bool(game_ui.call("_handle_controller_chat_controls", select_button)))
+ await process_frame
assert(chat_ui.is_open())
assert(chat_panel.mouse_filter == Control.MOUSE_FILTER_STOP)
var typed_chat_entry := chat_ui.find_child(
@@ -121,6 +190,8 @@ func _run() -> void:
accept_button.pressed = true
assert(bool(game_ui.call("_handle_controller_chat_controls", accept_button)))
assert(typed_chat_entry.virtual_keyboard_enabled)
+ await process_frame
+ assert(typed_chat_entry.has_focus())
var left_bumper := InputEventJoypadButton.new()
left_bumper.button_index = JOY_BUTTON_LEFT_SHOULDER
left_bumper.pressed = true
@@ -129,16 +200,50 @@ func _run() -> void:
assert(chat_panel.mouse_filter == Control.MOUSE_FILTER_IGNORE)
assert(not typed_chat_entry.virtual_keyboard_enabled)
assert(bool(game_ui.call("_handle_controller_chat_controls", left_bumper)))
- assert(chat_ui.is_open())
- assert(not typed_chat_entry.virtual_keyboard_enabled)
- assert(bool(game_ui.call("_handle_controller_chat_controls", left_bumper)))
assert(not chat_ui.is_open())
+ assert(not typed_chat_entry.virtual_keyboard_enabled)
assert(bool(game_ui.call("_handle_controller_chat_controls", select_button)))
assert(not chat_ui.is_open())
assert(chat_ui.is_collapsed())
assert(bool(game_ui.call("_handle_controller_chat_controls", select_button)))
assert(chat_ui.is_open())
chat_ui.refocus_gameplay()
+ var quick_menu := game_ui.get_node(
+ "%QuickRadialMenu"
+ ) as QuickRadialMenu
+ var emote_menu := game_ui.get_node(
+ "%EmoteRadialMenu"
+ ) as EmoteRadialMenu
+ assert(quick_menu != null and emote_menu != null)
+ assert(QuickRadialMenu.ACTIONS.size() == QuickRadialMenu.SECTOR_COUNT)
+ assert(QuickRadialMenu.ACTIONS.has(&"freecam"))
+ assert(QuickRadialMenu.ACTIONS.has(&"hud"))
+ game_ui.call("_on_quick_action_selected", &"freecam")
+ assert(player.is_free_camera_active())
+ assert(player.get_active_gameplay_camera().name == &"FreeCamera")
+ game_ui.call("_on_quick_action_selected", &"freecam")
+ assert(not player.is_free_camera_active())
+ game_ui.call("_on_quick_action_selected", &"hud")
+ await process_frame
+ assert(game_ui.is_gameplay_hud_hidden())
+ assert(chat_ui.is_hud_hidden())
+ assert(not (
+ game_ui.get_node("%GameplayTransientHUD") as Control
+ ).visible)
+ assert(not (
+ game_ui.get_node("%ExperiencePresentation") as Control
+ ).visible)
+ quick_menu.open_menu(true)
+ assert(quick_menu.visible and quick_menu.is_open())
+ quick_menu.close_menu()
+ emote_menu.open_menu(true)
+ assert(emote_menu.visible and emote_menu.is_open())
+ emote_menu.close_menu()
+ chat_ui.open_chat()
+ await process_frame
+ assert(chat_ui.is_open() and chat_panel.visible)
+ chat_ui.refocus_gameplay()
+ assert(chat_ui.is_hud_hidden())
var cancel_button := InputEventJoypadButton.new()
cancel_button.button_index = JOY_BUTTON_B
cancel_button.pressed = true
@@ -151,21 +256,29 @@ func _run() -> void:
player_menu.open_section(PlayerMenu.Section.PROFILE)
for _frame: int in 12:
await process_frame
+ assert(game_ui.is_gameplay_hud_hidden())
+ assert(player_menu.visible)
assert(root.gui_get_focus_owner() is not LineEdit)
- player_menu.close_menu()
- for _frame: int in 12:
- await process_frame
+ player_menu.close_menu(PlayerMenu.CloseReason.SESSION_END)
+ await process_frame
+ game_ui.call("_on_quick_action_selected", &"hud")
+ await process_frame
+ assert(not game_ui.is_gameplay_hud_hidden())
+ assert(not chat_ui.is_hud_hidden())
assert(not service.can_activate())
assert(not service.is_active() and not toolbar.visible)
assert(player.bag.add_item(ArtShopStock.ART_KIT_ITEM_ID, 1))
- assert(service.can_activate())
-
+ player.hotbar.select_slot(1)
+ assert(player.hotbar.assign_item(0, ArtShopStock.ART_KIT_ITEM_ID))
+ assert(not service.can_activate())
var paint_key := InputEventKey.new()
paint_key.physical_keycode = KEY_P
paint_key.pressed = true
- assert(service.handle_input(paint_key, true))
+ assert(not service.handle_input(paint_key, true))
+ assert(not service.is_active())
+ player.hotbar.select_slot(0)
await process_frame
- assert(service.is_active() and service.is_placement_mode())
+ assert(service.is_active() and not service.is_placement_mode())
assert(toolbar.visible)
var ui_root := game_ui.get_node("%UIRoot") as Control
assert(toolbar.get_parent() == ui_root)
@@ -180,6 +293,8 @@ func _run() -> void:
assert(toolbar.get_global_rect().end.y <= 720.0)
var top_panel := toolbar.get_node("%TopPanel") as PanelContainer
var color_panel := toolbar.get_node("%ColorPanel") as PanelContainer
+ assert(is_equal_approx(toolbar.size.x, SurfaceDrawingToolbar.TOOLBAR_WIDTH))
+ assert(is_equal_approx(top_panel.size.x, SurfaceDrawingToolbar.TOOLBAR_WIDTH))
assert(top_panel.position.is_equal_approx(Vector2.ZERO))
assert(color_panel.position.x > 0.0)
assert(is_equal_approx(color_panel.get_rect().end.x, top_panel.get_rect().end.x))
@@ -204,7 +319,6 @@ func _run() -> void:
var hide_button := toolbar.get_node("%HideGuideButton") as Button
var restore_button := toolbar.get_node("%RestoreGuideButton") as Button
var finalize_button := toolbar.get_node("%FinalizeGuideButton") as Button
- var close_button := toolbar.get_node("%CloseButton") as Button
assert(
mode_button != null
and eraser_button != null
@@ -212,8 +326,44 @@ func _run() -> void:
and hide_button != null
and restore_button != null
and finalize_button != null
- and close_button != null
)
+ assert(toolbar.get_node_or_null("%CloseButton") == null)
+ var expected_toolbar_icons: Dictionary[Button, String] = {
+ mode_button: "/art/art_kit_marker.png",
+ eraser_button: "/art/art_kit_eraser.png",
+ hide_button: "/art/art_kit_grid_hidden_light.png",
+ restore_button: "/art/art_kit_grid_restore_light.png",
+ finalize_button: "/art/art_kit_grid_finish_light.png",
+ }
+ for icon_button: Button in expected_toolbar_icons:
+ assert(icon_button.text.is_empty())
+ assert(icon_button.icon != null)
+ assert(
+ icon_button.icon.resource_path.ends_with(
+ expected_toolbar_icons[icon_button]
+ )
+ )
+ for icon_button: Button in [
+ eraser_button,
+ undo_button,
+ hide_button,
+ restore_button,
+ finalize_button,
+ ]:
+ assert(icon_button.custom_minimum_size == Vector2(48, 44))
+ assert(icon_button.get_theme_constant("icon_max_width") == 40)
+ var icon_style := (
+ icon_button.get_theme_stylebox("normal") as StyleBoxFlat
+ )
+ assert(is_equal_approx(icon_style.content_margin_left, 4.0))
+ assert(is_equal_approx(icon_style.content_margin_top, 2.0))
+ assert(mode_button.custom_minimum_size == Vector2(48, 48))
+ assert(mode_button.get_theme_constant("icon_max_width") == 40)
+ assert(mode_button.get_index() > finalize_button.get_index())
+ assert(hide_button.button_group != null)
+ assert(hide_button.button_group == restore_button.button_group)
+ assert(hide_button.button_group == finalize_button.button_group)
+ assert(hide_button.button_group.allow_unpress)
assert(brush_option.item_count == 4)
assert(grid_option.item_count == 4)
assert(not brush_option.get_popup().is_item_disabled(0))
@@ -239,9 +389,25 @@ func _run() -> void:
assert(service.get_color_id() == &"ocean_teal")
assert(service.get_brush_size() == 4)
assert(service.get_grid_size() == 128)
+ var marker_mode_material := mode_button.material as ShaderMaterial
+ assert(marker_mode_material != null)
+ assert(
+ marker_mode_material.shader.resource_path.ends_with(
+ "/ui/art_kit_marker_icon.gdshader"
+ )
+ )
+ assert(
+ marker_mode_material.get_shader_parameter("marker_color")
+ == SurfaceDrawingPalette.get_color(&"ocean_teal")
+ )
mode_button.pressed.emit()
- assert(not service.is_placement_mode())
+ assert(service.is_placement_mode())
+ assert(
+ mode_button.icon.resource_path.ends_with(
+ "/art/art_kit_grid_light.png"
+ )
+ )
eraser_button.pressed.emit()
assert(service.is_eraser_mode())
assert(eraser_button.button_pressed)
@@ -256,55 +422,118 @@ func _run() -> void:
world_click.button_index = MOUSE_BUTTON_LEFT
world_click.pressed = true
assert(service.handle_input(world_click, true))
+ assert(
+ service.get_armed_guide_action()
+ == NetworkSurfaceDrawingService.GuideAction.HIDE
+ )
+ assert(service.is_placement_mode())
+ assert(not service.is_eraser_mode())
+ assert(hide_button.button_pressed)
+ hide_button.pressed.emit()
assert(
service.get_armed_guide_action()
== NetworkSurfaceDrawingService.GuideAction.NONE
)
- assert(not service.is_placement_mode())
- assert(service.is_eraser_mode())
+ assert(not service.is_placement_mode() and service.is_eraser_mode())
restore_button.pressed.emit()
assert(
service.get_armed_guide_action()
== NetworkSurfaceDrawingService.GuideAction.RESTORE
)
- restore_button.pressed.emit()
- assert(
- service.get_armed_guide_action()
- == NetworkSurfaceDrawingService.GuideAction.NONE
- )
- assert(not service.is_placement_mode() and service.is_eraser_mode())
finalize_button.pressed.emit()
assert(
service.get_armed_guide_action()
== NetworkSurfaceDrawingService.GuideAction.FINALIZE
)
+ assert(not restore_button.button_pressed)
+ assert(finalize_button.button_pressed)
assert(service.handle_input(world_click, true))
+ assert(
+ service.get_armed_guide_action()
+ == NetworkSurfaceDrawingService.GuideAction.FINALIZE
+ )
+ finalize_button.pressed.emit()
+ assert(
+ service.get_armed_guide_action()
+ == NetworkSurfaceDrawingService.GuideAction.NONE
+ )
assert(not service.is_placement_mode() and service.is_eraser_mode())
(color_buttons[&"ocean_teal"] as Button).pressed.emit()
assert(not service.is_eraser_mode())
undo_button.pressed.emit()
assert(service.is_active())
- close_button.pressed.emit()
- assert(not service.is_active() and not toolbar.visible)
-
- assert(service.handle_input(paint_key, true))
- await process_frame
+ assert(not service.handle_input(paint_key, true))
assert(service.is_active() and toolbar.visible)
-
- assert(service.handle_input(paint_key, true))
- await process_frame
- assert(not service.is_active() and not toolbar.visible)
- assert(player.hotbar.assign_item(0, ArtShopStock.ART_KIT_ITEM_ID))
var fishing_spot := main.get_node("%FishingSpot") as FishingSpot
- fishing_spot.art_ui_toggle_requested.emit()
await process_frame
+ var held_art_kit_display := player.get("_held_art_kit_display") as Node3D
+ var held_art_kit_sprite := player.get("_held_art_kit_sprite") as Sprite3D
+ var pocket_animation_player := player.get(
+ "_character_animation_player"
+ ) as AnimationPlayer
+ var pocket_animation_name: StringName = player.get(
+ "_pocket_visual_animation"
+ )
+ if (
+ not held_art_kit_display.visible
+ and pocket_animation_player != null
+ and not pocket_animation_name.is_empty()
+ and pocket_animation_player.has_animation(pocket_animation_name)
+ ):
+ var pocket_animation: Animation = (
+ pocket_animation_player.get_animation(pocket_animation_name)
+ )
+ await create_timer(pocket_animation.length * 0.55).timeout
+ assert(held_art_kit_display.visible)
+ assert(held_art_kit_sprite.visible and held_art_kit_sprite.texture != null)
+ assert(held_art_kit_sprite.texture.resource_path.ends_with("/art/art_kit.png"))
+ assert(is_zero_approx(angle_difference(
+ held_art_kit_sprite.rotation.z,
+ -PI * 0.5,
+ )))
+ assert(held_art_kit_sprite.flip_h)
+ assert(not fishing_spot.has_signal(&"art_ui_toggle_requested"))
assert(service.is_active() and toolbar.visible)
assert(service.get_grid_size() == 128)
+ assert(service.handle_input(world_click, true))
+ assert(service.is_active() and toolbar.visible)
+ var hotbar_ui := game_ui.get_node("%Hotbar") as HotbarUI
+ var wheel_down := InputEventMouseButton.new()
+ wheel_down.button_index = MOUSE_BUTTON_WHEEL_DOWN
+ wheel_down.pressed = true
+ assert(not service.handle_input(wheel_down, true))
+ hotbar_ui._unhandled_input(wheel_down)
+ await process_frame
+ assert(player.hotbar.get_selected_slot() == 1)
+ assert(not service.is_active() and not toolbar.visible)
+
+ var number_one := InputEventKey.new()
+ number_one.physical_keycode = KEY_1
+ number_one.pressed = true
+ assert(not service.handle_input(number_one, true))
+ hotbar_ui._unhandled_input(number_one)
+ await process_frame
+ assert(service.is_active() and toolbar.visible)
+ assert(player.hotbar.get_selected_slot() == 0)
+ var number_two := InputEventKey.new()
+ number_two.physical_keycode = KEY_2
+ number_two.pressed = true
+ assert(not service.handle_input(number_two, true))
+ hotbar_ui._unhandled_input(number_two)
+ await process_frame
+ assert(player.hotbar.get_selected_slot() == 1)
+ assert(not service.is_active() and not toolbar.visible)
+ game_ui.call("_on_quick_action_selected", &"paint")
+ await process_frame
+ assert(player.hotbar.get_selected_slot() == 0)
+ assert(service.is_active() and toolbar.visible)
print("Art tools validation: PASS")
var session := main.get_node("%NetworkSession") as NetworkSession
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/character_scale_validation.gd b/tests/character_scale_validation.gd
index 1cc988c..213f64f 100644
--- a/tests/character_scale_validation.gd
+++ b/tests/character_scale_validation.gd
@@ -47,6 +47,10 @@ func _run() -> void:
assert(body != null)
var body_material := body.material_override as StandardMaterial3D
assert(body_material != null)
+ assert(
+ body_material.texture_filter
+ == BaseMaterial3D.TEXTURE_FILTER_NEAREST
+ )
assert(body_material.shading_mode == BaseMaterial3D.SHADING_MODE_UNSHADED)
assert(is_zero_approx(body_material.metallic))
assert(is_zero_approx(body_material.metallic_specular))
diff --git a/tests/controller_focus_presentation_validation.gd b/tests/controller_focus_presentation_validation.gd
new file mode 100644
index 0000000..f0d0355
--- /dev/null
+++ b/tests/controller_focus_presentation_validation.gd
@@ -0,0 +1,84 @@
+extends SceneTree
+
+const FocusPresentationType = preload(
+ "res://ui/controller_focus_presentation.gd"
+)
+
+var _failures: Array[String] = []
+
+
+func _initialize() -> void:
+ _run.call_deferred()
+
+
+func _run() -> void:
+ var stage := Control.new()
+ stage.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ root.add_child(stage)
+ var presentation := FocusPresentationType.new()
+ stage.add_child(presentation)
+ var standard_button := Button.new()
+ standard_button.text = "standard"
+ standard_button.custom_minimum_size = Vector2(120.0, 60.0)
+ stage.add_child(standard_button)
+ var authored_selector := Button.new()
+ authored_selector.text = "authored selector"
+ authored_selector.position = Vector2(140.0, 0.0)
+ authored_selector.custom_minimum_size = Vector2(160.0, 60.0)
+ authored_selector.set_meta(&"controller_focus_inversion_disabled", true)
+ stage.add_child(authored_selector)
+ await process_frame
+
+ var controller_event := InputEventJoypadButton.new()
+ controller_event.button_index = JOY_BUTTON_A
+ controller_event.pressed = true
+ presentation._input(controller_event)
+ standard_button.grab_focus()
+ await process_frame
+ _expect(
+ standard_button.material != null,
+ "ordinary controller focus receives inversion",
+ )
+ var pointer_motion := InputEventMouseMotion.new()
+ pointer_motion.position = Vector2(4.0, 4.0)
+ presentation._input(pointer_motion)
+ await process_frame
+ _expect(
+ standard_button.material == null,
+ "mouse motion clears controller focus presentation",
+ )
+ presentation._input(controller_event)
+
+ authored_selector.grab_focus()
+ await process_frame
+ _expect(
+ standard_button.material == null,
+ "inversion clears when focus moves",
+ )
+ _expect(
+ authored_selector.material == null,
+ "authored selector backgrounds opt out of inversion",
+ )
+
+ standard_button.grab_focus()
+ await process_frame
+ standard_button.focus_mode = Control.FOCUS_NONE
+ await process_frame
+ _expect(
+ standard_button.material == null,
+ "inversion clears when a focused control is defocused",
+ )
+
+ stage.queue_free()
+ if _failures.is_empty():
+ print("Controller focus presentation validation: PASS")
+ quit(0)
+ return
+ for failure: String in _failures:
+ push_error(failure)
+ quit(1)
+
+
+func _expect(condition: bool, message: String) -> void:
+ if not condition:
+ _failures.append(message)
diff --git a/tests/controller_focus_presentation_validation.gd.uid b/tests/controller_focus_presentation_validation.gd.uid
new file mode 100644
index 0000000..0cacf4a
--- /dev/null
+++ b/tests/controller_focus_presentation_validation.gd.uid
@@ -0,0 +1 @@
+uid://bjay8ki3albk6
diff --git a/tests/controller_focus_recovery_validation.gd b/tests/controller_focus_recovery_validation.gd
new file mode 100644
index 0000000..f598511
--- /dev/null
+++ b/tests/controller_focus_recovery_validation.gd
@@ -0,0 +1,184 @@
+extends SceneTree
+
+const ControllerFocusRecoveryType = preload(
+ "res://ui/controller_focus_recovery.gd"
+)
+
+var _failures: Array[String] = []
+
+
+func _initialize() -> void:
+ _run.call_deferred()
+
+
+func _run() -> void:
+ var stage := Control.new()
+ stage.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ root.add_child(stage)
+ var recovery := ControllerFocusRecoveryType.new()
+ stage.add_child(recovery)
+ var option_list := VBoxContainer.new()
+ option_list.position = Vector2(100.0, 100.0)
+ stage.add_child(option_list)
+ var original := _make_button("cute", "cute (show variants)")
+ option_list.add_child(original)
+ await process_frame
+ original.grab_focus()
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "programmatic focus stays pending outside navigation mode",
+ )
+ var keyboard_navigation := InputEventKey.new()
+ keyboard_navigation.keycode = KEY_DOWN
+ keyboard_navigation.pressed = true
+ recovery._input(keyboard_navigation)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == original,
+ "keyboard navigation restores pending initial focus",
+ )
+ var menu_shortcut := InputEventKey.new()
+ menu_shortcut.physical_keycode = KEY_TAB
+ menu_shortcut.pressed = true
+ recovery._input(menu_shortcut)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "the menu shortcut does not leave a pseudo-focused option",
+ )
+
+ var controller_event := InputEventJoypadButton.new()
+ controller_event.button_index = JOY_BUTTON_A
+ controller_event.pressed = true
+ recovery._input(controller_event)
+ await process_frame
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == original,
+ "controller navigation restores pending initial focus",
+ )
+
+ option_list.remove_child(original)
+ original.queue_free()
+ var replacement := _make_button("cute", "cute (hide variants)")
+ option_list.add_child(replacement)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == replacement,
+ "focus follows a rebuilt semantic option",
+ )
+
+ var explicit_target := _make_button("explicit", "explicit")
+ option_list.add_child(explicit_target)
+ option_list.remove_child(replacement)
+ replacement.queue_free()
+ explicit_target.grab_focus()
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == explicit_target,
+ "explicit focus changes take precedence over recovery",
+ )
+ var pointer_motion := InputEventMouseMotion.new()
+ pointer_motion.position = Vector2(4.0, 4.0)
+ recovery._input(pointer_motion)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "mouse motion releases controller focus",
+ )
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "mouse motion prevents automatic focus recovery",
+ )
+ recovery._input(controller_event)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == explicit_target,
+ "controller navigation can resume from pointer mode",
+ )
+ var pointer_press := InputEventMouseButton.new()
+ pointer_press.button_index = MOUSE_BUTTON_LEFT
+ pointer_press.pressed = true
+ recovery._input(pointer_press)
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == explicit_target,
+ "mouse-down preserves focus through button activation",
+ )
+ var pointer_release := InputEventMouseButton.new()
+ pointer_release.button_index = MOUSE_BUTTON_LEFT
+ pointer_release.pressed = false
+ recovery._input(pointer_release)
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "mouse-up clears the completed button focus",
+ )
+ recovery._input(controller_event)
+ await process_frame
+ await process_frame
+
+ var outside_button := _make_button("outside", "outside")
+ stage.add_child(outside_button)
+ option_list.hide()
+ root.gui_release_focus()
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "focus recovery never escapes a hidden menu scope",
+ )
+ option_list.show()
+ explicit_target.grab_focus()
+ await process_frame
+ var leave_world_ui_event := InputEventJoypadButton.new()
+ leave_world_ui_event.button_index = JOY_BUTTON_LEFT_SHOULDER
+ leave_world_ui_event.pressed = true
+ recovery._input(leave_world_ui_event)
+ root.gui_release_focus()
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "LB intentionally leaving world UI is never recovered",
+ )
+ var accessibility_only := Control.new()
+ accessibility_only.focus_mode = Control.FOCUS_ACCESSIBILITY
+ stage.add_child(accessibility_only)
+ await process_frame
+ _expect(
+ not bool(recovery.call("_is_focusable", accessibility_only)),
+ "accessibility-only controls are not recovery targets",
+ )
+
+ stage.queue_free()
+ if _failures.is_empty():
+ print("Controller focus recovery validation: PASS")
+ quit(0)
+ return
+ for failure: String in _failures:
+ push_error(failure)
+ quit(1)
+
+
+func _make_button(text: String, tooltip: String) -> Button:
+ var button := Button.new()
+ button.text = text
+ button.tooltip_text = tooltip
+ button.custom_minimum_size = Vector2(120.0, 48.0)
+ return button
+
+
+func _expect(condition: bool, message: String) -> void:
+ if not condition:
+ _failures.append(message)
diff --git a/tests/controller_focus_recovery_validation.gd.uid b/tests/controller_focus_recovery_validation.gd.uid
new file mode 100644
index 0000000..7bcb1a2
--- /dev/null
+++ b/tests/controller_focus_recovery_validation.gd.uid
@@ -0,0 +1 @@
+uid://cqk75fxykqrhs
diff --git a/tests/controller_mapping_validation.gd b/tests/controller_mapping_validation.gd
index 4416e2c..16c9ad0 100644
--- a/tests/controller_mapping_validation.gd
+++ b/tests/controller_mapping_validation.gd
@@ -18,6 +18,8 @@ func _run() -> void:
root.add_child(manager)
await process_frame
var failure: String = _validate_manager(manager)
+ if failure.is_empty():
+ failure = _validate_portmaster_launcher()
if failure.is_empty():
failure = _validate_auto_map(manager)
if failure.is_empty():
@@ -35,28 +37,31 @@ func _run() -> void:
func _validate_manager(manager: ControllerMappingManagerType) -> String:
var muos_mapping: String = (
ControllerMappingManagerType.build_muos_controller_mapping(
- "19004ca6010000000100000000010000",
+ "19000000010000000100000000010000",
"muOS-Keys",
)
)
for expected_binding: String in [
- "a:b2",
- "b:b0",
- "x:b1",
- "y:b3",
- "leftshoulder:b6",
- "rightshoulder:b7",
- "lefttrigger:b8",
- "righttrigger:b9",
- "back:b10",
- "start:b11",
+ "a:b0",
+ "b:b1",
+ "x:b3",
+ "y:b2",
+ "leftshoulder:b4",
+ "rightshoulder:b5",
+ "lefttrigger:b10",
+ "righttrigger:b11",
+ "back:b6",
+ "start:b7",
+ "guide:b8",
+ "leftstick:b9",
+ "rightstick:b12",
"leftx:a0",
"righty:a3",
]:
if expected_binding not in muos_mapping:
return "muOS compatibility mapping omitted " + expected_binding
if not muos_mapping.begins_with(
- "19004ca6010000000100000000010000,muOS-Keys,"
+ "19000000010000000100000000010000,muOS-Keys,"
):
return "muOS compatibility mapping does not use the runtime guid"
if not ControllerMappingManagerType.is_muos_controller_name(
@@ -76,7 +81,7 @@ func _validate_manager(manager: ControllerMappingManagerType) -> String:
"muOS-Keys",
true,
):
- return "recognized muOS controller would override its SDL mapping"
+ return "recognized muOS controller would be replaced at runtime"
if ControllerMappingManagerType.should_install_muos_compatibility_mapping(
"ordinary controller",
false,
@@ -191,6 +196,30 @@ func _validate_manager(manager: ControllerMappingManagerType) -> String:
return ""
+func _validate_portmaster_launcher() -> String:
+ const launcher_path: String = "res://scripts/portmaster/NETfishing.sh"
+ if not FileAccess.file_exists(launcher_path):
+ return "PortMaster launcher template is missing"
+ var launcher: String = FileAccess.get_file_as_string(launcher_path)
+ for expected_fragment: String in [
+ "19004ca6010000000100000000010000",
+ "19000000010000000100000000010000",
+ "a:b0,b:b1,x:b3,y:b2",
+ "leftshoulder:b4,rightshoulder:b5",
+ "lefttrigger:b10,righttrigger:b11",
+ "guide:b8,start:b7,back:b6",
+ "leftstick:b9",
+ "rightstick:b12",
+ "netfishing_controllerconfig=\"$GODOT_MUOS_MAPPING\"",
+ "SDL_GAMECONTROLLERCONFIG=\"$netfishing_controllerconfig\" \\",
+ ]:
+ if expected_fragment not in launcher:
+ return "PortMaster launcher omitted " + expected_fragment
+ if "$'\\n'" in launcher:
+ return "PortMaster launcher appends mappings across a Weston-unsafe newline"
+ return ""
+
+
func _validate_auto_map(manager: ControllerMappingManagerType) -> String:
var panel := ControllerMappingPanelType.new()
root.add_child(panel)
@@ -255,13 +284,35 @@ func _validate_auto_map(manager: ControllerMappingManagerType) -> String:
return "manual remapping still dictates a specific physical input"
if "any button" not in panel._progress_label.text.to_lower():
return "manual remapping does not request a generic controller input"
- var cancel_button := InputEventJoypadButton.new()
- cancel_button.device = manager.get_active_device_id()
- cancel_button.button_index = JOY_BUTTON_B
- cancel_button.pressed = true
- manager.controller_input_observed.emit(cancel_button)
- if panel.is_capturing():
- return "mapped controller back input did not cancel capture"
+ panel._cancel_capture()
+ panel._begin_auto_map()
+ panel._process(ControllerMappingPanelType.CAPTURE_NEUTRAL_SECONDS)
+ var lone_button := InputEventJoypadButton.new()
+ lone_button.device = manager.get_active_device_id()
+ lone_button.button_index = JOY_BUTTON_B
+ lone_button.pressed = true
+ manager.controller_input_observed.emit(lone_button)
+ if not panel._auto_map_active or panel._auto_map_index != 1:
+ return "a single controller button cancelled auto-map"
+ panel._cancel_capture()
+ panel._begin_auto_map()
+ panel._process(ControllerMappingPanelType.CAPTURE_NEUTRAL_SECONDS)
+ var left_bumper := InputEventJoypadButton.new()
+ left_bumper.device = manager.get_active_device_id()
+ left_bumper.button_index = JOY_BUTTON_LEFT_SHOULDER
+ left_bumper.pressed = true
+ manager.controller_input_observed.emit(left_bumper)
+ var right_bumper := InputEventJoypadButton.new()
+ right_bumper.device = manager.get_active_device_id()
+ right_bumper.button_index = JOY_BUTTON_RIGHT_SHOULDER
+ right_bumper.pressed = true
+ manager.controller_input_observed.emit(right_bumper)
+ panel._process(ControllerMappingPanelType.CANCEL_COMBO_HOLD_SECONDS - 0.01)
+ if not panel._auto_map_active:
+ return "bumper combo cancelled auto-map before the hold threshold"
+ panel._process(0.02)
+ if panel._auto_map_active or panel.is_capturing():
+ return "sustained bumper combo did not cancel auto-map"
panel._begin_auto_map()
panel._process(ControllerMappingPanelType.CAPTURE_NEUTRAL_SECONDS)
var held_left := InputEventJoypadMotion.new()
diff --git a/tests/controller_ui_navigation_validation.gd b/tests/controller_ui_navigation_validation.gd
new file mode 100644
index 0000000..7cecbab
--- /dev/null
+++ b/tests/controller_ui_navigation_validation.gd
@@ -0,0 +1,82 @@
+extends SceneTree
+
+const ControllerFocusNavigationType = preload(
+ "res://ui/controller_focus_navigation.gd"
+)
+const UIReferencePresentationType = preload(
+ "res://ui/ui_reference_presentation.gd"
+)
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ _validate_spatial_navigation()
+ _validate_controller_hierarchy_contract()
+ _validate_four_by_three_centering()
+ _validate_low_end_profile_contract()
+ print("Controller UI navigation validation: PASS")
+ quit()
+
+
+func _validate_spatial_navigation() -> void:
+ var host := Control.new()
+ root.add_child(host)
+ var center := _make_button(host, "center", Vector2(200.0, 200.0))
+ var left := _make_button(host, "left", Vector2(50.0, 200.0))
+ var right := _make_button(host, "right", Vector2(350.0, 200.0))
+ var top := _make_button(host, "top", Vector2(200.0, 50.0))
+ var bottom := _make_button(host, "bottom", Vector2(200.0, 350.0))
+ var controls: Array[Control] = [center, left, right, top, bottom]
+ ControllerFocusNavigationType.configure_spatial_neighbors(controls)
+ assert(center.get_node(center.focus_neighbor_left) == left)
+ assert(center.get_node(center.focus_neighbor_right) == right)
+ assert(center.get_node(center.focus_neighbor_top) == top)
+ assert(center.get_node(center.focus_neighbor_bottom) == bottom)
+ host.queue_free()
+
+
+func _validate_controller_hierarchy_contract() -> void:
+ var source: String = FileAccess.get_file_as_string(
+ "res://ui/player_menu.gd"
+ )
+ assert(source.contains("ROLE_POINTER_MODIFIER"))
+ assert(source.contains("ROLE_CAMERA_ZOOM"))
+ assert(source.contains("_handle_controller_secondary_switch"))
+ assert(source.contains("ROLE_LB"))
+ assert(source.contains("ROLE_RB"))
+ assert(source.contains("_reserve_main_navigation_for_page_switching"))
+
+
+func _validate_four_by_three_centering() -> void:
+ var stage_position: Vector2 = (
+ UIReferencePresentationType.get_stage_position(Vector2(640.0, 480.0))
+ )
+ assert(stage_position.is_equal_approx(Vector2(0.0, 120.0)))
+
+
+func _validate_low_end_profile_contract() -> void:
+ var launcher: String = FileAccess.get_file_as_string(
+ "res://scripts/portmaster/NETfishing.sh"
+ )
+ assert(launcher.contains("allwinner,h616"))
+ assert(launcher.contains("sun50iw9p1"))
+ assert(launcher.contains("NETFISHING_LOW_END=1"))
+ assert(launcher.contains("--max-fps 30"))
+ assert(launcher.contains("--audio-output-latency 40"))
+
+
+func _make_button(
+ host: Control,
+ button_name: String,
+ button_position: Vector2,
+) -> Button:
+ var button := Button.new()
+ button.name = button_name
+ button.position = button_position
+ button.size = Vector2(80.0, 80.0)
+ button.focus_mode = Control.FOCUS_ALL
+ host.add_child(button)
+ return button
diff --git a/tests/controller_ui_navigation_validation.gd.uid b/tests/controller_ui_navigation_validation.gd.uid
new file mode 100644
index 0000000..73ef752
--- /dev/null
+++ b/tests/controller_ui_navigation_validation.gd.uid
@@ -0,0 +1 @@
+uid://cbv0ia42rqu41
diff --git a/tests/dedicated_host_session_validation.gd b/tests/dedicated_host_session_validation.gd
new file mode 100644
index 0000000..2d098bd
--- /dev/null
+++ b/tests/dedicated_host_session_validation.gd
@@ -0,0 +1,60 @@
+extends SceneTree
+
+const TEST_PORT: int = 35777
+const OPERATOR_FINGERPRINT: String = (
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+)
+
+
+func _init() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var harness := Node.new()
+ root.add_child(harness)
+ var players := Node3D.new()
+ harness.add_child(players)
+ var spawn_service := PlayerSpawnService.new()
+ harness.add_child(spawn_service)
+ spawn_service.setup(players, null, Transform3D.IDENTITY)
+ var host_identity := HostIdentityStore.new()
+ harness.add_child(host_identity)
+ var known_players := KnownPlayerStore.new()
+ harness.add_child(known_players)
+ var host_bans := HostBanStore.new()
+ harness.add_child(host_bans)
+ var session := NetworkSession.new()
+ harness.add_child(session)
+ await process_frame
+ session.setup(
+ null,
+ null,
+ spawn_service,
+ null,
+ host_identity,
+ known_players,
+ null,
+ host_bans,
+ true,
+ )
+ assert(session.configure_dedicated_operators(
+ PackedStringArray([OPERATOR_FINGERPRINT])
+ ))
+ assert(session.start_dedicated_host(TEST_PORT, 5, "127.0.0.1"))
+ assert(session.is_dedicated_host())
+ assert(session.get_local_peer_id() == 0)
+ assert(session.get_player_count() == 0)
+ assert(session.get_session_max_players() == 5)
+ assert(session.get_host_port() == TEST_PORT)
+ assert(bool(session.call(
+ "_operator_for_fingerprint", OPERATOR_FINGERPRINT
+ )))
+ assert(session.set_host_open(true))
+ assert(session.is_open_host())
+ session.disconnect_session("Dedicated host validation complete.")
+ assert(not session.is_session_active())
+ assert(not session.is_dedicated_host())
+ harness.queue_free()
+ print("DEDICATED_HOST_SESSION_VALIDATION_OK")
+ quit(0)
diff --git a/tests/dedicated_host_session_validation.gd.uid b/tests/dedicated_host_session_validation.gd.uid
new file mode 100644
index 0000000..e50ebb3
--- /dev/null
+++ b/tests/dedicated_host_session_validation.gd.uid
@@ -0,0 +1 @@
+uid://ctky0gkb63nqa
diff --git a/tests/dedicated_server_client_validation.gd b/tests/dedicated_server_client_validation.gd
new file mode 100644
index 0000000..9688af2
--- /dev/null
+++ b/tests/dedicated_server_client_validation.gd
@@ -0,0 +1,49 @@
+extends SceneTree
+
+const MainScene = preload("res://main/main.tscn")
+const TEST_ENDPOINT: String = "127.0.0.1:7777"
+const EXPECTED_SERVER_NAME: String = "Dedicated-Client-Test"
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ root.size = Vector2i(1280, 720)
+ var main: Node = MainScene.instantiate()
+ root.add_child(main)
+ for _frame: int in 4:
+ await process_frame
+ if not bool(main.get("_application_initialized")):
+ main.call("_activate_selected_data_path", "", true)
+ for _frame: int in 8:
+ await process_frame
+ assert(bool(main.get("_application_initialized")))
+ main.call("_on_title_join_game_requested", TEST_ENDPOINT)
+ var session := main.get_node("%NetworkSession") as NetworkSession
+ var joined: bool = false
+ var deadline: int = Time.get_ticks_msec() + 20000
+ while Time.get_ticks_msec() < deadline:
+ await process_frame
+ if session.state == NetworkSession.State.VERIFYING_SERVER_IDENTITY:
+ main.call("_confirm_server_trust")
+ if session.is_joined_client() and bool(main.get("_gameplay_started")):
+ joined = true
+ break
+ assert(joined)
+ assert(session.get_local_peer_id() > 1)
+ assert(session.get_player_count() == 1)
+ var metadata: Dictionary = session.get_last_server_metadata()
+ assert(str(metadata.get("server_display_name", "")) == EXPECTED_SERVER_NAME)
+ var spawn_service := main.get_node(
+ "%PlayerSpawnService"
+ ) as PlayerSpawnService
+ assert(spawn_service.get_avatar(1) == null)
+ assert(spawn_service.get_avatar(session.get_local_peer_id()) != null)
+ print("DEDICATED_SERVER_CLIENT_VALIDATION_OK")
+ session.disconnect_session("Dedicated client validation complete.")
+ main.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ quit()
diff --git a/tests/dedicated_server_client_validation.gd.uid b/tests/dedicated_server_client_validation.gd.uid
new file mode 100644
index 0000000..ed7a3b7
--- /dev/null
+++ b/tests/dedicated_server_client_validation.gd.uid
@@ -0,0 +1 @@
+uid://cwum3r4puerll
diff --git a/tests/dedicated_server_config_validation.gd b/tests/dedicated_server_config_validation.gd
new file mode 100644
index 0000000..6fef7c6
--- /dev/null
+++ b/tests/dedicated_server_config_validation.gd
@@ -0,0 +1,209 @@
+extends SceneTree
+
+const ConfigType = preload("res://server/dedicated_server_config.gd")
+const OPERATOR_A: String = (
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+)
+const OPERATOR_B: String = (
+ "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
+)
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var defaults := ConfigType.new()
+ defaults.set("data_directory", "/tmp/netfishing-server")
+ defaults.call("_validate")
+ assert(defaults.is_valid())
+ assert(not bool(defaults.get("public_listing")))
+
+ var path: String = ProjectSettings.globalize_path(
+ "user://dedicated-server-validation.cfg"
+ )
+ var file := ConfigFile.new()
+ file.set_value("server", "name", "Configured Room")
+ file.set_value("server", "bind_address", "127.0.0.1")
+ file.set_value("server", "port", 17777)
+ file.set_value("server", "max_players", 12)
+ file.set_value("server", "public", true)
+ file.set_value("server", "data_directory", "/tmp/configured-server")
+ file.set_value("discovery", "url", "https://discovery.netfishing.org/")
+ file.set_value(
+ "moderation", "operators", PackedStringArray([OPERATOR_B, OPERATOR_A])
+ )
+ assert(file.save(path) == OK)
+
+ var configured := ConfigType.new()
+ assert(bool(configured.call("_load_file", path)))
+ configured.call("_validate")
+ assert(configured.is_valid())
+ assert(str(configured.get("server_name")) == "Configured Room")
+ assert(str(configured.get("bind_address")) == "127.0.0.1")
+ assert(int(configured.get("port")) == 17777)
+ assert(int(configured.get("max_players")) == 12)
+ assert(bool(configured.get("public_listing")))
+ assert(str(configured.get("discovery_url")) == "https://discovery.netfishing.org")
+ assert(
+ configured.get("operator_fingerprints")
+ == PackedStringArray([OPERATOR_A, OPERATOR_B])
+ )
+ assert(DirAccess.remove_absolute(path) == OK)
+
+ var parsed := ConfigType.new()
+ parsed.set(
+ "operator_fingerprints",
+ ConfigType._parse_fingerprint_list(
+ "%s, %s;%s" % [OPERATOR_B.to_upper(), OPERATOR_A, OPERATOR_A]
+ ),
+ )
+ parsed.set("data_directory", "/tmp/parsed-server")
+ parsed.call("_validate")
+ assert(parsed.is_valid())
+ assert(
+ parsed.get("operator_fingerprints")
+ == PackedStringArray([OPERATOR_A, OPERATOR_B])
+ )
+
+ var invalid_operator := ConfigType.new()
+ invalid_operator.set(
+ "operator_fingerprints", PackedStringArray(["not-a-fingerprint"])
+ )
+ invalid_operator.set("data_directory", "/tmp/invalid-operator-server")
+ invalid_operator.call("_validate")
+ assert(not invalid_operator.is_valid())
+
+ var invalid := ConfigType.new()
+ invalid.set("public_listing", true)
+ invalid.set("data_directory", "/tmp/invalid-server")
+ invalid.call("_validate")
+ assert(not invalid.is_valid())
+
+ var discovery := DiscoveryClient.new()
+ assert(
+ str(discovery.call("_default_room_name", "River"))
+ == "River's Server"
+ )
+ assert(
+ DiscoveryClient.UPNP_RENEW_INTERVAL_SECONDS
+ < float(DiscoveryClient.UPNP_MAPPING_DURATION_SECONDS)
+ )
+ assert(
+ DiscoveryClient.UPNP_RETRY_INTERVAL_SECONDS
+ < DiscoveryClient.UPNP_RENEW_INTERVAL_SECONDS
+ )
+ var discovery_settings_path: String = ProjectSettings.globalize_path(
+ DiscoveryClient.SETTINGS_PATH
+ )
+ assert(not FileAccess.file_exists(discovery_settings_path))
+ assert(discovery.set_room_name("Client Room"))
+ var client_settings: PackedByteArray = FileAccess.get_file_as_bytes(
+ discovery_settings_path
+ )
+ assert(not client_settings.is_empty())
+ var dedicated_discovery := DiscoveryClient.new()
+ dedicated_discovery.call("_load_settings")
+ assert(
+ dedicated_discovery.configure_dedicated_runtime("Headless Room")
+ )
+ assert(dedicated_discovery.get_room_name() == "Headless Room")
+ assert(
+ FileAccess.get_file_as_bytes(discovery_settings_path)
+ == client_settings
+ )
+ dedicated_discovery.free()
+ assert(DirAccess.remove_absolute(discovery_settings_path) == OK)
+ assert(
+ discovery.get_host_state()
+ == DiscoveryClient.HostState.CLOSED
+ )
+ assert(
+ discovery.get_public_join_state()
+ == DiscoveryClient.PublicJoinState.IDLE
+ )
+ discovery.set("_lease_room_id", "local-room")
+ assert(discovery.is_own_room({"room_id": "local-room"}))
+ assert(not discovery.is_own_room({"room_id": "another-room"}))
+ discovery.set("_lease_room_id", "")
+ assert(not discovery.is_own_room({"room_id": "local-room"}))
+ var listed_room := {
+ "room_id": "empty-dedicated-room",
+ "room_name": "Empty Dedicated Room",
+ "address": "203.0.113.10",
+ "port": 7777,
+ "current_players": 0,
+ "max_players": 8,
+ "game_version": str(ProjectSettings.get_setting(
+ "application/config/version", "unknown"
+ )),
+ "protocol_version": NetworkProtocol.PROTOCOL_VERSION,
+ }
+ assert(bool(discovery.call("_valid_public_room", listed_room)))
+ var incompatible_room: Dictionary = listed_room.duplicate(true)
+ incompatible_room["game_version"] = "0.0.0-alpha"
+ assert(not bool(discovery.call("_valid_public_room", incompatible_room)))
+ assert(
+ NetworkProtocol.game_version_rejection(
+ "0.6.4-alpha", "0.6.5-alpha"
+ ) == NetworkProtocol.RejectionCode.CLIENT_OUTDATED
+ )
+ assert(
+ NetworkProtocol.game_version_rejection(
+ "0.6.6-alpha", "0.6.5-alpha"
+ ) == NetworkProtocol.RejectionCode.SERVER_OUTDATED
+ )
+ assert(
+ NetworkProtocol.game_version_rejection(
+ "0.6.5-alpha", "0.6.5-alpha"
+ ) == NetworkProtocol.RejectionCode.NONE
+ )
+ assert(
+ NetworkProtocol.game_version_rejection(
+ "0.6.5-beta", "0.6.5-alpha"
+ ) == NetworkProtocol.RejectionCode.SERVER_OUTDATED
+ )
+ var outdated_discovery_error := {
+ "error": {
+ "code": "game_version_mismatch",
+ "message": "generic mismatch",
+ "required_game_version": "99.0.0-alpha",
+ },
+ }
+ var outdated_message: String = str(
+ discovery.call("_request_failure", outdated_discovery_error)
+ )
+ assert("out of date" in outdated_message)
+ assert("99.0.0-alpha" in outdated_message)
+ assert("will not be listed" in outdated_message)
+ discovery.set(
+ "_host_request_kind",
+ DiscoveryClient.HostRequestKind.CREATE,
+ )
+ discovery.set("_host_request_in_flight", true)
+ discovery.call(
+ "_on_host_request_completed",
+ HTTPRequest.RESULT_SUCCESS,
+ HTTPClient.RESPONSE_CONFLICT,
+ PackedStringArray(),
+ JSON.stringify(outdated_discovery_error).to_utf8_buffer(),
+ )
+ assert(discovery.get_host_state() == DiscoveryClient.HostState.ERROR)
+ assert(discovery.host_status_is_error())
+ assert(discovery.get_host_status_message() == outdated_message)
+ var newer_discovery_error := {
+ "error": {
+ "code": "game_version_mismatch",
+ "message": "generic mismatch",
+ "required_game_version": "0.0.0-alpha",
+ },
+ }
+ var newer_message: String = str(
+ discovery.call("_request_failure", newer_discovery_error)
+ )
+ assert("discovery is updated" in newer_message)
+ assert("will not be listed" in newer_message)
+ discovery.free()
+ print("DEDICATED_SERVER_CONFIG_VALIDATION_OK")
+ quit()
diff --git a/tests/dedicated_server_config_validation.gd.uid b/tests/dedicated_server_config_validation.gd.uid
new file mode 100644
index 0000000..4bc60d1
--- /dev/null
+++ b/tests/dedicated_server_config_validation.gd.uid
@@ -0,0 +1 @@
+uid://vm5lql2w6h3e
diff --git a/tests/economy_regression_validation.gd b/tests/economy_regression_validation.gd
index 9b40e74..51ba48d 100644
--- a/tests/economy_regression_validation.gd
+++ b/tests/economy_regression_validation.gd
@@ -82,7 +82,9 @@ func _run() -> void:
print("Economy regression validation: PASS")
session.disconnect_session("Economy validation complete.")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -96,7 +98,10 @@ func _run_multiplayer_host() -> void:
var session := main.get_node("%NetworkSession") as NetworkSession
assert(session.set_host_open(true))
var client_connected := false
- var connection_deadline: int = Time.get_ticks_msec() + 30000
+ # Loading the full client world can take longer on a cold import. Keep the
+ # host available until the client has completed authentication rather than
+ # timing out while the client is still starting.
+ var connection_deadline: int = Time.get_ticks_msec() + 60000
while Time.get_ticks_msec() < connection_deadline:
await process_frame
if session.get_authenticated_peer_ids().size() >= 2:
@@ -126,7 +131,9 @@ func _run_multiplayer_host() -> void:
print("Economy multiplayer host validation: PASS")
session.disconnect_session("Economy host validation complete.")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -228,7 +235,9 @@ func _run_multiplayer_client() -> void:
print("Economy multiplayer client validation: PASS")
session.disconnect_session("Economy client validation complete.")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -407,7 +416,7 @@ func _test_player_menu_sale(
assert(sell_action.mouse_filter == Control.MOUSE_FILTER_STOP)
assert(sell_action.focus_mode == Control.FOCUS_ALL)
assert(ui_viewport != null)
- await _activate_focused_button(sell_action, ui_viewport)
+ await _activate_pointer_control(sell_action, ui_viewport)
await process_frame
assert(confirmation.visible)
assert(confirm_button.visible and not confirm_button.disabled)
@@ -416,7 +425,7 @@ func _test_player_menu_sale(
> (player_menu.get_node("%CoolerOuterWall") as Control).z_index
)
_sale_result.clear()
- await _activate_focused_button(confirm_button, ui_viewport)
+ await _activate_pointer_control(confirm_button, ui_viewport)
await process_frame
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
@@ -435,18 +444,29 @@ func _test_player_menu_sale(
await create_timer(2.2).timeout
-func _activate_focused_button(
- button: Button,
+func _activate_pointer_control(
+ control: Control,
ui_viewport: SubViewport,
) -> void:
- button.grab_focus()
+ var presenter := ui_viewport.get_parent() as SubViewportContainer
+ assert(presenter != null)
+ var local_center: Vector2 = control.get_global_transform_with_canvas() * (
+ control.size * 0.5
+ )
+ var center: Vector2 = presenter.position + local_center * presenter.scale
+ var motion := InputEventMouseMotion.new()
+ motion.position = center
+ motion.global_position = center
+ root.push_input(motion, true)
await process_frame
- assert(button.has_focus())
+ assert(ui_viewport.gui_get_hovered_control() == control)
for is_pressed: bool in [true, false]:
- var accept := InputEventAction.new()
- accept.action = &"ui_accept"
- accept.pressed = is_pressed
- ui_viewport.push_input(accept, false)
+ var click := InputEventMouseButton.new()
+ click.button_index = MOUSE_BUTTON_LEFT
+ click.position = center
+ click.global_position = center
+ click.pressed = is_pressed
+ root.push_input(click, true)
await process_frame
@@ -495,6 +515,8 @@ func _test_host_art_shop_purchase(
ArtShopStock.ART_KIT_ITEM_ID
)
assert(art_item != null and art_item.hotbar_allowed and art_item.equippable)
+ assert(art_item.icon != null)
+ assert(art_item.icon.resource_path.ends_with("/art/art_kit.png"))
assert(player.hotbar.assign_item(0, ArtShopStock.ART_KIT_ITEM_ID))
for product_id: StringName in [
&"marker_ocean_teal", &"brush_2x", &"grid_32x",
@@ -552,20 +574,94 @@ func _test_fishing_shop_sale_ui(
var shop_panel_style := shop_panel.get_theme_stylebox("panel") as StyleBoxFlat
assert(shop_panel_style != null)
assert(shop_panel_style.corner_radius_top_left == 24)
- var buy_mode := shop.get_node("%BuyModeButton") as Button
- var sell_mode := shop.get_node("%SellModeButton") as Button
- assert(buy_mode.visible and sell_mode.visible)
+ var upgrade_grid := shop.get_node("%UpgradeGrid") as GridContainer
+ assert(upgrade_grid != null and upgrade_grid.columns == 3)
+ assert((shop.get_node("%Upgrades") as Control).visible)
+ assert(not (shop.get_node("%Supplies") as Control).visible)
+ for upgrade_name: String in [
+ "ReelPurchase", "BarrierPurchase", "CoolerPurchase"
+ ]:
+ var upgrade_button := shop.get_node("%%%s" % upgrade_name) as Button
+ assert(upgrade_button != null)
+ assert(upgrade_button.size == Vector2(144.0, 144.0))
+ assert(upgrade_button.text.is_empty())
+ assert(upgrade_button.icon != null)
+ assert(upgrade_button.tooltip_text.contains("level"))
+ assert(not shop.has_node("%ReelLevel"))
+ assert(not shop.has_node("%BarrierEffect"))
+ assert(not shop.has_node("%CoolerLevel"))
+ var balance_coin := shop.get_node(
+ "ShopPanel/Margin/Layout/Header/BalanceDisplay/CoinIcon"
+ ) as TextureRect
+ assert(balance_coin != null and balance_coin.texture != null)
+ assert(
+ balance_coin.texture.resource_path.ends_with(
+ "/shop/32_currency.png"
+ )
+ )
+ for cost_name: String in ["ReelCost", "BarrierCost", "CoolerCost"]:
+ var cost_display := shop.get_node("%%%s" % cost_name) as CurrencyAmount
+ assert(cost_display != null)
+ var cost_icon := cost_display.get_node("Icon") as TextureRect
+ assert(cost_icon != null and cost_icon.texture != null)
+ assert(
+ cost_icon.texture.resource_path.ends_with(
+ "/shop/32_currency.png"
+ )
+ )
+ assert(not shop.has_node("ShopPanel/Margin/Layout/ModeTabs"))
+ var shop_tabs: Array = shop.get("_shop_tabs") as Array
+ assert(shop_tabs.size() == 6)
+ var art_supplies_tab := shop_tabs[4] as Button
+ assert(art_supplies_tab != null and art_supplies_tab.text == "Art Supplies")
+ var sell_mode := shop_tabs[5] as Button
+ assert(sell_mode != null and sell_mode.text == "Sell Fish")
+ await _activate_pointer_control(art_supplies_tab, ui_viewport)
+ await process_frame
var stock_sections: Array[String] = []
for child: Node in shop.get_node("%SuppliesList").get_children():
if child is Label:
stock_sections.append((child as Label).text)
- assert(stock_sections == ["supplies", "art kit", "markers", "brushes", "grids"])
- await _activate_focused_button(sell_mode, ui_viewport)
+ assert(stock_sections == ["art kit", "markers", "brushes", "grids"])
+ var marker_icons := shop.find_children(
+ "MarkerIcon", "TextureRect", true, false
+ )
+ assert(marker_icons.size() == ArtShopStock.MARKER_PRODUCTS.size())
+ for index: int in marker_icons.size():
+ var marker_icon := marker_icons[index] as TextureRect
+ var marker_material := marker_icon.material as ShaderMaterial
+ var product_id: StringName = ArtShopStock.MARKER_PRODUCTS[index]
+ var color_id: StringName = PlayerArtUnlocks.color_id_for_product(
+ product_id
+ )
+ assert(marker_icon.texture.resource_path.ends_with("art_kit_marker.png"))
+ assert(marker_material != null)
+ assert(
+ marker_material.get_shader_parameter("marker_color")
+ == SurfaceDrawingPalette.get_color(color_id)
+ )
+ var price_bubbles := shop.find_children(
+ "PriceBubble", "PanelContainer", true, false
+ )
+ assert(not price_bubbles.is_empty())
+ for price_bubble: Node in price_bubbles:
+ var currency_icon := price_bubble.find_child(
+ "CurrencyIcon", true, false
+ ) as TextureRect
+ assert(currency_icon != null and currency_icon.texture != null)
+ assert(
+ currency_icon.texture.resource_path.ends_with(
+ "/shop/32_currency.png"
+ )
+ )
+ await _activate_pointer_control(sell_mode, ui_viewport)
await process_frame
assert(shop.visible and not player_menu.visible)
assert(not shop.has_node("ShopPanel/Margin/Layout/Body/FishSales"))
assert((shop.get_node("%ShopCoolerPage") as Control).visible)
- assert(not (shop.get_node("%ShopPanel") as Control).visible)
+ assert((shop.get_node("%ShopPanel") as Control).visible)
+ assert(not (shop.get_node("ShopPanel/Margin/Layout/Body") as Control).visible)
+ assert(not (shop.get_node("%Feedback") as Control).visible)
var mounted_cooler := player_menu.get("_cooler_page") as Control
assert(mounted_cooler != null and mounted_cooler.visible)
assert(
@@ -575,6 +671,11 @@ func _test_fishing_shop_sale_ui(
var water_surface := player_menu.get("_cooler_water_surface") as ColorRect
assert(cooler_outer_wall != null and cooler_outer_wall.visible)
assert(water_surface.visible and water_surface.material is ShaderMaterial)
+ var cooler_sort_option := player_menu.get("_cooler_sort_option") as Control
+ await _activate_pointer_control(cooler_sort_option, ui_viewport)
+ var cooler_choice_panel := cooler_sort_option.get("_choice_panel") as Control
+ assert(cooler_choice_panel.visible)
+ cooler_sort_option.call("close_choices")
assert(
StringName(
(player_menu.get("_sale_buyer_override") as FishBuyerProfile).id
@@ -585,10 +686,10 @@ func _test_fishing_shop_sale_ui(
var reserved_button := fish_nodes.get(reserved_catch.catch_id) as Button
assert(fish_button != null and fish_button.visible)
assert(reserved_button != null and reserved_button.visible)
- await _activate_focused_button(fish_button, ui_viewport)
+ await _activate_pointer_control(fish_button, ui_viewport)
var sell_button := player_menu.get("_sell_bubble") as Button
assert(sell_button.visible and not sell_button.disabled)
- await _activate_focused_button(sell_button, ui_viewport)
+ await _activate_pointer_control(sell_button, ui_viewport)
await process_frame
var confirmation := player_menu.get("_sale_confirmation") as Control
var confirm_button := player_menu.get("_confirm_sale_button") as Button
@@ -598,21 +699,21 @@ func _test_fishing_shop_sale_ui(
> cooler_outer_wall.z_index
)
_sale_result.clear()
- await _activate_focused_button(confirm_button, ui_viewport)
+ await _activate_pointer_control(confirm_button, ui_viewport)
await process_frame
assert(not _sale_result.is_empty() and bool(_sale_result[1]))
assert(not player.inventory.contains_catch_id(fish_catch.catch_id))
assert(player.wallet.get_balance() == balance_before + fish_catch.sale_value)
assert(not sale_service.is_local_sale_pending())
assert(reservations.release(reservation_id))
- var back_button := shop.get_node("%BackToShopButton") as Button
- await _activate_focused_button(back_button, ui_viewport)
+ await _activate_pointer_control(shop_tabs[0] as Button, ui_viewport)
await process_frame
assert(shop.visible and (shop.get_node("%ShopPanel") as Control).visible)
assert(not (shop.get_node("%ShopCoolerPage") as Control).visible)
assert(not player_menu.is_shop_cooler_mounted())
shop.close_shop()
- await process_frame
+ await shop.menu_visibility_changed
+ assert(not shop.visible)
func _assert_sale(
@@ -633,7 +734,9 @@ func _assert_sale(
assert(bool(_sale_result[1]) == expected_success)
assert(not sale_service.is_local_sale_pending())
if expected_success:
- assert(player.wallet.get_balance() > balance_before)
+ var payout: int = int(_sale_result[4])
+ assert(payout >= 0)
+ assert(player.wallet.get_balance() == balance_before + payout)
for catch_id: StringName in catch_ids:
assert(not player.inventory.contains_catch_id(catch_id))
else:
diff --git a/tests/exported_decal_hotfix_validation.gd b/tests/exported_decal_hotfix_validation.gd
index be70325..fe279b0 100644
--- a/tests/exported_decal_hotfix_validation.gd
+++ b/tests/exported_decal_hotfix_validation.gd
@@ -1,5 +1,11 @@
extends SceneTree
+const FEATURE_ASSET_ROOTS: Dictionary = {
+ "eyes": "res://art/exported/characters/faces/eyes",
+ "mouth": "res://art/exported/characters/faces/mouth",
+ "nose": "res://art/exported/characters/faces/noses",
+}
+
func _initialize() -> void:
call_deferred("_run")
@@ -27,10 +33,10 @@ func _run() -> void:
).is_empty()
)
- var expected_counts := {"eyes": 22, "mouth": 17, "nose": 17}
- for category_id: String in expected_counts:
+ for category_id: String in FEATURE_ASSET_ROOTS:
var options := CharacterCustomizationCatalog.options_for(category_id)
- assert(options.size() == int(expected_counts[category_id]) + 1)
+ var expected_ids: Dictionary = _feature_ids_on_disk(category_id)
+ assert(options.size() == expected_ids.size() + 1)
var seen_ids: Dictionary = {}
for option: Dictionary in options:
var option_id := str(option.get("id", ""))
@@ -42,6 +48,30 @@ func _run() -> void:
category_id, option_id
) != null
)
+ for expected_id: String in expected_ids:
+ assert(seen_ids.has(expected_id))
+ for mouth_id: String in ["open_ah", "open_oh", "open_smile"]:
+ assert(CharacterCustomizationCatalog.texture_for(
+ "mouth", mouth_id
+ ) != null)
print("Exported decal hotfix validation: PASS")
quit()
+
+
+func _feature_ids_on_disk(category_id: String) -> Dictionary:
+ var result: Dictionary = {}
+ var root_path: String = str(FEATURE_ASSET_ROOTS[category_id])
+ var directory := DirAccess.open(root_path)
+ assert(directory != null)
+ for file_name: String in directory.get_files():
+ if not file_name.to_lower().ends_with(".png"):
+ continue
+ var option_id: String = (
+ CharacterCustomizationCatalog._feature_id_from_filename(
+ category_id, file_name
+ )
+ )
+ if not option_id.is_empty():
+ result[option_id] = true
+ return result
diff --git a/tests/fish_catalog_content_validation.gd b/tests/fish_catalog_content_validation.gd
index 0b7235b..6746d70 100644
--- a/tests/fish_catalog_content_validation.gd
+++ b/tests/fish_catalog_content_validation.gd
@@ -313,7 +313,12 @@ func _validate_starter_water_bodies() -> void:
assert(pond.fish_pool == PondPool)
assert(ocean.fish_pool == OceanPool)
assert(region.get_node_or_null("ShorelineRibbons/Pond") == null)
- assert(region.get_node_or_null("ShorelineRibbons/Ocean") != null)
+ var shoreline_geometry := (
+ region.get_node_or_null("ShorelineRibbons/Ocean") as MeshInstance3D
+ )
+ assert(shoreline_geometry != null)
+ assert(not shoreline_geometry.visible)
+ assert(shoreline_geometry.material_override == null)
var pond_material := (
region.get_node("WaterBodies/Pond/VisualWater") as MeshInstance3D
).material_override as ShaderMaterial
diff --git a/tests/fish_hotbar_showcase_validation.gd b/tests/fish_hotbar_showcase_validation.gd
index ec802b0..06b2f4d 100644
--- a/tests/fish_hotbar_showcase_validation.gd
+++ b/tests/fish_hotbar_showcase_validation.gd
@@ -3,7 +3,6 @@ extends SceneTree
const MainScene = preload("res://main/main.tscn")
const FishCatchType = preload("res://fish/fish_catch.gd")
const FishDataType = preload("res://fish/fish_data.gd")
-const FishingSpotType = preload("res://fishing/fishing_spot.gd")
func _initialize() -> void:
@@ -40,7 +39,6 @@ func _run() -> void:
var service := main.get_node(
"%NetworkFishShowcaseService"
) as NetworkFishShowcaseService
- var fishing_spot := main.get_node("%FishingSpot") as FishingSpotType
assert(player != null and fish_catalog != null and service != null)
var fish: FishDataType = fish_catalog.get_fish_by_id(&"bluegill")
assert(fish != null)
@@ -83,22 +81,18 @@ func _run() -> void:
assert(player.hotbar.get_selected_fish_catch_id() == fish_catch.catch_id)
assert(player.hotbar.get_selected_item_id().is_empty())
- var press := InputEventMouseButton.new()
- press.button_index = MOUSE_BUTTON_LEFT
- press.pressed = true
- fishing_spot.call("_unhandled_input", press)
- await process_frame
assert(service.is_local_showcase_visible())
assert(service.get_local_showcase_catch_id() == fish_catch.catch_id)
- assert((player.get_node("%HeldFishDisplay") as Node3D).visible)
- fishing_spot.call("_unhandled_input", press)
+ await _wait_for_held_fish_visibility(player, true)
+ assert(service.toggle_selected_fish())
await process_frame
assert(not service.is_local_showcase_visible())
- assert(not (player.get_node("%HeldFishDisplay") as Node3D).visible)
+ await _wait_for_held_fish_visibility(player, false)
var saved_weather: WorldWeatherService.Weather = (
world_weather.get_weather()
)
var saved_weather_seconds: float = world_weather.get_seconds_remaining()
+ var saved_time_hours: float = world_time.get_time_hours()
assert(save_manager.save_now())
var save_path: String = str(save_manager.get("_save_path"))
@@ -116,7 +110,7 @@ func _run() -> void:
== 125
)
assert(absf(
- float((parsed as Dictionary)["world"]["time_hours"]) - 19.75
+ float((parsed as Dictionary)["world"]["time_hours"]) - saved_time_hours
) < 0.01)
assert(
int((parsed as Dictionary)["world"]["weather"])
@@ -149,7 +143,7 @@ func _run() -> void:
)
assert(save_manager.load_player_data())
assert(player.experience.get_total_experience() == 125)
- assert(absf(world_time.get_time_hours() - 19.75) < 0.01)
+ assert(absf(world_time.get_time_hours() - saved_time_hours) < 0.01)
assert(world_weather.get_weather() == saved_weather)
assert(absf(
world_weather.get_seconds_remaining() - saved_weather_seconds
@@ -163,14 +157,13 @@ func _run() -> void:
FishQuality.Tier.EXCEPTIONAL,
)
)
- assert(not service.is_local_showcase_visible())
- assert(service.toggle_selected_fish())
assert(service.is_local_showcase_visible())
+ await _wait_for_held_fish_visibility(player, true)
assert(player.inventory.remove_catch_by_id(fish_catch.catch_id) != null)
await process_frame
assert(player.hotbar.get_fish_catch_id(1).is_empty())
assert(not service.is_local_showcase_visible())
- assert(not (player.get_node("%HeldFishDisplay") as Node3D).visible)
+ await _wait_for_held_fish_visibility(player, false)
var valid_state: Dictionary = {
"session_id": "session",
@@ -188,7 +181,7 @@ func _run() -> void:
var invalid_state: Dictionary = valid_state.duplicate(true)
invalid_state["display_scale"] = 1000.0
assert(not NetworkFishShowcaseProtocol.validate_state(invalid_state))
- assert(NetworkProtocol.PROTOCOL_VERSION == 3)
+ assert(NetworkProtocol.PROTOCOL_VERSION == 4)
assert(NetworkProtocol.ENET_CHANNEL_COUNT == 10)
assert(
NetworkProtocol.FISH_QUALITY_CAPABILITY
@@ -202,5 +195,26 @@ func _run() -> void:
print("Fish hotbar showcase validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
+
+
+func _wait_for_held_fish_visibility(
+ player: Player,
+ expected_visible: bool,
+) -> void:
+ var held_fish_display := player.get("_held_fish_display") as Node3D
+ assert(held_fish_display != null)
+ var deadline_msec: int = Time.get_ticks_msec() + 2000
+ while (
+ held_fish_display.visible != expected_visible
+ and Time.get_ticks_msec() < deadline_msec
+ ):
+ await process_frame
+ assert(
+ held_fish_display.visible == expected_visible,
+ "Held fish display did not become %s within the timeout."
+ % expected_visible,
+ )
diff --git a/tests/fish_quality_validation.gd b/tests/fish_quality_validation.gd
index 366128f..555fb3c 100644
--- a/tests/fish_quality_validation.gd
+++ b/tests/fish_quality_validation.gd
@@ -25,7 +25,7 @@ func _run() -> void:
_validate_mail_round_trip()
_validate_collection_mastery()
_validate_version_four_migration()
- assert(NetworkProtocol.PROTOCOL_VERSION == 3)
+ assert(NetworkProtocol.PROTOCOL_VERSION == 4)
assert(NetworkProtocol.ENET_CHANNEL_COUNT == 10)
assert(NetworkProtocol.FISH_QUALITY_CAPABILITY == "fish_quality_v1")
print("Fish quality validation: PASS")
@@ -83,40 +83,68 @@ func _validate_barrier_challenge_curve() -> void:
var expected_maximums: Array[int] = [9, 50, 100, 200, 400]
var previous_health: int = 0
for quality: int in FishQualityType.TIER_COUNT:
+ var expected_range := Vector2i(
+ expected_minimums[quality], expected_maximums[quality]
+ )
+ assert(
+ FishQualityType.barrier_health_range(quality)
+ == expected_range
+ )
+ assert(
+ FishQualityType.roll_barrier_health(null, quality)
+ == expected_range.x
+ )
+ var rng := RandomNumberGenerator.new()
+ rng.seed = 73013 + quality
+ var observed_counts: Dictionary[int, int] = {}
+ var observed_minimum: int = expected_range.y
+ var observed_maximum: int = expected_range.x
+ var observed_total: int = 0
+ var band_size: int = expected_range.y - expected_range.x + 1
+ var sample_count: int = maxi(10000, band_size * 250)
+ for _sample: int in sample_count:
+ var rolled_health: int = FishQualityType.roll_barrier_health(
+ rng, quality
+ )
+ assert(
+ rolled_health >= expected_range.x
+ and rolled_health <= expected_range.y
+ )
+ observed_counts[rolled_health] = (
+ int(observed_counts.get(rolled_health, 0)) + 1
+ )
+ observed_minimum = mini(observed_minimum, rolled_health)
+ observed_maximum = maxi(observed_maximum, rolled_health)
+ observed_total += rolled_health
+ assert(observed_minimum == expected_range.x)
+ assert(observed_maximum == expected_range.y)
+ for authored_health: int in range(
+ expected_range.x, expected_range.y + 1
+ ):
+ assert(observed_counts.has(authored_health))
+ var observed_average: float = (
+ float(observed_total) / float(sample_count)
+ )
+ var authored_midpoint: float = (
+ float(expected_range.x + expected_range.y) / 2.0
+ )
+ assert(
+ absf(observed_average - authored_midpoint)
+ < maxf(0.15, float(band_size) * 0.01)
+ )
var health: int = FishQualityType.apply_barrier_health(8, quality)
assert(health > previous_health)
previous_health = health
assert(FishQualityType.apply_barrier_health(8, -1) == 8)
assert(FishQualityType.apply_barrier_health(0, FishQualityType.Tier.SHINY) == 4)
- var impressive_low_input: int = FishQualityType.barrier_health_for_catch(
- FishQualityType.Tier.IMPRESSIVE,
- 0,
- 0.0,
- 1.0,
- )
- var impressive_high_input: int = FishQualityType.barrier_health_for_catch(
- FishQualityType.Tier.IMPRESSIVE,
- 4,
- 1.0,
- 1.0,
- )
- assert(impressive_low_input >= 50 and impressive_low_input <= 100)
- assert(impressive_high_input > impressive_low_input)
- assert(impressive_high_input <= 100)
assert(
- FishQualityType.barrier_health_for_catch(
- FishQualityType.Tier.BORING,
- 4,
- 1.0,
- 1.0,
- ) <= 9
+ FishQualityType.barrier_health_range(-1)
+ == Vector2i(1, 9)
)
var profile := CatchDifficultyProfile.new()
profile.barrier_count_min = 1
profile.barrier_count_max = 1
- profile.barrier_health_min = 8
- profile.barrier_health_max = 8
profile.first_barrier_margin = 0.2
profile.final_barrier_margin = 0.2
profile.minimum_barrier_spacing = 0.1
@@ -141,12 +169,9 @@ func _validate_barrier_challenge_curve() -> void:
assert(health <= expected_maximums[quality])
controller.queue_free()
- var shiny_health: int = FishQualityType.barrier_health_for_catch(
- FishQualityType.Tier.SHINY,
- 4,
- 1.0,
- 1.0,
- )
+ var shiny_health: int = FishQualityType.barrier_health_range(
+ FishQualityType.Tier.SHINY
+ ).y
var base_power_clicks: int = ceili(float(shiny_health) / 1.0)
var max_power_clicks: int = ceili(
float(shiny_health)
diff --git a/tests/fish_showcase_multiplayer_validation.gd b/tests/fish_showcase_multiplayer_validation.gd
index 3b1ab54..72f4a59 100644
--- a/tests/fish_showcase_multiplayer_validation.gd
+++ b/tests/fish_showcase_multiplayer_validation.gd
@@ -35,8 +35,8 @@ func _run_host() -> void:
var fish_catch: FishCatch = _add_bluegill(main, player)
assert(player.hotbar.assign_fish(1, fish_catch.catch_id))
assert(player.hotbar.select_slot(1))
- assert(service.toggle_selected_fish())
assert(service.is_local_showcase_visible())
+ await _wait_for_held_fish_visibility(player, true)
assert(session.set_host_open(true))
var remote_peer_id: int = 0
@@ -53,7 +53,7 @@ func _run_host() -> void:
) as PlayerSpawnService
var remote_avatar: Player = spawn_service.get_avatar(remote_peer_id)
assert(remote_avatar != null)
- var remote_display := remote_avatar.get_node("%HeldFishDisplay") as Node3D
+ var remote_display := remote_avatar.get("_held_fish_display") as Node3D
var visible_deadline: int = Time.get_ticks_msec() + 10000
while Time.get_ticks_msec() < visible_deadline and not remote_display.visible:
await process_frame
@@ -66,7 +66,9 @@ func _run_host() -> void:
print("Fish showcase multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -95,29 +97,46 @@ func _run_client() -> void:
) as PlayerSpawnService
var host_avatar: Player = spawn_service.get_avatar(1)
assert(host_avatar != null)
- var host_display := host_avatar.get_node("%HeldFishDisplay") as Node3D
+ var host_display := host_avatar.get("_held_fish_display") as Node3D
var snapshot_deadline: int = Time.get_ticks_msec() + 10000
while Time.get_ticks_msec() < snapshot_deadline and not host_display.visible:
await process_frame
assert(host_display.visible)
var player := main.get("_player") as Player
+ var animation_player := player.get_node(
+ "Visuals/CharacterRig/AnimationPlayer"
+ ) as AnimationPlayer
+ for animation_name: StringName in [
+ &"pocket_idle_idle",
+ &"pocket_idle_show",
+ &"pocket_show_show",
+ &"pocket_show_idle",
+ ]:
+ assert(animation_player.has_animation(animation_name))
var service := main.get_node(
"%NetworkFishShowcaseService"
) as NetworkFishShowcaseService
var fish_catch: FishCatch = _add_bluegill(main, player)
assert(player.hotbar.assign_fish(1, fish_catch.catch_id))
assert(player.hotbar.select_slot(1))
- assert(service.toggle_selected_fish())
- assert((player.get_node("%HeldFishDisplay") as Node3D).visible)
+ assert(service.is_local_showcase_visible())
+ await _wait_for_held_fish_visibility(player, true)
await create_timer(2.0).timeout
assert(service.toggle_selected_fish())
- assert(not (player.get_node("%HeldFishDisplay") as Node3D).visible)
- await create_timer(1.0).timeout
+ var held_display := player.get("_held_fish_display") as Node3D
+ assert(held_display.visible)
+ assert(animation_player.current_animation == &"pocket_show_idle")
+ var pocket_deadline: int = Time.get_ticks_msec() + 5000
+ while Time.get_ticks_msec() < pocket_deadline and held_display.visible:
+ await process_frame
+ assert(not held_display.visible)
print("Fish showcase multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -151,3 +170,18 @@ func _create_initialized_main() -> Node:
await process_frame
assert(bool(main.get("_application_initialized")))
return main
+
+
+func _wait_for_held_fish_visibility(
+ player: Player,
+ expected_visible: bool,
+) -> void:
+ var held_fish_display := player.get("_held_fish_display") as Node3D
+ assert(held_fish_display != null)
+ var deadline_msec: int = Time.get_ticks_msec() + 2000
+ while (
+ held_fish_display.visible != expected_visible
+ and Time.get_ticks_msec() < deadline_msec
+ ):
+ await process_frame
+ assert(held_fish_display.visible == expected_visible)
diff --git a/tests/fishing_authority_validation.gd b/tests/fishing_authority_validation.gd
index dc79c44..6b0429d 100644
--- a/tests/fishing_authority_validation.gd
+++ b/tests/fishing_authority_validation.gd
@@ -31,13 +31,22 @@ func _run() -> void:
"%NetworkFishingService"
) as NetworkFishingService
var fishing_spot := main.get_node("%FishingSpot") as FishingSpotType
+ var game_ui := main.get_node("UIPresentation/UIViewport/GameUI")
+ var fishing_status := game_ui.get_node("%StatusLabel") as Label
+ var fishing_panel := game_ui.get_node("%FishingPanel") as PanelContainer
var player := main.get("_player") as Player
assert(session.is_host())
assert(not session.is_open_host())
assert(service != null and fishing_spot != null and player != null)
assert(player.hotbar.get_selected_item_id() == &"basic_fishing_rod")
+ var pond := main.get_node(
+ "TestWorld/Regions/StarterIslandRegion/WaterBodies/Pond"
+ ) as Node3D
+ var pond_region := pond.get_node("FishingRegion") as FishableWaterRegion
+ assert(pond != null and pond_region != null)
+ var pond_surface_y: float = pond_region.get_surface_height()
- player.global_position = Vector3(-0.5, 3.95, 2.1)
+ player.global_position = pond.global_position + Vector3(8.9, 1.44, 0.0)
var visuals := player.get_node("Visuals") as Node3D
visuals.rotation.y = PI * 0.5
for _frame: int in 4:
@@ -50,8 +59,8 @@ func _run() -> void:
fishing_spot.set("_cast_charge", 0.32)
fishing_spot.call("_update_cast_charge", 0.0)
var aimed_target: Vector3 = fishing_spot.get("_cast_target")
- assert(aimed_target.x < -1.35)
- assert(is_equal_approx(aimed_target.y, 2.51))
+ assert(aimed_target.x < player.global_position.x - 0.85)
+ assert(is_equal_approx(aimed_target.y, pond_surface_y))
assert(fishing_spot.is_target_fishable(aimed_target))
fishing_spot.call("_confirm_cast")
assert(fishing_spot.state == FishingSpotType.FishingState.CASTING)
@@ -65,10 +74,13 @@ func _run() -> void:
await process_frame
assert(fishing_spot.state == FishingSpotType.FishingState.WAITING_FOR_BITE)
assert(service.has_local_attempt())
+ assert(fishing_status.text.is_empty())
+ assert(not fishing_status.visible)
+ assert(not fishing_panel.visible)
var attempts: Dictionary = service.get("_attempts")
var attempt: NetworkFishingAttempt = attempts.get(session.get_local_peer_id())
assert(attempt != null)
- assert(is_equal_approx(attempt.target.y, 2.51))
+ assert(is_equal_approx(attempt.target.y, pond_surface_y))
assert(attempt.bobber_position.is_equal_approx(attempt.target))
fishing_spot.set("_withdrawal_input_held", true)
@@ -98,7 +110,7 @@ func _run() -> void:
assert(not bobber.visible)
# A private host rolls and retains the authoritative catch before the fight
- # so its quality can scale the same barriers clients receive in snapshots.
+ # so its quality selects the barrier band clients receive in snapshots.
fishing_spot.call("_begin_aiming", player)
fishing_spot.set("_cast_charge", 0.32)
fishing_spot.call("_update_cast_charge", 0.0)
@@ -124,35 +136,51 @@ func _run() -> void:
fish,
)
assert(fish_catch != null and fish_catch.is_valid())
- var baseline_controller := CatchController.new()
- root.add_child(baseline_controller)
- baseline_controller.start_authoritative_encounter(
+ var reference_controller := CatchController.new()
+ root.add_child(reference_controller)
+ reference_controller.start_authoritative_encounter(
fish.catch_profile,
attempt.reel_speed,
attempt.barrier_damage,
attempt.encounter_seed,
- FishQuality.Tier.BORING,
+ fish_catch.quality,
)
var quality_barriers: Array = attempt.controller.get("_barriers")
- var baseline_barriers: Array = baseline_controller.get("_barriers")
- assert(quality_barriers.size() == baseline_barriers.size())
+ var reference_barriers: Array = reference_controller.get("_barriers")
+ assert(quality_barriers.size() == reference_barriers.size())
for barrier_index: int in quality_barriers.size():
var quality_barrier: RefCounted = quality_barriers[barrier_index]
- var baseline_barrier: RefCounted = baseline_barriers[barrier_index]
+ var reference_barrier: RefCounted = reference_barriers[barrier_index]
assert(
- int(quality_barrier.get("maximum_health"))
- == FishQuality.apply_barrier_health(
- int(baseline_barrier.get("maximum_health")),
- fish_catch.quality,
+ is_equal_approx(
+ float(quality_barrier.get("position")),
+ float(reference_barrier.get("position")),
)
)
- baseline_controller.queue_free()
- service.call("_cancel_attempt", session.get_local_peer_id(), "")
+ assert(
+ int(quality_barrier.get("maximum_health"))
+ == int(reference_barrier.get("maximum_health"))
+ )
+ assert(
+ int(quality_barrier.get("maximum_health"))
+ >= FishQuality.BARRIER_HEALTH_MINIMUMS[fish_catch.quality]
+ )
+ assert(
+ int(quality_barrier.get("maximum_health"))
+ <= FishQuality.BARRIER_HEALTH_MAXIMUMS[fish_catch.quality]
+ )
+ reference_controller.queue_free()
+ service.call("_on_attempt_escaped", session.get_local_peer_id())
await process_frame
assert(not service.has_local_attempt())
+ assert(fishing_status.text.is_empty())
+ assert(not fishing_status.visible)
+ assert(not fishing_panel.visible)
print("Fishing authority validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/fishing_multiplayer_validation.gd b/tests/fishing_multiplayer_validation.gd
index fe9db15..c40e492 100644
--- a/tests/fishing_multiplayer_validation.gd
+++ b/tests/fishing_multiplayer_validation.gd
@@ -32,7 +32,7 @@ func _run_host() -> void:
"%NetworkFishingService"
) as NetworkFishingService
- var join_deadline: int = Time.get_ticks_msec() + 20000
+ var join_deadline: int = Time.get_ticks_msec() + 60000
while (
Time.get_ticks_msec() < join_deadline
and session.get_authenticated_peer_ids().size() < 2
@@ -50,10 +50,35 @@ func _run_host() -> void:
) as PlayerSpawnService
var remote_avatar: Player = spawn_service.get_avatar(remote_peer_id)
assert(remote_avatar != null)
+ assert(remote_avatar.bag.get_quantity(&"worms") == 0)
remote_avatar.global_position = Vector3(-0.5, 3.95, 2.1)
var remote_visuals := remote_avatar.get_node("Visuals") as Node3D
remote_visuals.rotation.y = PI * 0.5
session.publish_authoritative_teleport(remote_peer_id)
+ var aiming_deadline: int = Time.get_ticks_msec() + 15000
+ while (
+ Time.get_ticks_msec() < aiming_deadline
+ and int(remote_avatar.get("_fishing_visual_phase"))
+ != Player.FishingVisualPhase.CASTING
+ ):
+ await process_frame
+ assert(
+ int(remote_avatar.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.CASTING
+ )
+ var remote_position_error := (
+ remote_avatar.global_position - Vector3(-0.5, 3.95, 2.1)
+ )
+ remote_position_error.y = 0.0
+ assert(
+ remote_position_error.length() <= 0.25,
+ "remote casting position drifted: %s" % remote_avatar.global_position
+ )
+ assert(
+ remote_avatar.get_facing_direction().dot(Vector3.LEFT) > 0.99,
+ "remote casting facing drifted: %s"
+ % remote_avatar.get_facing_direction()
+ )
var saw_remote_attempt: bool = false
var remote_presentation: RemoteFishingPresentation
@@ -65,8 +90,8 @@ func _run_host() -> void:
if peer_id == session.get_local_peer_id():
continue
var attempt: NetworkFishingAttempt = attempts[peer_id]
- assert(is_equal_approx(attempt.target.y, 2.51))
- assert(attempt.bobber_position.y <= 2.51 + 0.001)
+ assert(attempt.target.is_finite())
+ assert(attempt.bobber_position.distance_to(attempt.target) <= 0.001)
var presentations: Dictionary = service.get("_remote_presentations")
remote_presentation = presentations.get(peer_id)
assert(remote_presentation != null)
@@ -78,6 +103,31 @@ func _run_host() -> void:
if saw_remote_attempt:
break
assert(saw_remote_attempt)
+ assert(
+ int(remote_avatar.get("_fishing_visual_phase"))
+ in [
+ Player.FishingVisualPhase.RELEASE,
+ Player.FishingVisualPhase.FISHING,
+ ]
+ )
+ var sitting_deadline: int = Time.get_ticks_msec() + 10000
+ while Time.get_ticks_msec() < sitting_deadline and not remote_avatar.is_sitting():
+ await process_frame
+ assert(remote_avatar.is_sitting())
+ var fishing_deadline: int = Time.get_ticks_msec() + 5000
+ while (
+ Time.get_ticks_msec() < fishing_deadline
+ and int(remote_avatar.get("_fishing_visual_phase"))
+ != Player.FishingVisualPhase.FISHING
+ ):
+ await process_frame
+ assert(
+ int(remote_avatar.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.FISHING
+ )
+ var remote_animation_player := remote_avatar.get_node(
+ "Visuals/CharacterRig/AnimationPlayer"
+ ) as AnimationPlayer
var return_deadline: int = Time.get_ticks_msec() + 5000
while (
Time.get_ticks_msec() < return_deadline
@@ -85,19 +135,24 @@ func _run_host() -> void:
):
await process_frame
assert(not service.has_peer_attempt(remote_peer_id))
- assert(is_instance_valid(remote_presentation))
- assert(remote_presentation.get("_return_tween") != null)
-
- var completion_deadline: int = Time.get_ticks_msec() + 12000
+ assert(
+ int(remote_avatar.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.RETRACT
+ )
+ var retract_animation_deadline: int = Time.get_ticks_msec() + 3000
while (
- Time.get_ticks_msec() < completion_deadline
- and session.get_authenticated_peer_ids().size() == 2
+ Time.get_ticks_msec() < retract_animation_deadline
+ and remote_animation_player.current_animation != &"retract_sit"
):
await process_frame
+ assert(remote_animation_player.current_animation == &"retract_sit")
+
print("Fishing multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -119,8 +174,23 @@ func _run_client() -> void:
var service := main.get_node(
"%NetworkFishingService"
) as NetworkFishingService
+ var cast_rejections: Array[String] = []
+ service.local_cast_rejected.connect(
+ func(message: String) -> void:
+ cast_rejections.append(message)
+ )
var fishing_spot := main.get_node("%FishingSpot") as FishingSpotType
var player := main.get("_player") as Player
+ var item_catalog := main.get("item_catalog") as ItemCatalog
+ var worms: ItemData = item_catalog.get_item_by_id(&"worms")
+ if player.bag.get_quantity(&"worms") == 0:
+ assert(player.bag.add_item(&"worms", 1))
+ assert(player.equip_bait(worms))
+ var worms_before_cast: int = player.bag.get_quantity(&"worms")
+ var character_animation_player := player.get_node(
+ "Visuals/CharacterRig/AnimationPlayer"
+ ) as AnimationPlayer
+ assert(character_animation_player.has_animation(&"retract_sit"))
var placement_deadline: int = Time.get_ticks_msec() + 5000
while (
Time.get_ticks_msec() < placement_deadline
@@ -131,14 +201,59 @@ func _run_client() -> void:
assert(player.global_position.distance_to(Vector3(-0.5, 3.95, 2.1)) <= 0.25)
assert(player.get_facing_direction().dot(Vector3.LEFT) > 0.99)
+ player.set_casting_visual()
+ assert(
+ int(player.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.CASTING
+ )
+ for _frame: int in 30:
+ await physics_frame
+ player.set_fishing_visual(false)
+ player.call("_set_sitting", true, true)
+ assert(player.is_sitting())
+ for _frame: int in 15:
+ await physics_frame
fishing_spot.call("_begin_aiming", player)
assert(player.is_movement_enabled())
- fishing_spot.set("_cast_charge", 0.32)
- fishing_spot.call("_update_cast_charge", 0.0)
- var target: Vector3 = fishing_spot.get("_cast_target")
- assert(fishing_spot.is_target_fishable(target))
- assert(is_equal_approx(target.y, 2.51))
- fishing_spot.call("_confirm_cast")
+ assert(
+ int(player.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.CASTING
+ )
+ var cast_charge: float = 0.0
+ var target: Vector3 = Vector3.ZERO
+ var cast_origin: Vector3 = fishing_spot.get("_cast_origin_position")
+ for charge_step: int in range(1, 21):
+ var candidate_charge := float(charge_step) / 20.0
+ fishing_spot.set("_cast_charge", candidate_charge)
+ fishing_spot.call("_update_cast_charge", 0.0)
+ var candidate_target: Vector3 = fishing_spot.get("_cast_target")
+ var candidate_surface := fishing_spot.get(
+ "_aim_surface_sample"
+ ) as FishingSurfaceSample
+ if (
+ candidate_surface.is_fishable()
+ and fishing_spot.is_cast_path_clear(cast_origin, candidate_target)
+ ):
+ cast_charge = candidate_charge
+ target = candidate_target
+ break
+ assert(cast_charge > 0.0, "no clear fishable test target was found")
+ var evidence: Dictionary = fishing_spot.call("_build_network_evidence")
+ fishing_spot.set("state", FishingSpotType.FishingState.CASTING)
+ player.set_movement_enabled(false)
+ player.set_release_visual()
+ assert(
+ int(player.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.RELEASE
+ )
+ assert(
+ not service.request_local_cast(
+ cast_origin,
+ target,
+ cast_charge,
+ evidence,
+ ).is_empty()
+ )
var accepted_deadline: int = Time.get_ticks_msec() + 6000
while (
@@ -146,8 +261,33 @@ func _run_client() -> void:
and fishing_spot.state != FishingSpotType.FishingState.WAITING_FOR_BITE
):
await process_frame
- assert(fishing_spot.state == FishingSpotType.FishingState.WAITING_FOR_BITE)
+ assert(
+ fishing_spot.state == FishingSpotType.FishingState.WAITING_FOR_BITE,
+ (
+ "cast acceptance timed out: state=%s local_attempt=%s target=%s "
+ + "rejections=%s"
+ ) % [
+ fishing_spot.state,
+ service.has_local_attempt(),
+ target,
+ cast_rejections,
+ ]
+ )
assert(service.has_local_attempt())
+ assert(player.bag.get_quantity(&"worms") == worms_before_cast - 1)
+ var fishing_deadline: int = Time.get_ticks_msec() + 5000
+ while (
+ Time.get_ticks_msec() < fishing_deadline
+ and int(player.get("_fishing_visual_phase"))
+ != Player.FishingVisualPhase.FISHING
+ ):
+ await process_frame
+ assert(
+ int(player.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.FISHING
+ )
+ for _frame: int in 30:
+ await physics_frame
fishing_spot.set("_withdrawal_input_held", true)
fishing_spot.set("_network_primary_input_held", true)
service.submit_local_input(true, true)
@@ -159,10 +299,24 @@ func _run_client() -> void:
):
await process_frame
assert(fishing_spot.state == FishingSpotType.FishingState.RETURNING)
+ assert(
+ int(player.get("_fishing_visual_phase"))
+ == Player.FishingVisualPhase.RETRACT
+ )
+ var retract_animation_deadline: int = Time.get_ticks_msec() + 3000
+ while (
+ Time.get_ticks_msec() < retract_animation_deadline
+ and character_animation_player.current_animation != &"retract_sit"
+ ):
+ await process_frame
+ assert(character_animation_player.current_animation == &"retract_sit")
var bobber := fishing_spot.get_node(
"FishingPresentation/Bobber"
) as MeshInstance3D
assert(bobber.visible)
+ while not player.is_retract_visual_complete():
+ assert(fishing_spot.state == FishingSpotType.FishingState.RETURNING)
+ await process_frame
var ready_deadline: int = Time.get_ticks_msec() + 3000
while (
@@ -173,10 +327,22 @@ func _run_client() -> void:
assert(fishing_spot.state == FishingSpotType.FishingState.READY)
assert(player.is_movement_enabled())
assert(not bobber.visible)
+ var host_observation_deadline: int = Time.get_ticks_msec() + 2000
+ while Time.get_ticks_msec() < host_observation_deadline:
+ await process_frame
print("Fishing multiplayer client validation: PASS")
- session.disconnect_session("")
+ var host_completion_deadline: int = Time.get_ticks_msec() + 10000
+ while (
+ Time.get_ticks_msec() < host_completion_deadline
+ and session.is_joined_client()
+ ):
+ await process_frame
+ if session.is_joined_client():
+ session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/fishing_surface_validation.gd b/tests/fishing_surface_validation.gd
index 2f4a4b7..5b52b41 100644
--- a/tests/fishing_surface_validation.gd
+++ b/tests/fishing_surface_validation.gd
@@ -50,6 +50,7 @@ func _validate_resolver_layers() -> void:
_add_solid_box(world, Vector3(40.0, 2.0, 12.0), Vector3(10.0, -1.0, 0.0))
_add_water_region(world, Vector3(0.0, 2.0, 0.0), Vector2(8.0, 8.0), PondPool)
_add_solid_box(world, Vector3(1.0, 1.0, 1.0), Vector3(2.0, 2.25, 0.0))
+ _add_solid_box(world, Vector3(1.0, 1.0, 1.0), Vector3(-2.0, 6.0, 0.0))
_add_water_region(world, Vector3(10.0, 5.0, 0.0), Vector2(6.0, 6.0), PondPool)
_add_water_region(world, Vector3(20.0, 3.0, 0.0), Vector2(6.0, 6.0), null)
await physics_frame
@@ -64,6 +65,14 @@ func _validate_resolver_layers() -> void:
)
assert(water.is_fishable())
assert(is_equal_approx(water.position.y, 2.0))
+ var water_under_overhang: FishingSurfaceSampleType = resolver.resolve_surface(
+ space_state,
+ Vector3(-2.0, 4.0, 0.0),
+ 4.0,
+ 0.08,
+ )
+ assert(water_under_overhang.is_fishable())
+ assert(is_equal_approx(water_under_overhang.position.y, 2.0))
var covered_water: FishingSurfaceSampleType = resolver.resolve_surface(
space_state,
@@ -153,6 +162,34 @@ func _validate_portable_water_body() -> void:
func _validate_starter_region_surfaces() -> void:
var region := StarterRegionScene.instantiate() as Node3D
root.add_child(region)
+ var ocean_region := region.get_node(
+ "WaterBodies/Ocean/FishingRegions/OceanFishingRegion"
+ ) as FishableWaterRegionType
+ var minimum_x: float = INF
+ var maximum_x: float = -INF
+ var minimum_z: float = INF
+ var maximum_z: float = -INF
+ for child: Node in ocean_region.get_children():
+ var shape_node := child as CollisionShape3D
+ assert(shape_node != null and shape_node.shape is BoxShape3D)
+ var box := shape_node.shape as BoxShape3D
+ assert(is_equal_approx(box.size.y, 2.0))
+ minimum_x = minf(minimum_x, shape_node.position.x - box.size.x * 0.5)
+ maximum_x = maxf(maximum_x, shape_node.position.x + box.size.x * 0.5)
+ minimum_z = minf(minimum_z, shape_node.position.z - box.size.z * 0.5)
+ maximum_z = maxf(maximum_z, shape_node.position.z + box.size.z * 0.5)
+ var ocean_footprint := Vector2(
+ maximum_x - minimum_x,
+ maximum_z - minimum_z,
+ )
+ assert(is_equal_approx(
+ ocean_footprint.x * ocean_footprint.y,
+ 12840.0,
+ ))
+ assert(is_equal_approx(
+ ocean_footprint.x / 107.0,
+ ocean_footprint.y / 80.0,
+ ))
var fishing_spot := FishingSpotScene.instantiate() as FishingSpotType
root.add_child(fishing_spot)
await physics_frame
@@ -170,6 +207,14 @@ func _validate_starter_region_surfaces() -> void:
)
assert(ocean.is_fishable())
assert(is_equal_approx(ocean.position.y, -0.45))
+ var expanded_ocean: FishingSurfaceSampleType = (
+ fishing_spot.resolve_fishing_surface(
+ Vector3(72.0, -0.45, 0.0),
+ 4.0,
+ )
+ )
+ assert(expanded_ocean.is_fishable())
+ assert(is_equal_approx(expanded_ocean.position.y, -0.45))
var covered_ocean: FishingSurfaceSampleType = (
fishing_spot.resolve_fishing_surface(
Vector3(20.0, -0.45, 0.0),
@@ -180,6 +225,27 @@ func _validate_starter_region_surfaces() -> void:
assert(not covered_ocean.is_fishable())
assert(covered_ocean.position.y > -0.45)
+ # The ocean fishing layer covers the island's complete editable footprint.
+ # Terrain at or above the waterline remains authoritative, while shoreline
+ # terrain lowered below the surface becomes fishable without reshaping a
+ # manually authored exclusion ring.
+ var editable_shallows_found := 0
+ for x_position: int in range(-24, 24, 2):
+ for z_position: int in range(-21, 22, 2):
+ var candidate: FishingSurfaceSampleType = (
+ fishing_spot.resolve_fishing_surface(
+ Vector3(x_position, -0.45, z_position),
+ 4.0,
+ )
+ )
+ if (
+ candidate.is_fishable()
+ and candidate.water_region.water_type
+ == WaterType.Type.SALT_WATER
+ ):
+ editable_shallows_found += 1
+ assert(editable_shallows_found > 0)
+
fishing_spot.queue_free()
region.queue_free()
await process_frame
@@ -257,11 +323,47 @@ func _validate_bite_wait_distribution() -> void:
if wait_seconds >= FishingSpotType.BITE_LONG_MAX_SECONDS:
very_long_count += 1
var average_wait_seconds: float = total_wait_seconds / 10000.0
- assert(quick_count >= 2300 and quick_count <= 2700)
+ var quick_ratio: float = float(quick_count) / 10000.0
+ var very_long_ratio: float = float(very_long_count) / 10000.0
+ var very_long_probability: float = 1.0 - (
+ FishingSpotType.BITE_QUICK_PROBABILITY
+ + FishingSpotType.BITE_TYPICAL_PROBABILITY
+ + FishingSpotType.BITE_LONG_PROBABILITY
+ )
+ var expected_average_wait_seconds: float = (
+ FishingSpotType.BITE_QUICK_PROBABILITY
+ * (
+ FishingSpotType.BITE_QUICK_MIN_SECONDS
+ + FishingSpotType.BITE_QUICK_MAX_SECONDS
+ )
+ * 0.5
+ + FishingSpotType.BITE_TYPICAL_PROBABILITY
+ * (
+ FishingSpotType.BITE_QUICK_MAX_SECONDS
+ + FishingSpotType.BITE_TYPICAL_MAX_SECONDS
+ )
+ * 0.5
+ + FishingSpotType.BITE_LONG_PROBABILITY
+ * (
+ FishingSpotType.BITE_TYPICAL_MAX_SECONDS
+ + FishingSpotType.BITE_LONG_MAX_SECONDS
+ )
+ * 0.5
+ + very_long_probability
+ * (
+ FishingSpotType.BITE_LONG_MAX_SECONDS
+ + FishingSpotType.BITE_MAX_SECONDS
+ )
+ * 0.5
+ )
+ assert(absf(
+ quick_ratio - FishingSpotType.BITE_QUICK_PROBABILITY
+ ) <= 0.02)
assert(typical_or_long_count > quick_count)
- assert(very_long_count >= 100 and very_long_count <= 300)
- assert(average_wait_seconds >= 45.0)
- assert(average_wait_seconds <= 49.0)
+ assert(absf(very_long_ratio - very_long_probability) <= 0.005)
+ assert(absf(
+ average_wait_seconds - expected_average_wait_seconds
+ ) <= 1.0)
fishing_spot.queue_free()
await process_frame
@@ -296,11 +398,16 @@ func _validate_remote_presentation() -> void:
fish_catch.sale_value = 1
assert(fish_catch.is_valid())
presentation.play_return(fish_catch)
- await create_timer(0.6).timeout
var catch_display := player.find_child(
"CatchDisplay", true, false
) as Node3D
assert(catch_display != null)
+ var showcase_deadline_msec: int = Time.get_ticks_msec() + 2000
+ while (
+ not catch_display.visible
+ and Time.get_ticks_msec() < showcase_deadline_msec
+ ):
+ await process_frame
assert(catch_display.visible)
await presentation.return_completed
assert(not catch_display.visible)
diff --git a/tests/fur_pattern_validation.gd b/tests/fur_pattern_validation.gd
new file mode 100644
index 0000000..0bd3eb2
--- /dev/null
+++ b/tests/fur_pattern_validation.gd
@@ -0,0 +1,192 @@
+extends SceneTree
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var legacy_snapshot := CharacterCustomizationCatalog.default_snapshot()
+ for added_id: String in [
+ "fur_style",
+ "fur_color_2",
+ "fur_color_3",
+ "fur_color_4",
+ ]:
+ legacy_snapshot.erase(added_id)
+ var migrated := CharacterCustomizationCatalog.sanitized_snapshot(
+ legacy_snapshot
+ )
+ assert(CharacterCustomizationCatalog.validate_snapshot(migrated))
+ assert(migrated["fur_style"] == "solid")
+ var fur_colors := CharacterCustomizationCatalog.options_for("fur_pattern")
+ assert(fur_colors.size() == 30)
+ for natural_color_id: String in [
+ "ivory",
+ "sand",
+ "tan",
+ "taupe",
+ "black",
+ "dark_brown",
+ "chocolate",
+ "chestnut",
+ "ginger",
+ "sage",
+ "forest",
+ ]:
+ assert(CharacterCustomizationCatalog.is_valid_option(
+ "fur_pattern",
+ natural_color_id,
+ ))
+
+ var pattern_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ "spots_bengal"
+ )
+ assert(pattern_texture != null)
+ assert(pattern_texture.get_width() == 1024)
+ assert(pattern_texture.get_height() == 1024)
+ var arm_pattern_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ "spots_bengal",
+ "body_arms",
+ )
+ assert(arm_pattern_texture != null)
+ assert(arm_pattern_texture.get_width() == 1024)
+ assert(arm_pattern_texture.get_height() == 1024)
+ var fox_pattern_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ "fox",
+ "body_main",
+ )
+ assert(fox_pattern_texture != null)
+ assert(fox_pattern_texture.get_width() == 1024)
+ assert(fox_pattern_texture.get_height() == 1024)
+ var fox_arm_pattern_texture := (
+ CharacterCustomizationCatalog.fur_pattern_texture(
+ "fox", "body_arms"
+ )
+ )
+ assert(fox_arm_pattern_texture != null)
+ assert(fox_arm_pattern_texture.get_width() == 1024)
+ assert(fox_arm_pattern_texture.get_height() == 1024)
+ var bengal_head_texture := (
+ CharacterCustomizationCatalog.fur_pattern_texture(
+ "spots_bengal", "head_round"
+ )
+ )
+ assert(bengal_head_texture != null)
+ assert(bengal_head_texture.get_width() == 1024)
+ assert(bengal_head_texture.get_height() == 1024)
+ var fox_head_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ "fox", "head_pointy"
+ )
+ assert(fox_head_texture != null)
+ assert(fox_head_texture.get_width() == 1024)
+ assert(fox_head_texture.get_height() == 1024)
+ var fox_round_head_texture := (
+ CharacterCustomizationCatalog.fur_pattern_texture(
+ "fox", "head_round"
+ )
+ )
+ assert(fox_round_head_texture != null)
+ assert(fox_round_head_texture.get_width() == 1024)
+ assert(fox_round_head_texture.get_height() == 1024)
+ var fox_tail_texture := CharacterCustomizationCatalog.fur_pattern_texture(
+ "fox", "tails_fox"
+ )
+ assert(fox_tail_texture != null)
+ assert(fox_tail_texture.get_width() == 1024)
+ assert(fox_tail_texture.get_height() == 1024)
+
+ var patterned := migrated.duplicate(true)
+ patterned["fur_pattern"] = "orange"
+ patterned["fur_style"] = "spots_bengal"
+ patterned["fur_color_2"] = "cream"
+ patterned["fur_color_3"] = "brown"
+ patterned["fur_color_4"] = "red"
+ assert(CharacterCustomizationCatalog.validate_snapshot(patterned))
+
+ var visuals := PlayerVisualPresenter.instantiate_visuals()
+ root.add_child(visuals)
+ PlayerVisualPresenter.apply_appearance(visuals, patterned)
+ var skeleton := visuals.find_child("Skeleton3D", true, false) as Skeleton3D
+ assert(skeleton != null)
+ var body := skeleton.get_node_or_null("body_main") as MeshInstance3D
+ assert(body != null)
+ var body_arrays := body.mesh.surface_get_arrays(0)
+ var body_uvs := body_arrays[Mesh.ARRAY_TEX_UV] as PackedVector2Array
+ assert(not body_uvs.is_empty())
+ var uv_min := Vector2(INF, INF)
+ var uv_max := Vector2(-INF, -INF)
+ for uv: Vector2 in body_uvs:
+ uv_min = uv_min.min(uv)
+ uv_max = uv_max.max(uv)
+ assert(uv_min.x < 0.05 and uv_min.y < 0.05)
+ assert(uv_max.x > 0.95 and uv_max.y > 0.95)
+ var material := body.material_override as ShaderMaterial
+ assert(material != null)
+ assert(material.shader == preload("res://player/fur_pattern.gdshader"))
+ assert(material.get_shader_parameter("pattern_texture") == pattern_texture)
+ assert(material.get_shader_parameter("base_color") == Color("c86c36"))
+ assert(material.get_shader_parameter("red_zone_color") == Color("e6d39b"))
+ assert(material.get_shader_parameter("green_zone_color") == Color("7b4a32"))
+ assert(material.get_shader_parameter("blue_zone_color") == Color("a9433f"))
+ var arms := skeleton.get_node_or_null("body_arms") as MeshInstance3D
+ assert(arms != null)
+ var arm_material := arms.material_override as ShaderMaterial
+ assert(arm_material != null)
+ assert(
+ arm_material.get_shader_parameter("pattern_texture")
+ == arm_pattern_texture
+ )
+ var round_head := skeleton.get_node_or_null("head_round") as MeshInstance3D
+ assert(round_head != null)
+ var round_head_material := round_head.material_override as ShaderMaterial
+ assert(round_head_material != null)
+ assert(
+ round_head_material.get_shader_parameter("pattern_texture")
+ == bengal_head_texture
+ )
+
+ var fox_snapshot := patterned.duplicate(true)
+ fox_snapshot["species"] = "pointy"
+ fox_snapshot["fur_style"] = "fox"
+ fox_snapshot["tail"] = "fox"
+ PlayerVisualPresenter.apply_appearance(visuals, fox_snapshot)
+ var pointy_head := (
+ skeleton.get_node_or_null("head_pointy") as MeshInstance3D
+ )
+ assert(pointy_head != null)
+ var pointy_head_material := pointy_head.material_override as ShaderMaterial
+ assert(pointy_head_material != null)
+ assert(
+ pointy_head_material.get_shader_parameter("pattern_texture")
+ == fox_head_texture
+ )
+ fox_snapshot["species"] = "round"
+ PlayerVisualPresenter.apply_appearance(visuals, fox_snapshot)
+ assert(
+ round_head_material.get_shader_parameter("pattern_texture")
+ == fox_round_head_texture
+ )
+ var fox_tail := skeleton.get_node_or_null("tails_fox") as MeshInstance3D
+ assert(fox_tail != null)
+ var fox_tail_material := fox_tail.material_override as ShaderMaterial
+ assert(fox_tail_material != null)
+ assert(
+ fox_tail_material.get_shader_parameter("pattern_texture")
+ == fox_tail_texture
+ )
+
+ var recolored := patterned.duplicate(true)
+ recolored["fur_color_3"] = "teal"
+ assert(
+ NetworkProfileProtocol.signature_fields({"appearance": patterned})
+ != NetworkProfileProtocol.signature_fields({"appearance": recolored})
+ )
+
+ PlayerVisualPresenter.apply_appearance(visuals, migrated)
+ assert(body.material_override is StandardMaterial3D)
+
+ print("Fur pattern validation: PASS")
+ visuals.queue_free()
+ await process_frame
+ quit()
diff --git a/tests/fur_pattern_validation.gd.uid b/tests/fur_pattern_validation.gd.uid
new file mode 100644
index 0000000..7333f9d
--- /dev/null
+++ b/tests/fur_pattern_validation.gd.uid
@@ -0,0 +1 @@
+uid://bwdmyn34biahx
diff --git a/tests/inventory_notepad_art_validation.gd b/tests/inventory_notepad_art_validation.gd
index cbe3414..de76221 100644
--- a/tests/inventory_notepad_art_validation.gd
+++ b/tests/inventory_notepad_art_validation.gd
@@ -58,11 +58,14 @@ func _run() -> void:
))
_validate_shared_inventory_geometry(player_menu)
_validate_inventory_layering(player_menu)
+ _validate_cooler_notepad_typography(player_menu)
_validate_resolution_matrix()
await _capture_inventory_pages(player_menu)
print("Inventory notepad artwork validation: PASS")
presentation_stage.queue_free()
- await process_frame
+ for _frame: int in 10:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -126,7 +129,7 @@ func _validate_inventory_layering(player_menu: PlayerMenu) -> void:
# The contextual Hotbar uses z=90 while the Player Menu is open.
assert(sale_confirmation.z_index > 90)
assert(sale_confirmation.position.is_equal_approx(Vector2(380.0, 265.0)))
- assert(sale_confirmation.size.is_equal_approx(Vector2(520.0, 190.0)))
+ assert(sale_confirmation.size.is_equal_approx(Vector2(520.0, 200.0)))
var confirmation_style := sale_confirmation.get_theme_stylebox(
"panel"
) as StyleBoxFlat
@@ -138,6 +141,39 @@ func _validate_inventory_layering(player_menu: PlayerMenu) -> void:
)
+func _validate_cooler_notepad_typography(player_menu: PlayerMenu) -> void:
+ var sort_choice := player_menu.get_node("%CoolerSortOption") as Control
+ var sort_direction := player_menu.get_node(
+ "%CoolerSortDirection"
+ ) as Button
+ var empty_selection := player_menu.get_node(
+ "%CoolerSelectionEmpty"
+ ) as Label
+ var favorite := player_menu.get_node("%FavoriteBubble") as Button
+ var sell := player_menu.get_node("%SellBubble") as Button
+ var sell_all := player_menu.get_node("%SellAllBubble") as Button
+ assert(sort_choice != null)
+ assert(sort_direction != null)
+ assert(empty_selection != null)
+ assert(favorite != null and sell != null and sell_all != null)
+ var displayed_value := sort_choice.get_node("%DisplayedValue") as Label
+ assert(displayed_value != null)
+ assert(displayed_value.get_theme_font_size("font_size") == 17)
+ for choice_name: StringName in [
+ &"CatchOrderChoice",
+ &"NameChoice",
+ &"RarityChoice",
+ ]:
+ var choice := sort_choice.get_node("%%%s" % choice_name) as Button
+ assert(choice != null)
+ assert(choice.get_theme_font_size("font_size") == 17)
+ assert(sort_direction.get_theme_font_size("font_size") == 17)
+ assert(empty_selection.get_theme_font_size("font_size") == 20)
+ assert(favorite.get_theme_font_size("font_size") == 19)
+ assert(sell.get_theme_font_size("font_size") == 19)
+ assert(sell_all.get_theme_font_size("font_size") == 17)
+
+
func _validate_resolution_matrix() -> void:
for target_size: Vector2 in TARGET_SIZES:
var stage_rect: Rect2 = UIReferencePresentationType.get_rect(
diff --git a/tests/job_multiplayer_validation.gd b/tests/job_multiplayer_validation.gd
index 5994eae..c31d392 100644
--- a/tests/job_multiplayer_validation.gd
+++ b/tests/job_multiplayer_validation.gd
@@ -23,13 +23,12 @@ func _run() -> void:
func _run_host() -> void:
var main: Node = await _create_initialized_main()
var session := main.get_node("%NetworkSession") as NetworkSession
- var save_manager := main.get("_save_manager") as PlayerSaveManager
var jobs := main.get_node("%PlayerJobService") as PlayerJobService
- assert(session.start_private_host(TEST_PORT))
- assert(save_manager.initialize_new_game())
- main.call("_enter_gameplay")
+ assert(session.start_dedicated_host(TEST_PORT, 8, "127.0.0.1"))
+ jobs.begin_progression_session()
await process_frame
assert(session.set_host_open(true))
+ assert(session.is_dedicated_host())
var host_board: Dictionary = jobs.get_host_board_network_data()
assert(PlayerJobService.validate_board(host_board))
@@ -56,7 +55,9 @@ func _run_host() -> void:
print("Job multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -85,6 +86,20 @@ func _run_client() -> void:
assert(not jobs.get_plan_id().is_empty())
assert(jobs.get_daily_jobs().size() == JobCatalog.DAILY_JOB_COUNT)
assert(jobs.get_forecast().size() == JobCatalog.WEATHER_SEGMENT_COUNT)
+ var preserved_plan_id: String = jobs.get_plan_id()
+ jobs.clear_remote_board()
+ assert(not jobs.has_active_board())
+ assert(jobs.get_plan_id() == preserved_plan_id)
+ var retry_deadline: int = Time.get_ticks_msec() + 5000
+ while (
+ Time.get_ticks_msec() < retry_deadline
+ and not jobs.has_active_board()
+ ):
+ await process_frame
+ assert(jobs.has_active_board())
+ assert(jobs.get_plan_id() == preserved_plan_id)
+ assert(jobs.get_daily_jobs().size() == JobCatalog.DAILY_JOB_COUNT)
+ assert(jobs.get_forecast().size() == JobCatalog.WEATHER_SEGMENT_COUNT)
assert(weather.get_daily_plan_id().is_empty())
var game_ui := main.get_node("%GameUI") as GameUI
var player_menu := game_ui.get("_player_menu") as PlayerMenu
@@ -93,7 +108,9 @@ func _run_client() -> void:
print("Job multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/job_system_validation.gd b/tests/job_system_validation.gd
index 24cad9d..32fe10e 100644
--- a/tests/job_system_validation.gd
+++ b/tests/job_system_validation.gd
@@ -85,6 +85,7 @@ func _run() -> void:
(player_menu.get_node("%NavigationCluster") as Control).get_child_count()
== 7
)
+ await _validate_unavailable_fishnet_layout()
var wallet_before: int = player.wallet.get_balance()
var experience_before: int = player.experience.get_total_experience()
@@ -162,10 +163,31 @@ func _run() -> void:
var pause_menu := game_ui.get_pause_menu()
var join_page := pause_menu.get_node("%JoinGamePage") as JoinGamePage
assert(join_page != null)
+ pause_menu.show()
+ join_page.set_status("Connection timed out.")
+ join_page.show()
+ join_page.call(
+ "_on_discovery_status_changed", "2 public rooms found", false
+ )
+ var join_status := join_page.get_node("%Status") as Label
+ assert(join_status.text == "Could not reach the server.")
+ join_page.hide()
+ join_page.call("_set_mode", JoinGamePage.Mode.DIRECT)
+ join_page.call("_set_mode", JoinGamePage.Mode.DISCOVER)
+ join_page.show()
+ join_page.call(
+ "_on_discovery_status_changed", "2 public rooms found", false
+ )
+ assert(join_status.text == "2 public rooms found")
+ join_page.close_page()
+ pause_menu.hide()
join_page.call("_refresh")
var session_summary := (
join_page.get_node("%SessionSummary") as Label
)
+ assert(not join_page.has_node(
+ "Paper/Margin/Layout/Actions/OpenCloseButton"
+ ))
assert("UDP 18138" in session_summary.text)
assert(session.set_host_open(true))
await process_frame
@@ -184,12 +206,63 @@ func _run() -> void:
assert(int(save_data.get("save_version", -1)) == 7)
assert(PlayerJobService.validate_save_data(save_data.get("jobs", {})))
+ _validate_pause_session_switch(main, session)
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
print("Job system validation: PASS")
quit()
+func _validate_pause_session_switch(
+ main: Node,
+ session: NetworkSession,
+) -> void:
+ var discovery := main.get_node("%DiscoveryClient") as DiscoveryClient
+ discovery.set("_pending_join_endpoint", "127.0.0.1:18141")
+ discovery.set("_pending_join_room_id", "session-switch-room")
+ discovery.set("_pending_join_token", "session-switch-token")
+ discovery.call(
+ "_set_public_join_state",
+ DiscoveryClient.PublicJoinState.CONNECTING,
+ )
+ main.call("_on_pause_join_game_requested", "127.0.0.1:18141")
+ assert(session.state == NetworkSession.State.CONNECTING)
+ assert(discovery.get("_pending_join_token") == "session-switch-token")
+ var join_probe_timer := discovery.get("_join_probe_timer") as Timer
+ assert(join_probe_timer != null and not join_probe_timer.is_stopped())
+ session.cancel_connection()
+ assert(session.state == NetworkSession.State.INACTIVE)
+ assert(str(discovery.get("_pending_join_token")).is_empty())
+
+
+func _validate_unavailable_fishnet_layout() -> void:
+ var unavailable_page := TheNetPage.new()
+ unavailable_page.size = Vector2(1280.0, 720.0)
+ root.add_child(unavailable_page)
+ for _frame: int in 3:
+ await process_frame
+ unavailable_page.call("_refresh_forecast", true)
+ await process_frame
+ var forecast_list := unavailable_page.get("_forecast_list") as HBoxContainer
+ assert(forecast_list != null)
+ assert(forecast_list.size.x >= 272.0)
+ assert(forecast_list.size.y <= 66.0)
+ assert(forecast_list.get_child_count() == 1)
+ var placeholder := forecast_list.get_child(0) as Label
+ assert(placeholder != null)
+ assert(placeholder.size.x >= 252.0)
+ assert(placeholder.size.y <= 66.0)
+ assert(placeholder.autowrap_mode == TextServer.AUTOWRAP_OFF)
+ var tabs := unavailable_page.get("_tabs") as HBoxContainer
+ assert(tabs != null)
+ assert(tabs.position.y + tabs.size.y < UtilityPageStyle.LAPTOP_RECT.end.y)
+ unavailable_page.queue_free()
+ for _frame: int in 2:
+ await process_frame
+
+
func _validate_weather_guarantees(board: Dictionary) -> void:
var jobs: Array = board.get("jobs", [])
var schedule: Array = board.get("weather_schedule", [])
diff --git a/tests/logbook_runtime_validation.gd b/tests/logbook_runtime_validation.gd
index 77280ea..88227aa 100644
--- a/tests/logbook_runtime_validation.gd
+++ b/tests/logbook_runtime_validation.gd
@@ -79,10 +79,15 @@ func _run() -> void:
"_show_section_immediate", PlayerMenu.Section.PROFILE
)
await process_frame
- assert(not bool(
+ assert(bool(
player_menu.call("_handle_direct_page_shortcut", shortcut)
))
+ await create_timer(0.5).timeout
assert(player_menu.visible)
+ assert(logbook.visible)
+ assert(
+ player_menu.get("_current_section") == PlayerMenu.Section.LOGBOOK
+ )
player_menu.close_menu(PlayerMenu.CloseReason.TEARDOWN, false)
print(
@@ -90,7 +95,9 @@ func _run() -> void:
% [root.size.x, root.size.y]
)
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/logbook_validation.gd b/tests/logbook_validation.gd
index 38b7ade..866a34f 100644
--- a/tests/logbook_validation.gd
+++ b/tests/logbook_validation.gd
@@ -171,7 +171,7 @@ func _validate_page() -> void:
page.activate()
await process_frame
assert(page.get("_category") == WaterType.Type.FRESH_WATER)
- assert((page.get("_catalog_grid") as GridContainer).columns == 5)
+ assert((page.get("_catalog_grid") as GridContainer).columns == 4)
var initial_detail_body := page.get("_detail_body") as VBoxContainer
assert(not initial_detail_body.get_parent() is ScrollContainer)
assert(
@@ -209,7 +209,7 @@ func _validate_page() -> void:
assert(portrait.source_texture == fish.display_texture)
assert(
portrait.custom_minimum_size
- == LogbookPortraitType.ENTRY_FRAME_SIZE
+ == LogbookPage.CATALOG_PORTRAIT_SIZE
)
assert(
portrait.expand_mode
diff --git a/tests/movement_multiplayer_validation.gd b/tests/movement_multiplayer_validation.gd
new file mode 100644
index 0000000..cb1d4eb
--- /dev/null
+++ b/tests/movement_multiplayer_validation.gd
@@ -0,0 +1,163 @@
+extends SceneTree
+
+const MainScene: PackedScene = preload("res://main/main.tscn")
+const TEST_PORT: int = 18141
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var arguments: PackedStringArray = OS.get_cmdline_user_args()
+ if arguments.has("host"):
+ await _run_host()
+ return
+ if arguments.has("client"):
+ await _run_client()
+ return
+ push_error("Movement multiplayer validation needs host or client mode.")
+ quit(1)
+
+
+func _run_host() -> void:
+ var main: Node = await _create_initialized_main()
+ var session := main.get_node("%NetworkSession") as NetworkSession
+ var save_manager := main.get("_save_manager") as PlayerSaveManager
+ assert(session.start_private_host(TEST_PORT))
+ assert(save_manager.initialize_new_game())
+ main.call("_enter_gameplay")
+ for _frame: int in 4:
+ await physics_frame
+ assert(session.set_host_open(true))
+ var remote_peer_id: int = await _wait_for_remote_peer(session)
+ assert(remote_peer_id > 1)
+ var player := main.get("_player") as Player
+ player.configure_network_remote(true)
+ player.apply_authoritative_network_input(_movement_input(1, true))
+ await create_timer(2.5).timeout
+ player.apply_authoritative_network_input(_movement_input(2, false))
+ await create_timer(2.5).timeout
+ player.apply_authoritative_network_input(_movement_input(3, false, false))
+ var disconnect_deadline: int = Time.get_ticks_msec() + 8000
+ while (
+ Time.get_ticks_msec() < disconnect_deadline
+ and session.is_authenticated_peer(remote_peer_id)
+ ):
+ await process_frame
+ assert(not session.is_authenticated_peer(remote_peer_id))
+ print("Movement multiplayer host validation: PASS")
+ session.disconnect_session("")
+ main.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
+ quit()
+
+
+func _run_client() -> void:
+ var main: Node = await _create_initialized_main()
+ main.call(
+ "_on_title_join_game_requested",
+ "127.0.0.1:%d" % TEST_PORT,
+ )
+ var session := main.get_node("%NetworkSession") as NetworkSession
+ var join_deadline: int = Time.get_ticks_msec() + 20000
+ while Time.get_ticks_msec() < join_deadline:
+ await process_frame
+ if session.state == NetworkSession.State.VERIFYING_SERVER_IDENTITY:
+ main.call("_confirm_server_trust")
+ if session.is_joined_client() and bool(main.get("_gameplay_started")):
+ break
+ assert(session.is_joined_client())
+ var spawn_service := main.get_node(
+ "%PlayerSpawnService"
+ ) as PlayerSpawnService
+ var host_avatar: Player = spawn_service.get_avatar(1)
+ assert(host_avatar != null)
+ var animation_player := host_avatar.get_node(
+ "Visuals/CharacterRig/AnimationPlayer"
+ ) as AnimationPlayer
+ var sprint_dust := host_avatar.get_node("%SprintDust") as SprintDustTrail
+ var saw_running: bool = false
+ var saw_walking: bool = false
+ var saw_animation_advance: bool = false
+ var saw_dust: bool = false
+ var previous_animation: StringName = &""
+ var previous_animation_position: float = -1.0
+ var observation_deadline: int = Time.get_ticks_msec() + 7000
+ while Time.get_ticks_msec() < observation_deadline:
+ await process_frame
+ var current_animation: StringName = animation_player.current_animation
+ saw_running = saw_running or current_animation.begins_with("running")
+ saw_walking = saw_walking or current_animation.begins_with("walking")
+ var current_position: float = (
+ animation_player.current_animation_position
+ )
+ if (
+ current_animation == previous_animation
+ and previous_animation_position >= 0.0
+ and absf(current_position - previous_animation_position) > 0.001
+ ):
+ saw_animation_advance = true
+ previous_animation = current_animation
+ previous_animation_position = current_position
+ saw_dust = saw_dust or sprint_dust.get_active_puff_count() > 0
+ if saw_running and saw_walking and saw_animation_advance and saw_dust:
+ break
+ assert(saw_running)
+ assert(saw_walking)
+ assert(saw_animation_advance)
+ assert(saw_dust)
+ print("Movement multiplayer client validation: PASS")
+ session.disconnect_session("")
+ main.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
+ quit()
+
+
+func _movement_input(
+ sequence: int,
+ sprinting: bool,
+ moving: bool = true,
+) -> Dictionary:
+ return {
+ "sequence": sequence,
+ "axis": [0.0, -1.0] if moving else [0.0, 0.0],
+ "camera_yaw": 0.0,
+ "jump": false,
+ "sprint": sprinting,
+ "sneak": false,
+ "slow_walk": false,
+ "sitting": false,
+ "casting": false,
+ "animation_action": (
+ NetworkPlayerAnimationProtocol.make_action_state()
+ ),
+ }
+
+
+func _create_initialized_main() -> Node:
+ root.size = Vector2i(1280, 720)
+ var main: Node = MainScene.instantiate()
+ root.add_child(main)
+ for _frame: int in 4:
+ await process_frame
+ if not bool(main.get("_application_initialized")):
+ main.call("_activate_selected_data_path", "", true)
+ for _frame: int in 8:
+ await process_frame
+ assert(bool(main.get("_application_initialized")))
+ return main
+
+
+func _wait_for_remote_peer(session: NetworkSession) -> int:
+ var deadline: int = Time.get_ticks_msec() + 20000
+ while Time.get_ticks_msec() < deadline:
+ await process_frame
+ for peer_id: int in session.get_authenticated_peer_ids():
+ if peer_id != session.get_local_peer_id():
+ return peer_id
+ return 0
diff --git a/tests/movement_multiplayer_validation.gd.uid b/tests/movement_multiplayer_validation.gd.uid
new file mode 100644
index 0000000..4d8c726
--- /dev/null
+++ b/tests/movement_multiplayer_validation.gd.uid
@@ -0,0 +1 @@
+uid://dlpu5lwb2pges
diff --git a/tests/network_player_animation_protocol_validation.gd b/tests/network_player_animation_protocol_validation.gd
new file mode 100644
index 0000000..8c3474c
--- /dev/null
+++ b/tests/network_player_animation_protocol_validation.gd
@@ -0,0 +1,49 @@
+extends SceneTree
+
+
+func _initialize() -> void:
+ var idle := NetworkPlayerAnimationProtocol.make_state(
+ NetworkPlayerAnimationProtocol.LOCOMOTION_IDLE,
+ true,
+ )
+ assert(NetworkPlayerAnimationProtocol.validate_state(idle))
+ var emote := NetworkPlayerAnimationProtocol.make_state(
+ NetworkPlayerAnimationProtocol.LOCOMOTION_RUNNING,
+ false,
+ &"wave_hello",
+ 17,
+ 1.25,
+ )
+ assert(NetworkPlayerAnimationProtocol.validate_state(emote))
+ var future_locomotion := NetworkPlayerAnimationProtocol.make_state(
+ &"swimming_fast",
+ false,
+ )
+ assert(NetworkPlayerAnimationProtocol.validate_state(future_locomotion))
+ var extra_future_field: Dictionary = emote.duplicate(true)
+ extra_future_field["future_layer"] = {"id": "umbrella"}
+ assert(NetworkPlayerAnimationProtocol.validate_state(extra_future_field))
+
+ var invalid_action: Dictionary = emote.duplicate(true)
+ invalid_action["action"] = {
+ "id": "../unsafe",
+ "sequence": 17,
+ "elapsed": 1.25,
+ }
+ assert(not NetworkPlayerAnimationProtocol.validate_state(invalid_action))
+ var invalid_sequence: Dictionary = emote.duplicate(true)
+ invalid_sequence["action"] = {
+ "id": "wave_hello",
+ "sequence": -1,
+ "elapsed": 1.25,
+ }
+ assert(not NetworkPlayerAnimationProtocol.validate_state(invalid_sequence))
+ var invalid_elapsed: Dictionary = emote.duplicate(true)
+ invalid_elapsed["action"] = {
+ "id": "wave_hello",
+ "sequence": 17,
+ "elapsed": INF,
+ }
+ assert(not NetworkPlayerAnimationProtocol.validate_state(invalid_elapsed))
+ print("Network player animation protocol validation: PASS")
+ quit()
diff --git a/tests/network_player_animation_protocol_validation.gd.uid b/tests/network_player_animation_protocol_validation.gd.uid
new file mode 100644
index 0000000..017146d
--- /dev/null
+++ b/tests/network_player_animation_protocol_validation.gd.uid
@@ -0,0 +1 @@
+uid://cjgelp62dkykn
diff --git a/tests/on_screen_keyboard_validation.gd b/tests/on_screen_keyboard_validation.gd
new file mode 100644
index 0000000..e794cda
--- /dev/null
+++ b/tests/on_screen_keyboard_validation.gd
@@ -0,0 +1,82 @@
+extends SceneTree
+
+const KeyboardType = preload("res://ui/on_screen_keyboard.gd")
+const SettingsManagerType = preload(
+ "res://settings/player_settings_manager.gd"
+)
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ _validate_default_and_persistence()
+ await _validate_keyboard_entry()
+ print("On-screen keyboard validation: PASS")
+ quit()
+
+
+func _validate_default_and_persistence() -> void:
+ var defaults := PlayerSettings.new()
+ assert(not defaults.on_screen_keyboard_enabled)
+ var manager := SettingsManagerType.new()
+ root.add_child(manager)
+ assert(manager.load_settings())
+ var edited: PlayerSettings = manager.current_settings.copy()
+ edited.on_screen_keyboard_enabled = true
+ assert(manager.apply_settings(edited))
+ var reloaded := SettingsManagerType.new()
+ root.add_child(reloaded)
+ assert(reloaded.load_settings())
+ assert(reloaded.current_settings.on_screen_keyboard_enabled)
+ manager.queue_free()
+ reloaded.queue_free()
+
+
+func _validate_keyboard_entry() -> void:
+ var host := Control.new()
+ root.add_child(host)
+ var edit := LineEdit.new()
+ edit.focus_mode = Control.FOCUS_ALL
+ host.add_child(edit)
+ var keyboard := KeyboardType.new()
+ host.add_child(keyboard)
+ await process_frame
+ keyboard.set_enabled(true)
+ edit.grab_focus()
+ var activate_event := InputEventJoypadButton.new()
+ activate_event.button_index = JOY_BUTTON_A
+ activate_event.pressed = true
+ keyboard.call("_input", activate_event)
+ assert(keyboard.is_open())
+ keyboard.call("_type_character", "a")
+ keyboard.call("_type_space")
+ keyboard.call("_set_page", KeyboardType.Page.UPPER)
+ keyboard.call("_type_character", "B")
+ assert(edit.text == "a B")
+ keyboard.call("_move_caret", -1)
+ keyboard.call("_type_character", "C")
+ assert(edit.text == "a CB")
+ var backspace_event := InputEventJoypadButton.new()
+ backspace_event.button_index = JOY_BUTTON_X
+ backspace_event.pressed = true
+ keyboard.call("_input", backspace_event)
+ assert(edit.text == "a B")
+ var defocus_event := InputEventJoypadButton.new()
+ defocus_event.button_index = JOY_BUTTON_LEFT_SHOULDER
+ defocus_event.pressed = true
+ keyboard.call("_input", defocus_event)
+ assert(not keyboard.is_open())
+ assert(root.gui_get_focus_owner() == null)
+ edit.grab_focus()
+ keyboard.call("_input", activate_event)
+ assert(keyboard.is_open())
+ var submitted: Array[String] = []
+ edit.text_submitted.connect(func(value: String) -> void:
+ submitted.append(value)
+ )
+ keyboard.call("_submit")
+ assert(not keyboard.is_open())
+ assert(submitted == ["a B"])
+ host.queue_free()
diff --git a/tests/on_screen_keyboard_validation.gd.uid b/tests/on_screen_keyboard_validation.gd.uid
new file mode 100644
index 0000000..973bdca
--- /dev/null
+++ b/tests/on_screen_keyboard_validation.gd.uid
@@ -0,0 +1 @@
+uid://bgmt6joqdk37q
diff --git a/tests/operator_multiplayer_validation.gd b/tests/operator_multiplayer_validation.gd
new file mode 100644
index 0000000..3712fd4
--- /dev/null
+++ b/tests/operator_multiplayer_validation.gd
@@ -0,0 +1,253 @@
+extends SceneTree
+
+const MainScene = preload("res://main/main.tscn")
+const TEST_PORT: int = 18140
+const FIRST_BANNED_FINGERPRINT: String = (
+ "1111111111111111111111111111111111111111111111111111111111111111"
+)
+const SECOND_BANNED_FINGERPRINT: String = (
+ "2222222222222222222222222222222222222222222222222222222222222222"
+)
+
+var _moderation_results: Array[Dictionary] = []
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var arguments: PackedStringArray = OS.get_cmdline_user_args()
+ if arguments.has("host"):
+ await _run_host()
+ return
+ if arguments.has("client"):
+ await _run_client()
+ return
+ push_error("Operator multiplayer validation needs host or client mode.")
+ quit(1)
+
+
+func _run_host() -> void:
+ var main: Node = await _create_initialized_main()
+ var session := main.get_node("%NetworkSession") as NetworkSession
+ var service := (
+ main.get_node("%NetworkPlayerListService")
+ as NetworkPlayerListService
+ )
+ var bans := main.get_node("%HostBanStore") as HostBanStore
+ assert(session.start_private_host(TEST_PORT))
+ assert(session.set_host_open(true))
+
+ var remote_peer_id: int = await _wait_for_remote_peer(session)
+ assert(remote_peer_id > 1)
+ var remote_record: PeerRegistry.PeerRecord = session.get_peer_record(
+ remote_peer_id
+ )
+ assert(remote_record != null and remote_record.identity_authenticated)
+ var host_fingerprint: String = session.get_host_identity_fingerprint()
+ assert(bans.ban(
+ host_fingerprint, FIRST_BANNED_FINGERPRINT, "First Banned Player"
+ ))
+
+ var entry: PlayerListEntry = _entry_for_peer(service, remote_peer_id)
+ assert(entry != null and entry.can_manage_operator)
+ assert(service.set_operator(
+ remote_peer_id,
+ remote_record.identity_fingerprint,
+ true,
+ entry.revision,
+ ))
+ assert(session.is_peer_operator(remote_peer_id))
+ var players_page := main.find_child(
+ "PlayersPage", true, false
+ ) as PlayersPage
+ assert(players_page != null)
+ players_page.call("_refresh")
+ assert(_has_button_text(players_page, "deop"))
+
+ var unban_deadline: int = Time.get_ticks_msec() + 12000
+ while (
+ Time.get_ticks_msec() < unban_deadline
+ and bans.is_banned(host_fingerprint, FIRST_BANNED_FINGERPRINT)
+ ):
+ await process_frame
+ assert(not bans.is_banned(
+ host_fingerprint, FIRST_BANNED_FINGERPRINT
+ ))
+ assert(bans.ban(
+ host_fingerprint, SECOND_BANNED_FINGERPRINT, "Second Banned Player"
+ ))
+
+ entry = _entry_for_peer(service, remote_peer_id)
+ assert(entry != null and entry.is_operator)
+ assert(service.set_operator(
+ remote_peer_id,
+ remote_record.identity_fingerprint,
+ false,
+ entry.revision,
+ ))
+ assert(not session.is_peer_operator(remote_peer_id))
+ await create_timer(2.0).timeout
+ assert(session.kick_authenticated_peer(
+ remote_peer_id,
+ remote_record.identity_fingerprint,
+ ))
+
+ var disconnect_deadline: int = Time.get_ticks_msec() + 8000
+ while (
+ Time.get_ticks_msec() < disconnect_deadline
+ and session.is_authenticated_peer(remote_peer_id)
+ ):
+ await process_frame
+ assert(not session.is_authenticated_peer(remote_peer_id))
+ assert(bans.is_banned(host_fingerprint, SECOND_BANNED_FINGERPRINT))
+ print("Operator multiplayer host validation: PASS")
+ session.disconnect_session("")
+ main.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
+ quit()
+
+
+func _run_client() -> void:
+ var main: Node = await _create_initialized_main()
+ main.call(
+ "_on_title_join_game_requested", "127.0.0.1:%d" % TEST_PORT
+ )
+ var session := main.get_node("%NetworkSession") as NetworkSession
+ var service := (
+ main.get_node("%NetworkPlayerListService")
+ as NetworkPlayerListService
+ )
+ service.moderation_finished.connect(
+ func(success: bool, message: String) -> void:
+ _moderation_results.append({
+ "success": success,
+ "message": message,
+ })
+ )
+ var join_deadline: int = Time.get_ticks_msec() + 20000
+ while Time.get_ticks_msec() < join_deadline:
+ await process_frame
+ if session.state == NetworkSession.State.VERIFYING_SERVER_IDENTITY:
+ main.call("_confirm_server_trust")
+ if session.is_joined_client():
+ break
+ assert(session.is_joined_client())
+
+ var operator_deadline: int = Time.get_ticks_msec() + 10000
+ while Time.get_ticks_msec() < operator_deadline and not session.is_local_operator():
+ await process_frame
+ assert(session.is_local_operator())
+ assert(service.is_local_moderator())
+ var players_page := main.find_child(
+ "PlayersPage", true, false
+ ) as PlayersPage
+ assert(players_page != null)
+ players_page.call("_refresh")
+ var tabs := players_page.get("_tabs") as HBoxContainer
+ assert((tabs.get_child(2) as Button).visible)
+ players_page.call("_select_tab", 2)
+ assert(int(players_page.get("_current_tab")) == 2)
+ var local_entry: PlayerListEntry = _entry_for_peer(
+ service, session.get_local_peer_id()
+ )
+ assert(local_entry != null and local_entry.is_operator)
+
+ var ban_deadline: int = Time.get_ticks_msec() + 10000
+ while (
+ Time.get_ticks_msec() < ban_deadline
+ and not _has_ban(service.get_bans(), FIRST_BANNED_FINGERPRINT)
+ ):
+ await process_frame
+ assert(_has_ban(service.get_bans(), FIRST_BANNED_FINGERPRINT))
+ assert(service.unban(FIRST_BANNED_FINGERPRINT))
+ var result_deadline: int = Time.get_ticks_msec() + 8000
+ while Time.get_ticks_msec() < result_deadline and _moderation_results.is_empty():
+ await process_frame
+ assert(not _moderation_results.is_empty())
+ assert(bool(_moderation_results.back().get("success", false)))
+
+ var deop_deadline: int = Time.get_ticks_msec() + 10000
+ while Time.get_ticks_msec() < deop_deadline and session.is_local_operator():
+ await process_frame
+ assert(not session.is_local_operator())
+ assert(not service.is_local_moderator())
+ assert(not (tabs.get_child(2) as Button).visible)
+ assert(int(players_page.get("_current_tab")) == 0)
+ service.request_unban.rpc_id(1, SECOND_BANNED_FINGERPRINT)
+ var disconnect_deadline: int = Time.get_ticks_msec() + 10000
+ while (
+ Time.get_ticks_msec() < disconnect_deadline
+ and session.state != NetworkSession.State.SERVER_LOST
+ ):
+ await process_frame
+ assert(session.state == NetworkSession.State.SERVER_LOST)
+ assert(not bool(main.get("_gameplay_started")))
+ var game_ui := main.get_node("%GameUI") as GameUI
+ var title_screen := game_ui.get_title_screen()
+ assert(title_screen.visible)
+ assert(not title_screen.is_awaiting_start_input())
+ assert((title_screen.get_node("%Center") as Control).visible)
+ assert((title_screen.get_node("%ButtonCenter") as Control).visible)
+ assert(not (title_screen.get_node("%JoinGamePage") as Control).visible)
+ var feedback := title_screen.get_node("%FeedbackLabel") as RichTextLabel
+ assert(feedback.visible)
+ assert("removed by the host" in feedback.text.to_lower())
+ print("Operator multiplayer client validation: PASS")
+ main.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
+ quit()
+
+
+func _create_initialized_main() -> Node:
+ root.size = Vector2i(1280, 720)
+ var main: Node = MainScene.instantiate()
+ root.add_child(main)
+ for _frame: int in 4:
+ await process_frame
+ if not bool(main.get("_application_initialized")):
+ main.call("_activate_selected_data_path", "", true)
+ for _frame: int in 8:
+ await process_frame
+ assert(bool(main.get("_application_initialized")))
+ return main
+
+
+func _wait_for_remote_peer(session: NetworkSession) -> int:
+ var deadline: int = Time.get_ticks_msec() + 20000
+ while Time.get_ticks_msec() < deadline:
+ await process_frame
+ for peer_id: int in session.get_authenticated_peer_ids():
+ if peer_id != session.get_local_peer_id():
+ return peer_id
+ return 0
+
+
+func _entry_for_peer(
+ service: NetworkPlayerListService,
+ peer_id: int,
+) -> PlayerListEntry:
+ for entry: PlayerListEntry in service.get_entries():
+ if entry.peer_id == peer_id:
+ return entry
+ return null
+
+
+func _has_ban(records: Array[Dictionary], fingerprint: String) -> bool:
+ for record: Dictionary in records:
+ if str(record.get("target_fingerprint", "")) == fingerprint:
+ return true
+ return false
+
+
+func _has_button_text(root_node: Node, text: String) -> bool:
+ for node: Node in root_node.find_children("*", "Button", true, false):
+ var button := node as Button
+ if button != null and button.text == text:
+ return true
+ return false
diff --git a/tests/operator_multiplayer_validation.gd.uid b/tests/operator_multiplayer_validation.gd.uid
new file mode 100644
index 0000000..2951ea6
--- /dev/null
+++ b/tests/operator_multiplayer_validation.gd.uid
@@ -0,0 +1 @@
+uid://cv17xsf20ue5t
diff --git a/tests/player_experience_ui_validation.gd b/tests/player_experience_ui_validation.gd
index 93c23eb..31ed497 100644
--- a/tests/player_experience_ui_validation.gd
+++ b/tests/player_experience_ui_validation.gd
@@ -12,6 +12,14 @@ func _run() -> void:
root.add_child(game_ui)
await process_frame
game_ui.set("_gameplay_ui_enabled", true)
+ var panel := game_ui.get_node("%ExperienceProgressPanel") as PanelContainer
+ var bubble := game_ui.get_node("%ExperienceBubble") as PanelContainer
+ var bubble_label := game_ui.get_node("%ExperienceBubbleLabel") as Label
+ var award_label := game_ui.get_node("%ExperienceAwardLabel") as Label
+ assert(panel != null and bubble != null)
+ assert(not panel.visible and not bubble.visible)
+ game_ui.call("_on_showcase_changed", "bluegill", "common", 1.0, 0, true)
+ await process_frame
game_ui.call(
"_on_experience_awarded",
50,
@@ -20,13 +28,6 @@ func _run() -> void:
1,
1,
)
- var panel := game_ui.get_node("%ExperienceProgressPanel") as PanelContainer
- var bubble := game_ui.get_node("%ExperienceBubble") as PanelContainer
- var bubble_label := game_ui.get_node("%ExperienceBubbleLabel") as Label
- var award_label := game_ui.get_node("%ExperienceAwardLabel") as Label
- assert(panel != null and bubble != null)
- assert(not panel.visible and not bubble.visible)
- game_ui.call("_on_showcase_changed", "bluegill", "common", 1.0, 0, true)
await process_frame
assert(not panel.visible and not bubble.visible)
game_ui.call("_on_showcase_changed", "", "", 0.0, 0, false)
@@ -43,5 +44,8 @@ func _run() -> void:
await create_timer(1.2).timeout
assert(not panel.visible and not bubble.visible)
game_ui.queue_free()
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
print("Player experience UI validation: PASS")
quit()
diff --git a/tests/shoreline_ambience_validation.gd b/tests/shoreline_ambience_validation.gd
index 505452a..4297d72 100644
--- a/tests/shoreline_ambience_validation.gd
+++ b/tests/shoreline_ambience_validation.gd
@@ -34,7 +34,7 @@ func _run() -> void:
runtime_audio.owner = controller
root.add_child(controller)
await process_frame
- assert(runtime_audio.bus == &"SFX")
+ assert(runtime_audio.bus == &"Environment")
assert(controller.near_distance < controller.far_distance)
assert(controller.near_volume_db > controller.far_volume_db)
var runtime_waves := runtime_audio.stream as AudioStreamWAV
diff --git a/tests/shoreline_ribbon_validation.gd b/tests/shoreline_ribbon_validation.gd
new file mode 100644
index 0000000..e78acb0
--- /dev/null
+++ b/tests/shoreline_ribbon_validation.gd
@@ -0,0 +1,97 @@
+extends SceneTree
+
+const ShorelineMesh: ArrayMesh = preload(
+ "res://world/generated/shorelines/starter_ocean_shoreline.tres"
+)
+const GEOMETRY_EPSILON := 0.0001
+const CROSSING_NEIGHBORHOOD := 32
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ assert(ShorelineMesh.get_surface_count() == 1)
+ var arrays := ShorelineMesh.surface_get_arrays(0)
+ var vertices := arrays[Mesh.ARRAY_VERTEX] as PackedVector3Array
+ var indices := arrays[Mesh.ARRAY_INDEX] as PackedInt32Array
+ assert(not vertices.is_empty())
+ assert(vertices.size() % 2 == 0)
+ assert(indices.size() == vertices.size() * 3)
+ var point_count := vertices.size() / 2
+ var land_edge := PackedVector2Array()
+ var water_edge := PackedVector2Array()
+ for index: int in point_count:
+ var land := vertices[index * 2]
+ var water := vertices[index * 2 + 1]
+ land_edge.append(Vector2(land.x, land.z))
+ water_edge.append(Vector2(water.x, water.z))
+ var ribbon_width := land.distance_to(water)
+ assert(ribbon_width >= 0.34)
+ assert(ribbon_width <= 1.5)
+ var crossing_count := (
+ _count_local_crossings(water_edge)
+ + _count_local_crossings(land_edge)
+ )
+ if crossing_count > 0:
+ push_error(
+ "Shoreline ribbon contains %d local edge crossings."
+ % crossing_count
+ )
+ quit(1)
+ return
+ print("Shoreline ribbon validation: PASS")
+ quit()
+
+
+func _count_local_crossings(points: PackedVector2Array) -> int:
+ var crossing_count := 0
+ for first: int in points.size():
+ var first_next := (first + 1) % points.size()
+ var checked_neighbors := mini(
+ CROSSING_NEIGHBORHOOD,
+ points.size() - 2,
+ )
+ for offset: int in range(2, checked_neighbors + 1):
+ var second := (first + offset) % points.size()
+ var second_next := (second + 1) % points.size()
+ if second_next == first:
+ continue
+ if _segments_cross(
+ points[first],
+ points[first_next],
+ points[second],
+ points[second_next],
+ ):
+ crossing_count += 1
+ return crossing_count
+
+
+func _segments_cross(
+ a: Vector2,
+ b: Vector2,
+ c: Vector2,
+ d: Vector2,
+) -> bool:
+ if (
+ maxf(a.x, b.x) < minf(c.x, d.x) - GEOMETRY_EPSILON
+ or maxf(c.x, d.x) < minf(a.x, b.x) - GEOMETRY_EPSILON
+ or maxf(a.y, b.y) < minf(c.y, d.y) - GEOMETRY_EPSILON
+ or maxf(c.y, d.y) < minf(a.y, b.y) - GEOMETRY_EPSILON
+ ):
+ return false
+ var first_direction := b - a
+ var second_direction := d - c
+ var denominator := first_direction.cross(second_direction)
+ if absf(denominator) <= GEOMETRY_EPSILON:
+ return false
+ var offset := c - a
+ var first_amount := offset.cross(second_direction) / denominator
+ var second_amount := offset.cross(first_direction) / denominator
+ return (
+ first_amount > GEOMETRY_EPSILON
+ and first_amount < 1.0 - GEOMETRY_EPSILON
+ and second_amount > GEOMETRY_EPSILON
+ and second_amount < 1.0 - GEOMETRY_EPSILON
+ )
diff --git a/tests/shoreline_ribbon_validation.gd.uid b/tests/shoreline_ribbon_validation.gd.uid
new file mode 100644
index 0000000..7989d89
--- /dev/null
+++ b/tests/shoreline_ribbon_validation.gd.uid
@@ -0,0 +1 @@
+uid://c73frygpfhred
diff --git a/tests/surface_drawing_multiplayer_validation.gd b/tests/surface_drawing_multiplayer_validation.gd
index 12925ba..74c86d2 100644
--- a/tests/surface_drawing_multiplayer_validation.gd
+++ b/tests/surface_drawing_multiplayer_validation.gd
@@ -32,6 +32,8 @@ func _run_host() -> void:
await physics_frame
var player := main.get("_player") as Player
assert(player.bag.add_item(&"art_kit", 1))
+ assert(player.hotbar.assign_item(0, &"art_kit"))
+ assert(player.hotbar.select_slot(0))
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
var service := main.get_node(
@@ -114,7 +116,9 @@ func _run_host() -> void:
print("Surface drawing multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -138,6 +142,8 @@ func _run_client() -> void:
))
var player := main.get("_player") as Player
assert(player.bag.add_item(&"art_kit", 1))
+ assert(player.hotbar.assign_item(0, &"art_kit"))
+ assert(player.hotbar.select_slot(0))
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
var service := main.get_node(
@@ -207,7 +213,9 @@ func _run_client() -> void:
print("Surface drawing multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/surface_drawing_runtime_validation.gd b/tests/surface_drawing_runtime_validation.gd
index 6e6e68d..8835127 100644
--- a/tests/surface_drawing_runtime_validation.gd
+++ b/tests/surface_drawing_runtime_validation.gd
@@ -29,12 +29,15 @@ func _run() -> void:
var player := main.get("_player") as Player
assert(player.bag.add_item(&"art_kit", 1))
+ assert(player.hotbar.assign_item(0, &"art_kit"))
+ assert(player.hotbar.select_slot(0))
assert(player.art_unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK))
var service := main.get_node(
"%NetworkSurfaceDrawingService"
) as NetworkSurfaceDrawingService
assert(service != null)
assert(session.supports_server_capability(SurfaceDrawingProtocol.CAPABILITY))
+ service.deactivate()
_validate_marker_controls(service, player)
var query := PhysicsRayQueryParameters3D.create(
player.global_position + Vector3.UP * 3.0,
@@ -110,7 +113,9 @@ func _run() -> void:
print("Surface drawing runtime validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -122,7 +127,7 @@ func _validate_marker_controls(
var activation_pointer := Vector2(824.0, 318.0)
service.activate(activation_pointer)
assert(service.is_active())
- assert(service.is_placement_mode())
+ assert(not service.is_placement_mode())
assert(service.get_pointer_screen_position() == activation_pointer)
if DisplayServer.get_name() != "headless":
assert(Input.mouse_mode == Input.MOUSE_MODE_VISIBLE)
@@ -131,7 +136,7 @@ func _validate_marker_controls(
placement_key.physical_keycode = KEY_R
placement_key.pressed = true
assert(service.handle_input(placement_key, true))
- assert(not service.is_placement_mode())
+ assert(service.is_placement_mode())
var pointer_before: Vector2 = service.get_pointer_screen_position()
var pointer_motion := InputEventMouseMotion.new()
@@ -169,6 +174,6 @@ func _validate_marker_controls(
assert(not service.handle_input(camera_release, true))
assert(service.handle_input(placement_key, true))
- assert(service.is_placement_mode())
+ assert(not service.is_placement_mode())
service.deactivate()
assert(Input.mouse_mode == prior_mouse_mode)
diff --git a/tests/surface_drawing_validation.gd b/tests/surface_drawing_validation.gd
index aa94f0f..596cec0 100644
--- a/tests/surface_drawing_validation.gd
+++ b/tests/surface_drawing_validation.gd
@@ -21,6 +21,8 @@ func _run() -> void:
await _validate_blocked_author_visibility()
_validate_peer_capability_tracking()
print("Surface drawing validation: PASS")
+ for _frame: int in 4:
+ await process_frame
quit()
@@ -118,6 +120,7 @@ func _validate_art_unlocks() -> void:
assert(unlocks.is_brush_size_unlocked(4))
assert(unlocks.is_grid_size_unlocked(128))
assert(not unlocks.restore_mask(PlayerArtUnlocks.ALL_UNLOCK_MASK + 1))
+ unlocks.free()
func _validate_grid_snapping() -> void:
@@ -265,6 +268,7 @@ func _validate_blocked_author_visibility() -> void:
})
var world := Node3D.new()
root.add_child(world)
+ world.add_child(relationships)
var canvas := SurfaceDrawingCanvas.new()
world.add_child(canvas)
var state: Dictionary = {
diff --git a/tests/terrain_blender_material_validation.gd b/tests/terrain_blender_material_validation.gd
new file mode 100644
index 0000000..fe3de22
--- /dev/null
+++ b/tests/terrain_blender_material_validation.gd
@@ -0,0 +1,190 @@
+extends SceneTree
+
+const REGION := preload("res://world/regions/starter_island_region.tscn")
+const TERRAIN_MODEL_PATH: String = (
+ "res://art/exported/environment/terrain/starter_island.glb"
+)
+const EXPECTED_SURFACES: Array[String] = [
+ "grass_lite",
+ "dirt",
+ "cliff_wall",
+ "dirt_wall",
+ "sand",
+ "sandstone_heavy",
+]
+
+var failures: Array[String] = []
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ var model_scene := load(TERRAIN_MODEL_PATH) as PackedScene
+ _check(model_scene != null, "Starter-island GLB must load as a scene.")
+ if model_scene == null:
+ _finish()
+ return
+
+ var model_root := model_scene.instantiate()
+ var model_terrain := _find_mesh(model_root, "starter_island")
+ _check(model_terrain != null, "GLB must contain the starter_island mesh.")
+ _check(_find_mesh(model_root, "Cube") == null, "GLB must not contain Cube.")
+ if model_terrain != null:
+ _validate_terrain_materials(model_terrain, "GLB")
+ model_root.free()
+
+ var region := REGION.instantiate()
+ root.add_child(region)
+ await process_frame
+ var runtime_terrain := region.get_node_or_null(
+ "Terrain/Visual/starter_island"
+ ) as MeshInstance3D
+ _check(runtime_terrain != null, "Region must contain the terrain mesh.")
+ if runtime_terrain != null:
+ _validate_terrain_materials(runtime_terrain, "Region")
+ for surface_index: int in runtime_terrain.mesh.get_surface_count():
+ _check(
+ runtime_terrain.get_surface_override_material(surface_index) == null,
+ "Region surface %d must use its Blender material." % surface_index,
+ )
+ _validate_region_collision(region)
+ region.free()
+ _finish()
+
+
+func _find_mesh(node: Node, mesh_name: String) -> MeshInstance3D:
+ if node is MeshInstance3D and node.name == mesh_name:
+ return node as MeshInstance3D
+ for child: Node in node.get_children():
+ var match := _find_mesh(child, mesh_name)
+ if match != null:
+ return match
+ return null
+
+
+func _validate_terrain_materials(
+ terrain: MeshInstance3D,
+ context: String,
+) -> void:
+ _check(terrain.mesh != null, "%s terrain must have a mesh." % context)
+ if terrain.mesh == null:
+ return
+ _check(
+ terrain.mesh.get_surface_count() == EXPECTED_SURFACES.size(),
+ "%s terrain must have %d surfaces." % [
+ context,
+ EXPECTED_SURFACES.size(),
+ ],
+ )
+ var checked_count := mini(
+ terrain.mesh.get_surface_count(),
+ EXPECTED_SURFACES.size(),
+ )
+ for surface_index: int in checked_count:
+ var expected_name := EXPECTED_SURFACES[surface_index]
+ _check(
+ terrain.mesh.surface_get_name(surface_index) == expected_name,
+ "%s surface %d must be named %s." % [
+ context,
+ surface_index,
+ expected_name,
+ ],
+ )
+ var material := terrain.get_active_material(surface_index)
+ _check(
+ material is StandardMaterial3D,
+ "%s surface %s must use a Blender material." % [
+ context,
+ expected_name,
+ ],
+ )
+ if material is StandardMaterial3D:
+ var texture := (material as StandardMaterial3D).albedo_texture
+ _check(
+ texture != null,
+ "%s surface %s must have an embedded texture." % [
+ context,
+ expected_name,
+ ],
+ )
+ if texture != null:
+ _check(
+ texture.resource_path.begins_with(TERRAIN_MODEL_PATH + "::"),
+ "%s surface %s must source its texture from the GLB." % [
+ context,
+ expected_name,
+ ],
+ )
+
+
+func _validate_region_collision(region: StarterIslandRegion) -> void:
+ _check(
+ region.rebuild_terrain_collision_on_ready,
+ "Starter-island collision must rebuild from the imported GLB.",
+ )
+ var visual_root := region.get_node_or_null("Terrain/Visual") as Node3D
+ var collision_shape := region.get_node_or_null(
+ "Terrain/Collision/Shape"
+ ) as CollisionShape3D
+ _check(visual_root != null, "Region must contain its visual hierarchy.")
+ _check(collision_shape != null, "Region must contain its collision owner.")
+ if visual_root == null or collision_shape == null:
+ return
+ var concave_shape := collision_shape.shape as ConcavePolygonShape3D
+ _check(
+ concave_shape != null,
+ "Region collision must be a generated concave polygon shape.",
+ )
+ if concave_shape == null:
+ return
+ var expected_faces := PackedVector3Array()
+ var mesh_count := _append_collision_faces(
+ region,
+ visual_root,
+ expected_faces,
+ )
+ var actual_faces := concave_shape.get_faces()
+ _check(mesh_count > 1, "Collision must include the imported prop meshes.")
+ _check(not expected_faces.is_empty(), "Imported meshes must provide collision.")
+ _check(
+ actual_faces == expected_faces,
+ "Generated collision must exactly match every imported mesh transform.",
+ )
+
+
+func _append_collision_faces(
+ region: StarterIslandRegion,
+ node: Node,
+ faces: PackedVector3Array,
+) -> int:
+ var mesh_count := 0
+ if node is MeshInstance3D:
+ var mesh_instance := node as MeshInstance3D
+ if mesh_instance.mesh != null:
+ var mesh_shape := mesh_instance.mesh.create_trimesh_shape()
+ if mesh_shape != null:
+ mesh_count += 1
+ for face_vertex: Vector3 in mesh_shape.get_faces():
+ faces.append(
+ region.to_local(mesh_instance.to_global(face_vertex))
+ )
+ for child: Node in node.get_children():
+ mesh_count += _append_collision_faces(region, child, faces)
+ return mesh_count
+
+
+func _check(condition: bool, message: String) -> void:
+ if not condition:
+ failures.append(message)
+
+
+func _finish() -> void:
+ if failures.is_empty():
+ print("Blender terrain and collision validation: PASS")
+ quit(0)
+ return
+ for failure: String in failures:
+ printerr("Blender terrain and collision validation: ", failure)
+ quit(1)
diff --git a/tests/terrain_projection_validation.gd.uid b/tests/terrain_blender_material_validation.gd.uid
similarity index 100%
rename from tests/terrain_projection_validation.gd.uid
rename to tests/terrain_blender_material_validation.gd.uid
diff --git a/tests/terrain_projection_validation.gd b/tests/terrain_projection_validation.gd
deleted file mode 100644
index 41053ef..0000000
--- a/tests/terrain_projection_validation.gd
+++ /dev/null
@@ -1,78 +0,0 @@
-extends SceneTree
-
-const REGION := preload("res://world/regions/starter_island_region.tscn")
-
-
-func _initialize() -> void:
- call_deferred("_run")
-
-
-func _run() -> void:
- var region := REGION.instantiate()
- root.add_child(region)
- await process_frame
- var terrain := region.get_node(
- "Terrain/Visual/starter_island"
- ) as MeshInstance3D
- assert(terrain != null)
- assert(terrain.mesh.get_surface_count() == 5)
- assert(terrain.mesh.surface_get_name(0) == "grass_lite")
- assert(terrain.mesh.surface_get_name(1) == "dirt")
- assert(terrain.mesh.surface_get_name(2) == "sand")
- assert(terrain.mesh.surface_get_name(3) == "cliff_wall")
- assert(terrain.mesh.surface_get_name(4) == "dirt_wall")
-
- _validate_projected_material(
- terrain.get_surface_override_material(0),
- "res://art/exported/environment/textures/grass_lite.png"
- )
- _validate_projected_material(
- terrain.get_surface_override_material(2),
- "res://art/exported/environment/textures/sand.png"
- )
- for surface: int in [1, 3, 4]:
- assert(terrain.get_surface_override_material(surface) == null)
- assert(terrain.mesh.surface_get_material(surface) is StandardMaterial3D)
-
- print("Terrain projection validation: PASS")
- region.free()
- quit()
-
-
-func _validate_projected_material(
- material: Material,
- expected_texture_path: String,
-) -> void:
- assert(material is ShaderMaterial)
- var shader_material := material as ShaderMaterial
- assert(
- shader_material.shader.resource_path
- == "res://world/materials/terrain_surface_projection.gdshader"
- )
- assert(
- is_equal_approx(
- float(shader_material.get_shader_parameter("tile_world_size")),
- 2.5
- )
- )
- assert(
- is_equal_approx(
- float(shader_material.get_shader_parameter("blend_sharpness")),
- 6.0
- )
- )
- assert(
- is_equal_approx(
- float(shader_material.get_shader_parameter("top_projection_bias")),
- 2.0
- )
- )
- var texture: Texture2D = shader_material.get_shader_parameter(
- "albedo_texture"
- ) as Texture2D
- assert(texture != null)
- assert(texture.resource_path == expected_texture_path)
- var imported_image: Image = texture.get_image()
- assert(imported_image != null)
- assert(not imported_image.has_mipmaps())
- assert(imported_image.get_format() == Image.FORMAT_RGBA8)
diff --git a/tests/texture_sampling_validation.gd b/tests/texture_sampling_validation.gd
new file mode 100644
index 0000000..deeabce
--- /dev/null
+++ b/tests/texture_sampling_validation.gd
@@ -0,0 +1,148 @@
+extends SceneTree
+
+const POLICY := preload("res://main/texture_sampling_policy.gd")
+
+var failures: Array[String] = []
+
+
+func _initialize() -> void:
+ call_deferred("_run")
+
+
+func _run() -> void:
+ _validate_runtime_policy()
+ _validate_repository_files("res://")
+ if failures.is_empty():
+ print("Texture sampling validation passed.")
+ quit(0)
+ return
+ for failure: String in failures:
+ printerr("Texture sampling validation: ", failure)
+ quit(1)
+
+
+func _validate_runtime_policy() -> void:
+ var texture_rect := TextureRect.new()
+ texture_rect.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR
+ POLICY.enforce_node(texture_rect)
+ _check(
+ texture_rect.texture_filter == CanvasItem.TEXTURE_FILTER_NEAREST,
+ "CanvasItem policy must replace linear sampling with nearest sampling.",
+ )
+ texture_rect.free()
+
+ var sprite := Sprite3D.new()
+ sprite.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR
+ POLICY.enforce_node(sprite)
+ _check(
+ sprite.texture_filter == BaseMaterial3D.TEXTURE_FILTER_NEAREST,
+ "Sprite3D policy must replace linear sampling with nearest sampling.",
+ )
+ sprite.free()
+
+ var material := StandardMaterial3D.new()
+ material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR
+ var quad := QuadMesh.new()
+ quad.material = material
+ var mesh_instance := MeshInstance3D.new()
+ mesh_instance.mesh = quad
+ POLICY.enforce_node(mesh_instance)
+ _check(
+ material.texture_filter == BaseMaterial3D.TEXTURE_FILTER_NEAREST,
+ "3D material policy must replace linear sampling with nearest sampling.",
+ )
+ mesh_instance.free()
+
+
+func _validate_repository_files(path: String) -> void:
+ var directory := DirAccess.open(path)
+ if directory == null:
+ failures.append("Could not scan %s." % path)
+ return
+ directory.list_dir_begin()
+ while true:
+ var name := directory.get_next()
+ if name.is_empty():
+ break
+ if name == ".godot" or name == ".git":
+ continue
+ var child_path := path.path_join(name)
+ if directory.current_is_dir():
+ _validate_repository_files(child_path)
+ continue
+ if name.ends_with(".import"):
+ _validate_import_file(child_path)
+ elif name.ends_with(".gdshader"):
+ _validate_shader_file(child_path)
+ elif name.ends_with(".tscn") or name.ends_with(".tres"):
+ _validate_serialized_resource(child_path)
+ elif name.ends_with(".gd") and child_path != get_script().resource_path:
+ _validate_script_file(child_path)
+ directory.list_dir_end()
+
+
+func _validate_import_file(path: String) -> void:
+ var source := FileAccess.get_file_as_string(path)
+ _check(
+ "mipmaps/generate=true" not in source,
+ "Texture import generates mipmaps: %s" % path,
+ )
+
+
+func _validate_shader_file(path: String) -> void:
+ var source := FileAccess.get_file_as_string(path)
+ var declaration_start := source.find("uniform sampler")
+ while declaration_start >= 0:
+ var declaration_end := source.find(";", declaration_start)
+ if declaration_end < 0:
+ _check(false, "Incomplete sampler declaration in %s." % path)
+ return
+ var declaration := source.substr(
+ declaration_start,
+ declaration_end - declaration_start,
+ )
+ _check(
+ "filter_nearest" in declaration,
+ "Shader sampler must declare filter_nearest: %s" % path,
+ )
+ declaration_start = source.find("uniform sampler", declaration_end + 1)
+
+
+func _validate_serialized_resource(path: String) -> void:
+ var source := FileAccess.get_file_as_string(path)
+ var uses_3d_filter_enum := false
+ for line: String in source.split("\n"):
+ if line.begins_with("["):
+ uses_3d_filter_enum = (
+ ("type=\"Sprite3D\"" in line)
+ or ("type=\"AnimatedSprite3D\"" in line)
+ or ("type=\"StandardMaterial3D\"" in line)
+ or ("type=\"ORMMaterial3D\"" in line)
+ )
+ if not line.begins_with("texture_filter = "):
+ continue
+ var value := int(line.trim_prefix("texture_filter = "))
+ if uses_3d_filter_enum:
+ _check(
+ value == BaseMaterial3D.TEXTURE_FILTER_NEAREST,
+ "3D resource declares non-nearest filtering: %s" % path,
+ )
+ else:
+ _check(
+ value == CanvasItem.TEXTURE_FILTER_PARENT_NODE
+ or value == CanvasItem.TEXTURE_FILTER_NEAREST,
+ "Canvas resource declares non-nearest filtering: %s" % path,
+ )
+
+
+func _validate_script_file(path: String) -> void:
+ var source := FileAccess.get_file_as_string(path)
+ _check(
+ "TEXTURE_FILTER_LINEAR" not in source,
+ "Script explicitly requests linear texture filtering: %s" % path,
+ )
+
+
+func _check(condition: bool, message: String) -> void:
+ if not condition:
+ failures.append(message)
diff --git a/tests/texture_sampling_validation.gd.uid b/tests/texture_sampling_validation.gd.uid
new file mode 100644
index 0000000..9a2f48b
--- /dev/null
+++ b/tests/texture_sampling_validation.gd.uid
@@ -0,0 +1 @@
+uid://dqm0j1xnkeox1
diff --git a/tests/title_credits_validation.gd b/tests/title_credits_validation.gd
new file mode 100644
index 0000000..7e50f89
--- /dev/null
+++ b/tests/title_credits_validation.gd
@@ -0,0 +1,207 @@
+extends SceneTree
+
+const TitleScreenScene := preload("res://ui/title_screen.tscn")
+const TitleCreditsPageType = preload("res://ui/title_credits_page.gd")
+
+var _failures: Array[String] = []
+
+
+func _initialize() -> void:
+ _run.call_deferred()
+
+
+func _run() -> void:
+ var original_size: Vector2i = root.size
+ root.size = Vector2i(1280, 720)
+ var title_screen := TitleScreenScene.instantiate() as TitleScreen
+ root.add_child(title_screen)
+ await process_frame
+ await process_frame
+
+ var credits_button := title_screen.get_node(
+ "%CreditsButton"
+ ) as BubbleButton
+ var credits_page := title_screen.get_node(
+ "%CreditsPage"
+ ) as TitleCreditsPageType
+ var back_button: Button = credits_page.get_back_button()
+ var presentation := title_screen.get_node("%Center") as Control
+ var bubble_field := title_screen.get_node("%BubbleField") as Control
+ title_screen.call("_update_title_layout")
+ (title_screen.get_node("%ButtonCenter") as Control).show()
+ bubble_field.show()
+ title_screen.call("_set_title_bubbles_interactive", true)
+ await process_frame
+
+ _expect(credits_button != null, "title menu exposes a credits button")
+ _expect(credits_page != null, "title screen contains the credits page")
+ _expect(not credits_page.visible, "credits page starts closed")
+ _expect(
+ Rect2(Vector2.ZERO, bubble_field.size).encloses(
+ Rect2(credits_button.position, credits_button.size)
+ ),
+ "credits bubble stays inside the authored title field",
+ )
+ _expect(
+ credits_button.mouse_filter == Control.MOUSE_FILTER_STOP,
+ "credits bubble accepts pointer input",
+ )
+ if OS.has_environment("NETFISHING_TITLE_MENU_CAPTURE"):
+ (title_screen.get_node("%StartPromptCenter") as Control).hide()
+ title_screen.set_process(true)
+ await create_timer(0.5).timeout
+ _expect(
+ _save_capture(
+ OS.get_environment("NETFISHING_TITLE_MENU_CAPTURE")
+ ) == OK,
+ "title menu validation capture saves successfully",
+ )
+ title_screen.set_process(false)
+
+ title_screen.set("_navigation_focus_active", false)
+ credits_button.pressed.emit()
+ await process_frame
+ _expect(credits_page.visible, "pointer activation opens credits")
+ _expect(not presentation.visible, "credits replace the primary title menu")
+ _expect(
+ root.gui_get_focus_owner() != back_button,
+ "pointer activation does not pseudo-select back",
+ )
+ await create_timer(0.25).timeout
+ _expect(
+ credits_page.mouse_filter == Control.MOUSE_FILTER_PASS,
+ "credits page becomes pointer-interactive after entry motion",
+ )
+ _expect(
+ back_button.mouse_filter == Control.MOUSE_FILTER_STOP,
+ "credits back button accepts pointer clicks",
+ )
+ if OS.has_environment("NETFISHING_CREDITS_CAPTURE"):
+ await process_frame
+ _expect(
+ _save_capture(
+ OS.get_environment("NETFISHING_CREDITS_CAPTURE")
+ ) == OK,
+ "credits validation capture saves successfully",
+ )
+ back_button.pressed.emit()
+ await process_frame
+ _expect(not credits_page.visible, "pointer back closes credits")
+ _expect(presentation.visible, "closing credits restores the title menu")
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "pointer return leaves the title menu unfocused",
+ )
+
+ title_screen.set("_navigation_focus_active", true)
+ credits_button.grab_focus()
+ credits_button.pressed.emit()
+ await process_frame
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == back_button,
+ "keyboard or controller activation focuses the credits back button",
+ )
+
+ var pointer_motion := InputEventMouseMotion.new()
+ pointer_motion.position = Vector2(640.0, 360.0)
+ title_screen._input(pointer_motion)
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == null,
+ "pointer motion clears credits navigation focus",
+ )
+
+ var navigate := InputEventAction.new()
+ navigate.action = &"ui_down"
+ navigate.pressed = true
+ title_screen._input(navigate)
+ await process_frame
+ _expect(
+ root.gui_get_focus_owner() == back_button,
+ "navigation input restores credits focus",
+ )
+
+ var cancel := InputEventAction.new()
+ cancel.action = &"ui_cancel"
+ cancel.pressed = true
+ title_screen._input(cancel)
+ await process_frame
+ _expect(not credits_page.visible, "ui cancel closes credits")
+ _expect(
+ root.gui_get_focus_owner() == credits_button,
+ "navigation return restores focus to the credits bubble",
+ )
+
+ var chillnfill_name := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/ChillnfillName"
+ ) as Label
+ var voyager_name := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/VoyagerName"
+ ) as Label
+ var endeavour_name := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/EndeavourName"
+ ) as Label
+ var chillnfill_credit := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/ChillnfillCredit"
+ ) as Label
+ var tekgator_name := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/TekgatorName"
+ ) as Label
+ var tekgator_credit := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits/TekgatorCredit"
+ ) as Label
+ var creative_credits := credits_page.get_node(
+ "Paper/Margin/Layout/Columns/CreativeCredits"
+ ) as VBoxContainer
+ _expect(voyager_name.text == "Voyager", "in-game credits use Voyager")
+ _expect(
+ endeavour_name.text == "Endeavour",
+ "in-game credits use Endeavour",
+ )
+ _expect(
+ chillnfill_name.text == "chillnfill",
+ "in-game credits name chillnfill",
+ )
+ _expect(
+ "trees and bridges" in chillnfill_credit.text.to_lower(),
+ "in-game credits describe the supplied model families",
+ )
+ _expect(
+ tekgator_name.text == "Tekgator",
+ "in-game credits name Tekgator",
+ )
+ _expect(
+ "shop icon" in tekgator_credit.text.to_lower(),
+ "in-game credits describe Tekgator's shop icon artwork",
+ )
+ _expect(
+ Rect2(Vector2.ZERO, creative_credits.size).encloses(
+ Rect2(tekgator_credit.position, tekgator_credit.size)
+ ),
+ "Tekgator's credit stays inside the authored credits column",
+ )
+
+ title_screen.queue_free()
+ root.size = original_size
+ await process_frame
+ await process_frame
+ if _failures.is_empty():
+ print("Title credits validation: PASS")
+ quit(0)
+ return
+ for failure: String in _failures:
+ push_error(failure)
+ quit(1)
+
+
+func _expect(condition: bool, message: String) -> void:
+ if not condition:
+ _failures.append(message)
+
+
+func _save_capture(path: String) -> Error:
+ var viewport_texture: Texture2D = root.get_texture()
+ if viewport_texture == null:
+ return ERR_UNAVAILABLE
+ return viewport_texture.get_image().save_png(path)
diff --git a/tests/title_credits_validation.gd.uid b/tests/title_credits_validation.gd.uid
new file mode 100644
index 0000000..747e70c
--- /dev/null
+++ b/tests/title_credits_validation.gd.uid
@@ -0,0 +1 @@
+uid://dimq4ehtlw64n
diff --git a/tests/ui_scaling_runtime_validation.gd b/tests/ui_scaling_runtime_validation.gd
index f3f4974..f7144eb 100644
--- a/tests/ui_scaling_runtime_validation.gd
+++ b/tests/ui_scaling_runtime_validation.gd
@@ -94,7 +94,10 @@ func _run() -> void:
assert(player_menu.size.is_equal_approx(
UIReferencePresentationType.REFERENCE_SIZE
))
- assert(hotbar.position.is_equal_approx(Vector2.ZERO))
+ assert(hotbar.position.is_equal_approx(Vector2(
+ 0.0,
+ canonical_stage.position.y,
+ )))
assert(hotbar.size.is_equal_approx(
UIReferencePresentationType.REFERENCE_SIZE
))
@@ -202,6 +205,8 @@ func _run() -> void:
presenter.queue_free()
root.size = original_size
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
print("UI scaling runtime validation: PASS")
quit()
diff --git a/tests/world_time_multiplayer_validation.gd b/tests/world_time_multiplayer_validation.gd
index 2d82aea..cebb0eb 100644
--- a/tests/world_time_multiplayer_validation.gd
+++ b/tests/world_time_multiplayer_validation.gd
@@ -3,7 +3,7 @@ extends SceneTree
const MainScene = preload("res://main/main.tscn")
const TEST_PORT: int = 17983
const INITIAL_HOST_TIME: float = 19.75
-const UPDATED_HOST_TIME: float = 20.75
+const UPDATED_HOST_TIME: float = WorldTimeService.DUSK_END_HOUR
const TIME_TOLERANCE_HOURS: float = 0.05
@@ -31,13 +31,15 @@ func _run_host() -> void:
main.get_node("%WorldWeatherService") as WorldWeatherService
)
assert(session.start_private_host(TEST_PORT))
+ var game_ui := main.get_node("%GameUI") as CanvasLayer
+ var chat_ui := game_ui.get_node("%ChatUI") as ChatUI
+ assert(chat_ui.call("_handle_chat_command", "/weather clear"))
+ assert(world_weather.get_weather() == WorldWeatherService.Weather.SUNNY)
world_time.synchronize_time(INITIAL_HOST_TIME)
assert(is_equal_approx(
world_time.get_persistent_time_hours(), INITIAL_HOST_TIME
))
- world_weather.apply_authoritative_snapshot(
- WorldWeatherService.Weather.RAINY, 300.0
- )
+ assert(chat_ui.call("_handle_chat_command", "/weather rainy"))
assert(
world_weather.get_persistent_weather()
== WorldWeatherService.Weather.RAINY
@@ -59,16 +61,31 @@ func _run_host() -> void:
assert(session.peer_supports_capability(
remote_peer_id, NetworkProtocol.WORLD_WEATHER_CAPABILITY
))
+ var remote_record: PeerRegistry.PeerRecord = session.get_peer_record(
+ remote_peer_id
+ )
+ assert(remote_record != null and remote_record.identity_authenticated)
+ assert(session.set_peer_operator(
+ remote_peer_id,
+ remote_record.identity_fingerprint,
+ true,
+ ))
assert(world_time.get_phase() == WorldTimeService.Phase.DUSK)
- await create_timer(1.0).timeout
- world_time.synchronize_time(UPDATED_HOST_TIME)
+ var command_deadline: int = Time.get_ticks_msec() + 10000
+ while (
+ Time.get_ticks_msec() < command_deadline
+ and _wrapped_time_difference(
+ world_time.get_time_hours(), UPDATED_HOST_TIME
+ ) > TIME_TOLERANCE_HOURS
+ ):
+ await process_frame
assert(is_equal_approx(
world_time.get_persistent_time_hours(), UPDATED_HOST_TIME
))
- world_weather.apply_authoritative_snapshot(
- WorldWeatherService.Weather.FOGGY, 300.0
- )
+ var fog_deadline: int = Time.get_ticks_msec() + 10000
+ while Time.get_ticks_msec() < fog_deadline and not world_weather.is_foggy():
+ await process_frame
assert(
world_weather.get_persistent_weather()
== WorldWeatherService.Weather.FOGGY
@@ -83,7 +100,9 @@ func _run_host() -> void:
print("World time multiplayer host validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
@@ -151,6 +170,11 @@ func _run_client() -> void:
assert(is_equal_approx(clock_panel.position.y, 10.0))
assert(is_equal_approx(weather_icon.position.y, 10.0))
assert(clock_panel.position.y + clock_panel.size.y < chat_panel.position.y)
+ var operator_deadline: int = Time.get_ticks_msec() + 10000
+ while Time.get_ticks_msec() < operator_deadline and not session.is_local_operator():
+ await process_frame
+ assert(session.is_local_operator())
+ assert(chat_ui.call("_handle_chat_command", "/time night"))
var update_deadline: int = Time.get_ticks_msec() + 10000
while (
@@ -166,6 +190,8 @@ func _run_client() -> void:
assert(world_time.get_phase() == WorldTimeService.Phase.NIGHT)
assert(is_equal_approx(world_time.get_persistent_time_hours(), 15.25))
assert(clock_label.text == world_time.get_clock_text())
+ await create_timer(0.6).timeout
+ assert(chat_ui.call("_handle_chat_command", "/weather foggy"))
var fog_deadline: int = Time.get_ticks_msec() + 8000
while (
Time.get_ticks_msec() < fog_deadline
@@ -195,7 +221,9 @@ func _run_client() -> void:
print("World time multiplayer client validation: PASS")
session.disconnect_session("")
main.queue_free()
- await process_frame
+ for _frame: int in 4:
+ await process_frame
+ await create_timer(0.1).timeout
quit()
diff --git a/tests/world_time_validation.gd b/tests/world_time_validation.gd
index 1fed6e7..b043718 100644
--- a/tests/world_time_validation.gd
+++ b/tests/world_time_validation.gd
@@ -23,8 +23,6 @@ const SaltWaterMaterial: ShaderMaterial = preload(
const FreshWaterMaterial: ShaderMaterial = preload(
"res://world/materials/stylized_water_fresh.tres"
)
-
-
func _initialize() -> void:
call_deferred("_run")
@@ -249,6 +247,33 @@ func _validate_environment_presentation() -> void:
< 0.01
)
var day_ambient_energy: float = runtime_environment.ambient_light_energy
+ assert(not runtime_environment.fog_enabled)
+ assert(is_equal_approx(runtime_environment.fog_sky_affect, 0.35))
+ var water_shader: Shader = preload(
+ "res://world/materials/stylized_water.gdshader"
+ )
+ var sky_shader: Shader = preload(
+ "res://world/environment/netfishing_sky.gdshader"
+ )
+ assert("uniform float fog_horizon_occlusion" in sky_shader.code)
+ assert("fog_horizon_color.rgb" in sky_shader.code)
+ assert("fog_disabled" in water_shader.code)
+ assert("surface_view_position = view_vertex.xyz" in water_shader.code)
+ assert("surface_view_distance = length(surface_view_position)" in water_shader.code)
+ assert(
+ "max(weather_fog_end, weather_fog_begin + 1.0),\n"
+ + "\t\tsurface_view_distance"
+ in water_shader.code
+ )
+ assert("weather_fog_near_amount" in water_shader.code)
+ assert("float weather_fog_alpha = mix(" in water_shader.code)
+ assert("ALPHA = clamp(water_alpha, 0.1, weather_fog_alpha)" in water_shader.code)
+ assert(is_zero_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
+ )))
+ assert(is_equal_approx(float(
+ SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
+ ), WorldTimeVisualController.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
var day_water_brightness := float(
SaltWaterMaterial.get_shader_parameter("environment_brightness")
)
@@ -279,6 +304,9 @@ func _validate_environment_presentation() -> void:
assert(night_moon_direction.y > 0.85)
assert(night_moon_direction.is_equal_approx(-night_sun_direction))
assert(runtime_environment.ambient_light_energy < day_ambient_energy)
+ assert(is_zero_approx(float(
+ runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
+ )))
var night_water_brightness := float(
SaltWaterMaterial.get_shader_parameter("environment_brightness")
)
@@ -292,17 +320,58 @@ func _validate_environment_presentation() -> void:
)
assert(night_water_tint.get_luminance() < 0.5)
var night_background_energy := runtime_environment.background_energy_multiplier
+ var night_ambient_energy := runtime_environment.ambient_light_energy
+ var night_fog_light_energy := runtime_environment.fog_light_energy
var night_adjustment_brightness := runtime_environment.adjustment_brightness
var night_adjustment_saturation := runtime_environment.adjustment_saturation
visuals.apply_weather_immediately(WorldWeatherService.Weather.FOGGY)
visuals.apply_time_immediately(0.0)
+ assert(runtime_environment.fog_enabled)
+ assert(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
+ ) > 0.99)
+ assert(is_equal_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
+ ), WorldTimeVisualController.FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT))
+ assert(is_equal_approx(float(
+ SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
+ ), WorldTimeVisualController.FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR))
+ assert(is_equal_approx(float(
+ runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
+ ), 1.0))
+ assert((
+ runtime_sky_material.get_shader_parameter("fog_horizon_color") as Color
+ ).is_equal_approx(WorldTimeVisualController.NIGHT_FOG))
+ var night_rendered_fog_color := (
+ runtime_environment.fog_light_color.srgb_to_linear()
+ )
+ night_rendered_fog_color.r *= runtime_environment.fog_light_energy
+ night_rendered_fog_color.g *= runtime_environment.fog_light_energy
+ night_rendered_fog_color.b *= runtime_environment.fog_light_energy
+ night_rendered_fog_color.a = 1.0
+ night_rendered_fog_color = night_rendered_fog_color.linear_to_srgb()
+ var night_water_fog_color := (
+ SaltWaterMaterial.get_shader_parameter("weather_fog_color") as Color
+ )
+ var corrected_night_fog_color := night_rendered_fog_color
+ corrected_night_fog_color.r *= (
+ WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.r
+ )
+ corrected_night_fog_color.g *= (
+ WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.g
+ )
+ corrected_night_fog_color.b *= (
+ WorldTimeVisualController.FOGGY_DARK_WATER_FOG_CORRECTION.b
+ )
+ assert(night_water_fog_color.is_equal_approx(corrected_night_fog_color))
var foggy_sky_horizon := (
runtime_sky_material.get_shader_parameter("sky_horizon_color") as Color
)
assert(foggy_sky_horizon.is_equal_approx(night_horizon))
- assert(is_zero_approx(runtime_environment.fog_sky_affect))
+ assert(is_equal_approx(runtime_environment.fog_sky_affect, 1.0))
+ assert(is_zero_approx(runtime_environment.fog_aerial_perspective))
assert(is_equal_approx(runtime_environment.fog_depth_begin, 3.0))
- assert(is_equal_approx(runtime_environment.fog_depth_end, 28.0))
+ assert(is_equal_approx(runtime_environment.fog_depth_end, 18.0))
assert(is_equal_approx(
float(SaltWaterMaterial.get_shader_parameter("environment_brightness")),
night_water_brightness,
@@ -311,6 +380,14 @@ func _validate_environment_presentation() -> void:
runtime_environment.background_energy_multiplier,
night_background_energy,
))
+ assert(is_equal_approx(
+ runtime_environment.ambient_light_energy,
+ night_ambient_energy,
+ ))
+ assert(is_equal_approx(
+ runtime_environment.fog_light_energy,
+ night_fog_light_energy,
+ ))
assert(is_equal_approx(
runtime_environment.adjustment_brightness,
night_adjustment_brightness,
@@ -319,8 +396,35 @@ func _validate_environment_presentation() -> void:
runtime_environment.adjustment_saturation,
night_adjustment_saturation,
))
+ visuals.apply_time_immediately(8.0)
+ assert(is_equal_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
+ ), WorldTimeVisualController.FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT))
+ assert(is_equal_approx(float(
+ runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
+ ), 1.0))
+ visuals.apply_time_immediately(20.0)
+ assert(is_zero_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
+ )))
+ assert(is_zero_approx(float(
+ runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
+ )))
visuals.apply_weather_immediately(WorldWeatherService.Weather.SUNNY)
visuals.apply_time_immediately(20.0)
+ assert(not runtime_environment.fog_enabled)
+ assert(is_zero_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_amount")
+ )))
+ assert(is_zero_approx(float(
+ SaltWaterMaterial.get_shader_parameter("weather_fog_near_amount")
+ )))
+ assert(is_equal_approx(float(
+ SaltWaterMaterial.get_shader_parameter("surface_highlight_night_floor")
+ ), WorldTimeVisualController.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
+ assert(is_zero_approx(float(
+ runtime_sky_material.get_shader_parameter("fog_horizon_occlusion")
+ )))
var dusk_horizon: Color = runtime_sky_material.get_shader_parameter(
"sky_horizon_color"
) as Color
diff --git a/tests/world_weather_validation.gd b/tests/world_weather_validation.gd
index 1035a09..a725117 100644
--- a/tests/world_weather_validation.gd
+++ b/tests/world_weather_validation.gd
@@ -24,6 +24,7 @@ func _initialize() -> void:
func _run() -> void:
_validate_weather_scheduler()
+ _validate_authoritative_weather_override()
_validate_weather_persistence()
_validate_snapshot_bounds()
_validate_fishing_weather_seams()
@@ -74,6 +75,54 @@ func _duration_is_valid(weather: WorldWeatherServiceType) -> bool:
return false
+func _validate_authoritative_weather_override() -> void:
+ var weather := WorldWeatherServiceType.new()
+ root.add_child(weather)
+ assert(not weather.set_authoritative_weather(
+ WorldWeatherServiceType.Weather.FOGGY
+ ))
+ weather.begin_authoritative_session(20260812)
+ assert(weather.set_authoritative_weather(
+ WorldWeatherServiceType.Weather.FOGGY
+ ))
+ assert(weather.is_foggy())
+ assert(_duration_is_valid(weather))
+ weather.end_session()
+ assert(not weather.set_authoritative_weather(
+ WorldWeatherServiceType.Weather.RAINY
+ ))
+
+ var clock := WorldTimeServiceType.new()
+ root.add_child(clock)
+ clock.begin_session(WorldTimeServiceType.DAY_START_HOUR)
+ var schedule: Array[Dictionary] = []
+ for index: int in WorldWeatherServiceType.DAILY_PLAN_SEGMENT_COUNT:
+ schedule.append({
+ "start_hour": fposmod(
+ WorldTimeServiceType.DAY_START_HOUR
+ + float(index)
+ * WorldWeatherServiceType.DAILY_PLAN_SEGMENT_HOURS,
+ WorldTimeServiceType.HOURS_PER_DAY,
+ ),
+ "weather": int(WorldWeatherServiceType.Weather.SUNNY),
+ })
+ assert(weather.configure_daily_plan("command-test", schedule, clock))
+ weather.begin_authoritative_session(20260812)
+ assert(weather.set_authoritative_weather(
+ WorldWeatherServiceType.Weather.RAINY
+ ))
+ weather.advance_weather(1.0)
+ assert(weather.is_raining())
+ clock.synchronize_time(
+ WorldTimeServiceType.DAY_START_HOUR
+ + WorldWeatherServiceType.DAILY_PLAN_SEGMENT_HOURS
+ )
+ weather.advance_weather(0.01)
+ assert(weather.get_weather() == WorldWeatherServiceType.Weather.SUNNY)
+ weather.queue_free()
+ clock.queue_free()
+
+
func _validate_weather_persistence() -> void:
var weather := WorldWeatherServiceType.new()
root.add_child(weather)
@@ -212,20 +261,136 @@ func _validate_weather_presentation() -> void:
weather.begin_remote_session()
var rain_target := Node3D.new()
world_root.add_child(rain_target)
+ var rain_camera := Camera3D.new()
+ world_root.add_child(rain_camera)
+ rain_target.global_position = Vector3(-18.0, 2.0, 14.0)
+ rain_camera.global_position = Vector3(24.0, 9.0, -18.0)
var visuals := WorldTimeVisualControllerType.new()
world_root.add_child(visuals)
visuals.setup(
- clock, world_environment, sun, weather, rain_target
+ clock,
+ world_environment,
+ sun,
+ weather,
+ rain_target,
+ func() -> Camera3D: return rain_camera,
)
var runtime_environment: Environment = world_environment.environment
+ var runtime_sky_material := (
+ runtime_environment.sky.sky_material as ShaderMaterial
+ )
+ var clear_background_energy: float = (
+ runtime_environment.background_energy_multiplier
+ )
+ var clear_ambient_energy: float = runtime_environment.ambient_light_energy
+ var clear_fog_light_energy: float = runtime_environment.fog_light_energy
+ var clear_brightness: float = runtime_environment.adjustment_brightness
var clear_saturation: float = runtime_environment.adjustment_saturation
+ var clear_sun_energy: float = sun.light_energy
+ var clear_water_brightness: float = float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "environment_brightness"
+ )
+ )
+ assert(not runtime_environment.fog_enabled)
+ assert(is_zero_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ )))
+ assert(is_equal_approx(runtime_environment.fog_sky_affect, 0.35))
+ assert(is_zero_approx(float(
+ runtime_sky_material.get_shader_parameter("cloud_opacity")
+ )))
+ var storm_clouds := visuals.get_node("LocalStormClouds") as Node3D
+ assert(storm_clouds != null)
+ assert(storm_clouds.call("get_patch_count") == 81)
+ var cloud_field := storm_clouds.get_node("CloudField") as MultiMeshInstance3D
+ assert(cloud_field != null)
+ assert(cloud_field.multimesh != null)
+ assert(cloud_field.multimesh.instance_count == 81)
+ assert(cloud_field.multimesh.mesh is ArrayMesh)
+ var cloud_shader: Shader = preload(
+ "res://world/environment/local_storm_cloud.gdshader"
+ )
+ assert("cull_disabled" in cloud_shader.code)
+ assert(LocalStormCloudLayer.WRAP_RADIUS >= 315.0)
+ assert(is_equal_approx(LocalStormCloudLayer.MAXIMUM_OPACITY, 1.0))
+ assert(
+ LocalStormCloudLayer.DISTANCE_FADE_END
+ < LocalStormCloudLayer.WRAP_RADIUS
+ )
+ assert(is_zero_approx(float(storm_clouds.call("get_storm_amount"))))
visuals.apply_weather_immediately(
WorldWeatherServiceType.Weather.FOGGY
)
+ assert(runtime_environment.fog_enabled)
+ assert(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ ) > 0.99)
+ assert(is_zero_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_near_amount"
+ )
+ )))
+ var water_fog_color := (
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_color"
+ ) as Color
+ )
+ var rendered_fog_color := (
+ runtime_environment.fog_light_color.srgb_to_linear()
+ )
+ rendered_fog_color.r *= runtime_environment.fog_light_energy
+ rendered_fog_color.g *= runtime_environment.fog_light_energy
+ rendered_fog_color.b *= runtime_environment.fog_light_energy
+ rendered_fog_color.a = 1.0
+ rendered_fog_color = rendered_fog_color.linear_to_srgb()
+ assert(water_fog_color.is_equal_approx(rendered_fog_color))
+ assert(is_equal_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "surface_highlight_night_floor"
+ )
+ ), WorldTimeVisualControllerType.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
assert(runtime_environment.fog_depth_begin <= 4.01)
- assert(runtime_environment.fog_depth_end <= 42.01)
- assert(is_zero_approx(runtime_environment.fog_sky_affect))
- assert(runtime_environment.fog_aerial_perspective >= 0.91)
+ assert(is_equal_approx(runtime_environment.fog_depth_end, 18.0))
+ assert(is_equal_approx(runtime_environment.fog_sky_affect, 1.0))
+ assert(is_zero_approx(runtime_environment.fog_aerial_perspective))
+ assert(is_zero_approx(float(
+ runtime_sky_material.get_shader_parameter("cloud_opacity")
+ )))
+ assert(is_equal_approx(
+ runtime_environment.background_energy_multiplier,
+ clear_background_energy
+ * WorldTimeVisualControllerType.FOG_DAYLIGHT_SCENE_BRIGHTNESS,
+ ))
+ assert(is_equal_approx(
+ runtime_environment.ambient_light_energy,
+ clear_ambient_energy
+ * WorldTimeVisualControllerType.FOG_DAYLIGHT_SCENE_BRIGHTNESS,
+ ))
+ assert(is_equal_approx(
+ runtime_environment.fog_light_energy,
+ clear_fog_light_energy
+ * WorldTimeVisualControllerType.FOG_DAYLIGHT_FOG_LIGHT_BRIGHTNESS,
+ ))
+ assert(is_equal_approx(
+ runtime_environment.adjustment_brightness,
+ clear_brightness
+ * WorldTimeVisualControllerType.FOG_DAYLIGHT_POST_BRIGHTNESS,
+ ))
+ assert(is_equal_approx(sun.light_energy, clear_sun_energy * 0.30))
+ assert(is_equal_approx(
+ float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "environment_brightness"
+ )
+ ),
+ clear_water_brightness
+ * WorldTimeVisualControllerType.FOG_DAYLIGHT_WATER_BRIGHTNESS,
+ ))
assert(is_equal_approx(
runtime_environment.adjustment_saturation,
clear_saturation,
@@ -233,13 +398,72 @@ func _validate_weather_presentation() -> void:
visuals.apply_weather_immediately(
WorldWeatherServiceType.Weather.RAINY
)
+ assert(runtime_environment.fog_enabled)
+ assert(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ ) > 0.99)
+ assert(is_zero_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_near_amount"
+ )
+ )))
+ var rainy_water_fog_color := (
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_color"
+ ) as Color
+ )
+ assert(
+ rainy_water_fog_color.is_equal_approx(
+ WorldTimeVisualControllerType.RAIN_WATER_FOG_COLOR
+ )
+ )
+ assert(is_equal_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "surface_highlight_night_floor"
+ )
+ ), WorldTimeVisualControllerType.DEFAULT_SURFACE_HIGHLIGHT_FLOOR))
+ assert(is_equal_approx(runtime_environment.fog_sky_affect, 0.68))
+ assert(
+ float(runtime_sky_material.get_shader_parameter("cloud_coverage"))
+ > 0.98
+ )
+ assert(
+ float(runtime_sky_material.get_shader_parameter("cloud_opacity"))
+ > 0.99
+ )
+ assert(float(storm_clouds.call("get_storm_amount")) > 0.87)
+ assert(storm_clouds.visible)
+ assert(is_equal_approx(
+ runtime_environment.adjustment_brightness,
+ clear_brightness
+ * 0.92
+ * WorldTimeVisualControllerType.RAIN_DAYLIGHT_POST_BRIGHTNESS,
+ ))
var rain := visuals.get_node("LocalRain") as GPUParticles3D
assert(rain != null)
+ assert(rain.global_position.is_equal_approx(
+ rain_camera.global_position
+ + WorldTimeVisualControllerType.RAIN_EMITTER_OFFSET
+ ))
+ rain_camera.global_position = Vector3(-31.0, 15.0, 42.0)
+ visuals.call("_update_rain_position")
+ assert(rain.global_position.is_equal_approx(
+ rain_camera.global_position
+ + WorldTimeVisualControllerType.RAIN_EMITTER_OFFSET
+ ))
assert(rain.emitting)
assert(rain.amount_ratio > 0.99)
assert(rain.amount == WorldTimeVisualControllerType.RAIN_PARTICLE_AMOUNT)
+ assert(rain.visibility_aabb == (
+ WorldTimeVisualControllerType.RAIN_VISIBILITY_AABB
+ ))
var rain_material := rain.process_material as ParticleProcessMaterial
assert(rain_material != null)
+ assert(rain_material.emission_box_extents.is_equal_approx(
+ WorldTimeVisualControllerType.RAIN_EMISSION_EXTENTS
+ ))
assert(is_equal_approx(
rain_material.initial_velocity_min,
WorldTimeVisualControllerType.RAIN_VELOCITY_MIN,
@@ -253,8 +477,52 @@ func _validate_weather_presentation() -> void:
assert(rain_mesh.size.is_equal_approx(
WorldTimeVisualControllerType.RAIN_DROP_SIZE
))
+ visuals.call(
+ "_on_weather_changed",
+ WorldWeatherServiceType.Weather.SUNNY,
+ 60.0,
+ )
+ visuals.call(
+ "_process",
+ WorldTimeVisualControllerType.WEATHER_TRANSITION_SECONDS * 0.5,
+ )
+ var halfway_water_fog: float = float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ )
+ assert(halfway_water_fog > 0.49 and halfway_water_fog < 0.51)
+ assert(is_equal_approx(
+ float(
+ WorldTimeVisualControllerType.FRESH_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ ),
+ halfway_water_fog,
+ ))
+ assert(runtime_environment.fog_enabled)
+ visuals.call(
+ "_process",
+ WorldTimeVisualControllerType.WEATHER_TRANSITION_SECONDS * 0.5,
+ )
+ assert(is_zero_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ )))
+ assert(not runtime_environment.fog_enabled)
+ visuals.apply_weather_immediately(
+ WorldWeatherServiceType.Weather.CLOUDY
+ )
+ assert(not runtime_environment.fog_enabled)
+ assert(is_zero_approx(float(
+ WorldTimeVisualControllerType.SALT_WATER_MATERIAL.get_shader_parameter(
+ "weather_fog_amount"
+ )
+ )))
visuals.apply_weather_immediately(
WorldWeatherServiceType.Weather.SUNNY
)
+ assert(not runtime_environment.fog_enabled)
assert(not rain.emitting)
world_root.queue_free()
diff --git a/ui/animalese_voice.gd b/ui/animalese_voice.gd
new file mode 100644
index 0000000..9a75434
--- /dev/null
+++ b/ui/animalese_voice.gd
@@ -0,0 +1,125 @@
+class_name AnimaleseVoice
+extends Node
+
+const SAMPLE_DIRECTORY := "res://sound/dialogue/animalese/placeholder"
+const SUPPORTED_CHARACTERS := "abcdefghijklmnopqrstuvwxyz"
+const DEFAULT_CHARACTERS_PER_SECOND: float = 28.0
+const POLYPHONY: int = 8
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
+const TypewriterRevealType = preload("res://ui/typewriter_reveal.gd")
+
+var base_pitch: float = 1.0
+var volume_db: float = -13.0
+
+var _samples: Dictionary[String, AudioStream] = {}
+var _player: AudioStreamPlayer
+var _playback: AudioStreamPlaybackPolyphonic
+
+
+func _ready() -> void:
+ _load_samples()
+ var polyphonic_stream := AudioStreamPolyphonic.new()
+ polyphonic_stream.polyphony = POLYPHONY
+ _player = AudioStreamPlayer.new()
+ _player.name = "AnimaleseAudio"
+ _player.bus = &"SFX"
+ _player.stream = polyphonic_stream
+ add_child(_player)
+ _player.play()
+ _playback = (
+ _player.get_stream_playback() as AudioStreamPlaybackPolyphonic
+ )
+
+
+func speak_text(
+ tween_owner: Node,
+ text: String,
+ voice_key: String,
+ voice_profile_id: String = VoiceProfilesType.DEFAULT_ID,
+ characters_per_second: float = -1.0,
+) -> Tween:
+ var speech_tween := tween_owner.create_tween()
+ var resolved_characters_per_second := (
+ characters_per_second
+ if characters_per_second > 0.0
+ else TypewriterRevealType.get_characters_per_second()
+ )
+ var character_seconds := 1.0 / maxf(
+ resolved_characters_per_second,
+ 1.0,
+ )
+ var voice_pitch := (
+ base_pitch * VoiceProfilesType.pitch_for(voice_profile_id)
+ )
+ for character_index: int in range(text.length()):
+ speech_tween.tween_interval(character_seconds)
+ speech_tween.tween_callback(
+ _play_character.bind(
+ text.substr(character_index, 1),
+ character_index,
+ text,
+ voice_key,
+ voice_pitch,
+ )
+ )
+ return speech_tween
+
+
+func _load_samples() -> void:
+ for character_index: int in range(SUPPORTED_CHARACTERS.length()):
+ var character := SUPPORTED_CHARACTERS.substr(character_index, 1)
+ _load_sample(character)
+ _load_sample("fallback")
+
+
+func _load_sample(sample_name: String) -> void:
+ var sample_path := "%s/%s.wav" % [SAMPLE_DIRECTORY, sample_name]
+ var sample := load(sample_path) as AudioStream
+ if sample != null:
+ _samples[sample_name] = sample
+
+
+func _play_character(
+ character: String,
+ character_index: int,
+ full_text: String,
+ voice_key: String,
+ voice_pitch: float,
+) -> void:
+ if _playback == null or character.strip_edges().is_empty():
+ return
+ var normalized := character.to_lower()
+ if normalized in [".", ",", "!", "?", ":", ";", "-", "_"]:
+ return
+ var sample_name := (
+ normalized if SUPPORTED_CHARACTERS.contains(normalized) else "fallback"
+ )
+ var sample: AudioStream = _samples.get(sample_name)
+ if sample == null:
+ return
+ var speaker_variation := (
+ float(posmod(hash(voice_key), 1001)) / 1000.0 - 0.5
+ ) * 0.16
+ var character_variation := (
+ float(posmod(hash("%s:%d" % [voice_key, character_index]), 1001))
+ / 1000.0
+ - 0.5
+ ) * 0.10
+ var question_lift := 0.0
+ var question_lift_start: int = floori(float(full_text.length()) * 0.75)
+ if full_text.ends_with("?") and character_index >= question_lift_start:
+ var final_progress := (
+ float(character_index) / maxf(float(full_text.length() - 1), 1.0)
+ )
+ question_lift = lerpf(0.0, 0.14, final_progress)
+ var pitch := clampf(
+ voice_pitch
+ + speaker_variation
+ + character_variation
+ + question_lift,
+ 0.72,
+ 1.45,
+ )
+ _playback.play_stream(sample, 0.0, volume_db, pitch)
diff --git a/ui/animalese_voice.gd.uid b/ui/animalese_voice.gd.uid
new file mode 100644
index 0000000..4cfdf9b
--- /dev/null
+++ b/ui/animalese_voice.gd.uid
@@ -0,0 +1 @@
+uid://djst00wf8yntj
diff --git a/ui/art_kit_marker_icon.gdshader b/ui/art_kit_marker_icon.gdshader
new file mode 100644
index 0000000..79a6564
--- /dev/null
+++ b/ui/art_kit_marker_icon.gdshader
@@ -0,0 +1,15 @@
+shader_type canvas_item;
+
+uniform vec4 marker_color : source_color = vec4(1.0, 0.0, 0.0, 1.0);
+
+
+void fragment() {
+ vec4 source = texture(TEXTURE, UV) * COLOR;
+ float red_dominance = source.r - max(source.g, source.b);
+ float marker_mask = smoothstep(0.04, 0.18, red_dominance);
+ vec3 colored_marker = marker_color.rgb * source.r;
+ COLOR = vec4(
+ mix(source.rgb, colored_marker, marker_mask),
+ source.a * marker_color.a
+ );
+}
diff --git a/ui/art_kit_marker_icon.gdshader.uid b/ui/art_kit_marker_icon.gdshader.uid
new file mode 100644
index 0000000..0e7148f
--- /dev/null
+++ b/ui/art_kit_marker_icon.gdshader.uid
@@ -0,0 +1 @@
+uid://bsg3cwrnjq6ev
diff --git a/ui/assets/logbook/ui_logbook.png b/ui/assets/logbook/ui_logbook.png
new file mode 100644
index 0000000..2e6126d
Binary files /dev/null and b/ui/assets/logbook/ui_logbook.png differ
diff --git a/ui/assets/logbook/ui_logbook.png.import b/ui/assets/logbook/ui_logbook.png.import
new file mode 100644
index 0000000..1ffd643
--- /dev/null
+++ b/ui/assets/logbook/ui_logbook.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bnwbcopsjmi3s"
+path="res://.godot/imported/ui_logbook.png-e45558834671114c04857bb4a6091575.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/assets/logbook/ui_logbook.png"
+dest_files=["res://.godot/imported/ui_logbook.png-e45558834671114c04857bb4a6091575.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/chat_ui.gd b/ui/chat_ui.gd
index 6cba3c4..c080a04 100644
--- a/ui/chat_ui.gd
+++ b/ui/chat_ui.gd
@@ -6,18 +6,20 @@ const RECENT_SECONDS: float = 8.0
const SPEECH_SECONDS: float = 6.0
const DRAFT_SAVE_DELAY: float = 0.4
const IDLE_ALPHA: float = 0.58
-const ORIGINAL_PANEL_WIDTH: float = 390.0
-const PANEL_WIDTH: float = ORIGINAL_PANEL_WIDTH * 0.85
+const CHAT_SURFACE_COLOR := Color(0.025, 0.13, 0.19, 0.94)
+const PANEL_WIDTH: float = 290.0
const COMPACT_HEIGHT: float = 250.0
-const BOTTOM_MARGIN: float = 94.0
+const BOTTOM_MARGIN: float = 12.0
+const EXPANDED_TOP_MARGIN: float = 94.0
const MIN_TOP_MARGIN: float = 24.0
const MIN_HISTORY_HEIGHT: float = 92.0
-const HISTORY_FONT_SIZE: int = 17
+const HISTORY_FONT_SIZE: int = 20
const INPUT_FONT_SIZE: int = 23
const HINT_FONT_SIZE: int = 12
const HISTORY_INPUT_GAP: int = 8
const HANDLE_SIZE := Vector2(34, 42)
const HANDLE_GAP: float = 6.0
+const HANDLE_TOP_INSET: float = 18.0
const COLLAPSED_REVEAL_WIDTH: float = 8.0
const HINT_EDGE_MARGIN: float = 4.0
const SPEECH_BUBBLE_WIDTH: float = 320.0
@@ -29,16 +31,40 @@ const MOBILE_EXPANDED_WIDTH: float = 820.0
const MOBILE_COMPACT_HEIGHT: float = 220.0
const MOBILE_EXPANDED_HEIGHT: float = 390.0
const MOBILE_EDGE_MARGIN: float = 12.0
-const CLOCK_SIZE := Vector2(116.0, 34.0)
+const CLOCK_SIZE := Vector2(174.0, 51.0)
+const CLOCK_FONT_SIZE: int = 27
const CLOCK_EDGE_MARGIN: float = 10.0
-const WEATHER_ICON_SIZE := Vector2(34.0, 34.0)
+const WEATHER_ICON_SIZE := Vector2(51.0, 51.0)
const WEATHER_ICON_GAP: float = 6.0
+const FISH_FINDER_EFFECT_ICON_SIZE := Vector2(18.0, 18.0)
+const FISH_FINDER_EFFECT_ICON: Texture2D = preload(
+ "res://items/icons/consumables/64_consumable_fishfinder.png"
+)
+const CHAT_SHOW_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_light_right_more.png"
+)
+const CHAT_HIDE_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_light_left_more.png"
+)
+const CHAT_EXPAND_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_light_up_more.png"
+)
+const CHAT_COMPACT_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_light_down_more.png"
+)
const WorldTimeServiceType = preload("res://world/world_time_service.gd")
const WorldWeatherServiceType = preload(
"res://world/world_weather_service.gd"
)
const WeatherIconType = preload("res://ui/weather_icon.gd")
+const TypewriterRevealType = preload("res://ui/typewriter_reveal.gd")
+const AnimaleseVoiceType = preload("res://ui/animalese_voice.gd")
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
+
+
enum PresentationState {
COLLAPSED,
COMPACT,
@@ -62,15 +88,18 @@ var _height_button: Button
var _unread_indicator: Label
var _hint: Label
var _speech_layer: Control
+var _animalese_voice: AnimaleseVoiceType
var _clock_panel: PanelContainer
var _clock_label: Label
var _weather_icon: WeatherIconType
+var _fish_finder_effect_icon: TextureRect
var _speech: Dictionary[int, Dictionary] = {}
var _draft_save_timer: Timer
var _opacity_tween: Tween
var _height_tween: Tween
var _opened: bool = false
var _available: bool = false
+var _hud_hidden: bool = false
var _presentation_state := PresentationState.COMPACT
var _visible_state_before_collapse := PresentationState.COMPACT
var _panel_hovered: bool = false
@@ -79,15 +108,15 @@ var _last_message_time: float = -INF
var _target_alpha: float = -1.0
var _send_pending: bool = false
var _pending_send_body: String = ""
-var _prior_movement: bool = true
-var _prior_camera: bool = true
var _controller_refocused: bool = false
var _input_lock_applied: bool = false
+var _last_submit_frame: int = -1
var _output_scale: float = 1.0
var _dock_right: bool = false
var _mobile_mode: bool = false
var _world_time: WorldTimeServiceType
var _world_weather: WorldWeatherServiceType
+var _item_effects: PlayerItemEffects
func _ready() -> void:
@@ -107,6 +136,7 @@ func setup(
settings: PlayerSettingsManager,
world_time: WorldTimeServiceType,
world_weather: WorldWeatherServiceType,
+ item_effects: PlayerItemEffects,
) -> void:
_service = service
_session = session
@@ -116,6 +146,14 @@ func setup(
_settings = settings
_world_time = world_time
_world_weather = world_weather
+ _item_effects = item_effects
+ if (
+ _fishing_spot != null
+ and not _fishing_spot.local_speech_requested.is_connected(
+ show_local_speech
+ )
+ ):
+ _fishing_spot.local_speech_requested.connect(show_local_speech)
if (
_world_time != null
and not _world_time.time_changed.is_connected(
@@ -143,6 +181,7 @@ func setup(
_service.local_message_confirmed.connect(_on_local_message_confirmed)
_service.history_replaced.connect(_on_history)
_service.send_rejected.connect(_on_rejected)
+ _service.world_command_finished.connect(_on_world_command_finished)
_session.peer_removed.connect(_on_peer_removed)
_entry.text = _settings.current_settings.chat_draft
_entry.caret_column = _entry.text.length()
@@ -167,24 +206,30 @@ func open_chat() -> void:
_controller_refocused = false
_opened = true
text_entry_ownership_changed.emit(true)
- _prior_movement = _player.is_movement_enabled()
- _prior_camera = _player.is_camera_input_enabled()
_input_lock_applied = true
- _player.set_movement_enabled(false)
- _player.set_camera_input_enabled(false)
+ _player.set_local_input_suppressed(INPUT_OWNER, true)
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, true)
# Clear the last authoritative input immediately. Merely disabling local
# prediction would let a remote host continue the last held movement.
_session.submit_neutral_local_movement()
_entry.show()
_entry.virtual_keyboard_enabled = false
- _entry.grab_focus()
_hint.hide()
_refresh_input_ownership()
+ call_deferred("_focus_entry_after_open")
_update_panel_opacity(true)
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
+func open_command_chat() -> void:
+ open_chat()
+ if not _opened:
+ return
+ if not _entry.text.begins_with("/"):
+ _entry.text = "/" + _entry.text
+ _entry.caret_column = _entry.text.length()
+
+
func set_available(value: bool) -> void:
_available = value
if not value:
@@ -199,12 +244,12 @@ func set_available(value: bool) -> void:
func close_chat() -> void:
var ownership_was_active: bool = _opened or _input_lock_applied
_opened = false
+ _set_status("")
_entry.virtual_keyboard_enabled = false
_entry.release_focus()
_entry.hide()
if _input_lock_applied:
- _player.set_movement_enabled(_prior_movement)
- _player.set_camera_input_enabled(_prior_camera)
+ _player.set_local_input_suppressed(INPUT_OWNER, false)
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, false)
_input_lock_applied = false
if ownership_was_active:
@@ -258,6 +303,13 @@ func request_virtual_keyboard() -> bool:
return true
+func _focus_entry_after_open() -> void:
+ if not _opened or not _entry.visible:
+ return
+ _entry.grab_focus()
+ _refresh_input_ownership()
+
+
func is_open() -> bool:
return _opened
@@ -268,22 +320,38 @@ func is_collapsed() -> bool:
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("open_chat"):
- toggle_chat()
+ if event is InputEventKey:
+ if _opened:
+ _focus_entry_after_open()
+ else:
+ open_chat()
+ else:
+ toggle_chat()
get_viewport().set_input_as_handled()
return
if event is InputEventKey and event.pressed and not event.echo:
if event.keycode in [KEY_ENTER, KEY_KP_ENTER]:
if _opened:
+ _last_submit_frame = Engine.get_process_frames()
_send()
elif (
_available
and get_viewport().gui_get_focus_owner() is not LineEdit
+ and Engine.get_process_frames() != _last_submit_frame
):
open_chat()
get_viewport().set_input_as_handled()
elif event.keycode == KEY_T and not _opened and _available:
open_chat()
get_viewport().set_input_as_handled()
+ elif (
+ event.unicode == 47
+ and not _opened
+ and _available
+ and get_viewport().gui_get_focus_owner() is not LineEdit
+ ):
+ open_command_chat()
+ get_viewport().set_input_as_handled()
elif event.keycode == KEY_ESCAPE and _opened:
close_chat()
get_viewport().set_input_as_handled()
@@ -296,6 +364,9 @@ func _process(_delta: float) -> void:
func _exit_tree() -> void:
+ if _input_lock_applied and is_instance_valid(_player):
+ _player.set_local_input_suppressed(INPUT_OWNER, false)
+ _input_lock_applied = false
_flush_draft()
@@ -315,11 +386,20 @@ func _build_ui() -> void:
_clock_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_clock_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
_clock_label.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
- _clock_label.add_theme_font_size_override("font_size", 18)
+ _clock_label.add_theme_font_size_override("font_size", CLOCK_FONT_SIZE)
_clock_label.add_theme_color_override(
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
)
_clock_panel.add_child(_clock_label)
+ _fish_finder_effect_icon = TextureRect.new()
+ _fish_finder_effect_icon.name = "FishFinderEffectIcon"
+ _fish_finder_effect_icon.texture = FISH_FINDER_EFFECT_ICON
+ _fish_finder_effect_icon.size = FISH_FINDER_EFFECT_ICON_SIZE
+ _fish_finder_effect_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ _fish_finder_effect_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ _fish_finder_effect_icon.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ _fish_finder_effect_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ add_child(_fish_finder_effect_icon)
_weather_icon = WeatherIconType.new()
_weather_icon.name = "WorldWeatherIcon"
_weather_icon.size = WEATHER_ICON_SIZE
@@ -357,7 +437,10 @@ func _build_ui() -> void:
_history.add_theme_stylebox_override("normal", _borderless_style(Color.TRANSPARENT))
box.add_child(_history)
_status = Label.new()
+ _status.name = "ChatStatus"
_status.custom_minimum_size = Vector2(0, 20)
+ _status.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ _status.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_status.hide()
_status.mouse_filter = Control.MOUSE_FILTER_IGNORE
_status.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
@@ -367,7 +450,7 @@ func _build_ui() -> void:
_entry.name = "ChatEntry"
_entry.placeholder_text = "type a message…"
_entry.max_length = NetworkChatProtocol.MAX_VISIBLE_CHARACTERS
- _entry.text_submitted.connect(func(_value: String) -> void: _send())
+ _entry.text_submitted.connect(_on_entry_text_submitted)
_entry.text_changed.connect(_on_draft_changed)
UtilityPageStyle.apply_ocean_line_edit(_entry)
_entry.add_theme_font_size_override("font_size", INPUT_FONT_SIZE)
@@ -379,6 +462,15 @@ func _build_ui() -> void:
_collapse_button.mouse_filter = Control.MOUSE_FILTER_STOP
_collapse_button.focus_mode = Control.FOCUS_ALL
_collapse_button.z_index = 3
+ _collapse_button.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ _collapse_button.expand_icon = true
+ _collapse_button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _collapse_button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _collapse_button.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
+ _collapse_button.add_theme_constant_override(
+ "icon_max_width",
+ roundi(minf(HANDLE_SIZE.x, HANDLE_SIZE.y) * 0.5),
+ )
_collapse_button.tooltip_text = "Collapse chat"
_collapse_button.pressed.connect(func() -> void:
if _presentation_state == PresentationState.COLLAPSED:
@@ -405,6 +497,15 @@ func _build_ui() -> void:
_height_button.mouse_filter = Control.MOUSE_FILTER_STOP
_height_button.focus_mode = Control.FOCUS_ALL
_height_button.z_index = 3
+ _height_button.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ _height_button.expand_icon = true
+ _height_button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _height_button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _height_button.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
+ _height_button.add_theme_constant_override(
+ "icon_max_width",
+ roundi(minf(HANDLE_SIZE.x, HANDLE_SIZE.y) * 0.5),
+ )
_height_button.pressed.connect(func() -> void:
if _presentation_state == PresentationState.COLLAPSED:
_visible_state_before_collapse = (
@@ -445,7 +546,6 @@ func _build_ui() -> void:
add_child(_unread_indicator)
_hint = Label.new()
_hint.name = "ChatHint"
- _hint.text = "Press Enter to chat"
_hint.size = Vector2(180, 18)
_hint.mouse_filter = Control.MOUSE_FILTER_IGNORE
_hint.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
@@ -461,6 +561,9 @@ func _build_ui() -> void:
_speech_layer.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_speech_layer.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(_speech_layer)
+ _animalese_voice = AnimaleseVoiceType.new()
+ _animalese_voice.name = "PlayerAnimaleseVoice"
+ add_child(_animalese_voice)
_draft_save_timer = Timer.new()
_draft_save_timer.one_shot = true
_draft_save_timer.wait_time = DRAFT_SAVE_DELAY
@@ -478,7 +581,7 @@ func _build_ui() -> void:
func _chat_panel_style() -> StyleBoxFlat:
- var style := _borderless_style(Color(0.025, 0.13, 0.19, 0.94))
+ var style := _borderless_style(CHAT_SURFACE_COLOR)
if _mobile_mode:
style.corner_radius_top_left = 0
style.corner_radius_top_right = 0
@@ -506,10 +609,25 @@ func _refresh_input_ownership() -> void:
)
_panel.mouse_filter = filter
_history.mouse_filter = filter
+ _entry.focus_mode = (
+ Control.FOCUS_ALL if _opened else Control.FOCUS_NONE
+ )
+ _collapse_button.focus_mode = (
+ Control.FOCUS_ALL if _opened else Control.FOCUS_NONE
+ )
+ _height_button.focus_mode = (
+ Control.FOCUS_ALL
+ if _opened and not _mobile_mode
+ else Control.FOCUS_NONE
+ )
+ if not _opened:
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner in [_entry, _collapse_button, _height_button]:
+ get_viewport().gui_release_focus()
func _clock_panel_style() -> StyleBoxFlat:
- var style := _borderless_style(Color(0.025, 0.13, 0.19, 0.94))
+ var style := _borderless_style(CHAT_SURFACE_COLOR)
style.set_corner_radius_all(12)
style.content_margin_left = 10
style.content_margin_right = 10
@@ -522,6 +640,10 @@ func _borderless_style(color: Color) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = color
style.set_border_width_all(0)
+ style.anti_aliasing = false
+ style.shadow_size = 0
+ style.shadow_color = Color.TRANSPARENT
+ style.shadow_offset = Vector2.ZERO
return style
@@ -530,6 +652,12 @@ func _flat_chat_button_style(color: Color) -> StyleBoxFlat:
style.bg_color = color
style.set_border_width_all(0)
style.set_corner_radius_all(0)
+ if _dock_right:
+ style.corner_radius_top_left = 10
+ style.corner_radius_bottom_left = 10
+ else:
+ style.corner_radius_top_right = 10
+ style.corner_radius_bottom_right = 10
style.anti_aliasing = false
style.shadow_size = 0
style.shadow_color = Color.TRANSPARENT
@@ -572,6 +700,18 @@ func _apply_flat_chat_button(button: Button) -> void:
button.add_theme_stylebox_override(
"disabled", _flat_chat_button_style(UtilityPageStyle.OCEAN_DISABLED)
)
+ for state: StringName in [
+ &"normal",
+ &"hover",
+ &"pressed",
+ &"hover_pressed",
+ &"focus",
+ &"disabled",
+ ]:
+ button.add_theme_stylebox_override(
+ state,
+ _flat_chat_button_style(CHAT_SURFACE_COLOR),
+ )
func _speech_panel_style() -> StyleBoxFlat:
@@ -601,10 +741,20 @@ func _create_speech_pointer() -> Polygon2D:
return pointer
+func _on_entry_text_submitted(_value: String) -> void:
+ _last_submit_frame = Engine.get_process_frames()
+ _send()
+
+
func _send() -> void:
if _send_pending:
return
var body := _entry.text
+ if body.strip_edges().is_empty():
+ close_chat()
+ return
+ if _handle_chat_command(body):
+ return
_send_pending = true
_pending_send_body = NetworkChatProtocol.sanitize_body(body)
_entry.editable = false
@@ -616,6 +766,72 @@ func _send() -> void:
_set_status("Sending…")
+func _handle_chat_command(body: String) -> bool:
+ var command_text := body.strip_edges()
+ if not command_text.begins_with("/"):
+ return false
+ var parts: PackedStringArray = command_text.split(" ", false)
+ var command := String(parts[0]).trim_prefix("/").to_lower()
+ match command:
+ "time":
+ _handle_time_command(parts)
+ "weather":
+ _handle_weather_command(parts)
+ "":
+ _set_status("Enter a command after /.")
+ _:
+ _set_status("Unknown command: /%s" % command)
+ _entry.clear()
+ _flush_draft()
+ return true
+
+
+func _handle_time_command(parts: PackedStringArray) -> void:
+ if parts.size() != 2:
+ _set_status("Usage: /time [dawn, day, dusk, night]")
+ return
+ if _service == null or _world_time == null:
+ _set_status("World time is unavailable.")
+ return
+ var phase_name := String(parts[1]).to_lower()
+ if phase_name not in ["dawn", "day", "dusk", "night"]:
+ _set_status("Usage: /time [dawn, day, dusk, night]")
+ return
+ if not _service.request_world_time_change(phase_name):
+ _set_status("Only the host or an operator can change world time.")
+ return
+ close_chat()
+
+
+func _handle_weather_command(parts: PackedStringArray) -> void:
+ if parts.size() != 2:
+ _set_status("Usage: /weather [clear, cloudy, rainy, foggy]")
+ return
+ if _service == null or _world_weather == null:
+ _set_status("World weather is unavailable.")
+ return
+ var weather_name := String(parts[1]).to_lower()
+ match weather_name:
+ "clear", "sunny":
+ weather_name = "clear"
+ "cloudy", "rainy", "foggy":
+ pass
+ _:
+ _set_status("Usage: /weather [clear, cloudy, rainy, foggy]")
+ return
+ if not _service.request_world_weather_change(weather_name):
+ _set_status("Only the host or an operator can change world weather.")
+ return
+ close_chat()
+
+
+func _on_world_command_finished(success: bool, message: String) -> void:
+ if success:
+ _set_status("")
+ elif not message.is_empty():
+ _set_status(message)
+
+
func _on_local_message_confirmed(message: Dictionary) -> void:
if (
not _send_pending
@@ -641,6 +857,24 @@ func _on_message(message: Dictionary) -> void:
if int(message["kind"]) != NetworkChatProtocol.Kind.PLAYER:
return
var peer_id: int = message["sender_peer_id"]
+ _show_speech_bubble(
+ peer_id,
+ str(message["body"]),
+ str(message.get("sender_fingerprint", "")),
+ )
+
+
+func show_local_speech(body: String) -> void:
+ if body.strip_edges().is_empty() or _session == null:
+ return
+ _show_speech_bubble(_session.get_local_peer_id(), body, "")
+
+
+func _show_speech_bubble(
+ peer_id: int,
+ body: String,
+ fingerprint: String,
+) -> void:
_on_peer_removed(peer_id)
var bubble := PanelContainer.new()
bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
@@ -649,7 +883,7 @@ func _on_message(message: Dictionary) -> void:
var pointer := _create_speech_pointer()
bubble.add_child(pointer)
var label := Label.new()
- label.text = str(message["body"])
+ label.text = body
label.custom_minimum_size = Vector2(
SPEECH_BUBBLE_WIDTH - 20.0,
0.0,
@@ -664,11 +898,28 @@ func _on_message(message: Dictionary) -> void:
)
bubble.add_child(label)
_speech_layer.add_child(bubble)
+ var reveal_seconds := TypewriterRevealType.start(label)
+ var voice_profile_id: String = VoiceProfilesType.DEFAULT_ID
+ var speaker_avatar := _spawn.get_avatar(peer_id)
+ if speaker_avatar != null:
+ voice_profile_id = VoiceProfilesType.sanitized_id(
+ speaker_avatar.get_animalese_voice_id()
+ )
+ _animalese_voice.speak_text(
+ label,
+ label.text,
+ str(peer_id),
+ voice_profile_id,
+ )
_speech[peer_id] = {
"bubble": bubble,
"pointer": pointer,
- "expires": Time.get_ticks_msec() / 1000.0 + SPEECH_SECONDS,
- "fingerprint": str(message.get("sender_fingerprint", "")),
+ "expires": (
+ Time.get_ticks_msec() / 1000.0
+ + reveal_seconds
+ + SPEECH_SECONDS
+ ),
+ "fingerprint": fingerprint,
}
@@ -692,6 +943,8 @@ func _on_rejected(message: String) -> void:
_set_status(message)
if not _opened:
open_chat()
+ else:
+ call_deferred("_focus_entry_after_open")
func _refresh_history() -> void:
@@ -715,6 +968,17 @@ func _refresh_visibility() -> void:
_panel.hide()
_clock_panel.hide()
_weather_icon.hide()
+ _fish_finder_effect_icon.hide()
+ _collapse_button.hide()
+ _height_button.hide()
+ _unread_indicator.hide()
+ _hint.hide()
+ return
+ if _hud_hidden and not _opened:
+ _panel.hide()
+ _clock_panel.hide()
+ _weather_icon.hide()
+ _fish_finder_effect_icon.hide()
_collapse_button.hide()
_height_button.hide()
_unread_indicator.hide()
@@ -722,12 +986,21 @@ func _refresh_visibility() -> void:
return
_clock_panel.show()
_weather_icon.show()
+ _fish_finder_effect_icon.visible = (
+ _item_effects != null
+ and _item_effects.is_active(PlayerItemEffects.FISH_FINDER_ID)
+ )
_collapse_button.show()
var collapsed := _presentation_state == PresentationState.COLLAPSED
_panel.show()
+ _collapse_button.focus_mode = (
+ Control.FOCUS_ALL if _opened else Control.FOCUS_NONE
+ )
_height_button.visible = not _mobile_mode
_height_button.focus_mode = (
- Control.FOCUS_NONE if _mobile_mode else Control.FOCUS_ALL
+ Control.FOCUS_ALL
+ if _opened and not _mobile_mode
+ else Control.FOCUS_NONE
)
_unread_indicator.visible = collapsed and _collapsed_has_unread
_hint.visible = not _opened
@@ -770,6 +1043,8 @@ func set_dock_right(should_dock_right: bool) -> void:
if not is_node_ready() or _panel == null:
return
_panel.add_theme_stylebox_override("panel", _chat_panel_style())
+ _apply_flat_chat_button(_collapse_button)
+ _apply_flat_chat_button(_height_button)
_refresh_handle_labels(_presentation_state)
_layout_presentation(false)
@@ -797,24 +1072,36 @@ func is_mobile_mode() -> bool:
return _mobile_mode
+func set_hud_hidden(hidden: bool) -> void:
+ _hud_hidden = hidden
+ _refresh_visibility()
+
+
+func is_hud_hidden() -> bool:
+ return _hud_hidden
+
+
func _refresh_handle_labels(state: PresentationState) -> void:
var collapsed := state == PresentationState.COLLAPSED
var height_state := _visible_state_before_collapse if collapsed else state
- if _mobile_mode:
- _collapse_button.text = "v" if collapsed else "^"
- elif _dock_right:
- _collapse_button.text = "<" if collapsed else ">"
- else:
- _collapse_button.text = ">" if collapsed else "<"
+ _collapse_button.text = ""
+ _collapse_button.icon = CHAT_SHOW_ICON if collapsed else CHAT_HIDE_ICON
_collapse_button.tooltip_text = (
"Show chat" if collapsed else "Hide chat"
)
- _height_button.text = "v" if height_state == PresentationState.EXPANDED else "^"
+ _collapse_button.accessibility_name = _collapse_button.tooltip_text
+ _height_button.text = ""
+ _height_button.icon = (
+ CHAT_COMPACT_ICON
+ if height_state == PresentationState.EXPANDED
+ else CHAT_EXPAND_ICON
+ )
_height_button.tooltip_text = (
"Compact chat"
if height_state == PresentationState.EXPANDED
else "Expand chat history"
)
+ _height_button.accessibility_name = _height_button.tooltip_text
func _update_panel_opacity(immediate_recheck: bool = false) -> void:
@@ -823,10 +1110,8 @@ func _update_panel_opacity(immediate_recheck: bool = false) -> void:
if _presentation_state == PresentationState.COLLAPSED:
if _height_tween == null or not _height_tween.is_running():
_panel.modulate.a = IDLE_ALPHA
- _collapse_button.modulate.a = (
- 1.0 if _collapsed_has_unread else 0.82
- )
- _height_button.modulate.a = 0.82
+ _collapse_button.modulate.a = IDLE_ALPHA
+ _height_button.modulate.a = IDLE_ALPHA
return
var recent := (
Time.get_ticks_msec() / 1000.0 - _last_message_time < RECENT_SECONDS
@@ -871,6 +1156,9 @@ func _update_speech() -> void:
if camera.is_position_behind(world_position):
bubble.hide()
continue
+ if _is_speech_world_occluded(camera, avatar, world_position):
+ bubble.hide()
+ continue
var screen_position := (
camera.unproject_position(world_position) / _output_scale
)
@@ -911,6 +1199,38 @@ func _update_speech() -> void:
bubble.show()
+func _is_speech_world_occluded(
+ camera: Camera3D,
+ speaker: Player,
+ world_position: Vector3,
+) -> bool:
+ var world := camera.get_world_3d()
+ if world == null:
+ return false
+ var excluded: Array[RID] = []
+ if _player != null:
+ excluded.append(_player.get_rid())
+ if speaker != _player:
+ excluded.append(speaker.get_rid())
+ var query := PhysicsRayQueryParameters3D.create(
+ camera.global_position,
+ world_position,
+ )
+ query.collide_with_areas = false
+ query.collide_with_bodies = true
+ for _attempt: int in range(8):
+ query.exclude = excluded
+ var hit: Dictionary = world.direct_space_state.intersect_ray(query)
+ if hit.is_empty():
+ return false
+ var collider := hit.get("collider") as CollisionObject3D
+ if collider is Player:
+ excluded.append(collider.get_rid())
+ continue
+ return true
+ return false
+
+
func _on_draft_changed(_value: String) -> void:
if _settings == null:
return
@@ -1000,7 +1320,7 @@ func _layout_presentation(animate: bool) -> void:
if layout_state == PresentationState.EXPANDED:
height = maxf(
MIN_HISTORY_HEIGHT,
- viewport_height - 2.0 * bottom_margin,
+ viewport_height - bottom_margin - EXPANDED_TOP_MARGIN,
)
height = minf(
height,
@@ -1019,10 +1339,7 @@ func _layout_presentation(animate: bool) -> void:
else 0.0
)
panel_y = bottom - height
- var handle_stack_height := HANDLE_SIZE.y * 2.0 + HANDLE_GAP
- var handle_stack_top := (
- bottom - COMPACT_HEIGHT * 0.5 - handle_stack_height * 0.5
- )
+ var handle_stack_top := panel_y + HANDLE_TOP_INSET
var handle_x: float = (
panel_x - HANDLE_SIZE.x
if _dock_right
@@ -1048,6 +1365,11 @@ func _layout_presentation(animate: bool) -> void:
clock_x,
CLOCK_EDGE_MARGIN,
)
+ var fish_finder_effect_position := Vector2(
+ clock_position.x
+ + (CLOCK_SIZE.x - FISH_FINDER_EFFECT_ICON_SIZE.x) * 0.5,
+ clock_position.y + CLOCK_SIZE.y + 2.0,
+ )
var weather_icon_x: float = (
clock_position.x - WEATHER_ICON_GAP - WEATHER_ICON_SIZE.x
if _dock_right
@@ -1071,6 +1393,8 @@ func _layout_presentation(animate: bool) -> void:
_panel.size = target_size
_clock_panel.position = clock_position
_clock_panel.size = CLOCK_SIZE
+ _fish_finder_effect_icon.position = fish_finder_effect_position
+ _fish_finder_effect_icon.size = FISH_FINDER_EFFECT_ICON_SIZE
_weather_icon.position = weather_icon_position
_weather_icon.size = WEATHER_ICON_SIZE
_collapse_button.position = collapse_position
@@ -1091,6 +1415,12 @@ func _layout_presentation(animate: bool) -> void:
clock_position,
UIMotion.CHAT_RESIZE_DURATION,
).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
+ _height_tween.tween_property(
+ _fish_finder_effect_icon,
+ "position",
+ fish_finder_effect_position,
+ UIMotion.CHAT_RESIZE_DURATION,
+ ).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
_height_tween.tween_property(
_weather_icon,
"position",
diff --git a/ui/components/bubble_hotbar/bubble_hotbar_slot.gd b/ui/components/bubble_hotbar/bubble_hotbar_slot.gd
index 11a7db3..4bebdfe 100644
--- a/ui/components/bubble_hotbar/bubble_hotbar_slot.gd
+++ b/ui/components/bubble_hotbar/bubble_hotbar_slot.gd
@@ -56,6 +56,8 @@ var _base_position: Vector2 = Vector2.ZERO
var _presented_size: Vector2 = Vector2.ZERO
var _compact: bool = false
var _presentation_initialized: bool = false
+var _controller_preview_active: bool = false
+var _controller_preview_texture: Texture2D
func _ready() -> void:
@@ -146,6 +148,15 @@ func set_drag_enabled(enabled: bool) -> void:
_hovered = false
+func set_controller_placement_preview(
+ active: bool,
+ texture: Texture2D,
+) -> void:
+ _controller_preview_active = active
+ _controller_preview_texture = texture
+ refresh()
+
+
func refresh() -> void:
if _hotbar == null:
return
@@ -161,11 +172,16 @@ func refresh() -> void:
if _fish_inventory != null and not catch_id.is_empty()
else null
)
- _item_icon.texture = (
+ var assigned_texture: Texture2D = (
fish_catch.fish.display_texture
if fish_catch != null
else item.icon if item != null else null
)
+ _item_icon.texture = (
+ _controller_preview_texture
+ if _controller_preview_active
+ else assigned_texture
+ )
var quantity: int = (
_bag.get_quantity(item_id)
if _bag != null and not item_id.is_empty()
@@ -177,7 +193,9 @@ func refresh() -> void:
else ""
)
_quantity_label.text = quantity_text
- _quantity_label.visible = not quantity_text.is_empty()
+ _quantity_label.visible = (
+ not _controller_preview_active and not quantity_text.is_empty()
+ )
tooltip_text = (
"%s · %.1f lb" % [
FishQualityType.qualified_name(
@@ -192,7 +210,11 @@ func refresh() -> void:
var was_selected: bool = _selected
var was_empty: bool = _empty
_selected = slot_index == _hotbar.get_selected_slot()
- _empty = item == null and fish_catch == null
+ _empty = (
+ not _controller_preview_active
+ and item == null
+ and fish_catch == null
+ )
if was_selected != _selected or was_empty != _empty:
_apply_style()
@@ -220,7 +242,9 @@ func _apply_style() -> void:
var normal_fill: Color = profile.normal_fill
normal_fill.a = 1.0
var selected_fill: Color = normal_fill
- if _selected:
+ if _controller_preview_active:
+ selected_fill = normal_fill.lightened(0.22)
+ elif _selected:
selected_fill = normal_fill.lightened(0.12)
add_theme_stylebox_override(
"normal",
diff --git a/ui/components/bubble_menu/README.md b/ui/components/bubble_menu/README.md
deleted file mode 100644
index ca549bb..0000000
--- a/ui/components/bubble_menu/README.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Bubble menu authoring
-
-Instance `bubble_button.tscn` for each action, or attach `bubble_button.gd`
-to an existing Button. Set its neutral size, desktop and compact anchors,
-font-size limits, and deterministic motion values in the Inspector. A label
-child can be assigned through `label_control_path` when wrapped text is needed.
-Text size is calculated once per layout from the neutral smaller dimension and
-the profile ratio.
-
-Place the buttons under a Control using `bubble_cluster.gd`. Give the cluster
-the ordered BubbleButton references with `configure()`, then call
-`apply_layout()` when its available size or responsive layout changes. The
-button order defines explicit keyboard and controller focus neighbors. Compact
-anchors and minimum sizes remain authored per button.
-
-The shared profile owns the palette, rounded styles, proportional-font ratio,
-hover response, and contact tuning. Labels, actions, sizes, anchors, per-button
-motion, responsive wrapping, availability, and confirmation behavior remain
-owned by the menu. Connect each Button's `pressed` signal in that parent menu.
-
-`motion_scale` defaults to `1.0`. Setting it to `0.0` removes idle drift and
-deformation while retaining hover and focus feedback.
-
-Contact is a deterministic, bounded visual correction around authored anchors.
-Real physics is intentionally avoided so layouts, focus order, and hit targets
-remain stable.
diff --git a/ui/components/bubble_menu/bubble_button.gd b/ui/components/bubble_menu/bubble_button.gd
index 15acb0e..f01d50b 100644
--- a/ui/components/bubble_menu/bubble_button.gd
+++ b/ui/components/bubble_menu/bubble_button.gd
@@ -1,6 +1,8 @@
class_name BubbleButton
extends Button
+const ICON_FILL_RATIO: float = 0.76
+
@export var profile: BubbleMenuProfile
@export_group("Authored Layout")
@@ -37,6 +39,54 @@ func _ready() -> void:
resized.connect(_update_pivot)
_update_pivot()
apply_profile()
+ _apply_icon_presentation(neutral_size)
+
+
+func _gui_input(event: InputEvent) -> void:
+ if _adjustment_direction(self) == 0:
+ return
+ var direction: int = 0
+ if event.is_action_pressed(&"ui_left"):
+ direction = -1
+ elif event.is_action_pressed(&"ui_right"):
+ direction = 1
+ if direction == 0:
+ return
+ var adjustment_button: BaseButton = _find_adjustment_button(direction)
+ if adjustment_button == null:
+ return
+ adjustment_button.pressed.emit()
+ accept_event()
+
+
+func _find_adjustment_button(direction: int) -> BaseButton:
+ var parent_node: Node = get_parent()
+ if parent_node == null:
+ return null
+ for child: Node in parent_node.get_children():
+ var button := child as BaseButton
+ if (
+ button != null
+ and button.visible
+ and not button.disabled
+ and _adjustment_direction(button) == direction
+ ):
+ return button
+ return null
+
+
+func _adjustment_direction(button: BaseButton) -> int:
+ var descriptions: Array[String] = [
+ button.text.strip_edges().to_lower(),
+ button.tooltip_text.strip_edges().to_lower(),
+ button.accessibility_name.strip_edges().to_lower(),
+ ]
+ for description: String in descriptions:
+ if description in ["-", "−", "minus", "decrease"]:
+ return -1
+ if description in ["+", "plus", "increase"]:
+ return 1
+ return 0
func apply_layout(
@@ -49,6 +99,7 @@ func apply_layout(
neutral_position = position
presented_size = bubble_size
_update_pivot()
+ _apply_icon_presentation(bubble_size)
var label_control: Control = get_label_control()
var font_size := clampi(
roundi(minf(bubble_size.x, bubble_size.y) * font_size_ratio),
@@ -63,6 +114,9 @@ func get_layout_size(layout_scale: float, compact: bool) -> Vector2:
if compact:
bubble_size.x = maxf(bubble_size.x, compact_minimum_size.x)
bubble_size.y = maxf(bubble_size.y, compact_minimum_size.y)
+ if _uses_icon_only_presentation():
+ var diameter: float = maxf(bubble_size.x, bubble_size.y)
+ bubble_size = Vector2(diameter, diameter)
return bubble_size
@@ -78,6 +132,24 @@ func get_label_control() -> Control:
return self
+func _uses_icon_only_presentation() -> bool:
+ return icon != null and text.is_empty() and label_control_path.is_empty()
+
+
+func _apply_icon_presentation(bubble_size: Vector2) -> void:
+ if not _uses_icon_only_presentation():
+ return
+ alignment = HORIZONTAL_ALIGNMENT_CENTER
+ icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
+ expand_icon = true
+ texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ add_theme_constant_override(
+ "icon_max_width",
+ maxi(1, roundi(minf(bubble_size.x, bubble_size.y) * ICON_FILL_RATIO)),
+ )
+
+
func advance_emphasis(delta: float) -> void:
var target: float = 1.0 if _hovered or _focused else 0.0
emphasis = move_toward(
@@ -122,6 +194,8 @@ func calculate_visual_scale(
* motion_scale
* lerpf(1.0, profile.emphasized_deformation_scale, emphasis)
)
+ if _uses_icon_only_presentation():
+ deformation_amount = 0.0
var hover_scale: float = lerpf(
1.0,
profile.hover_focus_scale,
diff --git a/ui/components/bubble_menu/bubble_cluster.gd b/ui/components/bubble_menu/bubble_cluster.gd
index 9a8d4d0..0ad2624 100644
--- a/ui/components/bubble_menu/bubble_cluster.gd
+++ b/ui/components/bubble_menu/bubble_cluster.gd
@@ -1,6 +1,10 @@
class_name BubbleCluster
extends Control
+const ControllerFocusNavigationType = preload(
+ "res://ui/controller_focus_navigation.gd"
+)
+
@export var profile: BubbleMenuProfile
@export var desktop_reference_size: Vector2 = Vector2(396.0, 318.0)
@export var compact_reference_size: Vector2 = Vector2(294.0, 200.0)
@@ -18,14 +22,6 @@ func configure(bubbles: Array[BubbleButton]) -> void:
if bubble.profile == null:
bubble.profile = profile
bubble.apply_profile()
- if index > 0:
- bubble.focus_neighbor_top = bubble.get_path_to(
- _bubbles[index - 1]
- )
- if index + 1 < _bubbles.size():
- bubble.focus_neighbor_bottom = bubble.get_path_to(
- _bubbles[index + 1]
- )
func apply_layout(field_size: Vector2, compact: bool) -> void:
@@ -52,6 +48,7 @@ func apply_layout(field_size: Vector2, compact: bool) -> void:
bubble_size,
profile.font_size_ratio
)
+ ControllerFocusNavigationType.configure_spatial_neighbors(_bubbles)
func advance_motion(delta: float) -> void:
diff --git a/ui/components/bubble_menu/bubble_status_bubble.gd b/ui/components/bubble_menu/bubble_status_bubble.gd
index 2a475fc..dc43d5c 100644
--- a/ui/components/bubble_menu/bubble_status_bubble.gd
+++ b/ui/components/bubble_menu/bubble_status_bubble.gd
@@ -5,6 +5,7 @@ extends PanelContainer
@onready var _heading: Label = %Heading
@onready var _value: Label = %Value
+@onready var _currency_icon: TextureRect = %CurrencyIcon
func _ready() -> void:
@@ -16,3 +17,10 @@ func _ready() -> void:
func set_content(heading: String, value: String) -> void:
_heading.text = heading
_value.text = value
+ _currency_icon.visible = false
+
+
+func set_currency_amount(heading: String, amount: int) -> void:
+ _heading.text = heading
+ _value.text = str(amount)
+ _currency_icon.visible = true
diff --git a/ui/components/bubble_menu/bubble_status_bubble.tscn b/ui/components/bubble_menu/bubble_status_bubble.tscn
index eb5bd9b..b898418 100644
--- a/ui/components/bubble_menu/bubble_status_bubble.tscn
+++ b/ui/components/bubble_menu/bubble_status_bubble.tscn
@@ -1,7 +1,8 @@
-[gd_scene load_steps=3 format=3]
+[gd_scene load_steps=4 format=3]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_status_bubble.gd" id="1_status"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="2_profile"]
+[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="3_currency"]
[node name="BubbleStatusBubble" type="PanelContainer"]
custom_minimum_size = Vector2(112, 62)
@@ -23,7 +24,25 @@ theme_override_font_sizes/font_size = 13
text = "status"
horizontal_alignment = 1
-[node name="Value" type="Label" parent="Labels"]
+[node name="ValueRow" type="HBoxContainer" parent="Labels"]
+layout_mode = 2
+mouse_filter = 2
+theme_override_constants/separation = 3
+alignment = 1
+
+[node name="CurrencyIcon" type="TextureRect" parent="Labels/ValueRow"]
+unique_name_in_owner = true
+visible = false
+custom_minimum_size = Vector2(18, 18)
+layout_mode = 2
+size_flags_vertical = 4
+mouse_filter = 2
+texture = ExtResource("3_currency")
+expand_mode = 1
+stretch_mode = 5
+texture_filter = 1
+
+[node name="Value" type="Label" parent="Labels/ValueRow"]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
diff --git a/ui/components/bubble_menu/cooler_fish_sprite.gd b/ui/components/bubble_menu/cooler_fish_sprite.gd
index d491969..be47c17 100644
--- a/ui/components/bubble_menu/cooler_fish_sprite.gd
+++ b/ui/components/bubble_menu/cooler_fish_sprite.gd
@@ -19,6 +19,7 @@ var _quality_color := Color.WHITE
func _ready() -> void:
+ set_meta(&"controller_focus_inversion_disabled", true)
resized.connect(_update_visual_pivot)
focus_entered.connect(_refresh_style)
focus_exited.connect(_refresh_style)
diff --git a/ui/components/currency_amount.gd b/ui/components/currency_amount.gd
new file mode 100644
index 0000000..bda2f7e
--- /dev/null
+++ b/ui/components/currency_amount.gd
@@ -0,0 +1,48 @@
+class_name CurrencyAmount
+extends HBoxContainer
+
+@export var amount: int = 0:
+ set(value):
+ amount = value
+ _display_text = str(value)
+ _refresh_amount()
+@export_range(8.0, 64.0, 1.0) var icon_size: float = 18.0:
+ set(value):
+ icon_size = value
+ _refresh_icon_size()
+
+@onready var _icon: TextureRect = %Icon
+@onready var _amount_label: Label = %Amount
+
+var _display_text: String = "0"
+
+
+func _ready() -> void:
+ mouse_filter = Control.MOUSE_FILTER_IGNORE
+ _refresh_icon_size()
+ _refresh_amount()
+
+
+func set_amount(value: int) -> void:
+ amount = value
+
+
+func set_amount_text(value: String) -> void:
+ _display_text = value
+ _refresh_amount()
+
+
+func get_amount_label() -> Label:
+ if _amount_label != null:
+ return _amount_label
+ return get_node_or_null("Amount") as Label
+
+
+func _refresh_amount() -> void:
+ if _amount_label != null:
+ _amount_label.text = _display_text
+
+
+func _refresh_icon_size() -> void:
+ if _icon != null:
+ _icon.custom_minimum_size = Vector2.ONE * icon_size
diff --git a/ui/components/currency_amount.gd.uid b/ui/components/currency_amount.gd.uid
new file mode 100644
index 0000000..dfb2290
--- /dev/null
+++ b/ui/components/currency_amount.gd.uid
@@ -0,0 +1 @@
+uid://b7jx040ujcol
diff --git a/ui/components/currency_amount.tscn b/ui/components/currency_amount.tscn
new file mode 100644
index 0000000..00c8ace
--- /dev/null
+++ b/ui/components/currency_amount.tscn
@@ -0,0 +1,29 @@
+[gd_scene load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://ui/components/currency_amount.gd" id="1_script"]
+[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="2_coin"]
+
+[node name="CurrencyAmount" type="HBoxContainer"]
+mouse_filter = 2
+theme_override_constants/separation = 3
+alignment = 1
+script = ExtResource("1_script")
+
+[node name="Icon" type="TextureRect" parent="."]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(18, 18)
+layout_mode = 2
+size_flags_vertical = 4
+mouse_filter = 2
+texture = ExtResource("2_coin")
+expand_mode = 1
+stretch_mode = 5
+texture_filter = 1
+
+[node name="Amount" type="Label" parent="."]
+unique_name_in_owner = true
+layout_mode = 2
+size_flags_vertical = 4
+mouse_filter = 2
+text = "0"
+vertical_alignment = 1
diff --git a/ui/components/organizer_tab.gd b/ui/components/organizer_tab.gd
index 8db5122..3625b9a 100644
--- a/ui/components/organizer_tab.gd
+++ b/ui/components/organizer_tab.gd
@@ -93,14 +93,14 @@ func _initialize_motion() -> void:
_set_visual_y(_target_y())
-func _on_toggled(pressed: bool) -> void:
- if _selected and not pressed:
+func _on_toggled(is_pressed: bool) -> void:
+ if _selected and not is_pressed:
# A selected organizer tab is a page marker, not a collapsible toggle.
# Restore without another signal before any lower-state frame is drawn.
set_pressed_no_signal(true)
refresh_state(false)
return
- _selected = pressed
+ _selected = is_pressed
refresh_state()
diff --git a/ui/controller_focus_navigation.gd b/ui/controller_focus_navigation.gd
new file mode 100644
index 0000000..cd93796
--- /dev/null
+++ b/ui/controller_focus_navigation.gd
@@ -0,0 +1,57 @@
+class_name ControllerFocusNavigation
+extends RefCounted
+
+const PERPENDICULAR_WEIGHT: float = 2.5
+const MINIMUM_FORWARD_DISTANCE: float = 0.5
+
+
+static func configure_spatial_neighbors(controls: Array) -> void:
+ var candidates: Array[Control] = []
+ for item: Variant in controls:
+ var control := item as Control
+ if control == null or not control.is_visible_in_tree():
+ continue
+ candidates.append(control)
+ for control: Control in candidates:
+ control.focus_neighbor_left = _neighbor_path(
+ control, candidates, Vector2.LEFT
+ )
+ control.focus_neighbor_right = _neighbor_path(
+ control, candidates, Vector2.RIGHT
+ )
+ control.focus_neighbor_top = _neighbor_path(
+ control, candidates, Vector2.UP
+ )
+ control.focus_neighbor_bottom = _neighbor_path(
+ control, candidates, Vector2.DOWN
+ )
+
+
+static func _neighbor_path(
+ origin: Control,
+ candidates: Array[Control],
+ direction: Vector2,
+) -> NodePath:
+ var origin_center: Vector2 = origin.get_global_rect().get_center()
+ var best: Control = null
+ var best_score: float = INF
+ for candidate: Control in candidates:
+ if candidate == origin or candidate.focus_mode == Control.FOCUS_NONE:
+ continue
+ var delta: Vector2 = (
+ candidate.get_global_rect().get_center() - origin_center
+ )
+ var forward_distance: float = delta.dot(direction)
+ if forward_distance <= MINIMUM_FORWARD_DISTANCE:
+ continue
+ var perpendicular_distance: float = absf(delta.cross(direction))
+ var score: float = (
+ forward_distance
+ + perpendicular_distance * PERPENDICULAR_WEIGHT
+ )
+ if score < best_score:
+ best = candidate
+ best_score = score
+ if best == null:
+ return NodePath()
+ return origin.get_path_to(best)
diff --git a/ui/controller_focus_navigation.gd.uid b/ui/controller_focus_navigation.gd.uid
new file mode 100644
index 0000000..d13ed12
--- /dev/null
+++ b/ui/controller_focus_navigation.gd.uid
@@ -0,0 +1 @@
+uid://dfb6bobetmujn
diff --git a/ui/controller_focus_presentation.gd b/ui/controller_focus_presentation.gd
new file mode 100644
index 0000000..7223ca7
--- /dev/null
+++ b/ui/controller_focus_presentation.gd
@@ -0,0 +1,99 @@
+class_name ControllerFocusPresentation
+extends Node
+
+const CONTROLLER_MOTION_THRESHOLD: float = 0.35
+const INVERSION_DISABLED_META: StringName = &"controller_focus_inversion_disabled"
+
+var _controller_active: bool = false
+var _focused_item: CanvasItem
+var _original_material: Material
+var _inversion_material: ShaderMaterial
+
+
+func _ready() -> void:
+ var inversion_shader := Shader.new()
+ inversion_shader.code = """
+shader_type canvas_item;
+render_mode unshaded;
+
+void fragment() {
+ vec4 source = texture(TEXTURE, UV) * COLOR;
+ COLOR = vec4(vec3(1.0) - source.rgb, source.a);
+}
+"""
+ _inversion_material = ShaderMaterial.new()
+ _inversion_material.shader = inversion_shader
+ get_viewport().gui_focus_changed.connect(_on_focus_changed)
+ set_process_input(true)
+ set_process(true)
+
+
+func _exit_tree() -> void:
+ _restore_focused_item()
+
+
+func _input(event: InputEvent) -> void:
+ if event is InputEventJoypadButton:
+ if (event as InputEventJoypadButton).pressed:
+ _set_controller_active(true)
+ elif event is InputEventJoypadMotion:
+ if absf((event as InputEventJoypadMotion).axis_value) >= (
+ CONTROLLER_MOTION_THRESHOLD
+ ):
+ _set_controller_active(true)
+ elif event is InputEventMouseMotion:
+ _set_controller_active(false)
+ elif event is InputEventMouseButton:
+ if (event as InputEventMouseButton).pressed:
+ _set_controller_active(false)
+ elif event is InputEventKey:
+ if (event as InputEventKey).pressed:
+ _set_controller_active(false)
+
+
+func _process(_delta: float) -> void:
+ if not is_instance_valid(_focused_item):
+ _focused_item = null
+ _original_material = null
+ return
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if (
+ focus_owner != _focused_item
+ or not focus_owner.is_visible_in_tree()
+ or focus_owner.focus_mode == Control.FOCUS_NONE
+ or bool(focus_owner.get_meta(INVERSION_DISABLED_META, false))
+ ):
+ _apply_to_focus(focus_owner)
+
+
+func _set_controller_active(active: bool) -> void:
+ if _controller_active == active:
+ return
+ _controller_active = active
+ _apply_to_focus(get_viewport().gui_get_focus_owner())
+
+
+func _on_focus_changed(control: Control) -> void:
+ _apply_to_focus(control)
+
+
+func _apply_to_focus(control: Control) -> void:
+ _restore_focused_item()
+ if (
+ not _controller_active
+ or control == null
+ or not control.is_visible_in_tree()
+ or control.focus_mode == Control.FOCUS_NONE
+ or bool(control.get_meta(INVERSION_DISABLED_META, false))
+ ):
+ return
+ _focused_item = control
+ _original_material = _focused_item.material
+ _focused_item.material = _inversion_material
+
+
+func _restore_focused_item() -> void:
+ if is_instance_valid(_focused_item):
+ _focused_item.material = _original_material
+ _focused_item = null
+ _original_material = null
diff --git a/ui/controller_focus_presentation.gd.uid b/ui/controller_focus_presentation.gd.uid
new file mode 100644
index 0000000..29b0a72
--- /dev/null
+++ b/ui/controller_focus_presentation.gd.uid
@@ -0,0 +1 @@
+uid://b2ccvcx1rfd1x
diff --git a/ui/controller_focus_recovery.gd b/ui/controller_focus_recovery.gd
new file mode 100644
index 0000000..bcaf6c8
--- /dev/null
+++ b/ui/controller_focus_recovery.gd
@@ -0,0 +1,277 @@
+class_name ControllerFocusRecovery
+extends Node
+
+const CONTROLLER_AXIS_THRESHOLD: float = 0.35
+const SEMANTIC_MATCH_BONUS: float = 1000000.0
+const KEYBOARD_NAVIGATION_ACTIONS: Array[StringName] = [
+ &"ui_accept",
+ &"ui_cancel",
+ &"ui_up",
+ &"ui_down",
+ &"ui_left",
+ &"ui_right",
+ &"ui_focus_next",
+ &"ui_focus_prev",
+ &"ui_page_up",
+ &"ui_page_down",
+ &"ui_home",
+ &"ui_end",
+]
+
+var _controller_active: bool = false
+var _focus_navigation_active: bool = false
+var _last_focus_center: Vector2 = Vector2.ZERO
+var _last_focus_key: String = ""
+var _scope_chain: Array[WeakRef] = []
+var _pending_focus: WeakRef
+var _pointer_button_down: bool = false
+var _recovery_generation: int = 0
+
+
+func _ready() -> void:
+ set_process_input(true)
+ set_process(true)
+ get_viewport().gui_focus_changed.connect(_on_gui_focus_changed)
+
+
+func _exit_tree() -> void:
+ var viewport := get_viewport()
+ if viewport.gui_focus_changed.is_connected(_on_gui_focus_changed):
+ viewport.gui_focus_changed.disconnect(_on_gui_focus_changed)
+
+
+func _input(event: InputEvent) -> void:
+ if event is InputEventJoypadButton:
+ var button_event := event as InputEventJoypadButton
+ if button_event.pressed:
+ _pointer_button_down = false
+ _controller_active = true
+ _focus_navigation_active = true
+ if button_event.button_index == JOY_BUTTON_LEFT_SHOULDER:
+ _recovery_generation += 1
+ _scope_chain.clear()
+ _pending_focus = null
+ return
+ _request_pending_focus()
+ return
+ if event is InputEventJoypadMotion:
+ if absf((event as InputEventJoypadMotion).axis_value) >= (
+ CONTROLLER_AXIS_THRESHOLD
+ ):
+ _pointer_button_down = false
+ _controller_active = true
+ _focus_navigation_active = true
+ _request_pending_focus()
+ return
+ if event is InputEventMouseMotion:
+ _pointer_button_down = (
+ (event as InputEventMouseMotion).button_mask != 0
+ )
+ _leave_focus_navigation(not _pointer_button_down)
+ return
+ if event is InputEventMouseButton:
+ var mouse_button := event as InputEventMouseButton
+ if mouse_button.button_index in [
+ MOUSE_BUTTON_LEFT,
+ MOUSE_BUTTON_RIGHT,
+ MOUSE_BUTTON_MIDDLE,
+ ]:
+ _pointer_button_down = mouse_button.pressed
+ _leave_focus_navigation(false)
+ if not mouse_button.pressed:
+ _release_current_pointer_focus.call_deferred()
+ return
+ if event is InputEventKey and (event as InputEventKey).pressed:
+ _pointer_button_down = false
+ _controller_active = false
+ if _is_keyboard_navigation_event(event):
+ _focus_navigation_active = true
+ _request_pending_focus()
+ else:
+ _leave_focus_navigation()
+
+
+func _process(_delta: float) -> void:
+ if (
+ _controller_active
+ and not _scope_chain.is_empty()
+ and get_viewport().gui_get_focus_owner() == null
+ ):
+ _recover_focus(_recovery_generation)
+
+
+func _on_gui_focus_changed(control: Control) -> void:
+ _recovery_generation += 1
+ if control != null:
+ if _focus_navigation_active:
+ _pending_focus = null
+ if _controller_active and control is BaseButton:
+ _remember_focus(control)
+ return
+ if _keeps_pointer_focus(control):
+ return
+ if _is_focusable(control):
+ _pending_focus = weakref(control)
+ _release_focus_if_inactive.call_deferred(control)
+ return
+ if not _controller_active or _scope_chain.is_empty():
+ return
+ var generation: int = _recovery_generation
+ _recover_focus.call_deferred(generation)
+
+
+func _remember_focus(control: Control) -> void:
+ _last_focus_center = control.get_global_rect().get_center()
+ _last_focus_key = _semantic_key(control)
+ _scope_chain.clear()
+ var recovery_root: Node = get_parent()
+ var ancestor: Node = control.get_parent()
+ while ancestor != null:
+ if ancestor is Control:
+ _scope_chain.append(weakref(ancestor))
+ if ancestor == recovery_root:
+ break
+ ancestor = ancestor.get_parent()
+
+
+func _recover_focus(generation: int) -> void:
+ if generation != _recovery_generation:
+ return
+ if not _controller_active or get_viewport().gui_get_focus_owner() != null:
+ return
+ for scope_reference: WeakRef in _scope_chain:
+ var scope := scope_reference.get_ref() as Control
+ if (
+ scope == null
+ or not is_instance_valid(scope)
+ or not scope.is_inside_tree()
+ ):
+ continue
+ if not scope.is_visible_in_tree():
+ _scope_chain.clear()
+ return
+ var replacement := _best_replacement_in(scope)
+ if replacement != null:
+ replacement.grab_focus()
+ else:
+ _scope_chain.clear()
+ return
+ _scope_chain.clear()
+
+
+func _best_replacement_in(scope: Control) -> Control:
+ var best: Control = null
+ var best_score: float = INF
+ for node: Node in scope.find_children("*", "Control", true, false):
+ var candidate := node as Control
+ if not _is_focusable(candidate):
+ continue
+ var distance: float = candidate.get_global_rect().get_center().distance_squared_to(
+ _last_focus_center
+ )
+ if not _last_focus_key.is_empty() and _semantic_key(candidate) == _last_focus_key:
+ distance -= SEMANTIC_MATCH_BONUS
+ if distance < best_score:
+ best = candidate
+ best_score = distance
+ return best
+
+
+func _is_focusable(control: Control) -> bool:
+ if (
+ control == null
+ or not control.is_inside_tree()
+ or not control.is_visible_in_tree()
+ or control.focus_mode not in [Control.FOCUS_CLICK, Control.FOCUS_ALL]
+ ):
+ return false
+ var button := control as BaseButton
+ return button == null or not button.disabled
+
+
+func _semantic_key(control: Control) -> String:
+ if control.has_meta(&"controller_focus_key"):
+ return str(control.get_meta(&"controller_focus_key"))
+ var button := control as Button
+ var label: String = button.text if button != null else ""
+ var tooltip: String = control.tooltip_text
+ tooltip = tooltip.trim_suffix(" (show variants)")
+ tooltip = tooltip.trim_suffix(" (hide variants)")
+ return "%s|%s|%s" % [control.get_class(), label, tooltip]
+
+
+func _leave_focus_navigation(release_focus: bool = true) -> void:
+ _controller_active = false
+ _focus_navigation_active = false
+ _recovery_generation += 1
+ _scope_chain.clear()
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner == null or _keeps_pointer_focus(focus_owner):
+ return
+ if _is_focusable(focus_owner):
+ _pending_focus = weakref(focus_owner)
+ if release_focus:
+ _release_focus_if_inactive.call_deferred(focus_owner)
+
+
+func _release_focus_if_inactive(control: Control) -> void:
+ if (
+ _focus_navigation_active
+ or _pointer_button_down
+ or control == null
+ or not is_instance_valid(control)
+ or get_viewport().gui_get_focus_owner() != control
+ or _keeps_pointer_focus(control)
+ ):
+ return
+ get_viewport().gui_release_focus()
+
+
+func _release_current_pointer_focus() -> void:
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner != null:
+ _release_focus_if_inactive(focus_owner)
+
+
+func _request_pending_focus() -> void:
+ if (
+ not _focus_navigation_active
+ or _pending_focus == null
+ or get_viewport().gui_get_focus_owner() != null
+ ):
+ return
+ _restore_pending_focus.call_deferred(_recovery_generation)
+
+
+func _restore_pending_focus(generation: int) -> void:
+ if (
+ generation != _recovery_generation
+ or not _focus_navigation_active
+ or _pending_focus == null
+ or get_viewport().gui_get_focus_owner() != null
+ ):
+ return
+ var target := _pending_focus.get_ref() as Control
+ if not _is_focusable(target):
+ _pending_focus = null
+ return
+ _pending_focus = null
+ target.grab_focus()
+
+
+func _is_keyboard_navigation_event(event: InputEvent) -> bool:
+ if event.is_action_pressed(&"open_backpack"):
+ return false
+ if (
+ event.is_action_pressed(&"ui_cancel")
+ and get_viewport().gui_get_focus_owner() == null
+ ):
+ return false
+ for action: StringName in KEYBOARD_NAVIGATION_ACTIONS:
+ if event.is_action_pressed(action):
+ return true
+ return false
+
+
+func _keeps_pointer_focus(control: Control) -> bool:
+ return control is LineEdit or control is TextEdit
diff --git a/ui/controller_focus_recovery.gd.uid b/ui/controller_focus_recovery.gd.uid
new file mode 100644
index 0000000..b7f8ce9
--- /dev/null
+++ b/ui/controller_focus_recovery.gd.uid
@@ -0,0 +1 @@
+uid://c7cw61ethr3pt
diff --git a/ui/controller_mapping_panel.gd b/ui/controller_mapping_panel.gd
index 809f3b5..42fdf92 100644
--- a/ui/controller_mapping_panel.gd
+++ b/ui/controller_mapping_panel.gd
@@ -8,6 +8,7 @@ const ControllerMappingManagerType = preload(
)
const UtilityPageStyleType = preload("res://ui/utility_page_style.gd")
const CAPTURE_NEUTRAL_SECONDS: float = 0.22
+const CANCEL_COMBO_HOLD_SECONDS: float = 1.25
var _mapping_manager: ControllerMappingManagerType
var _binding_buttons: Dictionary = {}
@@ -24,6 +25,9 @@ var _auto_map_draft: Dictionary = {}
var _capture_device_id: int = 0
var _waiting_for_neutral: bool = false
var _neutral_elapsed: float = 0.0
+var _cancel_left_bumper_pressed: bool = false
+var _cancel_right_bumper_pressed: bool = false
+var _cancel_combo_elapsed: float = 0.0
func _ready() -> void:
@@ -112,6 +116,14 @@ func _process(delta: float) -> void:
or _capturing_role.is_empty()
):
return
+ if _cancel_left_bumper_pressed and _cancel_right_bumper_pressed:
+ _cancel_combo_elapsed += delta
+ _progress_label.text = "keep holding both bumpers to cancel"
+ if _cancel_combo_elapsed >= CANCEL_COMBO_HOLD_SECONDS:
+ _cancel_capture()
+ _progress_label.text = "controller mapping cancelled"
+ return
+ _cancel_combo_elapsed = 0.0
if _waiting_for_neutral:
if not _mapping_manager.are_capture_inputs_neutral(_capture_device_id):
_neutral_elapsed = 0.0
@@ -152,18 +164,7 @@ func _on_controller_input_observed(event: InputEvent) -> void:
return
if event_device != _capture_device_id:
return
- if (
- button_event != null
- and button_event.pressed
- and _capturing_role != ControllerMappingManagerType.ROLE_B
- and _mapping_manager.event_matches_role(
- event,
- ControllerMappingManagerType.ROLE_B,
- )
- ):
- _cancel_capture()
- _progress_label.text = "controller mapping cancelled"
- return
+ _track_cancel_combo_button(button_event)
if _waiting_for_neutral:
return
_try_capture_event(event)
@@ -332,6 +333,7 @@ func _begin_auto_map() -> void:
_auto_map_active = true
_auto_map_index = 0
_auto_map_draft = {}
+ _reset_cancel_combo()
_capture_device_id = _mapping_manager.get_active_device_id()
_set_capture_role(ControllerMappingManagerType.ROLE_ORDER[_auto_map_index])
@@ -340,6 +342,7 @@ func _begin_manual_capture(role: StringName) -> void:
_auto_map_active = false
_auto_map_index = -1
_auto_map_draft.clear()
+ _reset_cancel_combo()
_capture_device_id = _mapping_manager.get_active_device_id()
_set_capture_role(role)
@@ -356,10 +359,14 @@ func _refresh_capture_prompt() -> void:
if _capturing_role.is_empty():
return
if _auto_map_active:
- _progress_label.text = "step %d of %d: %s" % [
+ _progress_label.text = (
+ "step %d of %d: %s\n"
+ + "hold both bumpers for %.2f seconds to cancel"
+ ) % [
_auto_map_index + 1,
ControllerMappingManagerType.ROLE_ORDER.size(),
_mapping_manager.get_role_prompt(_capturing_role),
+ CANCEL_COMBO_HOLD_SECONDS,
]
return
var input_instruction: String = "press any controller button"
@@ -382,22 +389,22 @@ func _accept_captured_binding(binding: Dictionary) -> void:
ControllerMappingManagerType.ROLE_ORDER[_auto_map_index]
)
return
- var saved: bool = _mapping_manager.replace_active_bindings(
+ var profile_saved: bool = _mapping_manager.replace_active_bindings(
_auto_map_draft
)
_cancel_capture()
_progress_label.text = (
"controller mapped successfully"
- if saved else "could not save the controller mapping"
+ if profile_saved else "could not save the controller mapping"
)
_refresh_bindings()
return
var role: StringName = _capturing_role
- var saved: bool = _mapping_manager.set_binding(role, binding)
+ var binding_saved: bool = _mapping_manager.set_binding(role, binding)
_cancel_capture()
_progress_label.text = (
"updated " + _mapping_manager.get_role_label(role)
- if saved else "could not save that controller input"
+ if binding_saved else "could not save that controller input"
)
_refresh_bindings()
@@ -408,11 +415,34 @@ func _cancel_capture() -> void:
_auto_map_draft.clear()
_waiting_for_neutral = false
_neutral_elapsed = 0.0
+ _reset_cancel_combo()
_set_action_buttons_disabled(false)
if _progress_label != null:
_progress_label.text = ""
+func _track_cancel_combo_button(button_event: InputEventJoypadButton) -> void:
+ if button_event == null:
+ return
+ match button_event.button_index:
+ JOY_BUTTON_LEFT_SHOULDER:
+ _cancel_left_bumper_pressed = button_event.pressed
+ JOY_BUTTON_RIGHT_SHOULDER:
+ _cancel_right_bumper_pressed = button_event.pressed
+ _:
+ return
+ if not (
+ _cancel_left_bumper_pressed and _cancel_right_bumper_pressed
+ ):
+ _cancel_combo_elapsed = 0.0
+
+
+func _reset_cancel_combo() -> void:
+ _cancel_left_bumper_pressed = false
+ _cancel_right_bumper_pressed = false
+ _cancel_combo_elapsed = 0.0
+
+
func _set_action_buttons_disabled(disabled: bool) -> void:
if _auto_map_button != null:
_auto_map_button.disabled = disabled
diff --git a/ui/currency_presentation.gd b/ui/currency_presentation.gd
new file mode 100644
index 0000000..22fb32a
--- /dev/null
+++ b/ui/currency_presentation.gd
@@ -0,0 +1,28 @@
+class_name CurrencyPresentation
+extends RefCounted
+
+const ICON_PATH: String = (
+ "res://items/icons/shop/32_currency.png"
+)
+const AMOUNT_SCENE: PackedScene = preload(
+ "res://ui/components/currency_amount.tscn"
+)
+
+
+static func instantiate_amount(
+ value: int,
+ icon_size: float = 18.0,
+) -> CurrencyAmount:
+ var display := AMOUNT_SCENE.instantiate() as CurrencyAmount
+ display.icon_size = icon_size
+ display.amount = value
+ return display
+
+
+static func bbcode_amount(value: int, icon_size: int = 18) -> String:
+ return "[img=%dx%d]%s[/img] %d" % [
+ icon_size,
+ icon_size,
+ ICON_PATH,
+ value,
+ ]
diff --git a/ui/currency_presentation.gd.uid b/ui/currency_presentation.gd.uid
new file mode 100644
index 0000000..210c2b8
--- /dev/null
+++ b/ui/currency_presentation.gd.uid
@@ -0,0 +1 @@
+uid://bcvy1l2jqqbmt
diff --git a/ui/fishing_shop.gd b/ui/fishing_shop.gd
index f984b77..d8678b7 100644
--- a/ui/fishing_shop.gd
+++ b/ui/fishing_shop.gd
@@ -25,8 +25,23 @@ const ShopInteractionType = preload(
"res://world/fishing_shop_interaction.gd"
)
const UtilityPageStyleType = preload("res://ui/utility_page_style.gd")
+const OrganizerTabType = preload("res://ui/components/organizer_tab.gd")
+const UIMotionType = preload("res://ui/ui_motion.gd")
+const FALLBACK_SUPPLY_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/x_light.png"
+)
+const ART_KIT_MARKER_ICON: Texture2D = preload(
+ "res://items/icons/art/art_kit_marker.png"
+)
+const ART_KIT_MARKER_SHADER: Shader = preload(
+ "res://ui/art_kit_marker_icon.gdshader"
+)
+const CURRENCY_ICON: Texture2D = preload(
+ "res://items/icons/shop/32_currency.png"
+)
signal menu_visibility_changed(is_open: bool)
+signal menu_exit_started
signal sell_fish_requested
signal shop_cooler_return_requested
signal shop_cooler_confirmation_cancel_requested
@@ -39,26 +54,56 @@ enum CloseReason {
TEARDOWN,
}
+enum ShopSection {
+ UPGRADES,
+ BAIT,
+ SNACKS,
+ EQUIPMENT,
+ ART_SUPPLIES,
+ SELL_FISH,
+}
+
+const SHOP_SECTION_LABELS: Array[String] = [
+ "Upgrades",
+ "Bait and Lures",
+ "Snacks",
+ "Equipment",
+ "Art Supplies",
+ "Sell Fish",
+]
+const SUPPLY_ICON_GRID_COLUMNS: int = 9
+const SUPPLY_ICON_TILE_SIZE := Vector2(72.0, 72.0)
+const SUPPLY_ICON_HOST_SIZE := Vector2(72.0, 84.0)
+const SUPPLY_ICON_GRID_SEPARATION: int = 8
+const SUPPLY_PRICE_COLOR := Color("c3dfe6")
+const SUPPLY_PRICE_FONT_SIZE: int = 15
+const SUPPLY_PRICE_Y: float = 60.0
+const SUPPLY_PRICE_HEIGHT: float = 24.0
+const SUPPLY_PRICE_HORIZONTAL_PADDING: float = 12.0
+const SUPPLY_PRICE_ICON_SIZE: float = 18.0
+const SUPPLY_PRICE_ICON_GAP: float = 3.0
+
@onready var _wallet_label: Label = %WalletLabel
@onready var _shop_panel: PanelContainer = %ShopPanel
+@onready var _shop_panel_margin: MarginContainer = $ShopPanel/Margin
+@onready var _shop_panel_layout: VBoxContainer = $ShopPanel/Margin/Layout
@onready var _shop_cooler_page: Control = %ShopCoolerPage
@onready var _shop_cooler_mount: Control = %ShopCoolerMount
-@onready var _back_to_shop_button: Button = %BackToShopButton
-@onready var _buy_mode_button: Button = %BuyModeButton
-@onready var _sell_mode_button: Button = %SellModeButton
-@onready var _feedback: Label = %Feedback
-@onready var _reel_level: Label = %ReelLevel
-@onready var _reel_effect: Label = %ReelEffect
-@onready var _reel_cost: Label = %ReelCost
+@onready var _shop_body: HBoxContainer = $ShopPanel/Margin/Layout/Body
+@onready var _feedback: RichTextLabel = %Feedback
+@onready var _shop_tab_bar: HBoxContainer = %ShopTabBar
+@onready var _upgrades_content: VBoxContainer = %Upgrades
+@onready var _supplies_content: VBoxContainer = %Supplies
+@onready var _stock_title: Label = %StockTitle
+@onready var _reel_cost: CurrencyAmount = %ReelCost
+@onready var _reel_price_bubble: PanelContainer = %ReelPriceBubble
@onready var _reel_purchase: Button = %ReelPurchase
-@onready var _barrier_level: Label = %BarrierLevel
-@onready var _barrier_effect: Label = %BarrierEffect
-@onready var _barrier_cost: Label = %BarrierCost
+@onready var _barrier_cost: CurrencyAmount = %BarrierCost
+@onready var _barrier_price_bubble: PanelContainer = %BarrierPriceBubble
@onready var _barrier_purchase: Button = %BarrierPurchase
@onready var _supplies_list: VBoxContainer = %SuppliesList
-@onready var _cooler_level: Label = %CoolerLevel
-@onready var _cooler_effect: Label = %CoolerEffect
-@onready var _cooler_cost: Label = %CoolerCost
+@onready var _cooler_cost: CurrencyAmount = %CoolerCost
+@onready var _cooler_price_bubble: PanelContainer = %CoolerPriceBubble
@onready var _cooler_purchase: Button = %CoolerPurchase
var _player: PlayerType
@@ -79,40 +124,116 @@ var _snapshot_stored: bool = false
var _mouse_snapshot_stored: bool = false
var _transaction_in_progress: bool = false
var _closing: bool = false
+var _close_generation: int = 0
+var _close_tween: Tween
var _cooler_page_active: bool = false
var _cooler_modal_open: bool = false
+var _shop_section: ShopSection = ShopSection.UPGRADES
+var _shop_tabs: Array[OrganizerTab] = []
func _ready() -> void:
UtilityPageStyleType.apply_page(self)
_apply_shop_styles()
+ _build_shop_tabs()
%CloseButton.pressed.connect(close_shop)
- _buy_mode_button.pressed.connect(_focus_buy_page)
- _sell_mode_button.pressed.connect(_request_shop_cooler)
- _back_to_shop_button.pressed.connect(shop_cooler_return_requested.emit)
_reel_purchase.pressed.connect(_purchase_reel_speed)
_barrier_purchase.pressed.connect(_purchase_barrier_power)
_cooler_purchase.pressed.connect(_purchase_cooler_capacity)
-func _request_shop_cooler() -> void:
+func _request_shop_cooler() -> bool:
if _transaction_in_progress:
- _feedback.text = "Finish the current transaction first."
- return
+ _set_feedback("Finish the current transaction first.")
+ return false
if not _is_transaction_context_valid():
- _feedback.text = "The fishing shop is no longer available."
- return
+ _set_feedback("The fishing shop is no longer available.")
+ return false
sell_fish_requested.emit()
+ return _cooler_page_active
-func _focus_buy_page() -> void:
- _feedback.text = ""
- for child: Node in _supplies_list.get_children():
+func _focus_shop_section() -> void:
+ _set_feedback("")
+ if _shop_section == ShopSection.UPGRADES:
+ _reel_purchase.grab_focus()
+ return
+ if _shop_section == ShopSection.SELL_FISH:
+ _shop_tabs[int(ShopSection.SELL_FISH)].grab_focus()
+ return
+ for child: Node in _supplies_list.find_children(
+ "*", "Button", true, false
+ ):
var stock_button := child as Button
if stock_button != null and not stock_button.disabled:
stock_button.grab_focus()
return
- _reel_purchase.grab_focus()
+ var section_index: int = int(_shop_section)
+ if section_index >= 0 and section_index < _shop_tabs.size():
+ _shop_tabs[section_index].grab_focus()
+
+
+func _build_shop_tabs() -> void:
+ _shop_tab_bar.custom_minimum_size.y = 44.0
+ _shop_tab_bar.show()
+ for section_index: int in range(ShopSection.size()):
+ if section_index == ShopSection.SELL_FISH:
+ var tab_group_spacer := Control.new()
+ tab_group_spacer.name = "SellTabSpacer"
+ tab_group_spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ tab_group_spacer.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ _shop_tab_bar.add_child(tab_group_spacer)
+ var tab: OrganizerTab = OrganizerTabType.new()
+ tab.text = SHOP_SECTION_LABELS[section_index]
+ tab.palette_index = section_index
+ tab.custom_minimum_size = Vector2(132.0, 42.0)
+ tab.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ tab.focus_mode = Control.FOCUS_ALL
+ tab.mouse_filter = Control.MOUSE_FILTER_STOP
+ tab.pressed.connect(_select_shop_section.bind(section_index, true))
+ _shop_tab_bar.add_child(tab)
+ tab.show()
+ _shop_tabs.append(tab)
+ _select_shop_section(ShopSection.UPGRADES, false)
+
+
+func _select_shop_section(section_index: int, focus_content: bool) -> void:
+ if _closing:
+ return
+ if section_index == int(_shop_section):
+ if section_index != ShopSection.SELL_FISH:
+ var showing_upgrades := section_index == ShopSection.UPGRADES
+ _upgrades_content.visible = showing_upgrades
+ _supplies_content.visible = not showing_upgrades
+ _update_shop_tab_selection()
+ if focus_content:
+ _focus_shop_section()
+ return
+ if section_index == ShopSection.SELL_FISH:
+ if not _request_shop_cooler():
+ _update_shop_tab_selection()
+ return
+ _shop_section = ShopSection.SELL_FISH
+ _update_shop_tab_selection()
+ return
+ if _cooler_page_active:
+ shop_cooler_return_requested.emit()
+ _shop_section = section_index as ShopSection
+ var showing_upgrades: bool = _shop_section == ShopSection.UPGRADES
+ _upgrades_content.visible = showing_upgrades
+ _supplies_content.visible = not showing_upgrades
+ _update_shop_tab_selection()
+ _refresh_supplies()
+ if focus_content and visible:
+ _focus_shop_section()
+
+
+func _update_shop_tab_selection() -> void:
+ for tab_index: int in range(_shop_tabs.size()):
+ _shop_tabs[tab_index].set_selected(
+ tab_index == int(_shop_section),
+ true,
+ )
func _apply_shop_styles() -> void:
@@ -127,29 +248,38 @@ func _apply_shop_styles() -> void:
"panel", shop_panel_style
)
for panel: PanelContainer in [
- $ShopPanel/Margin/Layout/Body/Upgrades/ReelCard,
- $ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard,
- $ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard,
+ _reel_price_bubble,
+ _barrier_price_bubble,
+ _cooler_price_bubble,
]:
- panel.add_theme_stylebox_override(
- "panel", UtilityPageStyleType.row_style()
+ var price_style := UtilityPageStyleType.rounded_style(
+ UtilityPageStyleType.OCEAN_FIELD,
+ 18,
)
+ price_style.content_margin_left = 8.0
+ price_style.content_margin_right = 8.0
+ price_style.content_margin_top = 2.0
+ price_style.content_margin_bottom = 2.0
+ panel.add_theme_stylebox_override(
+ "panel", price_style
+ )
+ for price: CurrencyAmount in [
+ _reel_cost,
+ _barrier_cost,
+ _cooler_cost,
+ ]:
+ var amount_label := price.get_amount_label()
+ amount_label.add_theme_color_override(
+ "font_color", SUPPLY_PRICE_COLOR
+ )
+ amount_label.add_theme_font_size_override("font_size", 18)
for button: BaseButton in [
%CloseButton,
- _buy_mode_button,
- _sell_mode_button,
_reel_purchase,
_barrier_purchase,
_cooler_purchase,
- _back_to_shop_button,
]:
UtilityPageStyleType.apply_ocean_button(button)
- _buy_mode_button.add_theme_stylebox_override(
- "normal",
- UtilityPageStyleType.ocean_button_style(
- UtilityPageStyleType.OCEAN_SELECTED
- ),
- )
_feedback.add_theme_color_override(
"font_color", UtilityPageStyleType.OCEAN_TEXT_SECONDARY
)
@@ -219,7 +349,10 @@ func open_shop() -> bool:
or _buyer.id != MAIN_SHOP_BUYER_ID
):
return false
+ _cancel_close_tween()
+ _close_generation += 1
_closing = false
+ modulate.a = 1.0
_transaction_in_progress = (
_network_shop != null
and _network_shop.is_local_purchase_pending()
@@ -233,11 +366,13 @@ func open_shop() -> bool:
_player.set_camera_input_enabled(false)
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, true)
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
- _feedback.text = ""
+ _set_feedback("")
deactivate_shop_cooler_page()
show()
+ _shop_tab_bar.show()
+ _select_shop_section(ShopSection.UPGRADES, false)
_refresh_all()
- _buy_mode_button.grab_focus()
+ _reel_purchase.grab_focus()
menu_visibility_changed.emit(true)
return true
@@ -245,11 +380,13 @@ func open_shop() -> bool:
func consume_escape() -> bool:
if not visible:
return false
+ if _closing:
+ return true
if _cooler_page_active:
if _cooler_modal_open:
shop_cooler_confirmation_cancel_requested.emit()
else:
- shop_cooler_return_requested.emit()
+ _select_shop_section(ShopSection.UPGRADES, true)
return true
close_shop()
return true
@@ -261,24 +398,42 @@ func get_shop_cooler_mount() -> Control:
func activate_shop_cooler_page() -> void:
_cooler_page_active = true
- _shop_panel.hide()
+ _shop_panel.show()
+ _set_shop_panel_background_pointer_blocking(false)
+ _shop_body.hide()
+ _feedback.hide()
_shop_cooler_page.show()
- _back_to_shop_button.disabled = false
func deactivate_shop_cooler_page() -> void:
+ if visible:
+ _shop_tab_bar.show()
_cooler_page_active = false
_cooler_modal_open = false
- _back_to_shop_button.disabled = false
+ _set_shop_panel_background_pointer_blocking(true)
+ for tab: OrganizerTab in _shop_tabs:
+ tab.disabled = false
_shop_cooler_page.hide()
_shop_panel.show()
- if visible:
- _buy_mode_button.grab_focus()
+ _shop_body.show()
+ _feedback.show()
+
+
+func _set_shop_panel_background_pointer_blocking(blocking: bool) -> void:
+ var mouse_filter := (
+ Control.MOUSE_FILTER_STOP
+ if blocking
+ else Control.MOUSE_FILTER_IGNORE
+ )
+ _shop_panel.mouse_filter = mouse_filter
+ _shop_panel_margin.mouse_filter = mouse_filter
+ _shop_panel_layout.mouse_filter = mouse_filter
func set_shop_cooler_modal_open(is_open: bool) -> void:
_cooler_modal_open = is_open
- _back_to_shop_button.disabled = is_open
+ for tab: OrganizerTab in _shop_tabs:
+ tab.disabled = is_open
func close_shop(
@@ -287,12 +442,47 @@ func close_shop(
) -> void:
if not visible:
return
+ if _closing:
+ if reason in [
+ CloseReason.WATER_RECOVERY,
+ CloseReason.SESSION_END,
+ CloseReason.TEARDOWN,
+ ]:
+ _finish_close(reason, restore_controls, _close_generation)
+ return
_closing = true
_transaction_in_progress = false
- hide()
var current_viewport: Viewport = get_viewport()
if current_viewport != null:
current_viewport.gui_release_focus()
+ menu_exit_started.emit()
+ _close_generation += 1
+ var generation: int = _close_generation
+ if reason in [CloseReason.USER, CloseReason.RANGE_EXIT]:
+ _close_tween = create_tween()
+ _close_tween.tween_property(
+ self,
+ "modulate:a",
+ 0.0,
+ UIMotionType.PLAYER_MENU_EXIT_DURATION,
+ ).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
+ _close_tween.finished.connect(
+ _finish_close.bind(reason, restore_controls, generation)
+ )
+ return
+ _finish_close(reason, restore_controls, generation)
+
+
+func _finish_close(
+ reason: CloseReason,
+ restore_controls: bool,
+ generation: int,
+) -> void:
+ if generation != _close_generation or not visible:
+ return
+ _cancel_close_tween()
+ hide()
+ modulate.a = 1.0
if _fishing_spot != null and is_instance_valid(_fishing_spot):
_fishing_spot.set_local_menu_input_suppressed(INPUT_OWNER, false)
if (
@@ -310,6 +500,13 @@ func close_shop(
deactivate_shop_cooler_page()
+func _cancel_close_tween() -> void:
+ if _close_tween == null:
+ return
+ _close_tween.kill()
+ _close_tween = null
+
+
func close_for_range_exit() -> void:
close_shop(CloseReason.RANGE_EXIT)
@@ -342,9 +539,9 @@ func _refresh_all() -> void:
func _refresh_wallet() -> void:
_wallet_label.text = (
- "wallet: $%d" % _wallet.get_balance()
+ str(_wallet.get_balance())
if _wallet != null
- else "wallet: $0"
+ else "0"
)
@@ -353,7 +550,6 @@ func _refresh_upgrades() -> void:
return
var reel_level: int = _upgrades.get_reel_speed_level()
var reel_cost: int = _upgrades.get_next_reel_speed_cost()
- _reel_level.text = "level %d" % reel_level
_reel_purchase.disabled = (
reel_cost < 0
or _transaction_in_progress
@@ -362,27 +558,30 @@ func _refresh_upgrades() -> void:
or not _network_shop.can_request_purchase()
or not _upgrades.can_purchase_reel_speed(_wallet)
)
- _reel_purchase.tooltip_text = (
- "Purchases are unavailable in this session."
- if _network_shop == null or not _network_shop.can_request_purchase()
- else ""
- )
+ var reel_effect: String
if reel_cost < 0:
- _reel_effect.text = "%.2f×" % _upgrades.get_reel_speed_multiplier()
- _reel_cost.text = "max"
+ reel_effect = "%.2f× reel speed · maximum level" % (
+ _upgrades.get_reel_speed_multiplier()
+ )
+ _reel_price_bubble.hide()
else:
- _reel_effect.text = (
+ _reel_price_bubble.show()
+ reel_effect = (
"%.2f× → %.2f×"
% [
_upgrades.get_reel_speed_multiplier(),
1.0 + float(reel_level + 1) * 0.10,
]
)
- _reel_cost.text = "$%d" % reel_cost
- _reel_purchase.text = "max" if reel_cost < 0 else "purchase"
+ _reel_cost.set_amount(reel_cost)
+ _reel_purchase.tooltip_text = _upgrade_tooltip(
+ "reel speed",
+ reel_level,
+ reel_effect,
+ )
+ _reel_purchase.accessibility_name = _reel_purchase.tooltip_text
var barrier_level: int = _upgrades.get_barrier_power_level()
var barrier_cost: int = _upgrades.get_next_barrier_power_cost()
- _barrier_level.text = "level %d" % barrier_level
_barrier_purchase.disabled = (
barrier_cost < 0
or _transaction_in_progress
@@ -391,20 +590,39 @@ func _refresh_upgrades() -> void:
or not _network_shop.can_request_purchase()
or not _upgrades.can_purchase_barrier_power(_wallet)
)
- _barrier_purchase.tooltip_text = _reel_purchase.tooltip_text
+ var barrier_effect: String
if barrier_cost < 0:
- _barrier_effect.text = "%d damage" % _upgrades.get_barrier_damage()
- _barrier_cost.text = "max"
+ barrier_effect = "%d damage · maximum level" % (
+ _upgrades.get_barrier_damage()
+ )
+ _barrier_price_bubble.hide()
else:
- _barrier_effect.text = (
+ _barrier_price_bubble.show()
+ barrier_effect = (
"%d damage → %d damage"
% [
_upgrades.get_barrier_damage(),
barrier_level + 2,
]
)
- _barrier_cost.text = "$%d" % barrier_cost
- _barrier_purchase.text = "max" if barrier_cost < 0 else "purchase"
+ _barrier_cost.set_amount(barrier_cost)
+ _barrier_purchase.tooltip_text = _upgrade_tooltip(
+ "rod power",
+ barrier_level,
+ barrier_effect,
+ )
+ _barrier_purchase.accessibility_name = _barrier_purchase.tooltip_text
+
+
+func _upgrade_tooltip(
+ upgrade_name: String,
+ level: int,
+ effect: String,
+) -> String:
+ var tooltip := "%s\nlevel %d\n%s" % [upgrade_name, level, effect]
+ if _network_shop == null or not _network_shop.can_request_purchase():
+ tooltip += "\nPurchases are unavailable in this session."
+ return tooltip
func _refresh_supplies() -> void:
@@ -413,59 +631,160 @@ func _refresh_supplies() -> void:
for child: Node in _supplies_list.get_children():
_supplies_list.remove_child(child)
child.queue_free()
- _add_stock_section("supplies")
- for item_id: StringName in FishingShopStockType.get_stock_item_ids():
+ if _shop_section in [ShopSection.UPGRADES, ShopSection.SELL_FISH]:
+ return
+ _stock_title.text = SHOP_SECTION_LABELS[int(_shop_section)]
+ var stock_item_ids: Array[StringName] = (
+ FishingShopStockType.get_stock_item_ids()
+ )
+ if _shop_section == ShopSection.BAIT:
+ var grouped_item_ids: Array[StringName] = []
+ for item_id: StringName in stock_item_ids:
+ var bait_item: ItemDataType = _item_catalog.get_item_by_id(item_id)
+ if bait_item != null and bait_item.is_bait():
+ grouped_item_ids.append(item_id)
+ for item_id: StringName in stock_item_ids:
+ var lure_item: ItemDataType = _item_catalog.get_item_by_id(item_id)
+ if lure_item != null and lure_item.is_lure():
+ grouped_item_ids.append(item_id)
+ stock_item_ids = grouped_item_ids
+ var current_stock_group: StringName = StringName()
+ var current_stock_grid: GridContainer
+ if _shop_section in [ShopSection.SNACKS, ShopSection.EQUIPMENT]:
+ current_stock_grid = _add_stock_icon_grid()
+ for item_id: StringName in stock_item_ids:
var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
- if item == null:
+ if item == null or not _item_belongs_in_current_section(item):
continue
+ if _shop_section == ShopSection.BAIT:
+ var stock_group: StringName = (
+ &"bait" if item.is_bait() else &"lures"
+ )
+ if stock_group != current_stock_group:
+ _add_stock_section(str(stock_group))
+ current_stock_grid = _add_stock_icon_grid()
+ current_stock_group = stock_group
var button := Button.new()
button.custom_minimum_size = Vector2(195, 54)
- button.icon = item.icon
+ button.icon = item.icon if item.icon != null else FALLBACK_SUPPLY_ICON
button.expand_icon = true
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
- button.text = "%s\n$%d • owned %d" % [
+ var owned: int = _bag.get_quantity(item_id)
+ var bait_topoff: bool = FishingShopStockType.is_bait_topoff(item_id)
+ var bait_unlocked: bool = (
+ not bait_topoff or _bag.is_bait_unlocked(item_id)
+ )
+ var quantity: int = FishingShopStockType.get_purchase_quantity(
+ item_id, owned, item.max_stack
+ )
+ var total_cost: int = FishingShopStockType.get_purchase_cost(
+ item_id, quantity, bait_unlocked
+ )
+ var use_icon_tile: bool = (
+ current_stock_grid != null
+ )
+ button.text = "%s\nowned %d" % [
item.display_name,
- FishingShopStockType.get_price(item_id),
- _bag.get_quantity(item_id),
+ owned,
]
- if FishingShopStockType.is_bait_topoff(item_id):
- button.text = "%s\n$%d each • %d/%d" % [
+ var item_tooltip_text: String = item.description
+ if bait_topoff:
+ if use_icon_tile:
+ button.custom_minimum_size = SUPPLY_ICON_TILE_SIZE
+ button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ button.text = ""
+ else:
+ button.text = (
+ "%s\nunlock and fill" % item.display_name
+ if not bait_unlocked
+ else "%s\n%d/%d owned" % [
+ item.display_name,
+ owned,
+ item.max_stack,
+ ]
+ )
+ item_tooltip_text = (
+ "%s\nunlock and fill to %d/%d\n%s" % [
+ item.display_name,
+ item.max_stack,
+ item.max_stack,
+ item.description,
+ ]
+ if not bait_unlocked
+ else "%s\n%d/%d owned\n%s" % [
+ item.display_name,
+ owned,
+ item.max_stack,
+ item.description,
+ ]
+ )
+ elif use_icon_tile:
+ button.custom_minimum_size = SUPPLY_ICON_TILE_SIZE
+ button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ button.text = ""
+ item_tooltip_text = "%s\nowned %d\n%s" % [
item.display_name,
- FishingShopStockType.get_price(item_id),
- _bag.get_quantity(item_id),
- FishingShopStockType.WORM_MAX_STACK,
+ owned,
+ item.description,
]
- button.tooltip_text = item.description
button.disabled = (
_transaction_in_progress
or _closing
or _network_shop == null
or not _network_shop.can_request_purchase()
- or FishingShopStockType.get_purchase_quantity(item_id, _bag.get_quantity(item_id)) <= 0
- or not _bag.can_add_item(item_id, FishingShopStockType.get_purchase_quantity(item_id, _bag.get_quantity(item_id)))
- or not _wallet.can_afford(
- FishingShopStockType.get_price(item_id) * FishingShopStockType.get_purchase_quantity(item_id, _bag.get_quantity(item_id))
- )
+ or quantity <= 0
+ or total_cost < 0
+ or not _bag.can_add_item(item_id, quantity)
+ or not _wallet.can_afford(total_cost)
)
button.tooltip_text = (
"Purchases are unavailable in this session."
if _network_shop == null or not _network_shop.can_request_purchase()
- else item.description
+ else item_tooltip_text
)
UtilityPageStyleType.apply_ocean_button(button)
button.pressed.connect(_purchase_supply.bind(item_id))
- _supplies_list.add_child(button)
- _add_stock_section("art kit")
- _add_art_kit_button()
- _add_stock_section("markers")
- for product_id: StringName in ArtShopStockType.MARKER_PRODUCTS:
- _add_art_upgrade_button(product_id)
- _add_stock_section("brushes")
- for product_id: StringName in ArtShopStockType.BRUSH_PRODUCTS:
- _add_art_upgrade_button(product_id)
- _add_stock_section("grids")
- for product_id: StringName in ArtShopStockType.GRID_PRODUCTS:
- _add_art_upgrade_button(product_id)
+ if current_stock_grid != null:
+ _add_supply_icon_tile(
+ current_stock_grid,
+ button,
+ (
+ total_cost
+ if bait_topoff and not bait_unlocked
+ else FishingShopStockType.get_price(item_id)
+ ),
+ )
+ else:
+ _supplies_list.add_child(button)
+ if _shop_section == ShopSection.ART_SUPPLIES:
+ _add_stock_section("art kit")
+ var art_kit_grid := _add_stock_icon_grid()
+ _add_art_kit_button(art_kit_grid)
+ _add_stock_section("markers")
+ var marker_grid := _add_stock_icon_grid()
+ for product_id: StringName in ArtShopStockType.MARKER_PRODUCTS:
+ _add_art_upgrade_button(product_id, marker_grid)
+ _add_stock_section("brushes")
+ var brush_grid := _add_stock_icon_grid()
+ for product_id: StringName in ArtShopStockType.BRUSH_PRODUCTS:
+ _add_art_upgrade_button(product_id, brush_grid)
+ _add_stock_section("grids")
+ var canvas_grid := _add_stock_icon_grid()
+ for product_id: StringName in ArtShopStockType.GRID_PRODUCTS:
+ _add_art_upgrade_button(product_id, canvas_grid)
+
+
+func _item_belongs_in_current_section(item: ItemDataType) -> bool:
+ match _shop_section:
+ ShopSection.BAIT:
+ return item.is_bait() or item.is_lure()
+ ShopSection.SNACKS:
+ return item.category == ItemDataType.Category.CONSUMABLE
+ ShopSection.EQUIPMENT:
+ return item.category == ItemDataType.Category.TOOL
+ return false
func _add_stock_section(title: String) -> void:
@@ -478,7 +797,21 @@ func _add_stock_section(title: String) -> void:
_supplies_list.add_child(label)
-func _add_art_kit_button() -> void:
+func _add_stock_icon_grid() -> GridContainer:
+ var grid := GridContainer.new()
+ grid.columns = SUPPLY_ICON_GRID_COLUMNS
+ grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ grid.add_theme_constant_override(
+ "h_separation", SUPPLY_ICON_GRID_SEPARATION
+ )
+ grid.add_theme_constant_override(
+ "v_separation", SUPPLY_ICON_GRID_SEPARATION
+ )
+ _supplies_list.add_child(grid)
+ return grid
+
+
+func _add_art_kit_button(parent: GridContainer) -> void:
var item: ItemDataType = _item_catalog.get_item_by_id(
ArtShopStockType.ART_KIT_ITEM_ID
)
@@ -486,15 +819,22 @@ func _add_art_kit_button() -> void:
return
var owned: bool = _bag.get_quantity(ArtShopStockType.ART_KIT_ITEM_ID) > 0
var button: Button = _make_stock_button(
- "%s\n$%d • %s" % [
+ "%s\n%s" % [
item.display_name,
- ArtShopStockType.ART_KIT_PRICE,
"owned" if owned else "not owned",
],
- item.description,
+ "%s\n%s\n%s" % [
+ item.display_name,
+ "owned" if owned else "not owned",
+ item.description,
+ ],
+ )
+ _configure_supply_icon_tile(button, item.icon)
+ _add_supply_icon_tile(
+ parent,
+ button,
+ ArtShopStockType.ART_KIT_PRICE,
)
- button.icon = item.icon
- button.expand_icon = true
button.disabled = (
owned
or _transaction_in_progress
@@ -507,18 +847,39 @@ func _add_art_kit_button() -> void:
button.pressed.connect(_purchase_art_kit)
-func _add_art_upgrade_button(product_id: StringName) -> void:
+func _add_art_upgrade_button(
+ product_id: StringName,
+ parent: GridContainer,
+) -> void:
var kit_owned: bool = (
_bag.get_quantity(ArtShopStockType.ART_KIT_ITEM_ID) > 0
)
var unlocked: bool = _art_unlocks.owns_product(product_id)
var button: Button = _make_stock_button(
- "%s\n$%d • %s" % [
+ "%s\n%s" % [
ArtShopStockType.get_display_name(product_id),
- ArtShopStockType.UPGRADE_PRICE,
"unlocked" if unlocked else "locked",
],
- ArtShopStockType.get_description(product_id),
+ "%s\n%s\n%s" % [
+ ArtShopStockType.get_display_name(product_id),
+ "unlocked" if unlocked else "locked",
+ ArtShopStockType.get_description(product_id),
+ ],
+ )
+ var marker_color_id: StringName = (
+ PlayerArtUnlocksType.color_id_for_product(product_id)
+ )
+ if marker_color_id.is_empty():
+ _configure_supply_icon_tile(button, FALLBACK_SUPPLY_ICON)
+ else:
+ _configure_marker_icon_tile(
+ button,
+ SurfaceDrawingPalette.get_color(marker_color_id),
+ )
+ _add_supply_icon_tile(
+ parent,
+ button,
+ ArtShopStockType.UPGRADE_PRICE,
)
button.disabled = (
not kit_owned
@@ -532,24 +893,143 @@ func _add_art_upgrade_button(product_id: StringName) -> void:
button.pressed.connect(_purchase_art_upgrade.bind(product_id))
-func _make_stock_button(button_text: String, tooltip: String) -> Button:
+func _make_stock_button(
+ button_text: String,
+ tooltip: String,
+) -> Button:
var button := Button.new()
button.custom_minimum_size = Vector2(195, 54)
button.alignment = HORIZONTAL_ALIGNMENT_LEFT
button.text = button_text
button.tooltip_text = tooltip
UtilityPageStyleType.apply_ocean_button(button)
- _supplies_list.add_child(button)
return button
+func _configure_supply_icon_tile(
+ button: Button,
+ icon: Texture2D,
+) -> void:
+ button.custom_minimum_size = SUPPLY_ICON_TILE_SIZE
+ button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ button.icon = icon if icon != null else FALLBACK_SUPPLY_ICON
+ button.expand_icon = true
+ button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ button.text = ""
+
+
+func _configure_marker_icon_tile(
+ button: Button,
+ marker_color: Color,
+) -> void:
+ button.custom_minimum_size = SUPPLY_ICON_TILE_SIZE
+ button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ button.icon = null
+ button.text = ""
+ var icon := TextureRect.new()
+ icon.name = "MarkerIcon"
+ icon.position = Vector2(4.0, 4.0)
+ icon.size = Vector2(64.0, 64.0)
+ icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ var marker_material := ShaderMaterial.new()
+ marker_material.shader = ART_KIT_MARKER_SHADER
+ marker_material.set_shader_parameter("marker_color", marker_color)
+ icon.material = marker_material
+ icon.texture = ART_KIT_MARKER_ICON
+ button.add_child(icon)
+
+
+func _add_supply_icon_tile(
+ parent: GridContainer,
+ button: Button,
+ price: int,
+) -> void:
+ var tile_host := Control.new()
+ tile_host.custom_minimum_size = SUPPLY_ICON_HOST_SIZE
+ tile_host.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ parent.add_child(tile_host)
+ button.position = Vector2.ZERO
+ button.size = SUPPLY_ICON_TILE_SIZE
+ tile_host.add_child(button)
+ var price_text := str(price)
+ var price_text_width: float = UtilityPageStyleType.TuffyFont.get_string_size(
+ price_text,
+ HORIZONTAL_ALIGNMENT_LEFT,
+ -1.0,
+ SUPPLY_PRICE_FONT_SIZE,
+ ).x
+ var price_width: float = minf(
+ SUPPLY_ICON_TILE_SIZE.x,
+ ceilf(
+ price_text_width
+ + SUPPLY_PRICE_ICON_SIZE
+ + SUPPLY_PRICE_ICON_GAP
+ + SUPPLY_PRICE_HORIZONTAL_PADDING
+ ),
+ )
+ var price_bubble := PanelContainer.new()
+ price_bubble.name = "PriceBubble"
+ price_bubble.position = Vector2(
+ (SUPPLY_ICON_TILE_SIZE.x - price_width) * 0.5,
+ SUPPLY_PRICE_Y,
+ )
+ price_bubble.size = Vector2(price_width, SUPPLY_PRICE_HEIGHT)
+ price_bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ price_bubble.z_index = 2
+ var price_style := UtilityPageStyleType.rounded_style(
+ UtilityPageStyleType.OCEAN_FIELD,
+ 12,
+ )
+ price_style.content_margin_left = 6.0
+ price_style.content_margin_right = 6.0
+ price_style.content_margin_top = 0.0
+ price_style.content_margin_bottom = 0.0
+ price_bubble.add_theme_stylebox_override("panel", price_style)
+ tile_host.add_child(price_bubble)
+ var price_row := HBoxContainer.new()
+ price_row.name = "CurrencyAmount"
+ price_row.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ price_row.alignment = BoxContainer.ALIGNMENT_CENTER
+ price_row.add_theme_constant_override(
+ "separation", int(SUPPLY_PRICE_ICON_GAP)
+ )
+ price_bubble.add_child(price_row)
+ var price_icon := TextureRect.new()
+ price_icon.name = "CurrencyIcon"
+ price_icon.custom_minimum_size = Vector2.ONE * SUPPLY_PRICE_ICON_SIZE
+ price_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ price_icon.texture = CURRENCY_ICON
+ price_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ price_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ price_icon.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ price_row.add_child(price_icon)
+ var price_label := Label.new()
+ price_label.name = "Price"
+ price_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ price_label.text = price_text
+ price_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ price_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ price_label.add_theme_font_override(
+ "font", UtilityPageStyleType.TuffyFont
+ )
+ price_label.add_theme_font_size_override(
+ "font_size", SUPPLY_PRICE_FONT_SIZE
+ )
+ price_label.add_theme_color_override(
+ "font_color", SUPPLY_PRICE_COLOR
+ )
+ price_label.add_theme_constant_override("outline_size", 0)
+ price_row.add_child(price_label)
+
+
func _refresh_cooler_capacity() -> void:
if _cooler_capacity == null:
return
var level: int = _cooler_capacity.get_level()
var cost: int = _cooler_capacity.get_next_cost()
var next_capacity: int = _cooler_capacity.get_next_capacity()
- _cooler_level.text = "level %d" % level
_cooler_purchase.disabled = (
cost < 0
or _transaction_in_progress
@@ -558,18 +1038,25 @@ func _refresh_cooler_capacity() -> void:
or not _network_shop.can_request_purchase()
or not _cooler_capacity.can_purchase(_wallet)
)
- _cooler_purchase.tooltip_text = _reel_purchase.tooltip_text
+ var cooler_effect: String
if cost < 0:
- _cooler_effect.text = "%d fish" % _cooler_capacity.get_capacity()
- _cooler_cost.text = "max"
- _cooler_purchase.text = "max"
+ cooler_effect = "%d fish · maximum level" % (
+ _cooler_capacity.get_capacity()
+ )
+ _cooler_price_bubble.hide()
else:
- _cooler_effect.text = "%d → %d fish" % [
+ _cooler_price_bubble.show()
+ cooler_effect = "%d → %d fish" % [
_cooler_capacity.get_capacity(),
next_capacity,
]
- _cooler_cost.text = "$%d" % cost
- _cooler_purchase.text = "purchase"
+ _cooler_cost.set_amount(cost)
+ _cooler_purchase.tooltip_text = _upgrade_tooltip(
+ "cooler capacity",
+ level,
+ cooler_effect,
+ )
+ _cooler_purchase.accessibility_name = _cooler_purchase.tooltip_text
func _purchase_reel_speed() -> void:
@@ -582,56 +1069,65 @@ func _purchase_barrier_power() -> void:
func _purchase_supply(item_id: StringName) -> void:
if _transaction_in_progress or not _is_transaction_context_valid():
- _feedback.text = "unable to complete purchase."
+ _set_feedback("unable to complete purchase.")
return
var owned: int = _bag.get_quantity(item_id)
- var quantity: int = FishingShopStockType.get_purchase_quantity(item_id, owned)
- if quantity <= 0 or not _bag.can_add_item(item_id, quantity):
- _feedback.text = "Your Bag is full."
+ var item: ItemDataType = _item_catalog.get_item_by_id(item_id)
+ if item == null:
+ _set_feedback("Purchase could not be completed.")
return
- if not _wallet.can_afford(FishingShopStockType.get_price(item_id) * quantity):
- _feedback.text = "Not enough fish coin."
+ var quantity: int = FishingShopStockType.get_purchase_quantity(
+ item_id, owned, item.max_stack
+ )
+ if quantity <= 0 or not _bag.can_add_item(item_id, quantity):
+ _set_feedback("Your Bag is full.")
+ return
+ var total_cost: int = FishingShopStockType.get_purchase_cost(
+ item_id, quantity, _bag.is_bait_unlocked(item_id)
+ )
+ if total_cost < 0 or not _wallet.can_afford(total_cost):
+ _set_feedback("Insufficient funds.")
return
if _network_shop == null:
- _feedback.text = "Purchase could not be completed."
+ _set_feedback("Purchase could not be completed.")
return
_network_shop.request_supply(item_id)
func _purchase_art_kit() -> void:
if _network_shop == null or not _is_transaction_context_valid():
- _feedback.text = "Purchase could not be completed."
+ _set_feedback("Purchase could not be completed.")
return
_network_shop.request_art_kit()
func _purchase_art_upgrade(product_id: StringName) -> void:
if _network_shop == null or not _is_transaction_context_valid():
- _feedback.text = "Purchase could not be completed."
+ _set_feedback("Purchase could not be completed.")
return
_network_shop.request_art_upgrade(product_id)
func _purchase_cooler_capacity() -> void:
if _transaction_in_progress or not _is_transaction_context_valid():
- _feedback.text = "unable to complete purchase."
+ _set_feedback("unable to complete purchase.")
return
var cost: int = _cooler_capacity.get_next_cost()
if cost < 0:
- _feedback.text = "Upgrade is already at maximum."
+ _set_feedback("Upgrade is already at maximum.")
return
if not _wallet.can_afford(cost):
- _feedback.text = "Not enough fish coin."
+ _set_feedback("Insufficient funds.")
return
if _network_shop == null:
- _feedback.text = "Purchase could not be completed."
+ _set_feedback("Purchase could not be completed.")
return
_network_shop.request_cooler_capacity_upgrade()
func _purchase_upgrade(is_reel_speed: bool) -> void:
if _transaction_in_progress or not _is_transaction_context_valid():
- _feedback.text = "unable to complete purchase."
+ _set_feedback("unable to complete purchase.")
return
var cost: int = (
_upgrades.get_next_reel_speed_cost()
@@ -639,13 +1135,13 @@ func _purchase_upgrade(is_reel_speed: bool) -> void:
else _upgrades.get_next_barrier_power_cost()
)
if cost < 0:
- _feedback.text = "Upgrade is already at maximum."
+ _set_feedback("Upgrade is already at maximum.")
return
if not _wallet.can_afford(cost):
- _feedback.text = "Not enough fish coin."
+ _set_feedback("Insufficient funds.")
return
if _network_shop == null:
- _feedback.text = "Purchase could not be completed."
+ _set_feedback("Purchase could not be completed.")
return
if is_reel_speed:
_network_shop.request_reel_speed_upgrade()
@@ -656,7 +1152,7 @@ func _purchase_upgrade(is_reel_speed: bool) -> void:
func _on_network_purchase_pending(_request_id: String) -> void:
_transaction_in_progress = true
if visible:
- _feedback.text = "Purchasing…"
+ _set_feedback("Purchasing…")
_refresh_all()
@@ -672,14 +1168,21 @@ func _on_network_purchase_finished(
_transaction_in_progress = false
if not visible:
return
- _feedback.text = (
- "Purchase complete. $%d spent." % total_cost
+ _set_feedback(
+ (
+ "Purchase complete • %s spent."
+ % CurrencyPresentation.bbcode_amount(total_cost, 18)
+ )
if accepted
else message
)
_refresh_all()
+func _set_feedback(message: String) -> void:
+ _feedback.text = "[center]%s[/center]" % message
+
+
func _is_transaction_context_valid() -> bool:
return (
visible
diff --git a/ui/fishing_shop.tscn b/ui/fishing_shop.tscn
index 2b1914d..5d0b9ec 100644
--- a/ui/fishing_shop.tscn
+++ b/ui/fishing_shop.tscn
@@ -1,11 +1,13 @@
-[gd_scene load_steps=7 format=3]
+[gd_scene load_steps=9 format=3]
[ext_resource type="Script" path="res://ui/fishing_shop.gd" id="1_script"]
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
-[ext_resource type="Texture2D" path="res://items/icons/placeholder/reel_speed_upgrade.svg" id="3_reel"]
-[ext_resource type="Texture2D" path="res://items/icons/placeholder/barrier_power_upgrade.svg" id="4_barrier"]
-[ext_resource type="Texture2D" path="res://items/icons/placeholder/fish_coin.svg" id="5_coin"]
-[ext_resource type="Texture2D" path="res://items/icons/placeholder/cooler_expansion.svg" id="6_cooler"]
+[ext_resource type="Texture2D" path="res://items/icons/shop/64_speed_plus.png" id="3_reel"]
+[ext_resource type="Texture2D" path="res://items/icons/shop/64_power_plus.png" id="4_barrier"]
+[ext_resource type="Texture2D" path="res://items/icons/shop/32_currency.png" id="5_coin"]
+[ext_resource type="Texture2D" path="res://items/icons/equipment/64_cooler_plus.png" id="6_cooler"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_light.png" id="7_close"]
+[ext_resource type="PackedScene" path="res://ui/components/currency_amount.tscn" id="8_currency"]
[node name="FishingShop" type="Control"]
unique_name_in_owner = true
@@ -34,7 +36,7 @@ mouse_filter = 0
[node name="ShopCoolerPage" type="Control" parent="."]
unique_name_in_owner = true
visible = false
-z_index = 90
+z_index = 102
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -53,17 +55,8 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 1
-[node name="BackToShopButton" type="Button" parent="ShopCoolerPage"]
-unique_name_in_owner = true
-z_index = 110
-layout_mode = 0
-offset_left = 1052.0
-offset_top = 54.0
-offset_right = 1218.0
-offset_bottom = 104.0
-text = "back to shop"
-
[node name="ShopPanel" type="PanelContainer" parent="."]
+z_index = 101
unique_name_in_owner = true
layout_mode = 1
anchors_preset = 8
@@ -100,55 +93,68 @@ text = "fishing shop"
theme_override_font_sizes/font_size = 32
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
-[node name="CoinIcon" type="TextureRect" parent="ShopPanel/Margin/Layout/Header"]
-custom_minimum_size = Vector2(24, 24)
+[node name="BalanceDisplay" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Header"]
+custom_minimum_size = Vector2(0, 48)
layout_mode = 2
+size_flags_vertical = 4
+theme_override_constants/separation = 6
+alignment = 1
+
+[node name="CoinIcon" type="TextureRect" parent="ShopPanel/Margin/Layout/Header/BalanceDisplay"]
+custom_minimum_size = Vector2(26, 26)
+layout_mode = 2
+size_flags_vertical = 4
texture = ExtResource("5_coin")
expand_mode = 1
stretch_mode = 5
texture_filter = 1
-[node name="WalletLabel" type="Label" parent="ShopPanel/Margin/Layout/Header"]
+[node name="WalletLabel" type="Label" parent="ShopPanel/Margin/Layout/Header/BalanceDisplay"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 32)
layout_mode = 2
-text = "wallet: $0"
+size_flags_vertical = 4
+text = "0"
+vertical_alignment = 1
[node name="CloseButton" type="Button" parent="ShopPanel/Margin/Layout/Header"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(48, 48)
layout_mode = 2
-text = "close"
-custom_minimum_size = Vector2(104, 48)
+tooltip_text = "Close shop"
+flat = true
+icon = ExtResource("7_close")
+expand_icon = true
+icon_max_width = 40
-[node name="ModeTabs" type="HBoxContainer" parent="ShopPanel/Margin/Layout"]
-layout_mode = 2
-alignment = 1
-theme_override_constants/separation = 10
-
-[node name="BuyModeButton" type="Button" parent="ShopPanel/Margin/Layout/ModeTabs"]
-unique_name_in_owner = true
-custom_minimum_size = Vector2(180, 42)
-layout_mode = 2
-text = "buy gear & supplies"
-
-[node name="SellModeButton" type="Button" parent="ShopPanel/Margin/Layout/ModeTabs"]
-unique_name_in_owner = true
-custom_minimum_size = Vector2(180, 42)
-layout_mode = 2
-text = "sell fish"
-
-[node name="Feedback" type="Label" parent="ShopPanel/Margin/Layout"]
+[node name="Feedback" type="RichTextLabel" parent="ShopPanel/Margin/Layout"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 28)
layout_mode = 2
text = ""
-horizontal_alignment = 1
-theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
+bbcode_enabled = true
+fit_content = true
+scroll_active = false
+theme_override_colors/default_color = Color(1, 0.82, 0.4, 1)
+theme_override_font_sizes/normal_font_size = 20
+
+[node name="ShopTabBar" type="HBoxContainer" parent="."]
+unique_name_in_owner = true
+z_index = 100
+offset_left = 180.0
+offset_top = 26.0
+offset_right = 1100.0
+offset_bottom = 70.0
+alignment = 1
+theme_override_constants/separation = 6
[node name="Body" type="HBoxContainer" parent="ShopPanel/Margin/Layout"]
layout_mode = 2
size_flags_vertical = 3
-theme_override_constants/separation = 12
+theme_override_constants/separation = 0
[node name="Upgrades" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
+unique_name_in_owner = true
custom_minimum_size = Vector2(270, 0)
layout_mode = 2
size_flags_horizontal = 3
@@ -160,12 +166,14 @@ text = "fishing upgrades"
theme_override_font_sizes/font_size = 23
[node name="Supplies" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body"]
+unique_name_in_owner = true
custom_minimum_size = Vector2(210, 0)
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 6
-[node name="Title" type="Label" parent="ShopPanel/Margin/Layout/Body/Supplies"]
+[node name="StockTitle" type="Label" parent="ShopPanel/Margin/Layout/Body/Supplies"]
+unique_name_in_owner = true
layout_mode = 2
text = "shop stock"
theme_override_font_sizes/font_size = 23
@@ -181,164 +189,102 @@ layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 5
-[node name="ReelCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
+[node name="UpgradeScroll" type="ScrollContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
layout_mode = 2
+size_flags_vertical = 3
+horizontal_scroll_mode = 0
-[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard"]
-layout_mode = 2
-theme_override_constants/margin_left = 9
-theme_override_constants/margin_top = 7
-theme_override_constants/margin_right = 9
-theme_override_constants/margin_bottom = 7
-
-[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin"]
-layout_mode = 2
-theme_override_constants/separation = 9
-
-[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
-custom_minimum_size = Vector2(44, 44)
-layout_mode = 2
-texture = ExtResource("3_reel")
-expand_mode = 1
-stretch_mode = 5
-texture_filter = 1
-
-[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
+[node name="UpgradeGrid" type="GridContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll"]
+unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
+theme_override_constants/h_separation = 20
+theme_override_constants/v_separation = 20
+columns = 3
-[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
+[node name="ReelTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
+custom_minimum_size = Vector2(144, 168)
layout_mode = 2
-text = "reel speed"
-theme_override_font_sizes/font_size = 22
+mouse_filter = 2
-[node name="ReelLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
+[node name="ReelPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile"]
+unique_name_in_owner = true
+offset_right = 144.0
+offset_bottom = 144.0
+tooltip_text = "reel speed"
+icon = ExtResource("3_reel")
+expand_icon = true
+icon_max_width = 128
+
+[node name="ReelPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile"]
+unique_name_in_owner = true
+z_index = 2
+offset_left = 22.0
+offset_top = 128.0
+offset_right = 122.0
+offset_bottom = 160.0
+mouse_filter = 2
+
+[node name="ReelCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/ReelTile/ReelPriceBubble" instance=ExtResource("8_currency")]
unique_name_in_owner = true
layout_mode = 2
-text = "level 0"
-theme_override_font_sizes/font_size = 18
+amount = 50
+icon_size = 24.0
-[node name="ReelEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
+[node name="BarrierTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
+custom_minimum_size = Vector2(144, 168)
+layout_mode = 2
+mouse_filter = 2
+
+[node name="BarrierPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile"]
+unique_name_in_owner = true
+offset_right = 144.0
+offset_bottom = 144.0
+tooltip_text = "rod power"
+icon = ExtResource("4_barrier")
+expand_icon = true
+icon_max_width = 128
+
+[node name="BarrierPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile"]
+unique_name_in_owner = true
+z_index = 2
+offset_left = 22.0
+offset_top = 128.0
+offset_right = 122.0
+offset_bottom = 160.0
+mouse_filter = 2
+
+[node name="BarrierCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/BarrierTile/BarrierPriceBubble" instance=ExtResource("8_currency")]
unique_name_in_owner = true
layout_mode = 2
-text = "1.00× → 1.10×"
-theme_override_font_sizes/font_size = 18
+amount = 100
+icon_size = 24.0
-[node name="ReelCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row/Data"]
+[node name="CoolerTile" type="Control" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid"]
+custom_minimum_size = Vector2(144, 168)
+layout_mode = 2
+mouse_filter = 2
+
+[node name="CoolerPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile"]
+unique_name_in_owner = true
+offset_right = 144.0
+offset_bottom = 144.0
+tooltip_text = "cooler capacity"
+icon = ExtResource("6_cooler")
+expand_icon = true
+icon_max_width = 128
+
+[node name="CoolerPriceBubble" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile"]
+unique_name_in_owner = true
+z_index = 2
+offset_left = 22.0
+offset_top = 128.0
+offset_right = 122.0
+offset_bottom = 160.0
+mouse_filter = 2
+
+[node name="CoolerCost" parent="ShopPanel/Margin/Layout/Body/Upgrades/UpgradeScroll/UpgradeGrid/CoolerTile/CoolerPriceBubble" instance=ExtResource("8_currency")]
unique_name_in_owner = true
layout_mode = 2
-text = "$50"
-theme_override_font_sizes/font_size = 18
-
-[node name="ReelPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/ReelCard/Margin/Row"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "purchase"
-
-[node name="BarrierCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
-layout_mode = 2
-
-[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard"]
-layout_mode = 2
-theme_override_constants/margin_left = 9
-theme_override_constants/margin_top = 7
-theme_override_constants/margin_right = 9
-theme_override_constants/margin_bottom = 7
-
-[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin"]
-layout_mode = 2
-theme_override_constants/separation = 9
-
-[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
-custom_minimum_size = Vector2(44, 44)
-layout_mode = 2
-texture = ExtResource("4_barrier")
-expand_mode = 1
-stretch_mode = 5
-texture_filter = 1
-
-[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
-layout_mode = 2
-size_flags_horizontal = 3
-
-[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
-layout_mode = 2
-text = "barrier power"
-theme_override_font_sizes/font_size = 22
-
-[node name="BarrierLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "level 0"
-theme_override_font_sizes/font_size = 18
-
-[node name="BarrierEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "1 damage → 2 damage"
-theme_override_font_sizes/font_size = 18
-
-[node name="BarrierCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "$100"
-theme_override_font_sizes/font_size = 18
-
-[node name="BarrierPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/BarrierCard/Margin/Row"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "purchase"
-
-[node name="CoolerCard" type="PanelContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades"]
-layout_mode = 2
-
-[node name="Margin" type="MarginContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard"]
-layout_mode = 2
-theme_override_constants/margin_left = 9
-theme_override_constants/margin_top = 7
-theme_override_constants/margin_right = 9
-theme_override_constants/margin_bottom = 7
-
-[node name="Row" type="HBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin"]
-layout_mode = 2
-theme_override_constants/separation = 9
-
-[node name="Icon" type="TextureRect" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
-custom_minimum_size = Vector2(44, 44)
-layout_mode = 2
-texture = ExtResource("6_cooler")
-expand_mode = 1
-stretch_mode = 5
-texture_filter = 1
-
-[node name="Data" type="VBoxContainer" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
-layout_mode = 2
-size_flags_horizontal = 3
-
-[node name="Name" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
-layout_mode = 2
-text = "cooler capacity"
-theme_override_font_sizes/font_size = 22
-
-[node name="CoolerLevel" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "level 0"
-theme_override_font_sizes/font_size = 18
-
-[node name="CoolerEffect" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "12 → 18 fish"
-theme_override_font_sizes/font_size = 18
-
-[node name="CoolerCost" type="Label" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row/Data"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "$75"
-theme_override_font_sizes/font_size = 18
-
-[node name="CoolerPurchase" type="Button" parent="ShopPanel/Margin/Layout/Body/Upgrades/CoolerCard/Margin/Row"]
-unique_name_in_owner = true
-layout_mode = 2
-text = "purchase"
+amount = 75
+icon_size = 24.0
diff --git a/ui/fonts/Seattle-Avenue-LICENSE.txt b/ui/fonts/Seattle-Avenue-LICENSE.txt
new file mode 100644
index 0000000..22cdbca
--- /dev/null
+++ b/ui/fonts/Seattle-Avenue-LICENSE.txt
@@ -0,0 +1,23 @@
+Seattle Avenue Regular
+Creator: JLH Fonts
+Status: Public domain — dedicated by the author/creator
+
+Source record retrieved 2026-08-12:
+https://www.publicdomainfiles.com/show_file.php?id=13486266913972
+
+The source page states that the file was dedicated to the public domain by the
+author/creator and may be freely reproduced, distributed, transmitted, used,
+modified, built upon, or otherwise exploited for commercial or noncommercial
+purposes.
+
+Additional longstanding attribution and public-domain listing:
+https://www.dafont.com/seattle-avenue.font
+
+Repository font file:
+ui/fonts/seattle_avenue.otf
+
+Repository font SHA-256:
+ee288a4a3c67a5339141bc08b14e7da84b7657d73ec1655c03869285c8af6324
+
+This record documents the published public-domain dedication and creator
+attribution. It does not impose additional restrictions on the font.
diff --git a/ui/game_theme.tres b/ui/game_theme.tres
index 7da4650..e21f90b 100644
--- a/ui/game_theme.tres
+++ b/ui/game_theme.tres
@@ -144,6 +144,17 @@ corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
+[sub_resource type="StyleBoxFlat" id="TooltipPanel"]
+content_margin_left = 12.0
+content_margin_top = 8.0
+content_margin_right = 12.0
+content_margin_bottom = 8.0
+bg_color = Color(0.031, 0.122, 0.169, 1)
+corner_radius_top_left = 10
+corner_radius_top_right = 10
+corner_radius_bottom_right = 10
+corner_radius_bottom_left = 10
+
[resource]
default_font = ExtResource("1_font")
default_font_size = 23
@@ -175,3 +186,6 @@ OptionButton/styles/hover = SubResource("ButtonHover")
OptionButton/styles/normal = SubResource("ButtonNormal")
OptionButton/styles/pressed = SubResource("ButtonPressed")
PanelContainer/styles/panel = SubResource("Panel")
+TooltipLabel/colors/font_color = Color(0.765, 0.875, 0.902, 1)
+TooltipLabel/font_sizes/font_size = 18
+TooltipPanel/styles/panel = SubResource("TooltipPanel")
diff --git a/ui/game_ui.gd b/ui/game_ui.gd
index 830f291..27db6e8 100644
--- a/ui/game_ui.gd
+++ b/ui/game_ui.gd
@@ -12,6 +12,7 @@ const PlayerMenuType = preload("res://ui/player_menu.gd")
const PlayerType = preload("res://player/player.gd")
const PlayerWalletType = preload("res://economy/player_wallet.gd")
const ItemCatalogType = preload("res://items/item_catalog.gd")
+const ItemDataType = preload("res://items/item_data.gd")
const PlayerBagType = preload("res://inventory/player_bag.gd")
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
const HotbarUIType = preload("res://ui/hotbar.gd")
@@ -57,6 +58,12 @@ const PlayerExperienceType = preload(
const UIReferencePresentationType = preload(
"res://ui/ui_reference_presentation.gd"
)
+const MAIN_BUBBLE_PROFILE: BubbleMenuProfile = preload(
+ "res://ui/components/bubble_menu/bubble_menu_profile.tres"
+)
+const ACTIVE_BAIT_EMPTY_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/x_dark.png"
+)
signal pixelation_settings_visibility_changed(is_visible: bool)
signal crisp_reset_focus_requested
@@ -84,7 +91,12 @@ const FISHING_PANEL_SHOWCASE_TOP_OFFSET: float = -174.0
const FISHING_PANEL_SHOWCASE_BOTTOM_OFFSET: float = -104.0
@onready var _status_label: Label = %StatusLabel
+@onready var _bite_prompt_button: Button = %BitePromptButton
@onready var _gameplay_transient_hud: Control = %GameplayTransientHUD
+@onready var _active_bait_indicator: Control = %ActiveBaitIndicator
+@onready var _active_bait_button: Button = %ActiveBaitButton
+@onready var _active_bait_quantity_badge: Panel = %ActiveBaitQuantityBadge
+@onready var _active_bait_quantity: Label = %ActiveBaitQuantity
@onready var _experience_presentation: Control = %ExperiencePresentation
@onready var _catch_track: Control = %CatchTrack
@onready var _green_catch_progress: ProgressBar = %GreenCatchProgress
@@ -101,15 +113,35 @@ const FISHING_PANEL_SHOWCASE_BOTTOM_OFFSET: float = -104.0
@onready var _experience_progress: ProgressBar = %ExperienceProgress
@onready var _experience_bubble: PanelContainer = %ExperienceBubble
@onready var _experience_bubble_label: Label = %ExperienceBubbleLabel
+const TypewriterRevealType = preload("res://ui/typewriter_reveal.gd")
+const AnimaleseVoiceType = preload("res://ui/animalese_voice.gd")
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
+const SHOP_ANIMALESE_VOICE_ID: String = "natural"
+const SHOP_ANIMALESE_BASE_PITCH: float = 1.08
+const SHOP_SPEECH_CHARACTERS_PER_SECOND: float = 28.0
+const SHOP_NPC_SPEECH_COOLDOWN_MILLISECONDS: int = 5000
+const ART_KIT_ITEM_ID: StringName = &"art_kit"
+
+
@onready var _canonical_stage: Control = %CanonicalStage
-@onready var _ui_root: Control = %UIRoot
@onready var _player_menu: PlayerMenuType = %PlayerMenu
@onready var _screen_fade: ScreenFade = %ScreenFade
@onready var _title_screen: TitleScreenType = %TitleScreen
@onready var _pause_menu: PauseMenuType = %PauseMenu
@onready var _hotbar_ui: HotbarUIType = %Hotbar
@onready var _fishing_shop: FishingShopType = %FishingShop
-@onready var _shop_prompt: PanelContainer = %ShopPrompt
+@onready var _shop_prompt: Control = %ShopPrompt
+@onready var _shop_prompt_bubble: PanelContainer = %ShopPromptBubble
+@onready var _shop_prompt_message: Label = %ShopPromptMessage
+@onready var _shop_prompt_key_badge: Panel = %ShopPromptKeyBadge
+@onready var _shop_prompt_key: Label = %ShopPromptKey
+@onready var _shop_prompt_pointer: Polygon2D = %ShopPromptPointer
+var _shop_animalese_voice: AnimaleseVoiceType
+var _shop_npc_player_in_range: bool = false
+var _shop_npc_spoken_for_current_visit: bool = false
+var _shop_npc_next_speech_msec: int = 0
@onready var _effect_status: Label = %EffectStatus
@onready var _chat_ui: ChatUIType = %ChatUI
@onready var _emote_radial_menu: EmoteRadialMenuType = %EmoteRadialMenu
@@ -129,8 +161,15 @@ const FISHING_PANEL_SHOWCASE_BOTTOM_OFFSET: float = -104.0
var _showcase_active: bool = false
var _player: PlayerType
+var _network_chat_service: NetworkChatService
+var _network_profile: NetworkProfilePreferences
+var _spawn_service: PlayerSpawnService
+var _bag: PlayerBagType
+var _hotbar: PlayerHotbarType
+var _item_catalog: ItemCatalogType
var _player_menu_open: bool = false
var _gameplay_ui_enabled: bool = false
+var _gameplay_hud_hidden: bool = false
var _fishing_spot: FishingSpotType
var _system_menu_open: bool = false
var _shop_open: bool = false
@@ -140,6 +179,7 @@ var _item_effects: PlayerItemEffectsType
var _main_shop_buyer: FishBuyerProfileType
var _shop_interaction: ShopInteractionType
var _surface_drawing: NetworkSurfaceDrawingService
+var _surface_drawing_hotbar_selected: bool = false
var _experience: PlayerExperienceType
var _experience_award_queue: Array[Dictionary] = []
var _experience_animation_active: bool = false
@@ -163,6 +203,9 @@ var _settings_manager: PlayerSettingsManagerType
func _ready() -> void:
+ _bite_prompt_button.pressed.connect(_on_bite_prompt_pressed)
+ _apply_active_bait_indicator_style()
+ _refresh_active_bait_indicator()
# Reward feedback must remain above full-screen canonical menus. Keeping the
# overlay as the final stage child makes that ownership explicit instead of
# relying on scene declaration order when another menu adds high-z children.
@@ -180,6 +223,18 @@ func _ready() -> void:
_hotbar_ui.presentation_transition_finished.connect(
_on_hotbar_presentation_transition_finished
)
+ _player_menu.controller_hotbar_placement_requested.connect(
+ _on_controller_hotbar_placement_requested
+ )
+ _player_menu.controller_hotbar_placement_ended.connect(
+ _on_controller_hotbar_placement_ended
+ )
+ _player_menu.controller_hotbar_management_requested.connect(
+ _on_controller_hotbar_management_requested
+ )
+ _player_menu.controller_hotbar_management_ended.connect(
+ _on_controller_hotbar_management_ended
+ )
_title_settings_panel.panel_visibility_changed.connect(
_on_settings_visibility_changed
)
@@ -226,6 +281,7 @@ func setup(
reservations: PlayerAssetReservationService,
network_profile_service: NetworkProfileService,
network_player_list: NetworkPlayerListService,
+ discovery: DiscoveryClient,
settings_manager: PlayerSettingsManagerType,
surface_drawing: NetworkSurfaceDrawingService,
art_unlocks: PlayerArtUnlocks,
@@ -236,10 +292,40 @@ func setup(
world_sun: DirectionalLight3D,
) -> void:
_player = player
+ _network_chat_service = network_chat_service
+ _network_profile = network_profile
+ _spawn_service = spawn_service
+ _bag = bag
+ _hotbar = hotbar
+ _item_catalog = item_catalog
_settings_manager = settings_manager
_fishing_spot = fishing_spot
_item_effects = item_effects
_experience = experience
+ if (
+ _player != null
+ and not _player.active_bait_changed.is_connected(
+ _on_hud_active_bait_changed
+ )
+ ):
+ _player.active_bait_changed.connect(_on_hud_active_bait_changed)
+ if (
+ _bag != null
+ and not _bag.contents_changed.is_connected(
+ _on_hud_bait_inventory_changed
+ )
+ ):
+ _bag.contents_changed.connect(_on_hud_bait_inventory_changed)
+ _refresh_active_bait_indicator()
+ if (
+ _network_chat_service != null
+ and not _network_chat_service.character_call_received.is_connected(
+ _on_character_call_received
+ )
+ ):
+ _network_chat_service.character_call_received.connect(
+ _on_character_call_received
+ )
if (
_experience != null
and not _experience.experience_awarded.is_connected(
@@ -249,7 +335,7 @@ func setup(
_experience.experience_awarded.connect(_on_experience_awarded)
_chat_ui.setup(
network_chat_service, network_session, spawn_service, player,
- fishing_spot, settings_manager, world_time, world_weather
+ fishing_spot, settings_manager, world_time, world_weather, item_effects
)
_title_settings_panel.setup_network_profile(
network_profile, network_session
@@ -258,9 +344,9 @@ func setup(
network_profile, network_session
)
fishing_spot.status_changed.connect(_on_fishing_status_changed)
+ fishing_spot.bite_prompt_changed.connect(_on_bite_prompt_changed)
fishing_spot.catch_display_changed.connect(_on_catch_display_changed)
fishing_spot.showcase_changed.connect(_on_showcase_changed)
- fishing_spot.art_ui_toggle_requested.connect(_toggle_surface_drawing)
_player_menu.menu_visibility_changed.connect(
_on_player_menu_visibility_changed
)
@@ -291,6 +377,7 @@ func setup(
reservations,
network_profile_service,
network_player_list,
+ discovery,
player_jobs,
world_time,
world_environment,
@@ -320,6 +407,7 @@ func setup(
network_shop_service,
)
_fishing_shop.menu_visibility_changed.connect(_on_shop_visibility_changed)
+ _fishing_shop.menu_exit_started.connect(_on_shop_exit_started)
_fishing_shop.sell_fish_requested.connect(_on_shop_sell_fish_requested)
_fishing_shop.shop_cooler_return_requested.connect(
_on_shop_cooler_return_requested
@@ -345,21 +433,26 @@ func _input(event: InputEvent) -> void:
if _handle_controller_chat_controls(event):
get_viewport().set_input_as_handled()
return
+ if (
+ event.is_action_pressed("toggle_hud")
+ and not (event is InputEventKey and event.echo)
+ and _can_toggle_gameplay_hud()
+ ):
+ set_gameplay_hud_hidden(not _gameplay_hud_hidden)
+ get_viewport().set_input_as_handled()
+ return
if (
_surface_drawing_toolbar != null
and _surface_drawing_toolbar.owns_pointer_event(event)
):
return
- var drawing_can_open: bool = (
- _gameplay_ui_enabled
- and not _system_menu_open
- and not _player_menu_open
- and not _shop_open
- and not _chat_input_open
- and not _showcase_active
- and _fishing_spot != null
- and _fishing_spot.can_use_surface_drawing()
- )
+ if event.is_action_pressed("character_call") and _can_use_character_call():
+ _network_chat_service.send_local_character_call(
+ _network_profile.call_id
+ )
+ get_viewport().set_input_as_handled()
+ return
+ var drawing_can_open: bool = _can_surface_drawing_be_active()
if (
_surface_drawing != null
and _surface_drawing.handle_input(
@@ -418,6 +511,52 @@ func _input(event: InputEvent) -> void:
get_viewport().set_input_as_handled()
+func _can_use_character_call() -> bool:
+ return (
+ _gameplay_ui_enabled
+ and not _system_menu_open
+ and not _player_menu_open
+ and not _shop_open
+ and not _chat_input_open
+ and not _showcase_active
+ and not _virtual_mouse_active
+ and _network_chat_service != null
+ and _network_profile != null
+ )
+
+
+func _on_character_call_received(
+ peer_id: int,
+ call_id: String,
+ pitch_scale: float,
+) -> void:
+ if _spawn_service == null:
+ return
+ var avatar: PlayerType = _spawn_service.get_avatar(peer_id)
+ if avatar == null:
+ return
+ avatar.play_character_call_visual()
+ var audio_path: String = VoiceProfilesType.call_audio_path(call_id)
+ if not ResourceLoader.exists(audio_path, "AudioStream"):
+ return
+ var stream: AudioStream = load(audio_path) as AudioStream
+ if stream == null:
+ return
+ var call_player := AudioStreamPlayer3D.new()
+ call_player.name = "CharacterCall"
+ call_player.bus = &"SFX"
+ call_player.stream = stream
+ call_player.pitch_scale = pitch_scale
+ call_player.max_distance = 28.0
+ call_player.unit_size = 4.0
+ call_player.position = (
+ Vector3.UP * 1.25 * avatar.get_character_visual_scale()
+ )
+ avatar.add_child(call_player)
+ call_player.finished.connect(call_player.queue_free)
+ call_player.play()
+
+
func _handle_controller_chat_controls(event: InputEvent) -> bool:
var button_event: InputEventJoypadButton = event as InputEventJoypadButton
if (
@@ -459,7 +598,7 @@ func _handle_controller_chat_controls(event: InputEvent) -> bool:
_chat_ui.toggle_chat()
return true
if focus_pressed:
- _chat_ui.toggle_focus()
+ _chat_ui.refocus_gameplay()
return true
if accept_pressed:
return _chat_ui.request_virtual_keyboard()
@@ -486,9 +625,14 @@ func _on_quick_action_selected(action_id: StringName) -> void:
&"online":
_player_menu.open_section(PlayerMenuType.Section.PLAYERS)
&"paint":
- _toggle_surface_drawing()
+ _select_art_kit_hotbar_slot()
&"chat":
_chat_ui.open_chat()
+ &"freecam":
+ if _player != null:
+ _player.toggle_free_camera()
+ &"hud":
+ set_gameplay_hud_hidden(not _gameplay_hud_hidden)
func _handle_virtual_mouse_input(event: InputEvent) -> bool:
@@ -972,13 +1116,44 @@ static func get_virtual_mouse_window_bounds(window_size: Vector2) -> Rect2:
return Rect2(cursor_margin, bounds_size)
-func _toggle_surface_drawing() -> void:
+func _select_art_kit_hotbar_slot() -> void:
+ if _hotbar == null:
+ return
+ for slot_index: int in range(PlayerHotbarType.SLOT_COUNT):
+ if _hotbar.get_item_id(slot_index) == ART_KIT_ITEM_ID:
+ _hotbar.select_slot(slot_index)
+ return
+
+
+func set_surface_drawing_hotbar_selected(is_selected: bool) -> void:
+ _surface_drawing_hotbar_selected = is_selected
+ _refresh_surface_drawing_activation()
+
+
+func _refresh_surface_drawing_activation() -> void:
if _surface_drawing == null:
return
- if _surface_drawing.is_active():
- _surface_drawing.deactivate()
- elif _surface_drawing.can_activate():
+ var should_be_active: bool = _can_surface_drawing_be_active()
+ if should_be_active and not _surface_drawing.is_active():
_surface_drawing.activate(_drawing_pointer_window_position())
+ elif not should_be_active and _surface_drawing.is_active():
+ _surface_drawing.deactivate()
+
+
+func _can_surface_drawing_be_active() -> bool:
+ return (
+ _surface_drawing_hotbar_selected
+ and _gameplay_ui_enabled
+ and not _system_menu_open
+ and not _player_menu_open
+ and not _shop_open
+ and not _chat_input_open
+ and not _showcase_active
+ and _fishing_spot != null
+ and _fishing_spot.can_use_surface_drawing()
+ and _surface_drawing != null
+ and _surface_drawing.can_activate()
+ )
func _drawing_pointer_window_position() -> Vector2:
@@ -1174,10 +1349,107 @@ func get_pause_menu() -> PauseMenuType:
return _pause_menu
+func _apply_active_bait_indicator_style() -> void:
+ var normal_style: StyleBoxFlat = MAIN_BUBBLE_PROFILE.make_normal_style()
+ var hover_style: StyleBoxFlat = MAIN_BUBBLE_PROFILE.make_hover_style()
+ var pressed_style: StyleBoxFlat = MAIN_BUBBLE_PROFILE.make_pressed_style()
+ var disabled_style: StyleBoxFlat = MAIN_BUBBLE_PROFILE.make_disabled_style()
+ for style: StyleBoxFlat in [
+ normal_style,
+ hover_style,
+ pressed_style,
+ disabled_style,
+ ]:
+ style.set_corner_radius_all(36)
+ style.content_margin_left = 13.5
+ style.content_margin_top = 13.5
+ style.content_margin_right = 13.5
+ style.content_margin_bottom = 13.5
+ _active_bait_button.add_theme_stylebox_override("normal", normal_style)
+ _active_bait_button.add_theme_stylebox_override("hover", hover_style)
+ _active_bait_button.add_theme_stylebox_override("focus", hover_style)
+ _active_bait_button.add_theme_stylebox_override("pressed", pressed_style)
+ _active_bait_button.add_theme_stylebox_override("disabled", disabled_style)
+ for state: StringName in [
+ &"icon_normal_color",
+ &"icon_hover_color",
+ &"icon_focus_color",
+ &"icon_pressed_color",
+ ]:
+ _active_bait_button.add_theme_color_override(state, Color.WHITE)
+ var badge_style := StyleBoxFlat.new()
+ badge_style.bg_color = Color("0b5558")
+ badge_style.set_corner_radius_all(12)
+ badge_style.anti_aliasing = false
+ _active_bait_quantity_badge.add_theme_stylebox_override(
+ "panel",
+ badge_style,
+ )
+
+
+func _refresh_active_bait_indicator() -> void:
+ _refresh_active_bait_indicator_visibility()
+ if not is_node_ready():
+ return
+ var item: ItemDataType
+ if (
+ _player != null
+ and _item_catalog != null
+ and not _player.active_bait_id.is_empty()
+ ):
+ item = _item_catalog.get_item_by_id(_player.active_bait_id)
+ var has_active_bait: bool = item != null and item.is_bait()
+ _active_bait_button.icon = (
+ item.icon
+ if has_active_bait and item.icon != null
+ else ACTIVE_BAIT_EMPTY_ICON
+ )
+ _active_bait_quantity_badge.visible = has_active_bait
+ if not has_active_bait:
+ _active_bait_button.tooltip_text = "no bait selected"
+ return
+ var quantity: int = (
+ _bag.get_quantity(item.item_id)
+ if _bag != null
+ else 0
+ )
+ _active_bait_quantity.text = str(quantity)
+ _active_bait_quantity.add_theme_font_size_override(
+ "font_size",
+ 13 if quantity >= 100 else 15,
+ )
+ _active_bait_button.tooltip_text = "%s ×%d" % [
+ item.display_name,
+ quantity,
+ ]
+
+
+func _on_hud_active_bait_changed(_item_id: StringName) -> void:
+ _refresh_active_bait_indicator()
+
+
+func _refresh_active_bait_indicator_visibility() -> void:
+ _active_bait_indicator.visible = (
+ _gameplay_ui_enabled
+ and not _gameplay_hud_hidden
+ and not _system_menu_open
+ and not _player_menu_open
+ and not _shop_open
+ )
+
+
+func _on_hud_bait_inventory_changed() -> void:
+ _refresh_active_bait_indicator()
+
+
func set_gameplay_ui_enabled(enabled: bool) -> void:
_gameplay_ui_enabled = enabled
- _gameplay_transient_hud.visible = enabled and not _player_menu_open
- _experience_presentation.visible = enabled
+ if not enabled:
+ _gameplay_hud_hidden = false
+ _refresh_active_bait_indicator_visibility()
+ if enabled:
+ _try_start_shop_npc_speech()
+ _refresh_gameplay_hud_visibility()
_refresh_chat_availability()
if not enabled:
_end_virtual_mouse()
@@ -1206,12 +1478,54 @@ func set_gameplay_ui_enabled(enabled: bool) -> void:
_hotbar_ui.set_gameplay_input_enabled(true)
_refresh_fishing_panel_visibility()
call_deferred("_start_next_experience_animation")
+ _refresh_surface_drawing_activation()
+
+
+func set_gameplay_hud_hidden(hidden: bool) -> void:
+ _gameplay_hud_hidden = hidden
+ if _quick_radial_menu != null:
+ _quick_radial_menu.set_hud_hidden(hidden)
+ _refresh_gameplay_hud_visibility()
+ _refresh_active_bait_indicator_visibility()
+ _refresh_hotbar_visibility()
+ _refresh_chat_availability()
+
+
+func is_gameplay_hud_hidden() -> bool:
+ return _gameplay_hud_hidden
+
+
+func _can_toggle_gameplay_hud() -> bool:
+ return (
+ _gameplay_ui_enabled
+ and not _system_menu_open
+ and not _player_menu_open
+ and not _shop_open
+ and not _chat_input_open
+ and not _showcase_active
+ and not _emote_radial_menu.is_open()
+ and not _quick_radial_menu.is_open()
+ )
+
+
+func _refresh_gameplay_hud_visibility() -> void:
+ var show_world_hud: bool = (
+ _gameplay_ui_enabled
+ and not _gameplay_hud_hidden
+ and not _system_menu_open
+ and not _player_menu_open
+ and not _shop_open
+ )
+ _gameplay_transient_hud.visible = show_world_hud
+ _experience_presentation.visible = (
+ _gameplay_ui_enabled and not _gameplay_hud_hidden
+ )
func set_system_menu_open(is_open: bool) -> void:
_system_menu_open = is_open
- if is_open and _surface_drawing != null:
- _surface_drawing.deactivate()
+ _refresh_surface_drawing_activation()
+ _refresh_gameplay_hud_visibility()
_refresh_chat_availability()
_refresh_hotbar_visibility()
_hotbar_ui.set_gameplay_input_enabled(
@@ -1231,14 +1545,149 @@ func get_fishing_shop() -> FishingShopType:
return _fishing_shop
-func set_shop_prompt_visible(is_visible: bool) -> void:
+func set_shop_prompt_visible(
+ requested_visible: bool,
+ world_anchor: Vector3 = Vector3(0.0, INF, 0.0),
+) -> void:
+ _apply_shop_prompt_style()
_shop_prompt.visible = (
- is_visible
+ requested_visible
and _gameplay_ui_enabled
and not _system_menu_open
and not _player_menu_open
and not _shop_open
)
+ if _shop_prompt.visible:
+ if world_anchor.is_finite():
+ _position_shop_prompt(world_anchor)
+
+
+func set_shop_npc_player_in_range(in_range: bool) -> void:
+ if _shop_npc_player_in_range == in_range:
+ return
+ _shop_npc_player_in_range = in_range
+ if not in_range:
+ _shop_npc_spoken_for_current_visit = false
+ return
+ _try_start_shop_npc_speech()
+
+
+func _try_start_shop_npc_speech() -> void:
+ if (
+ not _shop_npc_player_in_range
+ or _shop_npc_spoken_for_current_visit
+ or not _gameplay_ui_enabled
+ ):
+ return
+ _shop_npc_spoken_for_current_visit = true
+ var now_msec: int = Time.get_ticks_msec()
+ if now_msec < _shop_npc_next_speech_msec:
+ return
+ _shop_npc_next_speech_msec = (
+ now_msec + SHOP_NPC_SPEECH_COOLDOWN_MILLISECONDS
+ )
+ _ensure_shop_animalese_voice()
+ TypewriterRevealType.start(
+ _shop_prompt_message,
+ SHOP_SPEECH_CHARACTERS_PER_SECOND,
+ )
+ _shop_animalese_voice.speak_text(
+ _shop_prompt_message,
+ _shop_prompt_message.text,
+ "shopkeeper",
+ SHOP_ANIMALESE_VOICE_ID,
+ SHOP_SPEECH_CHARACTERS_PER_SECOND,
+ )
+
+
+func _ensure_shop_animalese_voice() -> void:
+ if _shop_animalese_voice != null:
+ return
+ _shop_animalese_voice = AnimaleseVoiceType.new()
+ _shop_animalese_voice.name = "ShopAnimaleseVoice"
+ _shop_animalese_voice.base_pitch = SHOP_ANIMALESE_BASE_PITCH
+ add_child(_shop_animalese_voice)
+
+
+func _apply_shop_prompt_style() -> void:
+ if _shop_prompt.has_meta(&"shop_prompt_styled"):
+ return
+ _shop_prompt.set_meta(&"shop_prompt_styled", true)
+ var bubble_style := StyleBoxFlat.new()
+ bubble_style.bg_color = Color(UtilityPageStyle.OCEAN_PANEL_MID, 0.96)
+ bubble_style.set_border_width_all(0)
+ bubble_style.set_corner_radius_all(12)
+ bubble_style.anti_aliasing = false
+ _shop_prompt_bubble.add_theme_stylebox_override("panel", bubble_style)
+ var badge_style := StyleBoxFlat.new()
+ badge_style.bg_color = Color("0b5558")
+ badge_style.set_border_width_all(0)
+ badge_style.set_corner_radius_all(12)
+ badge_style.anti_aliasing = false
+ _shop_prompt_key_badge.add_theme_stylebox_override("panel", badge_style)
+ for label: Label in [_shop_prompt_message, _shop_prompt_key]:
+ label.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
+ label.add_theme_color_override(
+ "font_color",
+ UtilityPageStyle.OCEAN_TEXT_PRIMARY,
+ )
+ _shop_prompt_pointer.color = Color(
+ UtilityPageStyle.OCEAN_PANEL_MID,
+ 0.96,
+ )
+
+
+func _position_shop_prompt(world_anchor: Vector3) -> void:
+ if _player == null:
+ _shop_prompt.hide()
+ return
+ var camera: Camera3D = _player.get_gameplay_camera()
+ if camera == null or camera.is_position_behind(world_anchor):
+ _shop_prompt.hide()
+ return
+ var camera_viewport_size := camera.get_viewport().get_visible_rect().size
+ var ui_viewport_size: Vector2 = _canonical_stage.size
+ if camera_viewport_size.x <= 0.0 or camera_viewport_size.y <= 0.0:
+ _shop_prompt.hide()
+ return
+ var screen_position := (
+ camera.unproject_position(world_anchor)
+ * ui_viewport_size
+ / camera_viewport_size
+ )
+ if (
+ screen_position.x < -80.0
+ or screen_position.x > ui_viewport_size.x + 80.0
+ or screen_position.y < -80.0
+ or screen_position.y > ui_viewport_size.y + 80.0
+ ):
+ _shop_prompt.hide()
+ return
+ var pointer_height := 10.0
+ var desired := screen_position - Vector2(
+ _shop_prompt.size.x * 0.5,
+ _shop_prompt.size.y + pointer_height,
+ )
+ _shop_prompt.position = Vector2(
+ clampf(
+ desired.x,
+ 8.0,
+ ui_viewport_size.x - _shop_prompt.size.x - 8.0,
+ ),
+ clampf(
+ desired.y,
+ 8.0,
+ ui_viewport_size.y - _shop_prompt.size.y - pointer_height - 8.0,
+ ),
+ )
+ _shop_prompt_pointer.position = Vector2(
+ clampf(
+ screen_position.x - _shop_prompt.position.x,
+ 20.0,
+ _shop_prompt.size.x - 20.0,
+ ),
+ _shop_prompt.size.y - 1.0,
+ )
func get_screen_fade() -> ScreenFade:
@@ -1319,6 +1768,7 @@ func _refresh_fishing_panel_visibility() -> void:
var has_content: bool = (
not _status_label.text.strip_edges().is_empty()
or not _showcase_details.text.strip_edges().is_empty()
+ or _bite_prompt_button.visible
)
_fishing_panel.visible = (
_gameplay_ui_enabled
@@ -1326,6 +1776,16 @@ func _refresh_fishing_panel_visibility() -> void:
)
+func _on_bite_prompt_changed(prompt_visible: bool) -> void:
+ _bite_prompt_button.visible = prompt_visible
+ _refresh_fishing_panel_visibility()
+
+
+func _on_bite_prompt_pressed() -> void:
+ if _fishing_spot != null:
+ _fishing_spot.confirm_pending_bite()
+
+
func _on_catch_display_changed(
progress: float,
chase_progress: float,
@@ -1333,10 +1793,10 @@ func _on_catch_display_changed(
barrier_health: PackedInt32Array,
_barrier_max_health: PackedInt32Array,
active_barrier_index: int,
- visible: bool,
+ encounter_requested_visible: bool,
) -> void:
var encounter_visible: bool = (
- visible
+ encounter_requested_visible
and _fishing_spot != null
and _fishing_spot.is_fighting()
)
@@ -1417,10 +1877,11 @@ func _on_showcase_changed(
rarity_name: String,
weight_lb: float,
quality: int,
- visible: bool,
+ showcase_visible: bool,
) -> void:
- _showcase_active = visible
- if not visible:
+ _showcase_active = showcase_visible
+ _refresh_surface_drawing_activation()
+ if not showcase_visible:
_set_fishing_panel_showcase_position(false)
_showcase_details.text = ""
_showcase_details.visible = false
@@ -1661,9 +2122,8 @@ func _on_player_menu_visibility_changed(is_open: bool) -> void:
_player_menu_open = is_open
if is_open:
_end_virtual_mouse()
- if is_open and _surface_drawing != null:
- _surface_drawing.deactivate()
- _gameplay_transient_hud.visible = _gameplay_ui_enabled and not is_open
+ _refresh_surface_drawing_activation()
+ _refresh_gameplay_hud_visibility()
if is_open:
_hotbar_ui.set_drag_enabled(false)
_hotbar_ui.set_presentation_visible(false, false)
@@ -1706,13 +2166,20 @@ func _on_player_menu_exit_started() -> void:
player_menu_backdrop_visibility_changed.emit(false)
+func _on_shop_exit_started() -> void:
+ if not _shop_open:
+ return
+ shop_backdrop_visibility_changed.emit(false)
+
+
func _on_shop_visibility_changed(is_open: bool) -> void:
_shop_open = is_open
- if is_open and _surface_drawing != null:
- _surface_drawing.deactivate()
- shop_backdrop_visibility_changed.emit(is_open)
+ _refresh_surface_drawing_activation()
+ if is_open:
+ shop_backdrop_visibility_changed.emit(true)
if not is_open and _player_menu.is_shop_cooler_mounted():
_player_menu.unmount_shop_cooler()
+ _refresh_gameplay_hud_visibility()
_refresh_chat_availability()
_refresh_hotbar_visibility()
_hotbar_ui.set_gameplay_input_enabled(
@@ -1780,11 +2247,53 @@ func _on_inventory_hotbar_context_changed(show_hotbar: bool) -> void:
_refresh_hotbar_visibility()
+func _on_controller_hotbar_placement_requested(
+ assignment_kind: PlayerHotbarType.AssignmentKind,
+ identity: StringName,
+ initial_slot: int,
+) -> void:
+ _player_menu_hotbar_visible = true
+ _hotbar_ui.set_player_menu_context(true)
+ _hotbar_ui.set_drag_enabled(false)
+ _hotbar_ui.set_presentation_visible(true, false)
+ _hotbar_ui.begin_controller_placement(
+ assignment_kind,
+ identity,
+ initial_slot,
+ )
+
+
+func _on_controller_hotbar_placement_ended() -> void:
+ _hotbar_ui.end_controller_placement()
+ _hotbar_ui.set_drag_enabled(
+ _player_menu_open
+ and _player_menu_hotbar_visible
+ and not _system_menu_open
+ )
+
+
+func _on_controller_hotbar_management_requested(initial_slot: int) -> void:
+ _player_menu_hotbar_visible = true
+ _hotbar_ui.set_player_menu_context(true)
+ _hotbar_ui.set_drag_enabled(false)
+ _hotbar_ui.set_presentation_visible(true, false)
+ _hotbar_ui.begin_controller_management(initial_slot)
+
+
+func _on_controller_hotbar_management_ended() -> void:
+ _hotbar_ui.end_controller_management()
+ _hotbar_ui.set_drag_enabled(
+ _player_menu_open
+ and _player_menu_hotbar_visible
+ and not _system_menu_open
+ )
+
+
func _on_hotbar_presentation_transition_finished(
- is_visible: bool,
+ presentation_visible: bool,
) -> void:
_hotbar_ui.set_drag_enabled(
- is_visible
+ presentation_visible
and _player_menu_open
and _player_menu_hotbar_visible
and not _system_menu_open
@@ -1794,6 +2303,10 @@ func _on_hotbar_presentation_transition_finished(
func _refresh_hotbar_visibility() -> void:
_hotbar_ui.set_presentation_visible(
_gameplay_ui_enabled
+ and (
+ not _gameplay_hud_hidden
+ or (_player_menu_open and _player_menu_hotbar_visible)
+ )
and not _system_menu_open
and not _shop_open
and (
@@ -1805,6 +2318,7 @@ func _refresh_hotbar_visibility() -> void:
func _emit_interactive_pointer_ui_changed() -> void:
+ _refresh_active_bait_indicator_visibility()
interactive_pointer_ui_changed.emit(
_system_menu_open or _player_menu_open or _shop_open or _chat_input_open
)
@@ -1812,8 +2326,8 @@ func _emit_interactive_pointer_ui_changed() -> void:
func _on_chat_text_entry_ownership_changed(active: bool) -> void:
_chat_input_open = active
- if active and _surface_drawing != null:
- _surface_drawing.deactivate()
+ _refresh_surface_drawing_activation()
+ _refresh_chat_availability()
_emit_interactive_pointer_ui_changed()
@@ -1827,4 +2341,5 @@ func _refresh_chat_availability() -> void:
and not _shop_open
)
_chat_ui.set_available(chat_available)
+ _chat_ui.set_hud_hidden(_gameplay_hud_hidden and not _chat_input_open)
passive_pointer_ui_changed.emit(chat_available)
diff --git a/ui/game_ui.tscn b/ui/game_ui.tscn
index 0726da0..1cbbc4a 100644
--- a/ui/game_ui.tscn
+++ b/ui/game_ui.tscn
@@ -82,6 +82,71 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
+[node name="ActiveBaitIndicator" type="Control" parent="UIRoot/CanonicalStage/GameplayTransientHUD"]
+unique_name_in_owner = true
+z_index = 54
+layout_mode = 1
+anchors_preset = 3
+anchor_left = 1.0
+anchor_top = 1.0
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = -88.0
+offset_top = -88.0
+offset_right = -16.0
+offset_bottom = -16.0
+grow_horizontal = 0
+grow_vertical = 0
+mouse_filter = 2
+theme = ExtResource("3_theme")
+
+[node name="ActiveBaitButton" type="Button" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ActiveBaitIndicator"]
+unique_name_in_owner = true
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+focus_mode = 0
+texture_filter = 1
+expand_icon = true
+alignment = 1
+icon_alignment = 1
+vertical_icon_alignment = 1
+
+[node name="ActiveBaitQuantityBadge" type="Panel" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ActiveBaitIndicator"]
+unique_name_in_owner = true
+z_index = 2
+layout_mode = 1
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -27.0
+offset_top = 3.0
+offset_right = -3.0
+offset_bottom = 27.0
+grow_horizontal = 0
+mouse_filter = 2
+
+[node name="ActiveBaitQuantity" type="Label" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ActiveBaitIndicator/ActiveBaitQuantityBadge"]
+unique_name_in_owner = true
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = 1.0
+offset_right = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+theme_override_colors/font_color = Color(0.905882, 0.960784, 0.956863, 1)
+theme_override_font_sizes/font_size = 15
+text = "0"
+horizontal_alignment = 1
+vertical_alignment = 1
+
[node name="ExperiencePresentation" type="Control" parent="UIRoot/CanonicalStage"]
unique_name_in_owner = true
z_index = 200
@@ -214,6 +279,16 @@ text = ""
horizontal_alignment = 1
theme_override_font_sizes/font_size = 16
+[node name="BitePromptButton" type="Button" parent="UIRoot/CanonicalStage/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
+unique_name_in_owner = true
+visible = false
+custom_minimum_size = Vector2(0, 42)
+layout_mode = 2
+focus_mode = 0
+mouse_default_cursor_shape = 2
+text = "you got a bite!"
+theme_override_font_sizes/font_size = 22
+
[node name="ShowcaseDetails" type="Label" parent="UIRoot/CanonicalStage/GameplayTransientHUD/FishingPanel/MarginContainer/VBoxContainer"]
unique_name_in_owner = true
visible = false
@@ -333,35 +408,67 @@ unique_name_in_owner = true
[node name="QuickRadialMenu" parent="UIRoot/CanonicalStage" instance=ExtResource("12_quick")]
unique_name_in_owner = true
-[node name="ShopPrompt" type="PanelContainer" parent="UIRoot/CanonicalStage/GameplayTransientHUD"]
+[node name="ShopPrompt" type="Control" parent="UIRoot/CanonicalStage/GameplayTransientHUD"]
unique_name_in_owner = true
visible = false
z_index = 55
-anchors_preset = 7
-anchor_left = 0.5
-anchor_top = 1.0
-anchor_right = 0.5
-anchor_bottom = 1.0
-offset_left = -150.0
-offset_top = -284.0
-offset_right = 150.0
-offset_bottom = -246.0
-grow_horizontal = 2
-grow_vertical = 0
+offset_right = 300.0
+offset_bottom = 72.0
mouse_filter = 2
theme = ExtResource("3_theme")
-[node name="Margin" type="MarginContainer" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt"]
+[node name="ShopPromptBubble" type="PanelContainer" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt"]
+unique_name_in_owner = true
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+
+[node name="Margin" type="MarginContainer" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt/ShopPromptBubble"]
layout_mode = 2
theme_override_constants/margin_left = 12
-theme_override_constants/margin_top = 7
+theme_override_constants/margin_top = 8
theme_override_constants/margin_right = 12
-theme_override_constants/margin_bottom = 7
+theme_override_constants/margin_bottom = 8
-[node name="Label" type="Label" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt/Margin"]
+[node name="ShopPromptMessage" type="Label" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt/ShopPromptBubble/Margin"]
+unique_name_in_owner = true
layout_mode = 2
-text = "press e to open fishing shop"
+theme_override_font_sizes/font_size = 18
+text = "Hey, if you've got any fish I've got cash! OwO"
horizontal_alignment = 1
+vertical_alignment = 1
+autowrap_mode = 2
+
+[node name="ShopPromptKeyBadge" type="Panel" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt"]
+unique_name_in_owner = true
+layout_mode = 0
+offset_left = 282.0
+offset_top = -8.0
+offset_right = 306.0
+offset_bottom = 16.0
+mouse_filter = 2
+
+[node name="ShopPromptKey" type="Label" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt/ShopPromptKeyBadge"]
+unique_name_in_owner = true
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 2
+theme_override_font_sizes/font_size = 15
+text = "E"
+horizontal_alignment = 1
+vertical_alignment = 1
+
+[node name="ShopPromptPointer" type="Polygon2D" parent="UIRoot/CanonicalStage/GameplayTransientHUD/ShopPrompt"]
+unique_name_in_owner = true
+polygon = PackedVector2Array(-8, 0, 8, 0, 0, 10)
[node name="FishingShop" parent="UIRoot/CanonicalStage" instance=ExtResource("8_shop")]
unique_name_in_owner = true
diff --git a/ui/hotbar.gd b/ui/hotbar.gd
index fa10df0..fe26cc6 100644
--- a/ui/hotbar.gd
+++ b/ui/hotbar.gd
@@ -4,6 +4,7 @@ extends Control
signal presentation_transition_finished(is_visible: bool)
const ItemCatalogType = preload("res://items/item_catalog.gd")
+const ItemDataType = preload("res://items/item_data.gd")
const PlayerBagType = preload("res://inventory/player_bag.gd")
const PlayerHotbarType = preload("res://inventory/player_hotbar.gd")
const FishInventoryType = preload("res://inventory/fish_inventory.gd")
@@ -16,9 +17,9 @@ const FishingSpotType = preload("res://fishing/fishing_spot.gd")
const DESKTOP_REFERENCE_SIZE := Vector2(1280.0, 720.0)
const COMPACT_REFERENCE_SIZE := Vector2(640.0, 480.0)
-const HOTBAR_PRESENTATION_SCALE: float = 0.60
-const HOTBAR_CANONICAL_POSITION := Vector2(256.0, 288.0)
-const HOTBAR_MENU_POSITION := Vector2(80.0, 198.0)
+const HOTBAR_PRESENTATION_SCALE: float = 0.80
+const HOTBAR_CANONICAL_POSITION := Vector2.ZERO
+const HOTBAR_MENU_POSITION := Vector2(-136.0, -90.0)
const HOTBAR_GAMEPLAY_Z_INDEX: int = 35
# PlayerMenu is z=30 and its authored inventory panels are relative z=50.
const HOTBAR_MENU_Z_INDEX: int = 90
@@ -41,6 +42,13 @@ var _item_name_suppressed: bool = false
var _motion_elapsed: float = 0.0
var _compact_layout: bool = false
var _player_menu_context: bool = false
+var _controller_placement_active: bool = false
+var _controller_management_active: bool = false
+var _controller_placement_kind: PlayerHotbarType.AssignmentKind = (
+ PlayerHotbarType.AssignmentKind.EMPTY
+)
+var _controller_placement_identity: StringName
+var _controller_placement_texture: Texture2D
var _visibility_tween: Tween
var _visibility_generation: int = 0
@@ -99,14 +107,115 @@ func set_drag_enabled(enabled: bool) -> void:
_hide_item_name()
+func begin_controller_placement(
+ assignment_kind: PlayerHotbarType.AssignmentKind,
+ identity: StringName,
+ initial_slot: int,
+) -> void:
+ if _hotbar == null or identity.is_empty():
+ return
+ _controller_placement_active = true
+ _controller_placement_kind = assignment_kind
+ _controller_placement_identity = identity
+ _controller_placement_texture = _resolve_controller_placement_texture()
+ var slot_count: int = _slots.size()
+ for index: int in slot_count:
+ var slot: BubbleHotbarSlotType = _slots[index]
+ slot.focus_mode = Control.FOCUS_ALL
+ slot.focus_neighbor_left = slot.get_path_to(
+ _slots[wrapi(index - 1, 0, slot_count)]
+ )
+ slot.focus_neighbor_right = slot.get_path_to(
+ _slots[wrapi(index + 1, 0, slot_count)]
+ )
+ slot.focus_neighbor_top = slot.get_path_to(slot)
+ slot.focus_neighbor_bottom = slot.get_path_to(slot)
+ var target_index: int = clampi(initial_slot, 0, slot_count - 1)
+ _hotbar.select_slot(target_index)
+ _refresh_controller_placement_preview()
+ _slots[target_index].call_deferred("grab_focus")
+
+
+func end_controller_placement() -> void:
+ if not _controller_placement_active:
+ return
+ _controller_placement_active = false
+ _controller_placement_kind = PlayerHotbarType.AssignmentKind.EMPTY
+ _controller_placement_identity = StringName()
+ _controller_placement_texture = null
+ for slot: BubbleHotbarSlotType in _slots:
+ slot.focus_mode = Control.FOCUS_NONE
+ slot.set_controller_placement_preview(false, null)
+ _show_selected_item_briefly()
+
+
+func begin_controller_management(initial_slot: int) -> void:
+ if _hotbar == null or _slots.is_empty():
+ return
+ _controller_management_active = true
+ var slot_count: int = _slots.size()
+ for index: int in slot_count:
+ var slot: BubbleHotbarSlotType = _slots[index]
+ slot.focus_mode = Control.FOCUS_ALL
+ slot.focus_neighbor_left = slot.get_path_to(
+ _slots[wrapi(index - 1, 0, slot_count)]
+ )
+ slot.focus_neighbor_right = slot.get_path_to(
+ _slots[wrapi(index + 1, 0, slot_count)]
+ )
+ slot.focus_neighbor_top = slot.get_path_to(slot)
+ slot.focus_neighbor_bottom = slot.get_path_to(slot)
+ var target_index: int = clampi(initial_slot, 0, slot_count - 1)
+ _hotbar.select_slot(target_index)
+ _slots[target_index].call_deferred("grab_focus")
+
+
+func end_controller_management() -> void:
+ if not _controller_management_active:
+ return
+ _controller_management_active = false
+ for slot: BubbleHotbarSlotType in _slots:
+ slot.focus_mode = Control.FOCUS_NONE
+ _show_selected_item_briefly()
+
+
+func _resolve_controller_placement_texture() -> Texture2D:
+ if (
+ _controller_placement_kind == PlayerHotbarType.AssignmentKind.FISH
+ and _fish_inventory != null
+ ):
+ var fish_catch: FishCatchType = _fish_inventory.get_catch_by_id(
+ _controller_placement_identity
+ )
+ return fish_catch.fish.display_texture if fish_catch != null else null
+ if (
+ _controller_placement_kind == PlayerHotbarType.AssignmentKind.ITEM
+ and _catalog != null
+ ):
+ var item: ItemDataType = _catalog.get_item_by_id(
+ _controller_placement_identity
+ )
+ return item.icon if item != null else null
+ return null
+
+
+func _refresh_controller_placement_preview() -> void:
+ if not _controller_placement_active or _hotbar == null:
+ return
+ var target_index: int = _hotbar.get_selected_slot()
+ for slot: BubbleHotbarSlotType in _slots:
+ slot.set_controller_placement_preview(
+ slot.slot_index == target_index,
+ _controller_placement_texture,
+ )
+
+
func set_player_menu_context(enabled: bool) -> void:
if _player_menu_context == enabled:
return
_player_menu_context = enabled
z_index = HOTBAR_MENU_Z_INDEX if enabled else HOTBAR_GAMEPLAY_Z_INDEX
- _presentation_scale_root.position = (
- HOTBAR_MENU_POSITION if enabled else HOTBAR_CANONICAL_POSITION
- )
+ _presentation_scale_root.position = _presentation_position()
func set_presentation_visible(
@@ -230,6 +339,9 @@ func _collect_slots() -> void:
slot.item_hover_ended.connect(_on_slot_item_hover_ended)
slot.item_drag_started.connect(_on_slot_drag_started)
slot.item_drag_finished.connect(_on_slot_drag_finished)
+ slot.focus_entered.connect(
+ _on_controller_slot_focused.bind(slot.slot_index)
+ )
_slots.append(slot)
_slots.sort_custom(
func(
@@ -249,11 +361,7 @@ func _apply_layout() -> void:
_presentation_scale_root.scale = (
Vector2.ONE * HOTBAR_PRESENTATION_SCALE
)
- _presentation_scale_root.position = (
- HOTBAR_MENU_POSITION
- if _player_menu_context
- else HOTBAR_CANONICAL_POSITION
- )
+ _presentation_scale_root.position = _presentation_position()
var field_size := (
Vector2(580.0, 82.0)
if _compact_layout
@@ -268,6 +376,21 @@ func _apply_layout() -> void:
slot.apply_layout(_compact_layout)
+func _presentation_position() -> Vector2:
+ var scaled_size: Vector2 = (
+ DESKTOP_REFERENCE_SIZE * HOTBAR_PRESENTATION_SCALE
+ )
+ var bottom_centered_offset := Vector2(
+ (DESKTOP_REFERENCE_SIZE.x - scaled_size.x) * 0.5,
+ DESKTOP_REFERENCE_SIZE.y - scaled_size.y,
+ )
+ return bottom_centered_offset + (
+ HOTBAR_MENU_POSITION
+ if _player_menu_context
+ else HOTBAR_CANONICAL_POSITION
+ )
+
+
func _refresh() -> void:
for slot: BubbleHotbarSlotType in _slots:
slot.refresh()
@@ -278,10 +401,24 @@ func _on_selected_slot_changed(
_item_id: StringName,
) -> void:
_refresh()
+ if _controller_placement_active:
+ _refresh_controller_placement_preview()
+ return
if _hovered_slot_index < 0:
_show_selected_item_briefly()
+func _on_controller_slot_focused(slot_index: int) -> void:
+ if (
+ not (_controller_placement_active or _controller_management_active)
+ or _hotbar == null
+ ):
+ return
+ _hotbar.select_slot(slot_index)
+ if _controller_placement_active:
+ _refresh_controller_placement_preview()
+
+
func _on_slot_item_hovered(
slot_index: int,
item_id: StringName,
diff --git a/ui/icons/pictograms/arrow_dark_down_full.png b/ui/icons/pictograms/arrow_dark_down_full.png
new file mode 100644
index 0000000..e2bdb9e
Binary files /dev/null and b/ui/icons/pictograms/arrow_dark_down_full.png differ
diff --git a/ui/icons/pictograms/arrow_dark_down_full.png.import b/ui/icons/pictograms/arrow_dark_down_full.png.import
new file mode 100644
index 0000000..2e7726a
--- /dev/null
+++ b/ui/icons/pictograms/arrow_dark_down_full.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d4aah3j5brkij"
+path="res://.godot/imported/arrow_dark_down_full.png-0e7bb59c41a81c0bd02261d6a7b319ef.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_dark_down_full.png"
+dest_files=["res://.godot/imported/arrow_dark_down_full.png-0e7bb59c41a81c0bd02261d6a7b319ef.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/arrow_dark_up_full.png b/ui/icons/pictograms/arrow_dark_up_full.png
new file mode 100644
index 0000000..a9d2f3d
Binary files /dev/null and b/ui/icons/pictograms/arrow_dark_up_full.png differ
diff --git a/ui/icons/pictograms/arrow_dark_up_full.png.import b/ui/icons/pictograms/arrow_dark_up_full.png.import
new file mode 100644
index 0000000..1cbc9ac
--- /dev/null
+++ b/ui/icons/pictograms/arrow_dark_up_full.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://d34x31jx5p5ll"
+path="res://.godot/imported/arrow_dark_up_full.png-907f3a8653cf6bf8b6ba95ad31b18e0d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_dark_up_full.png"
+dest_files=["res://.godot/imported/arrow_dark_up_full.png-907f3a8653cf6bf8b6ba95ad31b18e0d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/arrow_light_down_more.png b/ui/icons/pictograms/arrow_light_down_more.png
new file mode 100644
index 0000000..3c7683d
Binary files /dev/null and b/ui/icons/pictograms/arrow_light_down_more.png differ
diff --git a/ui/icons/pictograms/arrow_light_down_more.png.import b/ui/icons/pictograms/arrow_light_down_more.png.import
new file mode 100644
index 0000000..47a516b
--- /dev/null
+++ b/ui/icons/pictograms/arrow_light_down_more.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cmc7sguttrl2o"
+path="res://.godot/imported/arrow_light_down_more.png-a02fb5d09f2022507ddb6c06e3f22732.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_light_down_more.png"
+dest_files=["res://.godot/imported/arrow_light_down_more.png-a02fb5d09f2022507ddb6c06e3f22732.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/arrow_light_left_more.png b/ui/icons/pictograms/arrow_light_left_more.png
new file mode 100644
index 0000000..361adab
Binary files /dev/null and b/ui/icons/pictograms/arrow_light_left_more.png differ
diff --git a/ui/icons/pictograms/arrow_light_left_more.png.import b/ui/icons/pictograms/arrow_light_left_more.png.import
new file mode 100644
index 0000000..07d5a52
--- /dev/null
+++ b/ui/icons/pictograms/arrow_light_left_more.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b3lx64prsccyk"
+path="res://.godot/imported/arrow_light_left_more.png-a92f7c96dbcafd9c1b2cb612e94fef44.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_light_left_more.png"
+dest_files=["res://.godot/imported/arrow_light_left_more.png-a92f7c96dbcafd9c1b2cb612e94fef44.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/arrow_light_right_more.png b/ui/icons/pictograms/arrow_light_right_more.png
new file mode 100644
index 0000000..39d6148
Binary files /dev/null and b/ui/icons/pictograms/arrow_light_right_more.png differ
diff --git a/ui/icons/pictograms/arrow_light_right_more.png.import b/ui/icons/pictograms/arrow_light_right_more.png.import
new file mode 100644
index 0000000..e0a72ff
--- /dev/null
+++ b/ui/icons/pictograms/arrow_light_right_more.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cedstrt57et53"
+path="res://.godot/imported/arrow_light_right_more.png-56d3df49848f9fee268e5c4b6c279828.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_light_right_more.png"
+dest_files=["res://.godot/imported/arrow_light_right_more.png-56d3df49848f9fee268e5c4b6c279828.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/arrow_light_up_more.png b/ui/icons/pictograms/arrow_light_up_more.png
new file mode 100644
index 0000000..03e3817
Binary files /dev/null and b/ui/icons/pictograms/arrow_light_up_more.png differ
diff --git a/ui/icons/pictograms/arrow_light_up_more.png.import b/ui/icons/pictograms/arrow_light_up_more.png.import
new file mode 100644
index 0000000..60f266f
--- /dev/null
+++ b/ui/icons/pictograms/arrow_light_up_more.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dqu71oklbvofk"
+path="res://.godot/imported/arrow_light_up_more.png-7e8472cc9f410835ab24173229e09c9b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/arrow_light_up_more.png"
+dest_files=["res://.godot/imported/arrow_light_up_more.png-7e8472cc9f410835ab24173229e09c9b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/check_mark_dark.png b/ui/icons/pictograms/check_mark_dark.png
new file mode 100644
index 0000000..f1c398b
Binary files /dev/null and b/ui/icons/pictograms/check_mark_dark.png differ
diff --git a/ui/icons/pictograms/check_mark_dark.png.import b/ui/icons/pictograms/check_mark_dark.png.import
new file mode 100644
index 0000000..d2fa9e9
--- /dev/null
+++ b/ui/icons/pictograms/check_mark_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://3x5tryb721th"
+path="res://.godot/imported/check_mark_dark.png-d9abda15f33a6a8f8c29c5f148cda086.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/check_mark_dark.png"
+dest_files=["res://.godot/imported/check_mark_dark.png-d9abda15f33a6a8f8c29c5f148cda086.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/check_mark_light.png b/ui/icons/pictograms/check_mark_light.png
new file mode 100644
index 0000000..da0af7c
Binary files /dev/null and b/ui/icons/pictograms/check_mark_light.png differ
diff --git a/ui/icons/pictograms/check_mark_light.png.import b/ui/icons/pictograms/check_mark_light.png.import
new file mode 100644
index 0000000..c3af542
--- /dev/null
+++ b/ui/icons/pictograms/check_mark_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dtibvrik7ug0j"
+path="res://.godot/imported/check_mark_light.png-83417416d6580b7b5eb41987b7af5ccf.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/check_mark_light.png"
+dest_files=["res://.godot/imported/check_mark_light.png-83417416d6580b7b5eb41987b7af5ccf.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/online_dark.png b/ui/icons/pictograms/online_dark.png
new file mode 100644
index 0000000..1c643ca
Binary files /dev/null and b/ui/icons/pictograms/online_dark.png differ
diff --git a/ui/icons/pictograms/online_dark.png.import b/ui/icons/pictograms/online_dark.png.import
new file mode 100644
index 0000000..f917f4c
--- /dev/null
+++ b/ui/icons/pictograms/online_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://uxkgiwd7py03"
+path="res://.godot/imported/online_dark.png-081123db8a385b31ed626b7c95b20c3c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/online_dark.png"
+dest_files=["res://.godot/imported/online_dark.png-081123db8a385b31ed626b7c95b20c3c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/save_dark.png b/ui/icons/pictograms/save_dark.png
new file mode 100644
index 0000000..382648b
Binary files /dev/null and b/ui/icons/pictograms/save_dark.png differ
diff --git a/ui/icons/pictograms/save_dark.png.import b/ui/icons/pictograms/save_dark.png.import
new file mode 100644
index 0000000..33bbad8
--- /dev/null
+++ b/ui/icons/pictograms/save_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b71gds1q8ny61"
+path="res://.godot/imported/save_dark.png-6dbadbfe5b8057ede23f77629e3c1226.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/save_dark.png"
+dest_files=["res://.godot/imported/save_dark.png-6dbadbfe5b8057ede23f77629e3c1226.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/settings_dark.png b/ui/icons/pictograms/settings_dark.png
new file mode 100644
index 0000000..3777b39
Binary files /dev/null and b/ui/icons/pictograms/settings_dark.png differ
diff --git a/ui/icons/pictograms/settings_dark.png.import b/ui/icons/pictograms/settings_dark.png.import
new file mode 100644
index 0000000..fabd6c0
--- /dev/null
+++ b/ui/icons/pictograms/settings_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ul28xl5qed55"
+path="res://.godot/imported/settings_dark.png-7196550e6c3f5a58c1402ab0ccc9c9d0.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/settings_dark.png"
+dest_files=["res://.godot/imported/settings_dark.png-7196550e6c3f5a58c1402ab0ccc9c9d0.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/undo_dark.png b/ui/icons/pictograms/undo_dark.png
new file mode 100644
index 0000000..e26b579
Binary files /dev/null and b/ui/icons/pictograms/undo_dark.png differ
diff --git a/ui/icons/pictograms/undo_dark.png.import b/ui/icons/pictograms/undo_dark.png.import
new file mode 100644
index 0000000..e1cce7e
--- /dev/null
+++ b/ui/icons/pictograms/undo_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://deux1h722j33u"
+path="res://.godot/imported/undo_dark.png-652c08d6b38e19b70b66927ecfc6222c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/undo_dark.png"
+dest_files=["res://.godot/imported/undo_dark.png-652c08d6b38e19b70b66927ecfc6222c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/undo_light.png b/ui/icons/pictograms/undo_light.png
new file mode 100644
index 0000000..aa04205
Binary files /dev/null and b/ui/icons/pictograms/undo_light.png differ
diff --git a/ui/icons/pictograms/undo_light.png.import b/ui/icons/pictograms/undo_light.png.import
new file mode 100644
index 0000000..161faa8
--- /dev/null
+++ b/ui/icons/pictograms/undo_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://1qr5t7gx1eag"
+path="res://.godot/imported/undo_light.png-83dd161fb13faa93326dee6cb01e205c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/undo_light.png"
+dest_files=["res://.godot/imported/undo_light.png-83dd161fb13faa93326dee6cb01e205c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/x_dark.png b/ui/icons/pictograms/x_dark.png
new file mode 100644
index 0000000..d4d183d
Binary files /dev/null and b/ui/icons/pictograms/x_dark.png differ
diff --git a/ui/icons/pictograms/x_dark.png.import b/ui/icons/pictograms/x_dark.png.import
new file mode 100644
index 0000000..36797cb
--- /dev/null
+++ b/ui/icons/pictograms/x_dark.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cg8vi6sxnpl2t"
+path="res://.godot/imported/x_dark.png-5430cf57b7772f059ee1fac9842c6898.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/x_dark.png"
+dest_files=["res://.godot/imported/x_dark.png-5430cf57b7772f059ee1fac9842c6898.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/pictograms/x_light.png b/ui/icons/pictograms/x_light.png
new file mode 100644
index 0000000..68b3180
Binary files /dev/null and b/ui/icons/pictograms/x_light.png differ
diff --git a/ui/icons/pictograms/x_light.png.import b/ui/icons/pictograms/x_light.png.import
new file mode 100644
index 0000000..36b30e7
--- /dev/null
+++ b/ui/icons/pictograms/x_light.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cvb228ypykqaq"
+path="res://.godot/imported/x_light.png-b099203c17614ca6f36b269beabfcbab.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/pictograms/x_light.png"
+dest_files=["res://.godot/imported/x_light.png-b099203c17614ca6f36b269beabfcbab.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/close.png b/ui/icons/tab_menu/close.png
new file mode 100644
index 0000000..010564e
Binary files /dev/null and b/ui/icons/tab_menu/close.png differ
diff --git a/ui/icons/tab_menu/close.png.import b/ui/icons/tab_menu/close.png.import
new file mode 100644
index 0000000..97421f4
--- /dev/null
+++ b/ui/icons/tab_menu/close.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://i0di6nvyfgwq"
+path="res://.godot/imported/close.png-f592282e3f82852ae6231bd14b5fd099.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/close.png"
+dest_files=["res://.godot/imported/close.png-f592282e3f82852ae6231bd14b5fd099.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/fishnet_simple.png b/ui/icons/tab_menu/fishnet_simple.png
new file mode 100644
index 0000000..00f9a75
Binary files /dev/null and b/ui/icons/tab_menu/fishnet_simple.png differ
diff --git a/ui/icons/tab_menu/fishnet_simple.png.import b/ui/icons/tab_menu/fishnet_simple.png.import
new file mode 100644
index 0000000..3264172
--- /dev/null
+++ b/ui/icons/tab_menu/fishnet_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cjbdqfnyvsnm4"
+path="res://.godot/imported/fishnet_simple.png-4b51afc915ee521b23b2244427b7733d.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/fishnet_simple.png"
+dest_files=["res://.godot/imported/fishnet_simple.png-4b51afc915ee521b23b2244427b7733d.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/inventory_simple.png b/ui/icons/tab_menu/inventory_simple.png
new file mode 100644
index 0000000..94a41ef
Binary files /dev/null and b/ui/icons/tab_menu/inventory_simple.png differ
diff --git a/ui/icons/tab_menu/inventory_simple.png.import b/ui/icons/tab_menu/inventory_simple.png.import
new file mode 100644
index 0000000..c570770
--- /dev/null
+++ b/ui/icons/tab_menu/inventory_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cjcbjd5edx5x4"
+path="res://.godot/imported/inventory_simple.png-f67cb963aaeb25aa9f4d1cdb8c686d15.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/inventory_simple.png"
+dest_files=["res://.godot/imported/inventory_simple.png-f67cb963aaeb25aa9f4d1cdb8c686d15.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/logbook_icon_simple.png b/ui/icons/tab_menu/logbook_icon_simple.png
new file mode 100644
index 0000000..0455fdd
Binary files /dev/null and b/ui/icons/tab_menu/logbook_icon_simple.png differ
diff --git a/ui/icons/tab_menu/logbook_icon_simple.png.import b/ui/icons/tab_menu/logbook_icon_simple.png.import
new file mode 100644
index 0000000..3b6c86a
--- /dev/null
+++ b/ui/icons/tab_menu/logbook_icon_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bbrhsth08pra"
+path="res://.godot/imported/logbook_icon_simple.png-19496dc73a295b5d47ceff1151998546.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/logbook_icon_simple.png"
+dest_files=["res://.godot/imported/logbook_icon_simple.png-19496dc73a295b5d47ceff1151998546.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/mail_simple.png b/ui/icons/tab_menu/mail_simple.png
new file mode 100644
index 0000000..0c5569c
Binary files /dev/null and b/ui/icons/tab_menu/mail_simple.png differ
diff --git a/ui/icons/tab_menu/mail_simple.png.import b/ui/icons/tab_menu/mail_simple.png.import
new file mode 100644
index 0000000..6ed128e
--- /dev/null
+++ b/ui/icons/tab_menu/mail_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://jlg77ov0slgm"
+path="res://.godot/imported/mail_simple.png-95f4049e43a5076c9411faf284044682.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/mail_simple.png"
+dest_files=["res://.godot/imported/mail_simple.png-95f4049e43a5076c9411faf284044682.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/online_simple.png b/ui/icons/tab_menu/online_simple.png
new file mode 100644
index 0000000..e332392
Binary files /dev/null and b/ui/icons/tab_menu/online_simple.png differ
diff --git a/ui/icons/tab_menu/online_simple.png.import b/ui/icons/tab_menu/online_simple.png.import
new file mode 100644
index 0000000..51ea7ab
--- /dev/null
+++ b/ui/icons/tab_menu/online_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://br2rfqaxc0sjl"
+path="res://.godot/imported/online_simple.png-8eb00fe8c066e2f85263d1fb847d94d6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/online_simple.png"
+dest_files=["res://.godot/imported/online_simple.png-8eb00fe8c066e2f85263d1fb847d94d6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/tab_menu/profile_simple.png b/ui/icons/tab_menu/profile_simple.png
new file mode 100644
index 0000000..de13f5d
Binary files /dev/null and b/ui/icons/tab_menu/profile_simple.png differ
diff --git a/ui/icons/tab_menu/profile_simple.png.import b/ui/icons/tab_menu/profile_simple.png.import
new file mode 100644
index 0000000..1a7ab07
--- /dev/null
+++ b/ui/icons/tab_menu/profile_simple.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cd08b16j75wep"
+path="res://.godot/imported/profile_simple.png-4d3096990c6fb1ca6619433b80d957a2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/tab_menu/profile_simple.png"
+dest_files=["res://.godot/imported/profile_simple.png-4d3096990c6fb1ca6619433b80d957a2.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/weather/weather_clear_day.png b/ui/icons/weather/weather_clear_day.png
new file mode 100644
index 0000000..266887d
Binary files /dev/null and b/ui/icons/weather/weather_clear_day.png differ
diff --git a/ui/icons/weather/weather_clear_day.png.import b/ui/icons/weather/weather_clear_day.png.import
new file mode 100644
index 0000000..175f21f
--- /dev/null
+++ b/ui/icons/weather/weather_clear_day.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ce6ge5yypnnpf"
+path="res://.godot/imported/weather_clear_day.png-1cd1140830664281637d5589a748ef58.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/weather/weather_clear_day.png"
+dest_files=["res://.godot/imported/weather_clear_day.png-1cd1140830664281637d5589a748ef58.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/weather/weather_clear_night_full.png b/ui/icons/weather/weather_clear_night_full.png
new file mode 100644
index 0000000..6263b34
Binary files /dev/null and b/ui/icons/weather/weather_clear_night_full.png differ
diff --git a/ui/icons/weather/weather_clear_night_full.png.import b/ui/icons/weather/weather_clear_night_full.png.import
new file mode 100644
index 0000000..b9cffaf
--- /dev/null
+++ b/ui/icons/weather/weather_clear_night_full.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://78l0keyrvuiw"
+path="res://.godot/imported/weather_clear_night_full.png-3640fcf886e9bd01942e21cc0212bc45.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/weather/weather_clear_night_full.png"
+dest_files=["res://.godot/imported/weather_clear_night_full.png-3640fcf886e9bd01942e21cc0212bc45.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/weather/weather_cloudy.png b/ui/icons/weather/weather_cloudy.png
new file mode 100644
index 0000000..0e96583
Binary files /dev/null and b/ui/icons/weather/weather_cloudy.png differ
diff --git a/ui/icons/weather/weather_cloudy.png.import b/ui/icons/weather/weather_cloudy.png.import
new file mode 100644
index 0000000..c74657d
--- /dev/null
+++ b/ui/icons/weather/weather_cloudy.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://b17frlbta1p7f"
+path="res://.godot/imported/weather_cloudy.png-c41e4d98007294310395f752b39ddaa6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/weather/weather_cloudy.png"
+dest_files=["res://.godot/imported/weather_cloudy.png-c41e4d98007294310395f752b39ddaa6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/weather/weather_fog.png b/ui/icons/weather/weather_fog.png
new file mode 100644
index 0000000..00e93b6
Binary files /dev/null and b/ui/icons/weather/weather_fog.png differ
diff --git a/ui/icons/weather/weather_fog.png.import b/ui/icons/weather/weather_fog.png.import
new file mode 100644
index 0000000..8887cfb
--- /dev/null
+++ b/ui/icons/weather/weather_fog.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://wpaj2l01upt6"
+path="res://.godot/imported/weather_fog.png-0fe4352261121bbcc8da10ebc1995663.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/weather/weather_fog.png"
+dest_files=["res://.godot/imported/weather_fog.png-0fe4352261121bbcc8da10ebc1995663.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/icons/weather/weather_rain.png b/ui/icons/weather/weather_rain.png
new file mode 100644
index 0000000..b3de517
Binary files /dev/null and b/ui/icons/weather/weather_rain.png differ
diff --git a/ui/icons/weather/weather_rain.png.import b/ui/icons/weather/weather_rain.png.import
new file mode 100644
index 0000000..af5d773
--- /dev/null
+++ b/ui/icons/weather/weather_rain.png.import
@@ -0,0 +1,40 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cfqvlqp3nrfok"
+path="res://.godot/imported/weather_rain.png-affbb7091de81103538e2740c5b2c762.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://ui/icons/weather/weather_rain.png"
+dest_files=["res://.godot/imported/weather_rain.png-affbb7091de81103538e2740c5b2c762.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/ui/logbook_page.gd b/ui/logbook_page.gd
index 115b791..ee63797 100644
--- a/ui/logbook_page.gd
+++ b/ui/logbook_page.gd
@@ -16,6 +16,9 @@ const InventoryNotepadType = preload(
const LogbookPortraitType = preload(
"res://ui/components/logbook_portrait.gd"
)
+const CurrencyPresentationType = preload(
+ "res://ui/currency_presentation.gd"
+)
const DETAIL_FADE_DURATION: float = 0.12
const CATEGORY_FADE_DURATION: float = UIMotion.UTILITY_EXIT_DURATION
@@ -23,9 +26,26 @@ const HANDWRITTEN_NUMERIC_SCALE: float = 0.8
const PORTRAIT_VIEW_MAX_SIZE := Vector2(860.0, 480.0)
const INK := Color("251b10")
const MUTED_INK := Color("6d5b45")
-const PAPER := Color("f2e6c9")
-const PAPER_DARK := Color("e8d7b4")
-const LOGBOOK_TAB_LEFT_INSET: float = 34.0
+const LOGBOOK_ARTWORK: Texture2D = preload(
+ "res://ui/assets/logbook/ui_logbook.png"
+)
+const SCROLL_UP_TEXTURE: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_dark_up_full.png"
+)
+const SCROLL_DOWN_TEXTURE: Texture2D = preload(
+ "res://ui/icons/pictograms/arrow_dark_down_full.png"
+)
+const LOGBOOK_ARTWORK_SOURCE_SIZE := Vector2(512.0, 247.0)
+const LEFT_PAGE_CONTENT_RECT := Rect2(56.0, 26.0, 190.0, 198.0)
+const RIGHT_PAGE_CONTENT_RECT := Rect2(267.0, 26.0, 210.0, 198.0)
+const LOGBOOK_TAB_LEFT_INSET: float = 122.0
+const PAGE_CONTENT_SCALE: float = 0.97
+const CATALOG_PORTRAIT_SIZE := Vector2(78.0, 36.0)
+const CATALOG_ENTRY_SIZE := Vector2(92.0, 92.0)
+const CATALOG_ROW_STEP: float = 98.0
+const CATALOG_SNAP_DELAY: float = 0.12
+const DETAIL_PORTRAIT_SIZE := Vector2(160.0, 88.0)
+const DETAIL_BOTTOM_INSET: float = 35.0
var _collection_log: CollectionLogType
var _inventory: FishInventoryType
@@ -41,10 +61,14 @@ var _detail_tween: Tween
var _category_generation: int = 0
var _category_tween: Tween
var _silhouette_material: ShaderMaterial
+var _snapping_catalog_scroll: bool = false
+var _catalog_scroll_snap_timer: Timer
var _category_tabs: Array[Button] = []
var _catalog_scroll: ScrollContainer
var _catalog_grid: GridContainer
+var _catalog_scroll_up_indicator: TextureRect
+var _catalog_scroll_down_indicator: TextureRect
var _empty_state: Label
var _detail_body: VBoxContainer
var _detail_portrait_button: Button
@@ -145,7 +169,7 @@ func _build_interface() -> void:
var outer := MarginContainer.new()
outer.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
outer.add_theme_constant_override("margin_left", 52)
- outer.add_theme_constant_override("margin_top", 116)
+ outer.add_theme_constant_override("margin_top", 85)
outer.add_theme_constant_override("margin_right", 52)
outer.add_theme_constant_override("margin_bottom", 18)
add_child(outer)
@@ -155,9 +179,8 @@ func _build_interface() -> void:
outer.add_child(stack)
var tabs := HBoxContainer.new()
- # The 26 px page corner plus 8 px clearance keeps the flange behind
- # the straight portion of the spread.
- tabs.position = Vector2(LOGBOOK_TAB_LEFT_INSET, 20.0)
+ # Align the first flange with the authored left paper edge.
+ tabs.position = Vector2(LOGBOOK_TAB_LEFT_INSET, 37.0)
tabs.size = Vector2(384.0, 38.0)
tabs.z_index = 10
tabs.mouse_filter = Control.MOUSE_FILTER_PASS
@@ -179,71 +202,206 @@ func _build_interface() -> void:
_category_tabs.append(tab)
_configure_category_focus()
- var book := HBoxContainer.new()
+ var book := Control.new()
book.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
book.offset_top = 50.0
book.z_index = 20
- book.add_theme_constant_override("separation", 12)
+ book.mouse_filter = Control.MOUSE_FILTER_IGNORE
stack.add_child(book)
- var left_page := PanelContainer.new()
- left_page.size_flags_horizontal = Control.SIZE_EXPAND_FILL
- left_page.size_flags_stretch_ratio = 1.12
- left_page.add_theme_stylebox_override(
- "panel", _paper_style(PAPER, true)
- )
+ var artwork := TextureRect.new()
+ artwork.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ artwork.texture = LOGBOOK_ARTWORK
+ artwork.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ artwork.stretch_mode = TextureRect.STRETCH_SCALE
+ artwork.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ artwork.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ book.add_child(artwork)
+
+ var left_page := Control.new()
+ left_page.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ _apply_artwork_rect(left_page, LEFT_PAGE_CONTENT_RECT)
book.add_child(left_page)
- var left_margin := MarginContainer.new()
- _set_margins(left_margin, 18, 16, 18, 16)
- left_page.add_child(left_margin)
var left_layout := VBoxContainer.new()
+ left_layout.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
left_layout.add_theme_constant_override("separation", 8)
- left_margin.add_child(left_layout)
- var heading := _label("catch catalog", 25)
- heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
- left_layout.add_child(heading)
+ left_page.add_child(left_layout)
+ _apply_page_content_scale(left_layout)
+ var scroll_indicator_top_lane := Control.new()
+ scroll_indicator_top_lane.custom_minimum_size.y = 20.0
+ scroll_indicator_top_lane.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ left_layout.add_child(scroll_indicator_top_lane)
_empty_state = _label("", 18)
_empty_state.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_empty_state.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_empty_state.size_flags_vertical = Control.SIZE_EXPAND_FILL
left_layout.add_child(_empty_state)
+ var catalog_scroll_margin := MarginContainer.new()
+ catalog_scroll_margin.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ catalog_scroll_margin.add_theme_constant_override("margin_left", 20)
+ left_layout.add_child(catalog_scroll_margin)
_catalog_scroll = ScrollContainer.new()
_catalog_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
_catalog_scroll.horizontal_scroll_mode = (
ScrollContainer.SCROLL_MODE_DISABLED
)
- left_layout.add_child(_catalog_scroll)
+ _catalog_scroll.scroll_vertical_custom_step = CATALOG_ROW_STEP
+ catalog_scroll_margin.add_child(_catalog_scroll)
_catalog_grid = GridContainer.new()
- _catalog_grid.columns = 5
+ _catalog_grid.columns = 4
_catalog_grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL
- _catalog_grid.add_theme_constant_override("h_separation", 8)
- _catalog_grid.add_theme_constant_override("v_separation", 8)
+ _catalog_grid.add_theme_constant_override("h_separation", 6)
+ _catalog_grid.add_theme_constant_override("v_separation", 6)
_catalog_scroll.add_child(_catalog_grid)
-
- var gutter := ColorRect.new()
- gutter.custom_minimum_size.x = 10
- gutter.color = Color("795f3f")
- gutter.mouse_filter = Control.MOUSE_FILTER_IGNORE
- book.add_child(gutter)
-
- var right_page := PanelContainer.new()
- right_page.size_flags_horizontal = Control.SIZE_EXPAND_FILL
- right_page.add_theme_stylebox_override(
- "panel", _paper_style(PAPER_DARK, false)
+ var scroll_indicator_bottom_lane := Control.new()
+ scroll_indicator_bottom_lane.custom_minimum_size.y = 32.0
+ scroll_indicator_bottom_lane.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ left_layout.add_child(scroll_indicator_bottom_lane)
+ _configure_catalog_scroll_bar()
+ _catalog_scroll_up_indicator = _make_scroll_indicator(
+ "CatalogScrollUpIndicator",
+ SCROLL_UP_TEXTURE,
+ true,
)
+ left_page.add_child(_catalog_scroll_up_indicator)
+ _catalog_scroll_down_indicator = _make_scroll_indicator(
+ "CatalogScrollDownIndicator",
+ SCROLL_DOWN_TEXTURE,
+ false,
+ )
+ left_page.add_child(_catalog_scroll_down_indicator)
+
+ var right_page := Control.new()
+ right_page.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ _apply_artwork_rect(right_page, RIGHT_PAGE_CONTENT_RECT)
book.add_child(right_page)
- var right_margin := MarginContainer.new()
- _set_margins(right_margin, 22, 16, 22, 16)
- right_page.add_child(right_margin)
_detail_body = VBoxContainer.new()
+ _detail_body.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_detail_body.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_detail_body.size_flags_vertical = Control.SIZE_EXPAND_FILL
_detail_body.add_theme_constant_override("separation", 16)
- right_margin.add_child(_detail_body)
+ right_page.add_child(_detail_body)
+ _apply_page_content_scale(_detail_body)
_show_no_selection()
_build_portrait_overlay()
+func _apply_artwork_rect(control: Control, source_rect: Rect2) -> void:
+ control.anchor_left = source_rect.position.x / LOGBOOK_ARTWORK_SOURCE_SIZE.x
+ control.anchor_top = source_rect.position.y / LOGBOOK_ARTWORK_SOURCE_SIZE.y
+ control.anchor_right = source_rect.end.x / LOGBOOK_ARTWORK_SOURCE_SIZE.x
+ control.anchor_bottom = source_rect.end.y / LOGBOOK_ARTWORK_SOURCE_SIZE.y
+ control.offset_left = 0.0
+ control.offset_top = 0.0
+ control.offset_right = 0.0
+ control.offset_bottom = 0.0
+
+
+func _apply_page_content_scale(control: Control) -> void:
+ control.scale = Vector2.ONE * PAGE_CONTENT_SCALE
+ control.resized.connect(_center_scaled_content.bind(control))
+ _center_scaled_content.call_deferred(control)
+
+
+func _center_scaled_content(control: Control) -> void:
+ if is_instance_valid(control):
+ control.pivot_offset = control.size * 0.5
+
+
+func _configure_catalog_scroll_bar() -> void:
+ _catalog_scroll_snap_timer = Timer.new()
+ _catalog_scroll_snap_timer.one_shot = true
+ _catalog_scroll_snap_timer.wait_time = CATALOG_SNAP_DELAY
+ _catalog_scroll_snap_timer.timeout.connect(_snap_catalog_scroll_to_row)
+ _catalog_scroll.add_child(_catalog_scroll_snap_timer)
+ var scroll_bar: VScrollBar = _catalog_scroll.get_v_scroll_bar()
+ scroll_bar.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ scroll_bar.focus_mode = Control.FOCUS_NONE
+ scroll_bar.self_modulate = Color.TRANSPARENT
+ scroll_bar.custom_minimum_size.x = 0.0
+ scroll_bar.add_theme_constant_override("scroll_size", 0)
+ var empty_style := StyleBoxEmpty.new()
+ for style_name: StringName in [
+ &"scroll",
+ &"scroll_focus",
+ &"grabber",
+ &"grabber_highlight",
+ &"grabber_pressed",
+ ]:
+ scroll_bar.add_theme_stylebox_override(style_name, empty_style)
+ scroll_bar.changed.connect(_refresh_catalog_scroll_indicators)
+ scroll_bar.value_changed.connect(_on_catalog_scroll_value_changed)
+
+
+func _make_scroll_indicator(
+ indicator_name: String,
+ indicator_texture: Texture2D,
+ at_top: bool,
+) -> TextureRect:
+ var indicator := TextureRect.new()
+ indicator.name = indicator_name
+ indicator.anchor_left = 0.5
+ indicator.anchor_right = 0.5
+ indicator.anchor_top = 0.0 if at_top else 1.0
+ indicator.anchor_bottom = indicator.anchor_top
+ indicator.offset_left = -14.0
+ indicator.offset_right = 14.0
+ indicator.offset_top = -8.0 if at_top else -35.0
+ indicator.offset_bottom = 20.0 if at_top else -7.0
+ indicator.z_index = 30
+ indicator.texture = indicator_texture
+ indicator.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ indicator.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ indicator.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ indicator.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ indicator.visible = false
+ return indicator
+
+
+func _on_catalog_scroll_value_changed(_value: float) -> void:
+ if _snapping_catalog_scroll:
+ return
+ _catalog_scroll_snap_timer.start()
+ _refresh_catalog_scroll_indicators()
+
+
+func _snap_catalog_scroll_to_row() -> void:
+ var scroll_bar: VScrollBar = _catalog_scroll.get_v_scroll_bar()
+ var value: float = scroll_bar.value
+ var maximum_scroll: float = scroll_bar.max_value - scroll_bar.page
+ var snapped_value: float = clampf(
+ roundf(value / CATALOG_ROW_STEP) * CATALOG_ROW_STEP,
+ scroll_bar.min_value,
+ maximum_scroll,
+ )
+ if not is_equal_approx(value, snapped_value):
+ _snapping_catalog_scroll = true
+ _catalog_scroll.scroll_vertical = roundi(snapped_value)
+ _snapping_catalog_scroll = false
+ _refresh_catalog_scroll_indicators()
+
+
+func _refresh_catalog_scroll_indicators() -> void:
+ if (
+ _catalog_scroll == null
+ or _catalog_scroll_up_indicator == null
+ or _catalog_scroll_down_indicator == null
+ ):
+ return
+ var scroll_bar: VScrollBar = _catalog_scroll.get_v_scroll_bar()
+ var maximum_scroll: float = scroll_bar.max_value - scroll_bar.page
+ var has_overflow: bool = (
+ _catalog_scroll.visible
+ and maximum_scroll > scroll_bar.min_value + 0.5
+ )
+ _catalog_scroll_up_indicator.visible = (
+ has_overflow and scroll_bar.value > scroll_bar.min_value + 0.5
+ )
+ _catalog_scroll_down_indicator.visible = (
+ has_overflow and scroll_bar.value < maximum_scroll - 0.5
+ )
+
+
func _refresh_catalog() -> void:
if not is_node_ready():
return
@@ -293,11 +451,13 @@ func _refresh_catalog() -> void:
_refresh_selection_styles()
_refresh_details(false)
set_interactive(_interactive)
+ _refresh_catalog_scroll_indicators.call_deferred()
func _make_entry(fish: FishDataType, discovered: bool) -> Button:
var entry := Button.new()
- entry.custom_minimum_size = Vector2(102, 102)
+ entry.set_meta(&"controller_focus_inversion_disabled", true)
+ entry.custom_minimum_size = CATALOG_ENTRY_SIZE
entry.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
entry.size_flags_vertical = Control.SIZE_SHRINK_CENTER
entry.toggle_mode = true
@@ -344,7 +504,7 @@ func _add_entry_content(
var portrait_view := LogbookPortraitType.new()
portrait_view.configure(
portrait,
- LogbookPortraitType.ENTRY_FRAME_SIZE,
+ CATALOG_PORTRAIT_SIZE,
_silhouette_material if unknown else null,
)
content.add_child(portrait_view)
@@ -495,10 +655,14 @@ func _refresh_details(animate: bool) -> void:
func _build_known_details(fish: FishDataType) -> void:
_clear_details()
var catalog_number: int = LogbookCatalog.catalog_number(fish.id)
+ var summary_margin := MarginContainer.new()
+ summary_margin.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ _set_margins(summary_margin, 40, 0, 40, 0)
+ _detail_body.add_child(summary_margin)
var summary_columns := HBoxContainer.new()
summary_columns.size_flags_horizontal = Control.SIZE_EXPAND_FILL
summary_columns.add_theme_constant_override("separation", 24)
- _detail_body.add_child(summary_columns)
+ summary_margin.add_child(summary_columns)
var portrait_column := VBoxContainer.new()
portrait_column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
@@ -510,12 +674,11 @@ func _build_known_details(fish: FishDataType) -> void:
portrait_column.add_child(title)
if fish.display_texture != null:
_detail_portrait_button = Button.new()
- _detail_portrait_button.custom_minimum_size = (
- LogbookPortraitType.DETAIL_FRAME_SIZE
- )
+ _detail_portrait_button.custom_minimum_size = DETAIL_PORTRAIT_SIZE
_detail_portrait_button.size_flags_horizontal = (
Control.SIZE_SHRINK_CENTER
)
+ _detail_portrait_button.clip_contents = true
_detail_portrait_button.tooltip_text = "View larger artwork"
_detail_portrait_button.accessibility_name = (
"View larger artwork for %s" % fish.display_name
@@ -545,7 +708,7 @@ func _build_known_details(fish: FishDataType) -> void:
var artwork := LogbookPortraitType.new()
artwork.configure(
fish.display_texture,
- LogbookPortraitType.DETAIL_FRAME_SIZE,
+ DETAIL_PORTRAIT_SIZE,
)
artwork_center.add_child(artwork)
@@ -562,11 +725,15 @@ func _build_known_details(fish: FishDataType) -> void:
facts_column.add_child(facts)
_detail_body.add_child(_build_quality_progress(fish.id))
+ var stats_anchor := VBoxContainer.new()
+ stats_anchor.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ stats_anchor.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ stats_anchor.alignment = BoxContainer.ALIGNMENT_END
+ _detail_body.add_child(stats_anchor)
var stats_columns := HBoxContainer.new()
stats_columns.size_flags_horizontal = Control.SIZE_EXPAND_FILL
- stats_columns.size_flags_vertical = Control.SIZE_EXPAND_FILL
stats_columns.add_theme_constant_override("separation", 28)
- _detail_body.add_child(stats_columns)
+ stats_anchor.add_child(stats_columns)
var left_stats := _make_stats_column()
var right_stats := _make_stats_column()
stats_columns.add_child(left_stats)
@@ -592,30 +759,33 @@ func _build_known_details(fish: FishDataType) -> void:
_add_detail_row(left_stats, "number caught", "unknown")
_add_detail_row(right_stats, "rarity", fish.get_rarity_name().to_lower())
_add_detail_row(right_stats, "time of day", _availability_text(fish))
- _add_detail_row(
+ _add_currency_detail_row(
right_stats,
"value range",
- "%d–%d fish coin" % [
- FishQualityType.apply_sale_value(
- fish.sell_value_min,
- FishQualityType.Tier.BORING,
- ),
- FishQualityType.apply_sale_value(
- fish.sell_value_max,
- FishQualityType.Tier.SHINY,
- ),
- ],
+ FishQualityType.apply_sale_value(
+ fish.sell_value_min,
+ FishQualityType.Tier.BORING,
+ ),
+ FishQualityType.apply_sale_value(
+ fish.sell_value_max,
+ FishQualityType.Tier.SHINY,
+ ),
)
_add_detail_row(
right_stats,
"number owned",
str(_inventory.get_count(fish.id) if _inventory != null else 0),
)
+ var bottom_inset := Control.new()
+ bottom_inset.custom_minimum_size.y = DETAIL_BOTTOM_INSET
+ bottom_inset.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ stats_anchor.add_child(bottom_inset)
func _build_quality_progress(fish_id: StringName) -> VBoxContainer:
var quality_section := VBoxContainer.new()
- quality_section.add_theme_constant_override("separation", 3)
+ quality_section.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ quality_section.add_theme_constant_override("separation", 6)
var discovered_count: int = 0
for quality: int in FishQualityType.TIER_COUNT:
if _collection_log.has_discovered_quality(fish_id, quality):
@@ -625,29 +795,36 @@ func _build_quality_progress(fish_id: StringName) -> VBoxContainer:
discovered_count,
FishQualityType.TIER_COUNT,
],
- 14,
+ 17,
)
heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
heading.add_theme_color_override("font_color", MUTED_INK)
quality_section.add_child(heading)
- var tiers := HBoxContainer.new()
- tiers.alignment = BoxContainer.ALIGNMENT_CENTER
- tiers.add_theme_constant_override("separation", 10)
+ var tiers := VBoxContainer.new()
+ tiers.add_theme_constant_override("separation", 6)
quality_section.add_child(tiers)
for quality: int in FishQualityType.TIER_COUNT:
+ var row: HBoxContainer
+ if quality % 2 == 0:
+ row = HBoxContainer.new()
+ row.alignment = BoxContainer.ALIGNMENT_CENTER
+ row.add_theme_constant_override("separation", 28)
+ tiers.add_child(row)
+ else:
+ row = tiers.get_child(tiers.get_child_count() - 1) as HBoxContainer
var discovered: bool = _collection_log.has_discovered_quality(
fish_id,
quality,
)
var tier := HBoxContainer.new()
tier.alignment = BoxContainer.ALIGNMENT_CENTER
- tier.add_theme_constant_override("separation", 3)
+ tier.add_theme_constant_override("separation", 5)
var quality_color: Color = UIPalette.get_quality_color(quality)
- var dot := _label("●" if discovered else "○", 13)
+ var dot := _label("●" if discovered else "○", 17)
dot.add_theme_color_override("font_color", quality_color)
dot.modulate.a = 1.0 if discovered else 0.48
tier.add_child(dot)
- var tier_label := _label(FishQualityType.display_name(quality), 13)
+ var tier_label := _label(FishQualityType.display_name(quality), 16)
tier_label.add_theme_color_override(
"font_color",
INK if discovered else MUTED_INK,
@@ -659,7 +836,7 @@ func _build_quality_progress(fish_id: StringName) -> VBoxContainer:
else "%s quality not yet collected"
) % FishQualityType.display_name(quality)
tier.add_child(tier_label)
- tiers.add_child(tier)
+ row.add_child(tier)
return quality_section
@@ -702,6 +879,31 @@ func _add_detail_row(
parent.add_child(row)
+func _add_currency_detail_row(
+ parent: VBoxContainer,
+ row_name: String,
+ minimum_value: int,
+ maximum_value: int,
+) -> void:
+ var row := VBoxContainer.new()
+ row.add_theme_constant_override("separation", 2)
+ var heading := _field_label(row_name, 14)
+ heading.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ heading.add_theme_color_override("font_color", MUTED_INK)
+ row.add_child(heading)
+ var value: CurrencyAmount = (
+ CurrencyPresentationType.instantiate_amount(minimum_value, 16.0)
+ )
+ value.set_amount_text("%d–%d" % [minimum_value, maximum_value])
+ value.get_amount_label().add_theme_font_override(
+ "font", InventoryNotepadType.HANDWRITTEN_FONT
+ )
+ value.get_amount_label().add_theme_font_size_override("font_size", 16)
+ value.get_amount_label().add_theme_color_override("font_color", INK)
+ row.add_child(value)
+ parent.add_child(row)
+
+
func _make_stats_column() -> VBoxContainer:
var column := VBoxContainer.new()
column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
@@ -848,18 +1050,6 @@ func _entry_label_text(entry_name: String) -> String:
)
-func _paper_style(color: Color, left: bool) -> StyleBoxFlat:
- var style := StyleBoxFlat.new()
- style.bg_color = color
- style.border_color = Color("9b7a4f")
- style.set_border_width_all(3)
- style.corner_radius_top_left = 26 if left else 6
- style.corner_radius_bottom_left = 32 if left else 6
- style.corner_radius_top_right = 6 if left else 28
- style.corner_radius_bottom_right = 6 if left else 34
- return style
-
-
func _build_portrait_overlay() -> void:
_portrait_overlay = Control.new()
_portrait_overlay.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
diff --git a/ui/mail_page.gd b/ui/mail_page.gd
index c89d618..f1bd37d 100644
--- a/ui/mail_page.gd
+++ b/ui/mail_page.gd
@@ -1,8 +1,6 @@
class_name MailPage
extends Control
-signal focus_requested
-
const GREETING_LABELS := {
"dear": "Dear",
"to": "To",
@@ -17,6 +15,9 @@ const SALUTATION_LABELS := {
"good_luck_have_fun": "Good Luck Have Fun",
}
const FishQualityType = preload("res://fish/fish_quality.gd")
+const CurrencyPresentationType = preload(
+ "res://ui/currency_presentation.gd"
+)
var _service: NetworkMailService
var _reservations: PlayerAssetReservationService
@@ -38,14 +39,16 @@ var _signature: Label
var _attachment_kind: OptionButton
var _attachment_choice: OptionButton
var _attachment_amount: LineEdit
-var _coin_available: Label
+var _coin_available_heading: Label
+var _coin_available: CurrencyAmount
+var _attachment_amount_currency_icon: TextureRect
var _amount_minus: Button
var _amount_plus: Button
-var _attachment_summary: Label
+var _attachment_summary: RichTextLabel
var _send_button: Button
var _status: Label
var _letter_text: Label
-var _letter_gift: Label
+var _letter_gift: RichTextLabel
var _accept: Button
var _decline: Button
var _archive: Button
@@ -214,7 +217,7 @@ func _build_compose() -> Control:
_attachment_kind = OptionButton.new()
_attachment_kind.position = Vector2(688, 48)
_attachment_kind.size = Vector2(280, 46)
- for label: String in ["No gift", "Fish coin", "Fish", "Consumable"]:
+ for label: String in ["No gift", "Currency", "Fish", "Consumable"]:
_attachment_kind.add_item(label)
_attachment_kind.item_selected.connect(_refresh_attachment_choices)
page.add_child(_attachment_kind)
@@ -227,13 +230,34 @@ func _build_compose() -> Control:
_update_attachment_summary()
)
page.add_child(_attachment_choice)
- _coin_available = Label.new()
- _coin_available.position = Vector2(688, 158)
- _coin_available.size = Vector2(280, 28)
+ _coin_available_heading = Label.new()
+ _coin_available_heading.text = "Available"
+ _coin_available_heading.position = Vector2(688, 158)
+ _coin_available_heading.size = Vector2(80, 28)
+ page.add_child(_coin_available_heading)
+ _coin_available = CurrencyPresentationType.instantiate_amount(0, 18.0)
+ _coin_available.position = Vector2(770, 158)
+ _coin_available.size = Vector2(198, 28)
+ _coin_available.alignment = BoxContainer.ALIGNMENT_BEGIN
page.add_child(_coin_available)
+ _attachment_amount_currency_icon = TextureRect.new()
+ _attachment_amount_currency_icon.position = Vector2(746, 204)
+ _attachment_amount_currency_icon.size = Vector2(18, 18)
+ _attachment_amount_currency_icon.texture = preload(
+ "res://items/icons/shop/32_currency.png"
+ )
+ _attachment_amount_currency_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ _attachment_amount_currency_icon.stretch_mode = (
+ TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ )
+ _attachment_amount_currency_icon.texture_filter = (
+ CanvasItem.TEXTURE_FILTER_NEAREST
+ )
+ _attachment_amount_currency_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ page.add_child(_attachment_amount_currency_icon)
_attachment_amount = LineEdit.new()
- _attachment_amount.position = Vector2(746, 190)
- _attachment_amount.size = Vector2(164, 46)
+ _attachment_amount.position = Vector2(770, 190)
+ _attachment_amount.size = Vector2(140, 46)
_attachment_amount.placeholder_text = "0"
_attachment_amount.text = "0"
_attachment_amount.text_changed.connect(_on_attachment_amount_changed)
@@ -250,9 +274,12 @@ func _build_compose() -> Control:
_amount_plus.size = Vector2(48, 46)
_amount_plus.pressed.connect(_step_attachment_amount.bind(1))
page.add_child(_amount_plus)
- _attachment_summary = Label.new()
+ _attachment_summary = RichTextLabel.new()
_attachment_summary.position = Vector2(688, 246)
_attachment_summary.size = Vector2(280, 78)
+ _attachment_summary.bbcode_enabled = true
+ _attachment_summary.fit_content = true
+ _attachment_summary.scroll_active = false
_attachment_summary.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
page.add_child(_attachment_summary)
var cancel := Button.new()
@@ -283,9 +310,12 @@ func _build_letter() -> Control:
_letter_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_letter_text.vertical_alignment = VERTICAL_ALIGNMENT_TOP
page.add_child(_letter_text)
- _letter_gift = Label.new()
+ _letter_gift = RichTextLabel.new()
_letter_gift.position = Vector2(730, 46)
_letter_gift.size = Vector2(230, 180)
+ _letter_gift.bbcode_enabled = true
+ _letter_gift.fit_content = true
+ _letter_gift.scroll_active = false
_letter_gift.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
page.add_child(_letter_gift)
_accept = Button.new()
@@ -481,13 +511,18 @@ func _refresh_attachment_choices(_index: int) -> void:
_attachment_amount.visible = amount_visible
_amount_minus.visible = amount_visible
_amount_plus.visible = amount_visible
- _coin_available.visible = _attachment_kind.selected == 1
+ var currency_selected: bool = _attachment_kind.selected == 1
+ _coin_available_heading.visible = currency_selected
+ _coin_available.visible = currency_selected
+ _attachment_amount_currency_icon.visible = currency_selected
+ _attachment_amount.position.x = 770.0 if currency_selected else 746.0
+ _attachment_amount.size.x = 140.0 if currency_selected else 164.0
match _attachment_kind.selected:
0:
_attachment_choice.add_item("No attachment")
1:
- _attachment_choice.add_item("Fish coin")
- _coin_available.text = "Available: %d fish coin" % (
+ _attachment_choice.add_item("Currency")
+ _coin_available.set_amount(
_reservations.get_available_fish_coin()
)
2:
@@ -707,7 +742,9 @@ func _attachment_text(attachment: Dictionary) -> String:
PlayerAssetReservationService.AttachmentType.NONE:
return "No gift attached."
PlayerAssetReservationService.AttachmentType.FISH_COIN:
- return "%d fish coin" % int(attachment.get("amount", 0))
+ return CurrencyPresentationType.bbcode_amount(
+ int(attachment.get("amount", 0)), 18
+ )
PlayerAssetReservationService.AttachmentType.FISH:
var fish_catch := _inventory.get_catch_by_id(
StringName(str(attachment.get("catch_id", "")))
diff --git a/ui/network/join_game_page.gd b/ui/network/join_game_page.gd
index 160550e..ca3fbe5 100644
--- a/ui/network/join_game_page.gd
+++ b/ui/network/join_game_page.gd
@@ -5,11 +5,14 @@ signal join_requested(endpoint: String)
signal back_requested
enum Mode {
+ DISCOVER,
DIRECT,
SAVED,
RECENT,
}
+const DISCOVERY_REFRESH_SECONDS: float = 8.0
+
const ADDRESS_FORMAT_HELP: String = (
"Hostname, IPv4, or [IPv6]. Port 7777 is used when omitted; "
+ "include the port shown by a host when it differs."
@@ -27,17 +30,18 @@ const DIRECT_WORKFLOW_HELP: String = (
@onready var _name_helper: Label = %NameHelper
@onready var _server_list: ItemList = %ServerList
@onready var _details: Label = %Details
+@onready var _discover_button: Button = %DiscoverButton
@onready var _direct_button: Button = %DirectButton
@onready var _saved_button: Button = %SavedButton
@onready var _recent_button: Button = %RecentButton
@onready var _join_button: Button = %JoinButton
+@onready var _refresh_button: Button = %RefreshButton
@onready var _save_button: Button = %SaveButton
@onready var _edit_button: Button = %EditButton
@onready var _favorite_button: Button = %FavoriteButton
@onready var _delete_button: Button = %DeleteButton
@onready var _cancel_button: Button = %CancelButton
@onready var _back_button: Button = %BackButton
-@onready var _open_close_button: Button = %OpenCloseButton
@onready var _status: Label = %Status
@onready var _session_summary: Label = %SessionSummary
@onready var _delete_confirmation: BubbleConfirmationPage = (
@@ -47,13 +51,18 @@ const DIRECT_WORKFLOW_HELP: String = (
var _network_session: NetworkSession
var _saved_servers: SavedServerStore
var _server_trust: ServerTrustStore
+var _discovery: DiscoveryClient
var _gameplay_context: bool = false
-var _mode: Mode = Mode.DIRECT
+var _mode: Mode = Mode.DISCOVER
var _visible_entries: Array[SavedServerEntry] = []
var _selected_entry: SavedServerEntry
+var _discovery_rooms: Array[Dictionary] = []
+var _selected_discovery_index: int = -1
+var _discovery_refresh_timer: Timer
var _editing_entry_id: String = ""
var _name_entry_active: bool = false
var _delete_armed: bool = false
+var _connection_error_latched: bool = false
func _ready() -> void:
@@ -63,16 +72,19 @@ func _ready() -> void:
"panel", UtilityPageStyle.panel_style()
)
for button: BaseButton in [
- _direct_button, _saved_button, _recent_button, _join_button,
+ _discover_button, _direct_button, _saved_button, _recent_button,
+ _refresh_button, _join_button,
_save_button, _edit_button, _favorite_button, _delete_button,
- _cancel_button, _back_button, _open_close_button,
+ _cancel_button, _back_button,
]:
UtilityPageStyle.apply_ocean_button(button)
UtilityPageStyle.apply_ocean_line_edit(_address)
UtilityPageStyle.apply_ocean_line_edit(_name_edit)
+ _discover_button.pressed.connect(_set_mode.bind(Mode.DISCOVER))
_direct_button.pressed.connect(_set_mode.bind(Mode.DIRECT))
_saved_button.pressed.connect(_set_mode.bind(Mode.SAVED))
_recent_button.pressed.connect(_set_mode.bind(Mode.RECENT))
+ _refresh_button.pressed.connect(_request_discovery_refresh)
_join_button.pressed.connect(_request_join)
_save_button.pressed.connect(_on_save_pressed)
_edit_button.pressed.connect(_on_edit_pressed)
@@ -80,7 +92,6 @@ func _ready() -> void:
_delete_button.pressed.connect(_on_delete_pressed)
_cancel_button.pressed.connect(_on_cancel_pressed)
_back_button.pressed.connect(_on_back_pressed)
- _open_close_button.pressed.connect(_on_open_close_pressed)
_address.text_submitted.connect(func(_value: String) -> void:
if _name_entry_active:
_name_edit.grab_focus()
@@ -97,6 +108,11 @@ func _ready() -> void:
)
_delete_confirmation.confirmed.connect(_confirm_delete)
_delete_confirmation.cancelled.connect(_cancel_delete)
+ _discovery_refresh_timer = Timer.new()
+ _discovery_refresh_timer.wait_time = DISCOVERY_REFRESH_SECONDS
+ _discovery_refresh_timer.one_shot = false
+ _discovery_refresh_timer.timeout.connect(_request_discovery_refresh)
+ add_child(_discovery_refresh_timer)
hide()
@@ -105,11 +121,13 @@ func setup(
saved_servers: SavedServerStore,
gameplay_context: bool,
server_trust: ServerTrustStore = null,
+ discovery: DiscoveryClient = null,
) -> void:
_network_session = network_session
_saved_servers = saved_servers
_gameplay_context = gameplay_context
_server_trust = server_trust
+ _discovery = discovery
if not _network_session.state_changed.is_connected(_on_state_changed):
_network_session.state_changed.connect(_on_state_changed)
if not _network_session.status_message_changed.is_connected(
@@ -131,6 +149,29 @@ func setup(
and not _saved_servers.data_changed.is_connected(_on_store_changed)
):
_saved_servers.data_changed.connect(_on_store_changed)
+ if _discovery != null:
+ if not _discovery.rooms_updated.is_connected(
+ _on_discovery_rooms_updated
+ ):
+ _discovery.rooms_updated.connect(_on_discovery_rooms_updated)
+ if not _discovery.browse_status_changed.is_connected(
+ _on_discovery_status_changed
+ ):
+ _discovery.browse_status_changed.connect(
+ _on_discovery_status_changed
+ )
+ if not _discovery.public_join_prepared.is_connected(
+ _on_public_join_prepared
+ ):
+ _discovery.public_join_prepared.connect(
+ _on_public_join_prepared
+ )
+ if not _discovery.public_join_status_changed.is_connected(
+ _on_public_join_status_changed
+ ):
+ _discovery.public_join_status_changed.connect(
+ _on_public_join_status_changed
+ )
_refresh()
@@ -141,7 +182,7 @@ func open_page(preserved_endpoint: String = "") -> void:
_address.text = "127.0.0.1:7777"
show()
UtilityPageStyle.animate_in(self)
- _set_mode(_mode)
+ _set_mode(_mode, false)
if _mode == Mode.DIRECT:
_address.grab_focus()
_address.select_all()
@@ -149,6 +190,7 @@ func open_page(preserved_endpoint: String = "") -> void:
func close_page() -> void:
_clear_edit_state()
+ _discovery_refresh_timer.stop()
hide()
var current_viewport: Viewport = get_viewport()
if current_viewport != null:
@@ -160,15 +202,24 @@ func get_endpoint_text() -> String:
func set_status(message: String) -> void:
+ _connection_error_latched = true
_set_status(_friendly_connection_message(message), true)
-func _set_mode(mode: Mode) -> void:
+func _set_mode(mode: Mode, clear_connection_error: bool = true) -> void:
+ if clear_connection_error:
+ _connection_error_latched = false
_mode = mode
_selected_entry = null
+ _selected_discovery_index = -1
_clear_edit_state()
_refresh_entries()
_refresh()
+ if mode == Mode.DISCOVER:
+ _discovery_refresh_timer.start()
+ _request_discovery_refresh()
+ else:
+ _discovery_refresh_timer.stop()
if not is_visible_in_tree():
return
if mode == Mode.DIRECT:
@@ -178,16 +229,26 @@ func _set_mode(mode: Mode) -> void:
func _request_join() -> void:
+ _connection_error_latched = false
if _network_session.state in [
NetworkSession.State.CONNECTION_FAILED,
NetworkSession.State.SERVER_LOST,
]:
_network_session.reset_failure()
- var endpoint_text: String = (
- _selected_entry.normalized_endpoint
- if _mode != Mode.DIRECT and _selected_entry != null
- else _address.text
- )
+ var endpoint_text: String = _address.text
+ if _mode == Mode.DISCOVER:
+ var room: Dictionary = _selected_discovery_room()
+ if _discovery != null and _discovery.is_own_room(room):
+ _set_status("You are already hosting this room.", true)
+ return
+ if _discovery_room_is_full(room):
+ _set_status("That room is full.", true)
+ return
+ if _discovery == null or not _discovery.prepare_public_join(room):
+ _set_status("Could not prepare the public connection.", true)
+ return
+ elif _mode != Mode.DIRECT and _selected_entry != null:
+ endpoint_text = _selected_entry.normalized_endpoint
var endpoint: ConnectionEndpoint = EndpointParser.parse(endpoint_text)
if not endpoint.is_valid():
_set_status(endpoint.error_message, true)
@@ -197,6 +258,28 @@ func _request_join() -> void:
join_requested.emit(endpoint.normalized_display)
+func _on_public_join_prepared(endpoint_text: String) -> void:
+ if _mode != Mode.DISCOVER or not is_visible_in_tree():
+ return
+ var endpoint: ConnectionEndpoint = EndpointParser.parse(endpoint_text)
+ if not endpoint.is_valid():
+ _set_status("Discovery returned an invalid room address.", true)
+ return
+ _address.text = endpoint.normalized_display
+ _set_status("Connecting…")
+ join_requested.emit(endpoint.normalized_display)
+
+
+func _on_public_join_status_changed(message: String, is_error: bool) -> void:
+ if _mode == Mode.DISCOVER and is_visible_in_tree():
+ if is_error:
+ _connection_error_latched = true
+ elif _connection_error_latched:
+ return
+ _set_status(message, is_error)
+ _refresh()
+
+
func _on_save_pressed() -> void:
if _name_entry_active:
_commit_name_entry()
@@ -339,6 +422,13 @@ func _cancel_delete() -> void:
func _on_list_item_selected(index: int) -> void:
+ if _mode == Mode.DISCOVER:
+ if index < 0 or index >= _discovery_rooms.size():
+ return
+ _selected_discovery_index = index
+ _selected_entry = null
+ _refresh()
+ return
if index < 0 or index >= _visible_entries.size():
return
_selected_entry = _visible_entries[index]
@@ -357,6 +447,23 @@ func _select_entry_id(entry_id: String) -> void:
func _refresh_entries() -> void:
_visible_entries.clear()
_server_list.clear()
+ if _mode == Mode.DISCOVER:
+ for room: Dictionary in _discovery_rooms:
+ var player_count: int = int(room.get("current_players", 0))
+ var maximum: int = int(room.get("max_players", 0))
+ var own_room: bool = (
+ _discovery != null and _discovery.is_own_room(room)
+ )
+ _server_list.add_item(
+ "%s — %d / %d players%s%s" % [
+ str(room.get("room_name", "Public room")),
+ player_count,
+ maximum,
+ " — full" if player_count >= maximum else "",
+ " — your room" if own_room else "",
+ ]
+ )
+ return
if _saved_servers == null or _mode == Mode.DIRECT:
return
_visible_entries = (
@@ -392,9 +499,18 @@ func _refresh() -> void:
var connecting: bool = _network_session.state in [
NetworkSession.State.CONNECTING,
NetworkSession.State.AUTHENTICATING,
- ]
+ ] or (_discovery != null and _discovery.is_public_join_preparing())
var direct: bool = _mode == Mode.DIRECT
- var selected: bool = _selected_entry != null
+ var discovery_mode: bool = _mode == Mode.DISCOVER
+ var selected: bool = (
+ _selected_discovery_index >= 0
+ if discovery_mode
+ else _selected_entry != null
+ )
+ _discover_button.button_pressed = discovery_mode
+ _direct_button.button_pressed = direct
+ _saved_button.button_pressed = _mode == Mode.SAVED
+ _recent_button.button_pressed = _mode == Mode.RECENT
_address.visible = direct or _name_entry_active
_address_label.visible = _address.visible
_address_helper.visible = _address.visible
@@ -407,9 +523,26 @@ func _refresh() -> void:
_name_helper.visible = _name_entry_active
_server_list.visible = not direct and not _name_entry_active
_details.visible = not direct and not _name_entry_active
- _join_button.disabled = connecting or (not direct and not selected)
+ _join_button.disabled = (
+ connecting
+ or (not direct and not selected)
+ or (
+ discovery_mode
+ and selected
+ and _discovery_room_is_full(_selected_discovery_room())
+ )
+ or (
+ discovery_mode
+ and selected
+ and _discovery != null
+ and _discovery.is_own_room(_selected_discovery_room())
+ )
+ )
_join_button.text = "join\nnow" if direct else "join"
- _save_button.visible = direct or _mode == Mode.RECENT or _name_entry_active
+ _refresh_button.visible = discovery_mode and not _name_entry_active
+ _save_button.visible = (
+ direct or _mode == Mode.RECENT or _name_entry_active
+ )
_save_button.disabled = connecting or (
_mode == Mode.RECENT and not selected and not _name_entry_active
)
@@ -418,21 +551,16 @@ func _refresh() -> void:
_favorite_button.visible = _mode == Mode.SAVED and selected
_favorite_button.text = (
"unfavorite"
- if selected and _selected_entry.favorite
+ if _mode == Mode.SAVED
+ and _selected_entry != null
+ and _selected_entry.favorite
else "favorite"
)
- _delete_button.visible = not direct and selected
+ _delete_button.visible = (
+ _mode in [Mode.SAVED, Mode.RECENT] and selected
+ )
_delete_button.text = "remove" if _mode == Mode.RECENT else "delete"
_cancel_button.visible = connecting
- _open_close_button.visible = (
- _gameplay_context and _network_session.is_host()
- )
- if _open_close_button.visible:
- _open_close_button.text = (
- "close\ngame"
- if _network_session.is_open_host()
- else "open\ngame"
- )
_session_summary.visible = (
_gameplay_context
and _network_session.state != NetworkSession.State.INACTIVE
@@ -453,10 +581,20 @@ func _refresh() -> void:
)
if not direct:
if selected:
- _details.text = _format_entry_details(_selected_entry)
- elif _visible_entries.is_empty():
_details.text = (
- "No saved servers yet."
+ _format_discovery_details(_selected_discovery_room())
+ if discovery_mode
+ else _format_entry_details(_selected_entry)
+ )
+ elif (
+ _discovery_rooms.is_empty()
+ if discovery_mode
+ else _visible_entries.is_empty()
+ ):
+ _details.text = (
+ "No public rooms are available."
+ if discovery_mode
+ else "No saved servers yet."
if _mode == Mode.SAVED
else "No recent connections yet."
)
@@ -464,7 +602,7 @@ func _refresh() -> void:
_details.text = "Select a server."
var warning: String = (
_saved_servers.get_recovery_warning()
- if _saved_servers != null
+ if _saved_servers != null and not discovery_mode
else ""
)
if not warning.is_empty() and _status.text.is_empty():
@@ -517,6 +655,76 @@ func _format_entry_details(entry: SavedServerEntry) -> String:
return "\n".join(parts)
+func _format_discovery_details(room: Dictionary) -> String:
+ if room.is_empty():
+ return "Select a public room."
+ var lines: Array[String] = [
+ "Room: %s" % str(room.get("room_name", "Public room")),
+ "Players: %d / %d" % [
+ int(room.get("current_players", 0)),
+ int(room.get("max_players", 0)),
+ ],
+ "Connection: %s" % (
+ _discovery.room_endpoint(room) if _discovery != null else "—"
+ ),
+ "Direct UDP connection • ping is measured after joining",
+ ]
+ if _discovery != null and _discovery.is_own_room(room):
+ lines.append("This is the room you are currently hosting.")
+ return "\n".join(lines)
+
+
+func _selected_discovery_room() -> Dictionary:
+ if (
+ _selected_discovery_index < 0
+ or _selected_discovery_index >= _discovery_rooms.size()
+ ):
+ return {}
+ return _discovery_rooms[_selected_discovery_index]
+
+
+func _discovery_room_is_full(room: Dictionary) -> bool:
+ if room.is_empty():
+ return false
+ return int(room.get("current_players", 0)) >= int(room.get("max_players", 0))
+
+
+func _request_discovery_refresh() -> void:
+ if (
+ _discovery == null
+ or _mode != Mode.DISCOVER
+ or not is_visible_in_tree()
+ ):
+ return
+ _discovery.request_rooms()
+
+
+func _on_discovery_rooms_updated(rooms: Array[Dictionary]) -> void:
+ var selected_id: String = str(
+ _selected_discovery_room().get("room_id", "")
+ )
+ _discovery_rooms = rooms.duplicate(true)
+ _selected_discovery_index = -1
+ if _mode == Mode.DISCOVER:
+ _refresh_entries()
+ if not selected_id.is_empty():
+ for index: int in _discovery_rooms.size():
+ if str(_discovery_rooms[index].get("room_id", "")) == selected_id:
+ _selected_discovery_index = index
+ _server_list.select(index)
+ break
+ _refresh()
+
+
+func _on_discovery_status_changed(message: String, is_error: bool) -> void:
+ if (
+ _mode == Mode.DISCOVER
+ and is_visible_in_tree()
+ and not _connection_error_latched
+ ):
+ _set_status(message, is_error)
+
+
func _format_result_code(result_code: String) -> String:
match result_code.strip_edges().to_upper():
"SUCCESS":
@@ -545,6 +753,7 @@ func _friendly_connection_message(message: String) -> String:
return "Connection cancelled."
if (
"timeout" in normalized
+ or "timed out" in normalized
or "unavailable" in normalized
or "refused" in normalized
or "reach" in normalized
@@ -574,6 +783,7 @@ func _clear_edit_state() -> void:
func _on_cancel_pressed() -> void:
+ _connection_error_latched = false
if _network_session != null:
_network_session.cancel_connection()
_refresh()
@@ -595,23 +805,19 @@ func _on_back_pressed() -> void:
back_requested.emit()
-func _on_open_close_pressed() -> void:
- if _network_session == null or not _network_session.is_host():
- return
- _network_session.set_host_open(not _network_session.is_open_host())
- _refresh()
-
-
func _on_state_changed(_state: NetworkSession.State) -> void:
_refresh()
func _on_status_message_changed(message: String) -> void:
+ if _connection_error_latched:
+ return
_set_status(_friendly_connection_message(message))
_refresh()
func _on_connection_error(message: String) -> void:
+ _connection_error_latched = true
_set_status(_friendly_connection_message(message), true)
_refresh()
diff --git a/ui/network/join_game_page.tscn b/ui/network/join_game_page.tscn
index b2597a6..c4be4fa 100644
--- a/ui/network/join_game_page.tscn
+++ b/ui/network/join_game_page.tscn
@@ -114,22 +114,32 @@ layout_mode = 2
theme_override_constants/separation = 14
alignment = 1
+[node name="DiscoverButton" type="Button" parent="Paper/Margin/Layout/Modes"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(100, 72)
+layout_mode = 2
+toggle_mode = true
+text = "discover"
+
[node name="DirectButton" type="Button" parent="Paper/Margin/Layout/Modes"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 72)
layout_mode = 2
+toggle_mode = true
text = "direct"
[node name="SavedButton" type="Button" parent="Paper/Margin/Layout/Modes"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 72)
layout_mode = 2
+toggle_mode = true
text = "saved"
[node name="RecentButton" type="Button" parent="Paper/Margin/Layout/Modes"]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 72)
layout_mode = 2
+toggle_mode = true
text = "recent"
[node name="AddressLabel" type="Label" parent="Paper/Margin/Layout"]
@@ -258,6 +268,13 @@ layout_mode = 2
theme_override_constants/separation = 7
alignment = 1
+[node name="RefreshButton" type="Button" parent="Paper/Margin/Layout/Actions"]
+unique_name_in_owner = true
+visible = false
+custom_minimum_size = Vector2(82, 72)
+layout_mode = 2
+text = "refresh"
+
[node name="JoinButton" type="Button" parent="Paper/Margin/Layout/Actions"]
unique_name_in_owner = true
custom_minimum_size = Vector2(82, 72)
@@ -291,13 +308,6 @@ custom_minimum_size = Vector2(82, 68)
layout_mode = 2
text = "delete"
-[node name="OpenCloseButton" type="Button" parent="Paper/Margin/Layout/Actions"]
-unique_name_in_owner = true
-visible = false
-custom_minimum_size = Vector2(88, 72)
-layout_mode = 2
-text = "open\ngame"
-
[node name="CancelButton" type="Button" parent="Paper/Margin/Layout/Actions"]
unique_name_in_owner = true
visible = false
diff --git a/ui/on_screen_keyboard.gd b/ui/on_screen_keyboard.gd
new file mode 100644
index 0000000..0d7315d
--- /dev/null
+++ b/ui/on_screen_keyboard.gd
@@ -0,0 +1,456 @@
+class_name OnScreenKeyboard
+extends Control
+
+const ControllerFocusNavigationType = preload(
+ "res://ui/controller_focus_navigation.gd"
+)
+const CHECK_ICON: Texture2D = preload(
+ "res://ui/icons/pictograms/check_mark_dark.png"
+)
+const CHARACTER_KEY_SIZE: Vector2 = Vector2(96.0, 72.0)
+const CHARACTER_FONT_SIZE: int = 34
+const TRIGGER_PRESS_THRESHOLD: float = 0.55
+const TRIGGER_RELEASE_THRESHOLD: float = 0.25
+
+signal text_submitted(value: String)
+
+enum Page {
+ LOWER,
+ UPPER,
+ SYMBOLS,
+}
+
+var _enabled: bool = false
+var _page: Page = Page.LOWER
+var _target: Control
+var _target_virtual_keyboard_enabled: bool = true
+var _buffer: String = ""
+var _preview: Label
+var _page_buttons: Array[Button] = []
+var _keys_host: VBoxContainer
+var _key_buttons: Array[Button] = []
+var _caret_left_button: Button
+var _caret_right_button: Button
+var _backspace_button: Button
+var _space_button: Button
+var _check_button: Button
+var _left_trigger_pressed: bool = false
+var _right_trigger_pressed: bool = false
+
+
+func _ready() -> void:
+ process_mode = Node.PROCESS_MODE_ALWAYS
+ set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ z_index = 1000
+ mouse_filter = Control.MOUSE_FILTER_STOP
+ _build_interface()
+ hide()
+ set_process_input(true)
+
+
+func set_enabled(enabled: bool) -> void:
+ _enabled = enabled
+ if not _enabled and visible:
+ _close_keyboard(false)
+
+
+func is_enabled() -> bool:
+ return _enabled
+
+
+func is_open() -> bool:
+ return visible
+
+
+func _input(event: InputEvent) -> void:
+ if not _enabled:
+ return
+ if visible:
+ var joy_motion := event as InputEventJoypadMotion
+ if joy_motion != null and _handle_trigger_shortcut(joy_motion):
+ get_viewport().set_input_as_handled()
+ return
+ var joy_button := event as InputEventJoypadButton
+ if joy_button != null and joy_button.pressed:
+ if joy_button.button_index == JOY_BUTTON_X:
+ _backspace()
+ get_viewport().set_input_as_handled()
+ return
+ if joy_button.button_index == JOY_BUTTON_LEFT_SHOULDER:
+ _close_keyboard(false)
+ get_viewport().set_input_as_handled()
+ return
+ if joy_button.button_index == JOY_BUTTON_RIGHT_SHOULDER:
+ _set_page(wrapi(int(_page) + 1, 0, Page.size()))
+ get_viewport().set_input_as_handled()
+ return
+ if event.is_action_pressed(&"ui_cancel"):
+ _close_keyboard(true)
+ get_viewport().set_input_as_handled()
+ return
+ var joy_event := event as InputEventJoypadButton
+ if (
+ joy_event == null
+ or not joy_event.pressed
+ or (
+ joy_event.button_index != JOY_BUTTON_A
+ and not event.is_action_pressed(&"ui_accept")
+ )
+ ):
+ return
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if _can_edit(focus_owner):
+ _open_for(focus_owner)
+ get_viewport().set_input_as_handled()
+
+
+func _can_edit(control: Control) -> bool:
+ if control is LineEdit:
+ return (control as LineEdit).editable
+ if control is TextEdit:
+ return (control as TextEdit).editable
+ return false
+
+
+func _open_for(control: Control) -> void:
+ _target = control
+ _target_virtual_keyboard_enabled = bool(
+ _target.get("virtual_keyboard_enabled")
+ )
+ _target.set("virtual_keyboard_enabled", false)
+ _buffer = str(_target.get("text"))
+ _page = Page.LOWER
+ show()
+ _refresh_preview()
+ _rebuild_keys()
+
+
+func _close_keyboard(restore_focus: bool) -> void:
+ var prior_target: Control = _target
+ if is_instance_valid(prior_target):
+ prior_target.set(
+ "virtual_keyboard_enabled",
+ _target_virtual_keyboard_enabled
+ )
+ hide()
+ get_viewport().gui_release_focus()
+ _target = null
+ if restore_focus and is_instance_valid(prior_target):
+ prior_target.grab_focus()
+
+
+func _submit() -> void:
+ var submitted_target: Control = _target
+ var submitted_text: String = _buffer
+ _close_keyboard(false)
+ if submitted_target is LineEdit:
+ (submitted_target as LineEdit).text_submitted.emit(submitted_text)
+ elif submitted_target is TextEdit:
+ (submitted_target as TextEdit).text_changed.emit()
+ text_submitted.emit(submitted_text)
+
+
+func _type_character(character: String) -> void:
+ if not is_instance_valid(_target):
+ _close_keyboard(false)
+ return
+ var caret: int = _get_caret_column()
+ var next_text: String = (
+ _buffer.substr(0, caret)
+ + character
+ + _buffer.substr(caret)
+ )
+ if _target is LineEdit:
+ var line_edit := _target as LineEdit
+ if line_edit.max_length > 0 and next_text.length() > line_edit.max_length:
+ return
+ _buffer = next_text
+ _set_target_text(caret + character.length())
+
+
+func _type_space() -> void:
+ _type_character(" ")
+
+
+func _backspace() -> void:
+ if not is_instance_valid(_target) or _buffer.is_empty():
+ return
+ var caret: int = _get_caret_column()
+ if caret <= 0:
+ return
+ _buffer = _buffer.erase(caret - 1, 1)
+ _set_target_text(caret - 1)
+
+
+func _move_caret(direction: int) -> void:
+ if not is_instance_valid(_target):
+ _close_keyboard(false)
+ return
+ var caret: int = clampi(
+ _get_caret_column() + direction,
+ 0,
+ _buffer.length(),
+ )
+ if _target is LineEdit:
+ (_target as LineEdit).caret_column = caret
+ elif _target is TextEdit:
+ (_target as TextEdit).set_caret_column(caret)
+ _refresh_preview()
+
+
+func _handle_trigger_shortcut(event: InputEventJoypadMotion) -> bool:
+ if event.axis == JOY_AXIS_TRIGGER_LEFT:
+ if event.axis_value <= TRIGGER_RELEASE_THRESHOLD:
+ _left_trigger_pressed = false
+ elif (
+ event.axis_value >= TRIGGER_PRESS_THRESHOLD
+ and not _left_trigger_pressed
+ ):
+ _left_trigger_pressed = true
+ _move_caret(-1)
+ return true
+ elif event.axis == JOY_AXIS_TRIGGER_RIGHT:
+ if event.axis_value <= TRIGGER_RELEASE_THRESHOLD:
+ _right_trigger_pressed = false
+ elif (
+ event.axis_value >= TRIGGER_PRESS_THRESHOLD
+ and not _right_trigger_pressed
+ ):
+ _right_trigger_pressed = true
+ _move_caret(1)
+ return true
+ return false
+
+
+func _get_caret_column() -> int:
+ if _target is LineEdit:
+ return clampi(
+ (_target as LineEdit).caret_column,
+ 0,
+ _buffer.length()
+ )
+ return _buffer.length()
+
+
+func _set_target_text(caret: int) -> void:
+ if _target is LineEdit:
+ var line_edit := _target as LineEdit
+ line_edit.text = _buffer
+ line_edit.caret_column = caret
+ line_edit.text_changed.emit(_buffer)
+ elif _target is TextEdit:
+ var text_edit := _target as TextEdit
+ text_edit.text = _buffer
+ text_edit.text_changed.emit()
+ _refresh_preview()
+
+
+func _refresh_preview() -> void:
+ if _preview == null:
+ return
+ var displayed_text: String = _buffer
+ if _target is LineEdit and (_target as LineEdit).secret:
+ displayed_text = "*".repeat(_buffer.length())
+ var caret: int = clampi(_get_caret_column(), 0, displayed_text.length())
+ _preview.text = displayed_text.insert(caret, "|")
+
+
+func _set_page(page_index: int) -> void:
+ _page = page_index as Page
+ _rebuild_keys()
+
+
+func _rebuild_keys() -> void:
+ for child: Node in _keys_host.get_children():
+ _keys_host.remove_child(child)
+ child.queue_free()
+ _key_buttons.clear()
+ var rows: Array = _rows_for_page()
+ for row_value: Variant in rows:
+ var row := HBoxContainer.new()
+ row.alignment = BoxContainer.ALIGNMENT_CENTER
+ row.size_flags_vertical = Control.SIZE_SHRINK_CENTER
+ row.add_theme_constant_override("separation", 10)
+ _keys_host.add_child(row)
+ for character_value: Variant in row_value as Array:
+ var character: String = str(character_value)
+ var key_button: Button = _make_button(character, CHARACTER_KEY_SIZE)
+ key_button.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
+ key_button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
+ key_button.add_theme_font_size_override(
+ "font_size", CHARACTER_FONT_SIZE
+ )
+ key_button.pressed.connect(_type_character.bind(character))
+ row.add_child(key_button)
+ _key_buttons.append(key_button)
+ for index: int in _page_buttons.size():
+ _page_buttons[index].button_pressed = index == int(_page)
+ call_deferred("_configure_key_focus")
+
+
+func _configure_key_focus() -> void:
+ var focus_controls: Array[Control] = []
+ for button: Button in _key_buttons:
+ focus_controls.append(button)
+ for button: Button in [
+ _caret_left_button,
+ _caret_right_button,
+ _backspace_button,
+ _space_button,
+ _check_button,
+ ]:
+ focus_controls.append(button)
+ ControllerFocusNavigationType.configure_spatial_neighbors(focus_controls)
+ if not _key_buttons.is_empty():
+ _key_buttons[0].grab_focus()
+
+
+func _rows_for_page() -> Array:
+ match _page:
+ Page.UPPER:
+ return [
+ ["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"],
+ ["A", "S", "D", "F", "G", "H", "J", "K", "L"],
+ ["Z", "X", "C", "V", "B", "N", "M"],
+ ]
+ Page.SYMBOLS:
+ return [
+ ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
+ ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")"],
+ ["-", "_", "=", "+", "[", "]", "{", "}"],
+ [".", ",", "?", "/", ":", ";", "'", "\""]
+ ]
+ _:
+ return [
+ ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"],
+ ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
+ ["z", "x", "c", "v", "b", "n", "m"],
+ ]
+
+
+func _build_interface() -> void:
+ var backdrop := ColorRect.new()
+ backdrop.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ backdrop.color = Color(0.012, 0.075, 0.105, 0.82)
+ backdrop.mouse_filter = Control.MOUSE_FILTER_STOP
+ add_child(backdrop)
+ var screen_margin := MarginContainer.new()
+ screen_margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ for side: StringName in [
+ &"margin_left", &"margin_top", &"margin_right", &"margin_bottom"
+ ]:
+ screen_margin.add_theme_constant_override(side, 14)
+ add_child(screen_margin)
+ var panel := PanelContainer.new()
+ panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ panel.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ panel.add_theme_stylebox_override(
+ "panel",
+ _make_style(Color(0.075, 0.27, 0.34, 0.98), 18, 4)
+ )
+ screen_margin.add_child(panel)
+ var margin := MarginContainer.new()
+ for side: StringName in [&"margin_left", &"margin_top", &"margin_right", &"margin_bottom"]:
+ margin.add_theme_constant_override(side, 18)
+ panel.add_child(margin)
+ var layout := VBoxContainer.new()
+ layout.add_theme_constant_override("separation", 10)
+ margin.add_child(layout)
+ var preview_panel := PanelContainer.new()
+ preview_panel.custom_minimum_size = Vector2(0.0, 86.0)
+ preview_panel.add_theme_stylebox_override(
+ "panel",
+ _make_style(Color(0.82, 0.94, 0.95, 1.0), 10, 2)
+ )
+ layout.add_child(preview_panel)
+ _preview = Label.new()
+ _preview.add_theme_color_override("font_color", Color(0.025, 0.12, 0.17, 1.0))
+ _preview.add_theme_font_size_override("font_size", 30)
+ _preview.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
+ _preview.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ _preview.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
+ _preview.add_theme_constant_override("outline_size", 0)
+ preview_panel.add_child(_preview)
+ var page_row := HBoxContainer.new()
+ page_row.alignment = BoxContainer.ALIGNMENT_CENTER
+ page_row.add_theme_constant_override("separation", 12)
+ layout.add_child(page_row)
+ for page_name: String in ["lower", "upper", "symbols"]:
+ var page_button: Button = _make_button(page_name, Vector2(150.0, 44.0))
+ page_button.toggle_mode = true
+ page_button.focus_mode = Control.FOCUS_NONE
+ page_button.pressed.connect(_set_page.bind(_page_buttons.size()))
+ page_row.add_child(page_button)
+ _page_buttons.append(page_button)
+ _keys_host = VBoxContainer.new()
+ _keys_host.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ _keys_host.alignment = BoxContainer.ALIGNMENT_CENTER
+ _keys_host.add_theme_constant_override("separation", 12)
+ layout.add_child(_keys_host)
+ var utility_row := HBoxContainer.new()
+ utility_row.alignment = BoxContainer.ALIGNMENT_CENTER
+ utility_row.add_theme_constant_override("separation", 12)
+ layout.add_child(utility_row)
+ _caret_left_button = _make_button("LT <", Vector2(118.0, 64.0))
+ _caret_left_button.tooltip_text = "move text cursor left"
+ _caret_left_button.pressed.connect(_move_caret.bind(-1))
+ utility_row.add_child(_caret_left_button)
+ _caret_right_button = _make_button("> RT", Vector2(118.0, 64.0))
+ _caret_right_button.tooltip_text = "move text cursor right"
+ _caret_right_button.pressed.connect(_move_caret.bind(1))
+ utility_row.add_child(_caret_right_button)
+ _backspace_button = _make_button("backspace X", Vector2(180.0, 64.0))
+ _backspace_button.pressed.connect(_backspace)
+ utility_row.add_child(_backspace_button)
+ _space_button = _make_button("space", Vector2(350.0, 64.0))
+ _space_button.size_flags_stretch_ratio = 4.0
+ _space_button.pressed.connect(_type_space)
+ utility_row.add_child(_space_button)
+ _check_button = _make_button("", Vector2(92.0, 64.0))
+ _check_button.icon = CHECK_ICON
+ _check_button.expand_icon = true
+ _check_button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _check_button.icon_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _check_button.vertical_icon_alignment = VERTICAL_ALIGNMENT_CENTER
+ _check_button.tooltip_text = "submit"
+ _check_button.accessibility_name = "submit text"
+ _check_button.add_theme_constant_override("icon_max_width", 42)
+ _check_button.pressed.connect(_submit)
+ utility_row.add_child(_check_button)
+ _rebuild_keys()
+
+
+func _make_button(label: String, minimum_size: Vector2) -> Button:
+ var button := Button.new()
+ button.text = label
+ button.custom_minimum_size = minimum_size
+ button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ button.size_flags_vertical = Control.SIZE_EXPAND_FILL
+ button.focus_mode = Control.FOCUS_ALL
+ button.add_theme_font_size_override("font_size", 22)
+ button.add_theme_color_override("font_color", Color(0.025, 0.12, 0.17, 1.0))
+ button.add_theme_color_override("font_hover_color", Color(0.025, 0.12, 0.17, 1.0))
+ button.add_theme_color_override("font_focus_color", Color(0.025, 0.12, 0.17, 1.0))
+ button.add_theme_stylebox_override(
+ "normal",
+ _make_style(Color(0.72, 0.88, 0.91, 1.0), 10, 2)
+ )
+ button.add_theme_stylebox_override(
+ "hover",
+ _make_style(Color(0.87, 0.96, 0.96, 1.0), 10, 3)
+ )
+ button.add_theme_stylebox_override("focus", button.get_theme_stylebox("hover"))
+ button.add_theme_stylebox_override(
+ "pressed",
+ _make_style(Color(0.44, 0.72, 0.77, 1.0), 10, 3)
+ )
+ return button
+
+
+func _make_style(color: Color, radius: int, border_width: int) -> StyleBoxFlat:
+ var style := StyleBoxFlat.new()
+ style.bg_color = color
+ style.border_color = Color(0.025, 0.12, 0.17, 1.0)
+ style.set_border_width_all(border_width)
+ style.set_corner_radius_all(radius)
+ return style
diff --git a/ui/on_screen_keyboard.gd.uid b/ui/on_screen_keyboard.gd.uid
new file mode 100644
index 0000000..da300a2
--- /dev/null
+++ b/ui/on_screen_keyboard.gd.uid
@@ -0,0 +1 @@
+uid://dcanibf8hordh
diff --git a/ui/pause_menu.gd b/ui/pause_menu.gd
index b989972..dccac73 100644
--- a/ui/pause_menu.gd
+++ b/ui/pause_menu.gd
@@ -107,6 +107,7 @@ func setup(
network_session: NetworkSessionType,
saved_servers: SavedServerStoreType,
server_trust: ServerTrustStore,
+ discovery: DiscoveryClient,
) -> void:
_player = player
_save_manager = save_manager
@@ -114,7 +115,9 @@ func setup(
_fishing_spot = fishing_spot
_network_session = network_session
_saved_servers = saved_servers
- _join_game_page.setup(network_session, saved_servers, true, server_trust)
+ _join_game_page.setup(
+ network_session, saved_servers, true, server_trust, discovery
+ )
if not _fishing_spot.bite_activated.is_connected(_on_bite_activated):
_fishing_spot.bite_activated.connect(_on_bite_activated)
@@ -348,7 +351,10 @@ func _open_confirmation(
else BubbleConfirmationPageType.InitialFocus.CONFIRM
)
)
- _begin_root_exit(_show_confirmation)
+ # Confirmation actions reject input while the root page is still leaving.
+ # Finish that exit before exposing an interactive confirmation page so a
+ # pointer click can never land in the overlap window and be discarded.
+ _begin_root_exit(_show_confirmation, false)
func _show_confirmation() -> void:
@@ -447,7 +453,10 @@ func _finish_root_entry(generation: int) -> void:
_root_transition_active = false
-func _begin_root_exit(completed: Callable) -> void:
+func _begin_root_exit(
+ completed: Callable,
+ overlap_next_page: bool = true,
+) -> void:
if _root_transition_active or not _root_page.visible:
return
_root_transition_generation += 1
@@ -455,9 +464,14 @@ func _begin_root_exit(completed: Callable) -> void:
_emit_transition_flurry()
var generation: int = _root_transition_generation
_root_page.transition_out(
- _finish_root_exit.bind(generation),
+ _finish_root_exit.bind(
+ generation,
+ Callable() if overlap_next_page else completed,
+ ),
0.0
)
+ if not overlap_next_page:
+ return
await get_tree().create_timer(
UIMotion.BUBBLE_TRANSITION_OVERLAP_DELAY
).timeout
@@ -468,10 +482,13 @@ func _begin_root_exit(completed: Callable) -> void:
func _finish_root_exit(
generation: int,
+ completed: Callable,
) -> void:
if generation != _root_transition_generation or not visible:
return
_root_transition_active = false
+ if completed.is_valid():
+ completed.call()
func _finish_user_close() -> void:
diff --git a/ui/pause_menu.tscn b/ui/pause_menu.tscn
index 2477f23..941e26e 100644
--- a/ui/pause_menu.tscn
+++ b/ui/pause_menu.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=11 format=3]
+[gd_scene load_steps=16 format=3]
[ext_resource type="Script" path="res://ui/pause_menu.gd" id="1_script"]
[ext_resource type="PackedScene" path="res://ui/settings_panel.tscn" id="2_settings"]
@@ -10,6 +10,11 @@
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_transition_flurry.gd" id="8_flurry"]
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_confirmation_page.tscn" id="9_confirmation"]
[ext_resource type="PackedScene" path="res://ui/network/join_game_page.tscn" id="10_join_page"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/online_dark.png" id="11_online_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/save_dark.png" id="12_save_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/settings_dark.png" id="13_settings_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/undo_dark.png" id="14_undo_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_dark.png" id="15_x_dark"]
[node name="PauseMenu" type="Control"]
unique_name_in_owner = true
@@ -87,7 +92,9 @@ compact_reference_size = Vector2(608, 448)
[node name="ResumeButton" parent="ResponsivePauseStage/PausePresentationScaleRoot/RootPage/BubbleCluster" instance=ExtResource("5_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
-text = "return\nto game"
+texture_filter = 1
+icon = ExtResource("14_undo_dark")
+tooltip_text = "return to game"
accessibility_name = "return to game"
neutral_size = Vector2(174, 164)
desktop_anchor = Vector2(335, 220)
@@ -100,7 +107,9 @@ motion_phase = 0.3
[node name="SaveButton" parent="ResponsivePauseStage/PausePresentationScaleRoot/RootPage/BubbleCluster" instance=ExtResource("5_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
-text = "save\nnow"
+texture_filter = 1
+icon = ExtResource("12_save_dark")
+tooltip_text = "save now"
accessibility_name = "save now"
neutral_size = Vector2(126, 120)
desktop_anchor = Vector2(185, 185)
@@ -113,7 +122,10 @@ motion_phase = 1.15
[node name="SettingsButton" parent="ResponsivePauseStage/PausePresentationScaleRoot/RootPage/BubbleCluster" instance=ExtResource("5_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
-text = "settings"
+texture_filter = 1
+icon = ExtResource("13_settings_dark")
+tooltip_text = "settings"
+accessibility_name = "settings"
neutral_size = Vector2(144, 136)
desktop_anchor = Vector2(485, 170)
compact_anchor = Vector2(515, 175)
@@ -125,7 +137,9 @@ motion_phase = 2.05
[node name="JoinGameButton" parent="ResponsivePauseStage/PausePresentationScaleRoot/RootPage/BubbleCluster" instance=ExtResource("5_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
-text = "join\ngame"
+texture_filter = 1
+icon = ExtResource("11_online_dark")
+tooltip_text = "join game"
accessibility_name = "join game"
neutral_size = Vector2(126, 120)
desktop_anchor = Vector2(105, 320)
@@ -164,7 +178,10 @@ motion_phase = 3.9
[node name="QuitButton" parent="ResponsivePauseStage/PausePresentationScaleRoot/RootPage/BubbleCluster" instance=ExtResource("5_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
-text = "quit"
+texture_filter = 1
+icon = ExtResource("15_x_dark")
+tooltip_text = "quit"
+accessibility_name = "quit"
neutral_size = Vector2(102, 98)
desktop_anchor = Vector2(390, 395)
compact_anchor = Vector2(390, 410)
diff --git a/ui/player_menu.gd b/ui/player_menu.gd
index 1fac21f..7f73acd 100644
--- a/ui/player_menu.gd
+++ b/ui/player_menu.gd
@@ -14,6 +14,9 @@ const FishInventoryType = preload("res://inventory/fish_inventory.gd")
const InventoryNotepadType = preload(
"res://ui/components/inventory_notepad.gd"
)
+const CurrencyPresentationType = preload(
+ "res://ui/currency_presentation.gd"
+)
const OrganizerTabType = preload("res://ui/components/organizer_tab.gd")
const FishPoolType = preload("res://fish/fish_pool.gd")
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
@@ -85,6 +88,14 @@ const MAIN_SHOP_BUYER_ID: StringName = &"main_fishing_shop"
signal menu_visibility_changed(is_open: bool)
signal inventory_hotbar_context_changed(show_hotbar: bool)
+signal controller_hotbar_placement_requested(
+ assignment_kind: PlayerHotbarType.AssignmentKind,
+ identity: StringName,
+ initial_slot: int,
+)
+signal controller_hotbar_placement_ended
+signal controller_hotbar_management_requested(initial_slot: int)
+signal controller_hotbar_management_ended
signal menu_exit_started
signal shop_cooler_modal_changed(is_open: bool)
@@ -124,6 +135,13 @@ enum CloseReason {
TEARDOWN,
}
+enum ControllerOwnership {
+ ITEM_LIST,
+ NOTEPAD_ACTIONS,
+ HOTBAR_MANAGEMENT,
+ HOTBAR_PLACEMENT,
+}
+
const INVENTORY_MAIN_POSITION := Vector2(54.0, 166.0)
const INVENTORY_MAIN_SIZE := Vector2(882.0, 484.0)
const INVENTORY_PANEL_GAP := 16.0
@@ -153,7 +171,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _notepad_binding: Label = %BindingDecoration
@onready var _notepad_title: Label = %NotepadTitle
@onready var _notepad_rule: ColorRect = %NotepadRule
-@onready var _notepad_wallet_value: Label = %NotepadWalletValue
+@onready var _notepad_wallet_value: CurrencyAmount = %NotepadWalletValue
@onready var _notepad_capacity_value: Label = %NotepadCapacityValue
@onready var _cooler_detail_texture: TextureRect = %CoolerDetailTexture
@onready var _cooler_detail_name: Label = %CoolerDetailName
@@ -163,7 +181,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _cooler_weight_unit: Label = %CoolerWeightUnit
@onready var _cooler_offer_row: HBoxContainer = %CoolerOfferRow
@onready var _cooler_offer_label: Label = %CoolerOfferLabel
-@onready var _cooler_offer_value: Label = %CoolerOfferValue
+@onready var _cooler_offer_value: CurrencyAmount = %CoolerOfferValue
@onready var _cooler_selection_summary: Control = %CoolerSelectionSummary
@onready var _cooler_selection_empty: Label = %CoolerSelectionEmpty
@onready var _cooler_selected_count_row: HBoxContainer = %CoolerSelectedCountRow
@@ -171,9 +189,10 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _cooler_selected_count_label: Label = %CoolerSelectedCountLabel
@onready var _cooler_combined_offer_row: HBoxContainer = %CoolerCombinedOfferRow
@onready var _cooler_combined_offer_label: Label = %CoolerCombinedOfferLabel
-@onready var _cooler_combined_offer_value: Label = %CoolerCombinedOfferValue
+@onready var _cooler_combined_offer_value: CurrencyAmount = %CoolerCombinedOfferValue
@onready var _favorite_bubble: NotepadInkActionType = %FavoriteBubble
@onready var _sell_bubble: NotepadInkActionType = %SellBubble
+@onready var _sell_all_bubble: NotepadInkActionType = %SellAllBubble
@onready var _bag_page: Control = %BagPage
@onready var _tackle_box_page: Control = %TackleBoxPage
@onready var _inventory_sub_tabs: HBoxContainer = %InventorySubTabs
@@ -189,7 +208,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _lures_filter: Button = %LuresFilter
@onready var _tackle_empty: Label = %TackleEmpty
@onready var _tackle_detail_text: Label = %TackleDetailText
-@onready var _tackle_equip_button: Button = %TackleEquipButton
+@onready var _tackle_equip_button: NotepadInkActionType = %TackleEquipButton
@onready var _tackle_item_list: VBoxContainer = %TackleItemList
@onready var _bag_outer_wall: PanelContainer = %BagOuterWall
@onready var _bag_inner_liner: PanelContainer = %BagInnerLiner
@@ -198,7 +217,6 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _bag_item_field: Control = %BagItemField
@onready var _bag_empty_state: Label = %BagEmptyState
@onready var _bag_detail_constellation: Control = %BagDetailConstellation
-@onready var _bag_sprite_detail_bubble: Control = %BagDetailBubble
@onready var _bag_sprite_detail_texture: TextureRect = %BagSpriteDetailTexture
@onready var _bag_sprite_detail_name: Label = %BagSpriteDetailName
@onready var _bag_sprite_detail_data: Label = %BagSpriteDetailData
@@ -212,7 +230,6 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _book_spread: BoxContainer = %BookSpread
@onready var _left_page: PanelContainer = %LeftPage
@onready var _right_page: PanelContainer = %RightPage
-@onready var _book_gutter: ColorRect = %BookGutter
@onready var _left_heading: Label = %LeftHeading
@onready var _right_heading: Label = %RightHeading
@onready var _left_entry_field: BoxContainer = %LeftEntryField
@@ -233,7 +250,7 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _content_stage: Control = %Content
@onready var _cooler_scroll: ScrollContainer = %CoolerScroll
@onready var _cooler_host: Control = %CoolerHost
-@onready var _wallet_balance: Label = %WalletBalance
+@onready var _wallet_balance: CurrencyAmount = %WalletBalance
@onready var _header: Control = %Header
@onready var _separator: Control = %Separator
@onready var _wallet_status: BubbleStatusBubbleType = %WalletStatus
@@ -243,7 +260,6 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _offer_status: BubbleStatusBubbleType = %OfferStatus
@onready var _inventory_section: Control = %InventorySection
@onready var _bag_section: Control = %BagSection
-@onready var _logbook_section: Control = %LogbookSection
@onready var _bag_empty: Label = %BagEmpty
@onready var _bag_grid: GridContainer = %BagGrid
@onready var _bag_list: Control = %BagList
@@ -253,23 +269,19 @@ const SALE_CONFIRMATION_SIZE := Vector2(520.0, 190.0)
@onready var _bag_detail_data: Label = %BagDetailData
@onready var _sort_option: OptionButton = %SortOption
@onready var _sort_direction: Button = %SortDirection
-@onready var _held_value: Label = %HeldValue
+@onready var _held_value: CurrencyAmount = %HeldValue
@onready var _cooler_count: Label = %CoolerCount
@onready var _inventory_empty: Label = %InventoryEmpty
-@onready var _detail_texture: TextureRect = %DetailTexture
-@onready var _detail_name: Label = %DetailName
-@onready var _detail_data: Label = %DetailData
@onready var _selection_summary: Label = %SelectionSummary
@onready var _favorite_button: Button = %FavoriteButton
@onready var _sell_button: Button = %SellButton
@onready var _sale_unavailable: Label = %SaleUnavailable
-@onready var _transaction_feedback: Label = %TransactionFeedback
+@onready var _transaction_feedback: RichTextLabel = %TransactionFeedback
@onready var _sale_confirmation: PanelContainer = %SaleConfirmation
-@onready var _confirmation_message: Label = %ConfirmationMessage
+@onready var _confirmation_message: RichTextLabel = %ConfirmationMessage
@onready var _confirm_sale_button: Button = %ConfirmSaleButton
@onready var _cancel_sale_button: Button = %CancelSaleButton
@onready var _logbook_empty: Label = %LogbookEmpty
-@onready var _logbook_grid: GridContainer = %LogbookGrid
var _compact_layout: bool = false
var _player: PlayerType
@@ -302,6 +314,15 @@ var _last_inventory_section: Section = Section.COOLER
var _bag_view: BagView = BagView.EQUIPMENT
var _tackle_view: TackleView = TackleView.BAIT
var _selected_tackle_item_id: StringName
+var _controller_ownership: ControllerOwnership = ControllerOwnership.ITEM_LIST
+var _controller_source_section: Section = Section.COOLER
+var _controller_source_identity: StringName
+var _controller_notepad_actions: Array[BaseButton] = []
+var _controller_hotbar_assignment_kind: PlayerHotbarType.AssignmentKind = (
+ PlayerHotbarType.AssignmentKind.EMPTY
+)
+var _controller_hotbar_identity: StringName
+var _controller_previous_hotbar_slot: int = 0
var _sort_mode: SortMode = SortMode.CATCH_ORDER
var _sort_descending: bool = true
var _fish_selection := FishBatchSelectionType.new()
@@ -368,7 +389,7 @@ func _ready() -> void:
)
_bait_filter.pressed.connect(_set_tackle_view.bind(TackleView.BAIT))
_lures_filter.pressed.connect(_set_tackle_view.bind(TackleView.LURES))
- _tackle_equip_button.pressed.connect(_toggle_active_bait)
+ _tackle_equip_button.pressed.connect(_toggle_active_tackle)
_logbook_tab.pressed.connect(
_show_section.bind(Section.LOGBOOK)
)
@@ -385,6 +406,7 @@ func _ready() -> void:
_sell_button.pressed.connect(_on_sell_pressed)
_favorite_bubble.pressed.connect(_on_favorite_pressed)
_sell_bubble.pressed.connect(_on_sell_pressed)
+ _sell_all_bubble.pressed.connect(_on_sell_all_pressed)
_confirm_sale_button.pressed.connect(_on_confirm_sale_pressed)
_cancel_sale_button.pressed.connect(_close_sale_confirmation)
_configure_sale_confirmation_focus()
@@ -507,6 +529,7 @@ func setup(
reservations: PlayerAssetReservationService,
network_profile_service: NetworkProfileService,
network_player_list: NetworkPlayerListService,
+ discovery: DiscoveryClient,
player_jobs: PlayerJobService,
world_time: WorldTimeService,
world_environment: WorldEnvironment,
@@ -539,7 +562,7 @@ func setup(
world_environment,
world_sun,
)
- _players_page.setup(network_player_list)
+ _players_page.setup(network_player_list, discovery)
_catalog_logbook.setup(collection_log, inventory, catalog)
_the_net_page.setup(player_jobs, world_time)
_network_mail_service.unread_count_changed.connect(
@@ -569,6 +592,8 @@ func setup(
_bag.contents_changed.connect(_on_bag_changed)
if not _player.active_bait_changed.is_connected(_on_active_bait_changed):
_player.active_bait_changed.connect(_on_active_bait_changed)
+ if not _player.active_lure_changed.is_connected(_on_active_lure_changed):
+ _player.active_lure_changed.connect(_on_active_lure_changed)
if not _hotbar.slots_changed.is_connected(_on_hotbar_changed):
_hotbar.slots_changed.connect(_on_hotbar_changed)
if not _cooler_capacity.capacity_changed.is_connected(
@@ -589,12 +614,25 @@ func set_profile_preview_world_pixel_size(pixel_size: int) -> void:
_profile_page.set_world_pixel_size(pixel_size)
+var _left_page_trigger_held: bool = false
+var _right_page_trigger_held: bool = false
+
+
func _input(event: InputEvent) -> void:
if event is InputEventKey and event.echo:
return
+ if _handle_controller_ownership_input(event):
+ get_viewport().set_input_as_handled()
+ return
+ if visible:
+ _reserve_main_navigation_for_page_switching()
+ _reserve_visible_secondary_navigation()
if _handle_controller_page_switch(event):
get_viewport().set_input_as_handled()
return
+ if _handle_controller_secondary_switch(event):
+ get_viewport().set_input_as_handled()
+ return
if _handle_direct_page_shortcut(event):
get_viewport().set_input_as_handled()
return
@@ -613,47 +651,383 @@ func _input(event: InputEvent) -> void:
get_viewport().set_input_as_handled()
+func _handle_controller_ownership_input(event: InputEvent) -> bool:
+ if not visible:
+ return false
+ var button_event := event as InputEventJoypadButton
+ var accept_pressed: bool = (
+ button_event != null
+ and button_event.pressed
+ and _event_matches_controller_role(
+ event,
+ ControllerMappingManagerType.ROLE_A,
+ JOY_BUTTON_A,
+ )
+ )
+ var cancel_pressed: bool = (
+ button_event != null
+ and button_event.pressed
+ and _event_matches_controller_role(
+ event,
+ ControllerMappingManagerType.ROLE_B,
+ JOY_BUTTON_B,
+ )
+ )
+ var alternate_pressed: bool = (
+ button_event != null
+ and button_event.pressed
+ and _event_matches_controller_role(
+ event,
+ ControllerMappingManagerType.ROLE_Y,
+ JOY_BUTTON_Y,
+ )
+ )
+ if _controller_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
+ if cancel_pressed:
+ _release_controller_ownership(true, false)
+ return true
+ if alternate_pressed:
+ if _hotbar != null:
+ _hotbar.clear_slot(_hotbar.get_selected_slot())
+ return true
+ if accept_pressed:
+ return true
+ return false
+ if _controller_ownership == ControllerOwnership.HOTBAR_PLACEMENT:
+ if accept_pressed:
+ _confirm_controller_hotbar_placement()
+ return true
+ if cancel_pressed:
+ _release_controller_ownership(true, true)
+ return true
+ if alternate_pressed:
+ return true
+ return false
+ if _controller_ownership == ControllerOwnership.NOTEPAD_ACTIONS:
+ if cancel_pressed:
+ _release_controller_ownership(true, false)
+ return true
+ if alternate_pressed:
+ return true
+ var direction: int = 0
+ if event.is_action_pressed("ui_left") or event.is_action_pressed("ui_up"):
+ direction = -1
+ elif (
+ event.is_action_pressed("ui_right")
+ or event.is_action_pressed("ui_down")
+ ):
+ direction = 1
+ if direction != 0:
+ _focus_next_notepad_action(direction)
+ return true
+ return false
+ if alternate_pressed:
+ return _try_begin_controller_hotbar_placement()
+ if accept_pressed:
+ return _try_enter_notepad_controller_ownership()
+ return false
+
+
+func _event_matches_controller_role(
+ event: InputEvent,
+ role: StringName,
+ fallback_button: JoyButton,
+) -> bool:
+ if _controller_mapping_manager != null:
+ return _controller_mapping_manager.event_matches_role(event, role)
+ var button_event := event as InputEventJoypadButton
+ return button_event != null and button_event.button_index == fallback_button
+
+
+func _try_enter_notepad_controller_ownership() -> bool:
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner == null:
+ return false
+ var source_identity: StringName
+ var actions: Array[BaseButton] = []
+ if _current_section == Section.COOLER:
+ var fish_node := focus_owner as CoolerFishSpriteType
+ if fish_node == null or fish_node.catch_id.is_empty():
+ return false
+ source_identity = fish_node.catch_id
+ _on_catch_card_pressed(source_identity)
+ if not _favorite_bubble.disabled:
+ actions.append(_favorite_bubble)
+ if not _sell_bubble.disabled:
+ actions.append(_sell_bubble)
+ if not _sell_all_bubble.disabled:
+ actions.append(_sell_all_bubble)
+ elif _current_section == Section.TACKLE_BOX:
+ if not focus_owner.has_meta(&"controller_tackle_item_id"):
+ return false
+ source_identity = StringName(
+ str(focus_owner.get_meta(&"controller_tackle_item_id"))
+ )
+ _select_tackle_item(source_identity)
+ if _tackle_equip_button.visible and not _tackle_equip_button.disabled:
+ actions.append(_tackle_equip_button)
+ else:
+ return false
+ if actions.is_empty():
+ _restore_controller_item_focus(_current_section, source_identity)
+ return true
+ _controller_source_section = _current_section
+ _controller_source_identity = source_identity
+ _controller_notepad_actions = actions
+ _controller_ownership = ControllerOwnership.NOTEPAD_ACTIONS
+ actions.front().call_deferred("grab_focus")
+ return true
+
+
+func _focus_next_notepad_action(direction: int) -> void:
+ var available: Array[BaseButton] = []
+ for action: BaseButton in _controller_notepad_actions:
+ if (
+ is_instance_valid(action)
+ and action.visible
+ and not action.disabled
+ and action.focus_mode != Control.FOCUS_NONE
+ ):
+ available.append(action)
+ if available.is_empty():
+ return
+ var focused: Control = get_viewport().gui_get_focus_owner()
+ var current_index: int = available.find(focused)
+ if current_index < 0:
+ current_index = 0 if direction > 0 else available.size() - 1
+ else:
+ current_index = wrapi(
+ current_index + direction,
+ 0,
+ available.size(),
+ )
+ available[current_index].grab_focus()
+
+
+func _try_begin_controller_hotbar_placement() -> bool:
+ if _hotbar == null:
+ return false
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner == null:
+ return false
+ var assignment_kind: PlayerHotbarType.AssignmentKind = (
+ PlayerHotbarType.AssignmentKind.EMPTY
+ )
+ var identity: StringName
+ if _current_section == Section.COOLER:
+ var fish_node := focus_owner as CoolerFishSpriteType
+ if fish_node == null or fish_node.catch_id.is_empty():
+ return false
+ assignment_kind = PlayerHotbarType.AssignmentKind.FISH
+ identity = fish_node.catch_id
+ elif _current_section == Section.BAG:
+ var item_node := focus_owner as BagItemSpriteType
+ if item_node == null or item_node.item_id.is_empty():
+ return false
+ var item: ItemDataType = (
+ _item_catalog.get_item_by_id(item_node.item_id)
+ if _item_catalog != null
+ else null
+ )
+ if item == null or not item.hotbar_allowed:
+ return true
+ assignment_kind = PlayerHotbarType.AssignmentKind.ITEM
+ identity = item_node.item_id
+ else:
+ return false
+ _controller_source_section = _current_section
+ _controller_source_identity = identity
+ _controller_hotbar_assignment_kind = assignment_kind
+ _controller_hotbar_identity = identity
+ _controller_previous_hotbar_slot = _hotbar.get_selected_slot()
+ var initial_slot: int = _find_controller_hotbar_assignment(
+ assignment_kind,
+ identity,
+ )
+ if initial_slot < 0:
+ initial_slot = _controller_previous_hotbar_slot
+ _controller_ownership = ControllerOwnership.HOTBAR_PLACEMENT
+ controller_hotbar_placement_requested.emit(
+ assignment_kind,
+ identity,
+ initial_slot,
+ )
+ return true
+
+
+func _find_controller_hotbar_assignment(
+ assignment_kind: PlayerHotbarType.AssignmentKind,
+ identity: StringName,
+) -> int:
+ for slot_index: int in range(PlayerHotbarType.SLOT_COUNT):
+ if (
+ assignment_kind == PlayerHotbarType.AssignmentKind.FISH
+ and _hotbar.get_fish_catch_id(slot_index) == identity
+ ):
+ return slot_index
+ if (
+ assignment_kind == PlayerHotbarType.AssignmentKind.ITEM
+ and _hotbar.get_item_id(slot_index) == identity
+ ):
+ return slot_index
+ return -1
+
+
+func _confirm_controller_hotbar_placement() -> void:
+ if (
+ _controller_ownership != ControllerOwnership.HOTBAR_PLACEMENT
+ or _hotbar == null
+ ):
+ return
+ var slot_index: int = _hotbar.get_selected_slot()
+ var assigned: bool = false
+ if (
+ _controller_hotbar_assignment_kind
+ == PlayerHotbarType.AssignmentKind.FISH
+ ):
+ assigned = _hotbar.assign_fish(
+ slot_index,
+ _controller_hotbar_identity,
+ )
+ elif (
+ _controller_hotbar_assignment_kind
+ == PlayerHotbarType.AssignmentKind.ITEM
+ ):
+ assigned = _hotbar.assign_item(
+ slot_index,
+ _controller_hotbar_identity,
+ )
+ if assigned:
+ _release_controller_ownership(true, false)
+
+
+func _release_controller_ownership(
+ restore_source_focus: bool,
+ restore_previous_hotbar_slot: bool,
+) -> void:
+ if _controller_ownership == ControllerOwnership.ITEM_LIST:
+ return
+ var prior_ownership: ControllerOwnership = _controller_ownership
+ var source_section: Section = _controller_source_section
+ var source_identity: StringName = _controller_source_identity
+ _controller_ownership = ControllerOwnership.ITEM_LIST
+ _controller_notepad_actions.clear()
+ _controller_source_identity = StringName()
+ _controller_hotbar_assignment_kind = PlayerHotbarType.AssignmentKind.EMPTY
+ _controller_hotbar_identity = StringName()
+ if prior_ownership == ControllerOwnership.HOTBAR_PLACEMENT:
+ if restore_previous_hotbar_slot and _hotbar != null:
+ _hotbar.select_slot(_controller_previous_hotbar_slot)
+ controller_hotbar_placement_ended.emit()
+ if prior_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
+ controller_hotbar_management_ended.emit()
+ inventory_hotbar_context_changed.emit(
+ _current_section in [Section.COOLER, Section.BAG]
+ )
+ if restore_source_focus:
+ call_deferred(
+ "_restore_controller_item_focus",
+ source_section,
+ source_identity,
+ )
+
+
+func _restore_controller_item_focus(
+ section: Section,
+ identity: StringName,
+) -> void:
+ if not visible or section != _current_section:
+ return
+ if identity.is_empty():
+ _focus_current_section()
+ return
+ var target: Control
+ if section == Section.COOLER:
+ target = _fish_nodes.get(identity) as CoolerFishSpriteType
+ elif section == Section.BAG:
+ target = _bag_item_nodes.get(identity) as BagItemSpriteType
+ elif section == Section.TACKLE_BOX:
+ for child: Node in _tackle_item_list.get_children():
+ var button := child as BaseButton
+ if (
+ button != null
+ and button.has_meta(&"controller_tackle_item_id")
+ and StringName(str(button.get_meta(
+ &"controller_tackle_item_id"
+ ))) == identity
+ ):
+ target = button
+ break
+ if (
+ target != null
+ and is_instance_valid(target)
+ and target.is_visible_in_tree()
+ and target.focus_mode != Control.FOCUS_NONE
+ ):
+ target.grab_focus()
+ else:
+ _focus_current_section()
+
+
func _handle_controller_page_switch(event: InputEvent) -> bool:
var button_event: InputEventJoypadButton = event as InputEventJoypadButton
+ var motion_event: InputEventJoypadMotion = event as InputEventJoypadMotion
var use_mapping: bool = (
_controller_mapping_manager != null
)
- var uses_left_bumper: bool = (
+ var uses_left_trigger: bool = (
_controller_mapping_manager.event_uses_role(
- event, ControllerMappingManagerType.ROLE_LB
+ event, ControllerMappingManagerType.ROLE_POINTER_MODIFIER
)
if use_mapping
else (
- button_event != null
- and button_event.button_index == JOY_BUTTON_LEFT_SHOULDER
+ motion_event != null
+ and motion_event.axis == JOY_AXIS_TRIGGER_LEFT
)
)
- var uses_right_bumper: bool = (
+ var uses_right_trigger: bool = (
_controller_mapping_manager.event_uses_role(
- event, ControllerMappingManagerType.ROLE_RB
+ event, ControllerMappingManagerType.ROLE_CAMERA_ZOOM
)
if use_mapping
else (
- button_event != null
- and button_event.button_index == JOY_BUTTON_RIGHT_SHOULDER
+ motion_event != null
+ and motion_event.axis == JOY_AXIS_TRIGGER_RIGHT
)
)
if (
- button_event == null
- or not (uses_left_bumper or uses_right_bumper)
+ not (uses_left_trigger or uses_right_trigger)
or not visible
):
return false
- if not button_event.pressed:
+ var is_pressed: bool = (
+ button_event.pressed
+ if button_event != null
+ else motion_event.axis_value > 0.5
+ )
+ if not is_pressed:
+ if uses_left_trigger:
+ _left_page_trigger_held = false
+ if uses_right_trigger:
+ _right_page_trigger_held = false
return true
- # Shoulder input belongs to the Player Menu while it is visible, even when
- # a transition or modal temporarily prevents changing pages. This keeps LB
- # from opening Chat and RB from leaking into gameplay behind the menu.
+ if (
+ (uses_left_trigger and _left_page_trigger_held)
+ or (uses_right_trigger and _right_page_trigger_held)
+ ):
+ return true
+ if uses_left_trigger:
+ _left_page_trigger_held = true
+ if uses_right_trigger:
+ _right_page_trigger_held = true
+ # Trigger input belongs to the Player Menu while it is visible, even when a
+ # transition or modal temporarily prevents changing pages.
if (
_transitioning
or _page_transitioning
or _sale_confirmation.visible
or get_viewport().gui_is_dragging()
+ or _controller_ownership != ControllerOwnership.ITEM_LIST
):
return true
var sections: Array[Section] = [
@@ -670,13 +1044,167 @@ func _handle_controller_page_switch(event: InputEvent) -> bool:
if current_index < 0:
current_index = 0
var direction: int = (
- -1 if uses_left_bumper else 1
+ -1 if uses_left_trigger else 1
)
var next_index: int = wrapi(current_index + direction, 0, sections.size())
_show_section(sections[next_index])
return true
+func _handle_controller_secondary_switch(event: InputEvent) -> bool:
+ var button_event := event as InputEventJoypadButton
+ if button_event == null or not visible:
+ return false
+ var use_mapping: bool = _controller_mapping_manager != null
+ var uses_left_bumper: bool = (
+ _controller_mapping_manager.event_uses_role(
+ event, ControllerMappingManagerType.ROLE_LB
+ )
+ if use_mapping
+ else button_event.button_index == JOY_BUTTON_LEFT_SHOULDER
+ )
+ var uses_right_bumper: bool = (
+ _controller_mapping_manager.event_uses_role(
+ event, ControllerMappingManagerType.ROLE_RB
+ )
+ if use_mapping
+ else button_event.button_index == JOY_BUTTON_RIGHT_SHOULDER
+ )
+ if not (uses_left_bumper or uses_right_bumper):
+ return false
+ if not button_event.pressed:
+ return true
+ var direction: int = -1 if uses_left_bumper else 1
+ if _controller_ownership == ControllerOwnership.HOTBAR_MANAGEMENT:
+ _cycle_from_controller_hotbar_management(direction)
+ return true
+ if (
+ _transitioning
+ or _page_transitioning
+ or _sale_confirmation.visible
+ or get_viewport().gui_is_dragging()
+ or _controller_ownership != ControllerOwnership.ITEM_LIST
+ ):
+ return true
+ if _is_inventory_section(_current_section):
+ if (
+ (direction > 0 and _current_section == Section.BAG)
+ or (direction < 0 and _current_section == Section.COOLER)
+ ):
+ _begin_controller_hotbar_management()
+ return true
+ var inventory_sections: Array[Section] = [
+ Section.COOLER,
+ Section.TACKLE_BOX,
+ Section.BAG,
+ ]
+ var inventory_index: int = inventory_sections.find(_current_section)
+ _show_section(inventory_sections[wrapi(
+ inventory_index + direction,
+ 0,
+ inventory_sections.size(),
+ )])
+ return true
+ _cycle_visible_secondary_tabs(direction)
+ return true
+
+
+func _begin_controller_hotbar_management() -> void:
+ if _hotbar == null:
+ return
+ _controller_source_section = _current_section
+ _controller_source_identity = StringName()
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if _current_section == Section.COOLER:
+ var fish_node := focus_owner as CoolerFishSpriteType
+ if fish_node != null:
+ _controller_source_identity = fish_node.catch_id
+ elif _current_section == Section.BAG:
+ var item_node := focus_owner as BagItemSpriteType
+ if item_node != null:
+ _controller_source_identity = item_node.item_id
+ _controller_ownership = ControllerOwnership.HOTBAR_MANAGEMENT
+ controller_hotbar_management_requested.emit(_hotbar.get_selected_slot())
+
+
+func _cycle_from_controller_hotbar_management(direction: int) -> void:
+ _release_controller_ownership(false, false)
+ var target_section: Section = (
+ Section.COOLER if direction > 0 else Section.BAG
+ )
+ if target_section == _current_section:
+ call_deferred("_focus_current_section")
+ else:
+ _show_section(target_section)
+
+
+func _cycle_visible_secondary_tabs(direction: int) -> bool:
+ var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
+ var grouped_buttons: Dictionary = {}
+ _collect_visible_toggle_buttons(self, navigation_cluster, grouped_buttons)
+ var selected_group: Variant = null
+ var selected_group_y: float = INF
+ for group_value: Variant in grouped_buttons.keys():
+ var buttons := grouped_buttons[group_value] as Array
+ if buttons.size() < 2:
+ continue
+ var group_y: float = INF
+ for item: Variant in buttons:
+ var button := item as BaseButton
+ group_y = minf(group_y, button.global_position.y)
+ if group_y < selected_group_y:
+ selected_group = group_value
+ selected_group_y = group_y
+ if selected_group == null:
+ return false
+ var tabs := grouped_buttons[selected_group] as Array
+ tabs.sort_custom(func(first: BaseButton, second: BaseButton) -> bool:
+ return first.global_position.x < second.global_position.x
+ )
+ var current_index: int = 0
+ for index: int in tabs.size():
+ var tab := tabs[index] as BaseButton
+ if tab.button_pressed:
+ current_index = index
+ break
+ var target := tabs[wrapi(
+ current_index + direction, 0, tabs.size()
+ )] as BaseButton
+ target.set_pressed_no_signal(true)
+ target.pressed.emit()
+ return true
+
+
+func _collect_visible_toggle_buttons(
+ root: Node,
+ navigation_cluster: Control,
+ grouped_buttons: Dictionary,
+) -> void:
+ for child: Node in root.get_children():
+ var child_control := child as Control
+ if child_control != null and not child_control.is_visible_in_tree():
+ continue
+ var button := child as BaseButton
+ if (
+ button != null
+ and button.toggle_mode
+ and (
+ navigation_cluster == null
+ or not navigation_cluster.is_ancestor_of(button)
+ )
+ ):
+ var group_key: Variant = button.get_parent()
+ if button.button_group != null:
+ group_key = button.button_group
+ if not grouped_buttons.has(group_key):
+ grouped_buttons[group_key] = []
+ var buttons := grouped_buttons[group_key] as Array
+ buttons.append(button)
+ _collect_visible_toggle_buttons(
+ child, navigation_cluster, grouped_buttons
+ )
+
+
func _handle_direct_page_shortcut(event: InputEvent) -> bool:
var key_event := event as InputEventKey
if (
@@ -772,6 +1300,7 @@ func open_menu() -> void:
or not _fishing_spot.can_open_player_menu()
):
return
+ _release_controller_ownership(false, true)
_menu_generation += 1
_transition_generation += 1
_cancel_presentation_tween()
@@ -791,6 +1320,9 @@ func open_menu() -> void:
_update_shell_layout()
_begin_menu_entry()
menu_visibility_changed.emit(true)
+ inventory_hotbar_context_changed.emit(
+ _current_section in [Section.COOLER, Section.BAG]
+ )
func open_section(section: Section) -> bool:
@@ -847,7 +1379,7 @@ func mount_shop_cooler(
_set_content_interactive(true)
_update_cooler_water_mask()
set_process(true)
- call_deferred("_focus_shop_cooler")
+ _cooler_sort_option.call_deferred("grab_focus")
return true
@@ -921,6 +1453,7 @@ func close_menu(
if reason != CloseReason.USER:
_finish_close(reason, restore_controls, _menu_generation)
return
+ _release_controller_ownership(false, true)
get_viewport().gui_cancel_drag()
_close_sale_confirmation()
if reason in [
@@ -949,6 +1482,7 @@ func close_for_session_end() -> void:
func _exit_tree() -> void:
+ _release_controller_ownership(false, true)
_cancel_presentation_tween()
_cancel_page_tween()
if visible:
@@ -1007,6 +1541,7 @@ func _show_section(section: Section) -> void:
and _profile_page.request_close_confirmation()
):
return
+ _release_controller_ownership(false, true)
_begin_page_transition(section)
@@ -1122,22 +1657,39 @@ func _focus_current_section() -> void:
if _shop_cooler_context_active:
_focus_shop_cooler()
return
- if _current_section == Section.COOLER:
- _cooler_sub_tab.grab_focus()
- elif _current_section == Section.BAG:
- _bag_sub_tab.grab_focus()
- elif _current_section == Section.TACKLE_BOX:
- _tackle_sub_tab.grab_focus()
- elif _current_section == Section.LOGBOOK:
- _catalog_logbook.focus_initial()
- elif _current_section == Section.NET:
- _the_net_page.focus_initial()
- elif _current_section == Section.MAIL:
- _mail_tab.grab_focus()
- elif _current_section == Section.PLAYERS:
- _players_tab.grab_focus()
- else:
- _profile_tab.grab_focus()
+ _reserve_main_navigation_for_page_switching()
+ _reserve_visible_secondary_navigation()
+ var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
+ var candidates: Array[Control] = []
+ _collect_focusable_content(self, navigation_cluster, candidates)
+ if candidates.is_empty():
+ return
+ candidates.sort_custom(func(first: Control, second: Control) -> bool:
+ if not is_equal_approx(first.global_position.y, second.global_position.y):
+ return first.global_position.y < second.global_position.y
+ return first.global_position.x < second.global_position.x
+ )
+ candidates[0].grab_focus()
+
+
+func _collect_focusable_content(
+ root: Node,
+ navigation_cluster: Control,
+ output: Array[Control],
+) -> void:
+ for child: Node in root.get_children():
+ if child == navigation_cluster:
+ continue
+ var control := child as Control
+ if control != null and not control.is_visible_in_tree():
+ continue
+ if (
+ control != null
+ and control.focus_mode != Control.FOCUS_NONE
+ and not control is ScrollBar
+ ):
+ output.append(control)
+ _collect_focusable_content(child, navigation_cluster, output)
func _process(delta: float) -> void:
@@ -1161,6 +1713,7 @@ func _process(delta: float) -> void:
func _configure_navigation_focus() -> void:
+ _reserve_main_navigation_for_page_switching()
var navigation: Array[BubbleButtonType] = [
_inventory_tab,
_logbook_tab,
@@ -1182,6 +1735,48 @@ func _configure_navigation_focus() -> void:
bubble.focus_neighbor_right = bubble.get_path_to(next)
bubble.focus_neighbor_top = bubble.focus_neighbor_left
bubble.focus_neighbor_bottom = bubble.focus_neighbor_right
+
+
+func _reserve_main_navigation_for_page_switching() -> void:
+ var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
+ if navigation_cluster == null:
+ return
+ _set_descendant_focus_disabled(navigation_cluster)
+
+
+func _set_descendant_focus_disabled(root: Node) -> void:
+ for child: Node in root.get_children():
+ var control := child as Control
+ if control != null:
+ control.focus_mode = Control.FOCUS_NONE
+ _set_descendant_focus_disabled(child)
+
+
+func _reserve_visible_secondary_navigation() -> void:
+ var navigation_cluster := get_node_or_null("%NavigationCluster") as Control
+ var grouped_buttons: Dictionary = {}
+ _collect_visible_toggle_buttons(self, navigation_cluster, grouped_buttons)
+ var selected_tabs: Array = []
+ var selected_group_y: float = INF
+ for group_value: Variant in grouped_buttons.keys():
+ var buttons := grouped_buttons[group_value] as Array
+ if buttons.size() < 2:
+ continue
+ var group_y: float = INF
+ for item: Variant in buttons:
+ var button := item as BaseButton
+ group_y = minf(group_y, button.global_position.y)
+ if group_y < selected_group_y:
+ selected_tabs = buttons
+ selected_group_y = group_y
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ var displaced_focus: bool = selected_tabs.has(focus_owner)
+ for item: Variant in selected_tabs:
+ var tab := item as Control
+ tab.focus_mode = Control.FOCUS_NONE
+ if displaced_focus:
+ focus_owner.release_focus()
+ call_deferred("_focus_current_section")
var inventory_tabs: Array[Button] = [
_cooler_sub_tab,
_tackle_sub_tab,
@@ -1289,11 +1884,11 @@ func _apply_inventory_styles() -> void:
UtilityPageStyle.panel_style(),
)
_confirmation_message.add_theme_font_override(
- "font",
+ "normal_font",
UtilityPageStyle.TuffyFont,
)
_confirmation_message.add_theme_color_override(
- "font_color",
+ "default_color",
UtilityPageStyle.OCEAN_TEXT_PRIMARY,
)
UtilityPageStyle.apply_ocean_button(_confirm_sale_button)
@@ -1323,7 +1918,12 @@ func _refresh_tackle_box() -> void:
child.queue_free()
var matching_items: Array[OwnedItemType] = []
if _bag != null and _item_catalog != null:
- for owned: OwnedItemType in _bag.get_all_items():
+ var available_items: Array[OwnedItemType] = (
+ _bag.get_unlocked_bait_items()
+ if _tackle_view == TackleView.BAIT
+ else _bag.get_all_items()
+ )
+ for owned: OwnedItemType in available_items:
var item: ItemDataType = _item_catalog.get_item_by_id(
owned.item_id
)
@@ -1343,12 +1943,33 @@ func _refresh_tackle_box() -> void:
for owned: OwnedItemType in matching_items:
var item: ItemDataType = _item_catalog.get_item_by_id(owned.item_id)
var row := Button.new()
- row.text = "%s ×%d" % [item.display_name, owned.quantity]
row.icon = item.icon
- row.alignment = HORIZONTAL_ALIGNMENT_LEFT
+ row.tooltip_text = (
+ "%s ×%d" % [item.display_name, owned.quantity]
+ if item.is_bait()
+ else item.display_name
+ )
+ var compact_tackle_item: bool = item.is_bait() or item.is_lure()
+ if compact_tackle_item:
+ row.custom_minimum_size = Vector2(72, 72)
+ row.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
+ row.expand_icon = item.icon != null
+ row.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ row.text = "" if item.icon != null else item.display_name
+ if item.icon == null:
+ row.add_theme_font_size_override("font_size", 12)
+ else:
+ row.text = "%s ×%d" % [item.display_name, owned.quantity]
+ row.alignment = HORIZONTAL_ALIGNMENT_LEFT
row.toggle_mode = true
+ row.set_meta(&"controller_tackle_item_id", owned.item_id)
row.button_pressed = owned.item_id == _selected_tackle_item_id
- UtilityPageStyle.apply_ocean_button(row)
+ if compact_tackle_item:
+ _apply_tackle_bait_button_style(row)
+ if item.is_bait():
+ _add_tackle_quantity_badge(row, owned.quantity)
+ else:
+ UtilityPageStyle.apply_ocean_button(row)
row.pressed.connect(_select_tackle_item.bind(owned.item_id))
_tackle_item_list.add_child(row)
_tackle_empty.text = (
@@ -1360,6 +1981,68 @@ func _refresh_tackle_box() -> void:
_update_tackle_detail()
+func _add_tackle_quantity_badge(row: Button, quantity: int) -> void:
+ var badge := Panel.new()
+ badge.name = "QuantityBadge"
+ badge.anchor_left = 1.0
+ badge.anchor_right = 1.0
+ badge.offset_left = -27.0
+ badge.offset_top = 3.0
+ badge.offset_right = -3.0
+ badge.offset_bottom = 27.0
+ badge.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ badge.z_index = 2
+ var badge_style := StyleBoxFlat.new()
+ badge_style.bg_color = Color("0b5558")
+ badge_style.set_corner_radius_all(12)
+ badge_style.anti_aliasing = false
+ badge.add_theme_stylebox_override("panel", badge_style)
+ row.add_child(badge)
+ var quantity_label := Label.new()
+ quantity_label.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
+ quantity_label.offset_left = 1.0
+ quantity_label.offset_right = 1.0
+ quantity_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ quantity_label.text = str(quantity)
+ quantity_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ quantity_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ quantity_label.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
+ quantity_label.add_theme_font_size_override(
+ "font_size",
+ 13 if quantity >= 100 else 15,
+ )
+ quantity_label.add_theme_color_override("font_color", Color("e7f5f4"))
+ badge.add_child(quantity_label)
+
+
+func _apply_tackle_bait_button_style(button: Button) -> void:
+ var profile := BubbleMenuProfile.new()
+ var normal_style: StyleBoxFlat = profile.make_normal_style()
+ var hover_style: StyleBoxFlat = profile.make_hover_style()
+ var pressed_style: StyleBoxFlat = profile.make_pressed_style()
+ var disabled_style: StyleBoxFlat = profile.make_disabled_style()
+ for style: StyleBoxFlat in [
+ normal_style,
+ hover_style,
+ pressed_style,
+ disabled_style,
+ ]:
+ style.set_corner_radius_all(36)
+ style.content_margin_left = 13.5
+ style.content_margin_top = 13.5
+ style.content_margin_right = 13.5
+ style.content_margin_bottom = 13.5
+ button.add_theme_stylebox_override("normal", normal_style)
+ button.add_theme_stylebox_override("hover", hover_style)
+ button.add_theme_stylebox_override("focus", hover_style)
+ button.add_theme_stylebox_override("pressed", pressed_style)
+ button.add_theme_stylebox_override("disabled", disabled_style)
+ button.add_theme_color_override("icon_normal_color", Color.WHITE)
+ button.add_theme_color_override("icon_hover_color", Color.WHITE)
+ button.add_theme_color_override("icon_focus_color", Color.WHITE)
+ button.add_theme_color_override("icon_pressed_color", Color.WHITE)
+
+
func _select_tackle_item(item_id: StringName) -> void:
_selected_tackle_item_id = item_id
_refresh_tackle_box()
@@ -1373,13 +2056,14 @@ func _update_tackle_detail() -> void:
)
if item == null:
_tackle_equip_button.visible = false
+ _tackle_equip_button.persistent_mark = false
_tackle_detail_text.text = (
"Select bait for details."
if _tackle_view == TackleView.BAIT
else "Select a lure for details."
)
return
- _tackle_equip_button.visible = item.is_bait()
+ _tackle_equip_button.visible = item.is_bait() or item.is_lure()
var quantity: int = _bag.get_quantity(item.item_id) if _bag != null else 0
var assigned_slot: int = -1
if _hotbar != null:
@@ -1387,40 +2071,51 @@ func _update_tackle_detail() -> void:
if _hotbar.get_item_id(slot_index) == item.item_id:
assigned_slot = slot_index
break
- var state_text: String = (
- "hotbar slot %d" % (assigned_slot + 1)
- if assigned_slot >= 0
- else "not assigned"
- )
- _tackle_detail_text.text = (
- "%s\n\nType: %s\nQuantity: %d\n%s\n\n%s"
- % [
- item.display_name,
- item.get_category_name(),
- quantity,
- state_text,
- item.description,
- ]
- )
+ var detail_lines: Array[String] = [item.display_name, ""]
if item.is_bait():
+ detail_lines.append("quantity: %d" % quantity)
+ if assigned_slot >= 0:
+ detail_lines.append("hotbar slot %d" % (assigned_slot + 1))
+ detail_lines.append("")
+ detail_lines.append(item.description)
+ _tackle_detail_text.text = "\n".join(detail_lines)
+ if item.is_bait() or item.is_lure():
+ var is_equipped: bool = (
+ _player != null
+ and (
+ _player.active_bait_id == item.item_id
+ if item.is_bait()
+ else _player.active_lure_id == item.item_id
+ )
+ )
_tackle_equip_button.text = (
"dequip %s" % item.display_name
- if _player != null and _player.active_bait_id == item.item_id
+ if is_equipped
else "equip %s" % item.display_name
)
+ _tackle_equip_button.persistent_mark = is_equipped
_tackle_equip_button.disabled = quantity <= 0
+ _tackle_equip_button.refresh_ink_state()
-func _toggle_active_bait() -> void:
+func _toggle_active_tackle() -> void:
if _player == null or _item_catalog == null:
return
var item: ItemDataType = _item_catalog.get_item_by_id(_selected_tackle_item_id)
- if item == null or not item.is_bait():
+ if item == null:
return
- if _player.active_bait_id == item.item_id:
- _player.unequip_bait()
+ if item.is_bait():
+ if _player.active_bait_id == item.item_id:
+ _player.unequip_bait()
+ else:
+ _player.equip_bait(item)
+ elif item.is_lure():
+ if _player.active_lure_id == item.item_id:
+ _player.unequip_lure()
+ else:
+ _player.equip_lure(item)
else:
- _player.equip_bait(item)
+ return
_update_tackle_detail()
@@ -1428,6 +2123,10 @@ func _on_active_bait_changed(_item_id: StringName) -> void:
_update_tackle_detail()
+func _on_active_lure_changed(_item_id: StringName) -> void:
+ _update_tackle_detail()
+
+
func _apply_cooler_control_styles() -> void:
var profile: BubbleMenuProfile = _inventory_tab.profile
if profile == null:
@@ -1692,10 +2391,10 @@ func _update_shell_layout() -> void:
_cooler_sort_direction.custom_minimum_size = (
Vector2(140.0, 31.0) if compact else Vector2(123.0, 38.0)
)
- _cooler_sort_option.set_choice_font_size(12 if compact else 15)
+ _cooler_sort_option.set_choice_font_size(14 if compact else 17)
_cooler_sort_direction.add_theme_font_size_override(
"font_size",
- 12 if compact else 14,
+ 14 if compact else 17,
)
_notepad_wallet_value.position = (
Vector2(10.0, 33.0) if compact else Vector2(18.0, 61.0)
@@ -1709,14 +2408,13 @@ func _update_shell_layout() -> void:
_notepad_capacity_value.size = (
Vector2(142.0, 17.0) if compact else Vector2(124.0, 23.0)
)
- for status_value: Label in [
- _notepad_wallet_value,
- _notepad_capacity_value,
- ]:
- status_value.add_theme_font_size_override(
- "font_size",
- 10 if compact else 14,
- )
+ _notepad_wallet_value.icon_size = 10.0 if compact else 14.0
+ _notepad_wallet_value.get_amount_label().add_theme_font_size_override(
+ "font_size", 10 if compact else 14
+ )
+ _notepad_capacity_value.add_theme_font_size_override(
+ "font_size", 10 if compact else 14
+ )
_cooler_detail_texture.position = (
Vector2(5.0, 84.0) if compact else Vector2(80.0, 137.0)
)
@@ -1752,6 +2450,9 @@ func _update_shell_layout() -> void:
_sell_bubble.custom_minimum_size = (
Vector2(74.0, 42.0) if compact else Vector2(118.0, 50.0)
)
+ _sell_all_bubble.custom_minimum_size = (
+ Vector2(96.0, 38.0) if compact else Vector2(122.0, 44.0)
+ )
_favorite_bubble.position = (
Vector2(144.0, 148.0) if compact else Vector2(26.0, 378.0)
)
@@ -1764,11 +2465,20 @@ func _update_shell_layout() -> void:
_sell_bubble.size = (
Vector2(74.0, 42.0) if compact else Vector2(118.0, 50.0)
)
+ _sell_all_bubble.position = (
+ Vector2(102.0, 190.0) if compact else Vector2(78.0, 426.0)
+ )
+ _sell_all_bubble.size = (
+ Vector2(96.0, 38.0) if compact else Vector2(122.0, 44.0)
+ )
_favorite_bubble.add_theme_font_size_override(
- "font_size", 11 if compact else 17,
+ "font_size", 13 if compact else 19,
)
_sell_bubble.add_theme_font_size_override(
- "font_size", 11 if compact else 17,
+ "font_size", 13 if compact else 19,
+ )
+ _sell_all_bubble.add_theme_font_size_override(
+ "font_size", 12 if compact else 17,
)
_update_sort_direction_text()
_bag_page.size = reference_size
@@ -1886,24 +2596,25 @@ func _layout_cooler_detail_text(compact: bool) -> void:
"font_size",
13 if compact else 18,
)
- _cooler_offer_value.add_theme_font_size_override(
- "font_size",
- 10 if compact else 15,
+ _cooler_offer_value.icon_size = 10.0 if compact else 15.0
+ _cooler_offer_value.get_amount_label().add_theme_font_size_override(
+ "font_size", 10 if compact else 15
)
func _layout_cooler_selection_text(compact: bool) -> void:
var row_height: float = 17.5 if compact else 20.0
- for numeric_label: Label in [
- _cooler_selected_count_value,
- _cooler_combined_offer_value,
- ]:
- numeric_label.add_theme_font_size_override(
- "font_size",
- 10 if compact else 14,
- )
+ _cooler_selected_count_value.add_theme_font_size_override(
+ "font_size", 10 if compact else 14
+ )
+ _cooler_combined_offer_value.icon_size = 10.0 if compact else 14.0
+ _cooler_combined_offer_value.get_amount_label().add_theme_font_size_override(
+ "font_size", 10 if compact else 14
+ )
+ _cooler_selection_empty.add_theme_font_size_override(
+ "font_size", 14 if compact else 20
+ )
for word_label: Label in [
- _cooler_selection_empty,
_cooler_selected_count_label,
_cooler_combined_offer_label,
]:
@@ -2272,7 +2983,11 @@ func _set_content_interactive(interactive: bool) -> void:
var detail_interactive: bool = (
cooler_interactive and _detail_constellation.visible
)
- for action: NotepadInkActionType in [_favorite_bubble, _sell_bubble]:
+ for action: NotepadInkActionType in [
+ _favorite_bubble,
+ _sell_bubble,
+ _sell_all_bubble,
+ ]:
var action_interactive: bool = detail_interactive and not action.disabled
action.focus_mode = (
Control.FOCUS_ALL
@@ -2348,7 +3063,7 @@ func _on_sort_selected(index: int, source: OptionButton) -> void:
func _on_cooler_sort_selected(sort_id: int) -> void:
- _sort_mode = sort_id
+ _sort_mode = sort_id as SortMode
_sort_option.select(_sort_mode)
_cooler_sort_option.select(_sort_mode)
_refresh_inventory()
@@ -2635,7 +3350,7 @@ func _update_bag_detail() -> void:
item_state = "equippable"
elif item.usable:
item_state = "usable"
- _bag_detail_texture.texture = item.icon if item != null else null
+ _bag_detail_texture.texture = null
_bag_detail_name.text = item.display_name if item != null else ""
_bag_detail_data.text = (
"%s\nquantity: %d\n%s\n%s\n%s"
@@ -2649,7 +3364,10 @@ func _update_bag_detail() -> void:
if item != null
else "select a bag item for details."
)
- _bag_sprite_detail_texture.texture = item.icon if item != null else null
+ _bag_sprite_detail_texture.texture = null
+ if item != null:
+ _bag_detail_texture.texture = item.icon
+ _bag_sprite_detail_texture.texture = item.icon
_bag_sprite_detail_name.text = (
item.display_name if item != null else ""
)
@@ -2723,9 +3441,9 @@ func _refresh_economy_summary() -> void:
if _inventory != null
else 0
)
- _wallet_balance.text = "wallet: $%d" % balance
- _wallet_status.set_content("wallet", "$%d" % balance)
- _notepad_wallet_value.text = "$%d" % balance
+ _wallet_balance.set_amount(balance)
+ _wallet_status.set_currency_amount("wallet", balance)
+ _notepad_wallet_value.set_amount(balance)
_capacity_status.set_content("cooler", "%d / %d" % [
_inventory.get_all_catches().size() if _inventory != null else 0,
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
@@ -2734,8 +3452,8 @@ func _refresh_economy_summary() -> void:
_inventory.get_all_catches().size() if _inventory != null else 0,
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
]
- _held_value_status.set_content("held value", "$%d" % held_total)
- _held_value.text = "held fish base value: $%d" % held_total
+ _held_value_status.set_currency_amount("held value", held_total)
+ _held_value.set_amount(held_total)
_cooler_count.text = "%d / %d" % [
_inventory.get_all_catches().size() if _inventory != null else 0,
_cooler_capacity.get_capacity() if _cooler_capacity != null else 0,
@@ -2893,11 +3611,11 @@ func _configure_cooler_fish_focus() -> void:
if not _shop_cooler_context_active:
_cooler_sub_tab.focus_neighbor_bottom = NodePath()
return
- var top_control: Control = (
- _cooler_sort_option
- if _shop_cooler_context_active
- else _cooler_sub_tab
- )
+ var top_control: Control
+ if _shop_cooler_context_active:
+ top_control = _cooler_sort_option
+ else:
+ top_control = _cooler_sub_tab
if not _shop_cooler_context_active:
_cooler_sub_tab.focus_neighbor_bottom = _cooler_sub_tab.get_path_to(
controls.front()
@@ -2921,6 +3639,11 @@ func _configure_cooler_fish_focus() -> void:
not _favorite_bubble.disabled
and index + columns >= controls.size()
)
+ else control.get_path_to(_sell_all_bubble)
+ if (
+ not _sell_all_bubble.disabled
+ and index + columns >= controls.size()
+ )
else control.get_path_to(
controls[mini(index + columns, controls.size() - 1)]
)
@@ -2946,6 +3669,18 @@ func _configure_cooler_fish_focus() -> void:
_sell_bubble.get_path_to(_close_button)
)
_sell_bubble.focus_neighbor_top = _sell_bubble.get_path_to(focused_node)
+ _sell_bubble.focus_neighbor_bottom = (
+ _sell_bubble.get_path_to(_sell_all_bubble)
+ )
+ _sell_all_bubble.focus_neighbor_left = (
+ _sell_all_bubble.get_path_to(_favorite_bubble)
+ )
+ _sell_all_bubble.focus_neighbor_right = (
+ _sell_all_bubble.get_path_to(_close_button)
+ )
+ _sell_all_bubble.focus_neighbor_top = (
+ _sell_all_bubble.get_path_to(_sell_bubble)
+ )
func _compare_catches(left: FishCatchType, right: FishCatchType) -> bool:
@@ -2975,7 +3710,7 @@ func _on_catch_card_pressed(catch_id: StringName) -> void:
Input.is_key_pressed(KEY_CTRL),
Input.is_key_pressed(KEY_SHIFT)
)
- _transaction_feedback.text = ""
+ _set_transaction_feedback("")
_refresh_inventory()
@@ -2987,7 +3722,7 @@ func _on_fish_field_gui_input(event: InputEvent) -> void:
and not get_viewport().gui_is_dragging()
):
_fish_selection.clear()
- _transaction_feedback.text = ""
+ _set_transaction_feedback("")
_refresh_inventory()
@@ -3010,6 +3745,7 @@ func _close_detail_constellation() -> void:
_sell_bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
_favorite_bubble.refresh_ink_state()
_sell_bubble.refresh_ink_state()
+ _refresh_cooler_notepad_action_interactivity()
_configure_cooler_fish_focus()
@@ -3018,9 +3754,9 @@ func _clear_cooler_detail_stats() -> void:
_cooler_weight_value,
_cooler_weight_unit,
_cooler_offer_label,
- _cooler_offer_value,
]:
label.text = ""
+ _cooler_offer_value.visible = false
func _set_cooler_selection_summary_empty() -> void:
@@ -3031,10 +3767,10 @@ func _set_cooler_selection_summary_empty() -> void:
_cooler_selected_count_value,
_cooler_selected_count_label,
_cooler_combined_offer_label,
- _cooler_combined_offer_value,
]:
label.visible = false
label.text = ""
+ _cooler_combined_offer_value.visible = false
func _set_cooler_selection_summary(
@@ -3052,10 +3788,9 @@ func _set_cooler_selection_summary(
_cooler_selected_count_label.text = "fish selected"
if offer_value >= 0:
_cooler_combined_offer_label.text = "combined offer"
- _cooler_combined_offer_value.text = "$%d" % offer_value
+ _cooler_combined_offer_value.set_amount(offer_value)
else:
_cooler_combined_offer_label.text = "offer unavailable"
- _cooler_combined_offer_value.text = ""
func _update_inventory_detail(fish_catch: FishCatchType) -> void:
@@ -3076,6 +3811,7 @@ func _update_inventory_detail(fish_catch: FishCatchType) -> void:
_sell_bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
_favorite_bubble.refresh_ink_state()
_sell_bubble.refresh_ink_state()
+ _refresh_cooler_notepad_action_interactivity()
_configure_cooler_fish_focus()
return
_cooler_detail_texture.texture = fish_catch.fish.display_texture
@@ -3104,10 +3840,11 @@ func _update_inventory_detail(fish_catch: FishCatchType) -> void:
]
if buyer_offer >= 0 and active_buyer != null:
_cooler_offer_label.text = _get_offer_label(active_buyer)
- _cooler_offer_value.text = "$%d" % buyer_offer
+ _cooler_offer_value.visible = true
+ _cooler_offer_value.set_amount(buyer_offer)
else:
_cooler_offer_label.text = "buyer unavailable"
- _cooler_offer_value.text = ""
+ _cooler_offer_value.visible = false
_favorite_button.disabled = false
_favorite_button.text = (
"unfavorite" if fish_catch.is_favorited else "favorite"
@@ -3118,25 +3855,32 @@ func _update_inventory_detail(fish_catch: FishCatchType) -> void:
_favorite_bubble.refresh_ink_state()
_detail_constellation.visible = _current_section == Section.COOLER
_cooler_sort_controls.visible = true
+ _refresh_cooler_notepad_action_interactivity()
+ _configure_cooler_fish_focus()
+
+
+func _refresh_cooler_notepad_action_interactivity() -> void:
var detail_interactive: bool = (
_detail_constellation.visible
+ and _current_section == Section.COOLER
+ and (visible or _shop_cooler_context_active)
and not _transitioning
and not _page_transitioning
+ and not _sale_confirmation.visible
)
- for action: NotepadInkActionType in [_favorite_bubble, _sell_bubble]:
+ for action: NotepadInkActionType in [
+ _favorite_bubble,
+ _sell_bubble,
+ _sell_all_bubble,
+ ]:
var action_interactive: bool = detail_interactive and not action.disabled
- action.focus_mode = (
- Control.FOCUS_ALL
- if action_interactive
- else Control.FOCUS_NONE
- )
- action.mouse_filter = (
- Control.MOUSE_FILTER_STOP
- if action_interactive
- else Control.MOUSE_FILTER_IGNORE
- )
+ if action_interactive:
+ action.focus_mode = Control.FOCUS_ALL
+ action.mouse_filter = Control.MOUSE_FILTER_STOP
+ else:
+ action.focus_mode = Control.FOCUS_NONE
+ action.mouse_filter = Control.MOUSE_FILTER_IGNORE
action.refresh_ink_state()
- _configure_cooler_fish_focus()
func _update_sale_summary() -> void:
@@ -3144,6 +3888,7 @@ func _update_sale_summary() -> void:
var buyer_id: StringName = (
active_buyer.id if active_buyer != null else StringName()
)
+ _update_sell_all_action(active_buyer, buyer_id)
var offer_label: String = _get_offer_label(active_buyer)
var selected_ids: Array[StringName] = _fish_selection.get_selected_ids()
var selected_count: int = selected_ids.size()
@@ -3228,12 +3973,8 @@ func _update_sale_summary() -> void:
or preview.status == FishSaleResultType.Status.FAVORITED
)
):
- _selection_summary.text += "\n%s total offer: $%d" % [
- active_buyer.display_name,
- preview.payout,
- ]
_set_cooler_selection_summary(selected_count, preview.payout)
- _offer_status.set_content(offer_label, "$%d" % preview.payout)
+ _offer_status.set_currency_amount(offer_label, preview.payout)
else:
_set_cooler_selection_summary(selected_count, -1)
_offer_status.set_content(offer_label, "unavailable")
@@ -3253,6 +3994,55 @@ func _update_sale_summary() -> void:
_sale_unavailable.visible = not _sale_unavailable.text.is_empty()
+func _update_sell_all_action(
+ active_buyer: FishBuyerProfileType,
+ buyer_id: StringName,
+) -> void:
+ var sell_all_ids: Array[StringName] = _get_sell_all_catch_ids()
+ var sale_available: bool = (
+ not _sale_in_progress
+ and (
+ _network_sale_service == null
+ or not _network_sale_service.is_local_sale_pending()
+ )
+ and _network_sale_service != null
+ and not buyer_id.is_empty()
+ and _network_sale_service.can_request_sale(buyer_id)
+ and _sale_service != null
+ and active_buyer != null
+ and not sell_all_ids.is_empty()
+ )
+ if sale_available:
+ var preview: FishSaleResultType = _sale_service.preview_batch(
+ sell_all_ids,
+ active_buyer,
+ )
+ sale_available = preview.is_success()
+ _sell_all_bubble.text = "sell all fish"
+ _sell_all_bubble.disabled = not sale_available
+ _sell_all_bubble.persistent_mark = false
+ _sell_all_bubble.refresh_ink_state()
+
+
+func _get_sell_all_catch_ids() -> Array[StringName]:
+ var catch_ids: Array[StringName] = []
+ if _inventory == null:
+ return catch_ids
+ for fish_catch: FishCatchType in _inventory.get_all_catches():
+ if (
+ fish_catch == null
+ or not fish_catch.is_valid()
+ or fish_catch.is_favorited
+ or (
+ _reservations != null
+ and _reservations.is_fish_reserved(fish_catch.catch_id)
+ )
+ ):
+ continue
+ catch_ids.append(fish_catch.catch_id)
+ return catch_ids
+
+
func _on_favorite_pressed() -> void:
var focused_id: StringName = _fish_selection.get_focused_id()
if _inventory == null or focused_id.is_empty():
@@ -3267,7 +4057,7 @@ func _on_favorite_pressed() -> void:
fish_catch.catch_id,
not fish_catch.is_favorited
):
- _transaction_feedback.text = (
+ _set_transaction_feedback(
"%s %s."
% [
fish_catch.fish.display_name,
@@ -3277,6 +4067,18 @@ func _on_favorite_pressed() -> void:
func _on_sell_pressed() -> void:
+ _begin_sale_confirmation(_fish_selection.get_selected_ids())
+
+
+func _on_sell_all_pressed() -> void:
+ var catch_ids: Array[StringName] = _get_sell_all_catch_ids()
+ if catch_ids.is_empty():
+ _set_transaction_feedback("No sellable fish in the cooler.")
+ return
+ _begin_sale_confirmation(catch_ids)
+
+
+func _begin_sale_confirmation(catch_ids: Array[StringName]) -> void:
var active_buyer: FishBuyerProfileType = _get_active_sale_buyer()
var buyer_id: StringName = (
active_buyer.id if active_buyer != null else StringName()
@@ -3288,31 +4090,30 @@ func _on_sell_pressed() -> void:
and _network_sale_service.is_local_sale_pending()
)
):
- _transaction_feedback.text = "Selling…"
+ _set_transaction_feedback("Selling…")
return
if (
_network_sale_service == null
or buyer_id.is_empty()
or not _network_sale_service.can_request_sale(buyer_id)
):
- _transaction_feedback.text = (
+ _set_transaction_feedback(
"Selling is not supported by this server."
)
return
- var selected_ids: Array[StringName] = _fish_selection.get_selected_ids()
if (
_inventory == null
or _sale_service == null
or active_buyer == null
- or selected_ids.is_empty()
+ or catch_ids.is_empty()
):
return
var preview: FishSaleResultType = _sale_service.preview_batch(
- selected_ids,
+ catch_ids,
active_buyer
)
if not preview.is_success():
- _transaction_feedback.text = (
+ _set_transaction_feedback(
"favorited fish cannot be sold. "
+ "remove them from the selection first."
if preview.status == FishSaleResultType.Status.FAVORITED
@@ -3320,21 +4121,21 @@ func _on_sell_pressed() -> void:
)
_refresh_inventory()
return
- _confirmation_catch_ids = selected_ids.duplicate()
+ _confirmation_catch_ids = catch_ids.duplicate()
_confirmation_buyer = active_buyer
_confirmation_buyer_id = active_buyer.id
_confirmation_generation = _menu_generation
var fish_label: String = "fish"
_confirmation_message.text = (
- "sell %d %s to the %s for $%d?\ncombined base value: $%d"
- % [
- preview.fish_count,
- fish_label,
- _get_buyer_display_group(active_buyer),
- preview.payout,
- preview.base_value,
- ]
- )
+ "[center]sell %d %s to the %s for %s?\n"
+ + "combined base value: %s[/center]"
+ ) % [
+ preview.fish_count,
+ fish_label,
+ _get_buyer_display_group(active_buyer),
+ CurrencyPresentationType.bbcode_amount(preview.payout, 22),
+ CurrencyPresentationType.bbcode_amount(preview.base_value, 22),
+ ]
_sale_confirmation.visible = true
if _shop_cooler_context_active:
shop_cooler_modal_changed.emit(true)
@@ -3380,7 +4181,7 @@ func _on_confirm_sale_pressed() -> void:
and transaction_generation == _menu_generation
and (visible or _shop_cooler_context_active)
):
- _transaction_feedback.text = "Selling…"
+ _set_transaction_feedback("Selling…")
func _can_use_shared_world_actions() -> bool:
@@ -3393,7 +4194,7 @@ func _can_use_shared_world_actions() -> bool:
func _on_network_sale_pending(_request_id: String) -> void:
_sale_in_progress = true
if visible or _shop_cooler_context_active:
- _transaction_feedback.text = "Selling…"
+ _set_transaction_feedback("Selling…")
_update_sale_summary()
@@ -3411,11 +4212,12 @@ func _on_network_sale_finished(
return
_refresh_all()
var feedback_message: String = (
- "Sale complete. $%d received." % payout
+ "Sale complete • %s received."
+ % CurrencyPresentationType.bbcode_amount(payout, 20)
if accepted
else message
)
- _transaction_feedback.text = feedback_message
+ _set_transaction_feedback(feedback_message)
if not accepted:
_sale_unavailable.text = feedback_message
_sale_unavailable.visible = true
@@ -3471,7 +4273,7 @@ func _revalidate_confirmation() -> void:
or _confirmation_buyer.id != _confirmation_buyer_id
):
_close_sale_confirmation()
- _transaction_feedback.text = "sale selection is no longer available."
+ _set_transaction_feedback("sale selection is no longer available.")
return
var preview: FishSaleResultType = _sale_service.preview_batch(
_confirmation_catch_ids,
@@ -3486,7 +4288,7 @@ func _revalidate_confirmation() -> void:
)
):
_close_sale_confirmation()
- _transaction_feedback.text = (
+ _set_transaction_feedback(
"favorited fish cannot be sold. "
+ "remove them from the selection first."
if preview.status == FishSaleResultType.Status.FAVORITED
@@ -3506,6 +4308,10 @@ func _get_buyer_display_group(
return "buyer"
+func _set_transaction_feedback(message: String) -> void:
+ _transaction_feedback.text = "[center]%s[/center]" % message
+
+
func _get_active_sale_buyer() -> FishBuyerProfileType:
if _sale_buyer_override != null and _sale_buyer_override.is_valid():
return _sale_buyer_override
diff --git a/ui/player_menu.tscn b/ui/player_menu.tscn
index c2ebff5..e20077c 100644
--- a/ui/player_menu.tscn
+++ b/ui/player_menu.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=26 format=3]
+[gd_scene load_steps=34 format=3]
[ext_resource type="Script" path="res://ui/player_menu.gd" id="1_menu"]
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
@@ -24,6 +24,14 @@
[ext_resource type="Script" path="res://ui/components/inventory_notepad.gd" id="22_inventory_notepad"]
[ext_resource type="Script" path="res://ui/components/organizer_tab.gd" id="23_organizer_tab"]
[ext_resource type="PackedScene" path="res://ui/the_net_page.tscn" id="24_the_net_page"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/inventory_simple.png" id="25_inventory_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/logbook_icon_simple.png" id="26_logbook_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/fishnet_simple.png" id="27_fishnet_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/mail_simple.png" id="28_mail_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/profile_simple.png" id="29_profile_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/online_simple.png" id="30_online_simple"]
+[ext_resource type="Texture2D" path="res://ui/icons/tab_menu/close.png" id="31_close"]
+[ext_resource type="PackedScene" path="res://ui/components/currency_amount.tscn" id="32_currency"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_collection"]
@@ -217,7 +225,7 @@ theme_override_font_sizes/font_size = 19
text = "cooler notes"
horizontal_alignment = 1
-[node name="NotepadWalletValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
+[node name="NotepadWalletValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation" instance=ExtResource("32_currency")]
unique_name_in_owner = true
layout_mode = 0
offset_left = 18.0
@@ -225,9 +233,7 @@ offset_top = 61.0
offset_right = 138.0
offset_bottom = 84.0
mouse_filter = 2
-theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
-theme_override_font_sizes/font_size = 14
-text = "$0"
+icon_size = 14.0
[node name="NotepadCapacityValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
unique_name_in_owner = true
@@ -360,12 +366,11 @@ mouse_filter = 2
theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
theme_override_font_sizes/font_size = 18
-[node name="CoolerOfferValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerDetailStats/CoolerOfferRow"]
+[node name="CoolerOfferValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerDetailStats/CoolerOfferRow" instance=ExtResource("32_currency")]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
-theme_override_colors/font_color = Color(0.16, 0.16, 0.14, 1)
-theme_override_font_sizes/font_size = 15
+icon_size = 15.0
[node name="CoolerSelectionSummary" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation"]
unique_name_in_owner = true
@@ -386,7 +391,7 @@ grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
theme_override_colors/font_color = Color(0.2, 0.18, 0.15, 0.86)
-theme_override_font_sizes/font_size = 18
+theme_override_font_sizes/font_size = 20
text = "no fish selected"
horizontal_alignment = 1
vertical_alignment = 1
@@ -435,12 +440,11 @@ theme_override_colors/font_color = Color(0.2, 0.18, 0.15, 0.86)
theme_override_font_sizes/font_size = 18
text = "combined offer"
-[node name="CoolerCombinedOfferValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerSelectionSummary/CoolerCombinedOfferRow"]
+[node name="CoolerCombinedOfferValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation/CoolerSelectionSummary/CoolerCombinedOfferRow" instance=ExtResource("32_currency")]
unique_name_in_owner = true
layout_mode = 2
mouse_filter = 2
-theme_override_colors/font_color = Color(0.2, 0.18, 0.15, 0.86)
-theme_override_font_sizes/font_size = 14
+icon_size = 14.0
[node name="FavoriteBubble" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation" instance=ExtResource("12_ink_action")]
unique_name_in_owner = true
@@ -463,6 +467,16 @@ offset_right = 256.0
offset_bottom = 464.0
text = "sell fish"
+[node name="SellAllBubble" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/CoolerPage/DetailConstellation" instance=ExtResource("12_ink_action")]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(122, 44)
+layout_mode = 0
+offset_left = 78.0
+offset_top = 426.0
+offset_right = 200.0
+offset_bottom = 470.0
+text = "sell all fish"
+
[node name="BagPage" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
unique_name_in_owner = true
visible = false
@@ -700,11 +714,13 @@ layout_mode = 2
text = "Select bait or a lure for details."
autowrap_mode = 2
-[node name="TackleEquipButton" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleDetailPanel/Margin/Layout"]
+[node name="TackleEquipButton" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/TackleBoxPage/TackleDetailPanel/Margin/Layout" instance=ExtResource("12_ink_action")]
unique_name_in_owner = true
layout_mode = 2
-custom_minimum_size = Vector2(0, 44)
+custom_minimum_size = Vector2(150, 68)
+size_flags_horizontal = 4
text = "equip worms"
+allow_persistent_mark = true
[node name="LogbookPage" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot"]
unique_name_in_owner = true
@@ -946,24 +962,31 @@ unique_name_in_owner = true
layout_mode = 2
theme_override_constants/separation = 8
-[node name="WalletBalance" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header"]
+[node name="WalletHeading" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header"]
+layout_mode = 2
+text = "wallet"
+theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
+
+[node name="WalletBalance" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Header" instance=ExtResource("32_currency")]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
-text = "wallet: $0"
-theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
+alignment = 0
[node name="Separator" type="HSeparator" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
unique_name_in_owner = true
layout_mode = 2
-[node name="TransactionFeedback" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
+[node name="TransactionFeedback" type="RichTextLabel" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 30)
layout_mode = 2
text = ""
-horizontal_alignment = 1
-theme_override_colors/font_color = Color(1, 0.82, 0.4, 1)
-theme_override_font_sizes/font_size = 21
+bbcode_enabled = true
+fit_content = true
+scroll_active = false
+theme_override_colors/default_color = Color(1, 0.82, 0.4, 1)
+theme_override_font_sizes/normal_font_size = 21
[node name="Content" type="Control" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout"]
unique_name_in_owner = true
@@ -1038,12 +1061,16 @@ layout_mode = 2
text = "0 / 12"
theme_override_colors/font_color = Color(0.208, 0.725, 0.78, 1)
-[node name="HeldValue" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
+[node name="HeldValueHeading" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar"]
+visible = false
+layout_mode = 2
+text = "held fish base value"
+theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
+
+[node name="HeldValue" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection/SortBar" instance=ExtResource("32_currency")]
unique_name_in_owner = true
visible = false
layout_mode = 2
-text = "held fish base value: $0"
-theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
[node name="InventoryBody" type="BoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/MenuPanel/Margin/Layout/Content/InventorySection"]
unique_name_in_owner = true
@@ -1347,12 +1374,15 @@ layout_mode = 2
theme_override_constants/separation = 12
alignment = 1
-[node name="ConfirmationMessage" type="Label" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
+[node name="ConfirmationMessage" type="RichTextLabel" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 64)
layout_mode = 2
-theme_override_font_sizes/font_size = 22
+bbcode_enabled = true
+fit_content = true
+scroll_active = false
+theme_override_font_sizes/normal_font_size = 22
autowrap_mode = 2
-horizontal_alignment = 1
[node name="ConfirmationButtons" type="HBoxContainer" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/SaleConfirmation/ConfirmationMargin/ConfirmationLayout"]
layout_mode = 2
@@ -1388,7 +1418,8 @@ compact_reference_size = Vector2(840, 100)
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "stuff"
+icon = ExtResource("25_inventory_simple")
+tooltip_text = "stuff"
accessibility_name = "stuff"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
@@ -1409,7 +1440,9 @@ deformation_period = 6.4
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "logbook"
+icon = ExtResource("26_logbook_simple")
+tooltip_text = "logbook"
+accessibility_name = "logbook"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 108)
@@ -1429,7 +1462,8 @@ deformation_period = 6.7
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "fishnet"
+icon = ExtResource("27_fishnet_simple")
+tooltip_text = "fishnet"
accessibility_name = "net"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
@@ -1450,7 +1484,9 @@ deformation_period = 6.45
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "mail"
+icon = ExtResource("28_mail_simple")
+tooltip_text = "mail"
+accessibility_name = "mail"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 108)
@@ -1486,7 +1522,9 @@ vertical_alignment = 1
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "profile"
+icon = ExtResource("29_profile_simple")
+tooltip_text = "profile"
+accessibility_name = "profile"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(112, 108)
@@ -1506,7 +1544,9 @@ deformation_period = 6.5
unique_name_in_owner = true
layout_mode = 0
toggle_mode = true
-text = "online"
+texture_filter = 1
+icon = ExtResource("30_online_simple")
+tooltip_text = "online"
accessibility_name = "online"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
@@ -1526,7 +1566,9 @@ deformation_period = 6.4
[node name="CloseButton" type="Button" parent="ResponsivePlayerMenuStage/PlayerMenuPresentationScaleRoot/NavigationCluster"]
unique_name_in_owner = true
layout_mode = 0
-text = "close"
+icon = ExtResource("31_close")
+tooltip_text = "close"
+accessibility_name = "close"
script = ExtResource("6_bubble")
profile = ExtResource("4_profile")
neutral_size = Vector2(96, 94)
diff --git a/ui/players_page.gd b/ui/players_page.gd
index b5a62ee..380299e 100644
--- a/ui/players_page.gd
+++ b/ui/players_page.gd
@@ -1,11 +1,21 @@
class_name PlayersPage
extends Control
+const TOGGLE_STATE_COLOR := Color("c3dfe6")
+
var _service: NetworkPlayerListService
+var _discovery: DiscoveryClient
var _count_label: Label
var _tabs: HBoxContainer
var _list: VBoxContainer
var _status: Label
+var _host_settings_panel: PanelContainer
+var _room_name_edit: LineEdit
+var _online_toggle: Button
+var _online_state_label: Label
+var _discoverable_toggle: Button
+var _discoverable_state_label: Label
+var _host_discovery_status: Label
var _current_tab := 0
@@ -15,13 +25,22 @@ func _ready() -> void:
_build()
-func setup(service: NetworkPlayerListService) -> void:
+func setup(
+ service: NetworkPlayerListService,
+ discovery: DiscoveryClient,
+) -> void:
_service = service
+ _discovery = discovery
_service.entries_changed.connect(_refresh)
_service.moderation_finished.connect(func(_ok: bool, message: String) -> void:
_status.text = message
_refresh()
)
+ if _discovery != null:
+ _discovery.host_settings_changed.connect(
+ _on_host_settings_changed
+ )
+ _discovery.host_status_changed.connect(_on_host_status_changed)
_refresh()
@@ -61,6 +80,7 @@ func _build() -> void:
)
_count_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
tab_row.add_child(_count_label)
+ _build_host_settings(root)
var scroll := ScrollContainer.new()
scroll.custom_minimum_size = Vector2(0, 310)
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
@@ -77,8 +97,104 @@ func _build() -> void:
root.add_child(_status)
+func _build_host_settings(root: VBoxContainer) -> void:
+ _host_settings_panel = PanelContainer.new()
+ _host_settings_panel.add_theme_stylebox_override(
+ "panel", UtilityPageStyle.row_style(false)
+ )
+ root.add_child(_host_settings_panel)
+ var row := HBoxContainer.new()
+ row.custom_minimum_size.y = 58.0
+ row.add_theme_constant_override("separation", 10)
+ _host_settings_panel.add_child(row)
+ var label := Label.new()
+ label.text = "room name"
+ label.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ row.add_child(label)
+ _room_name_edit = LineEdit.new()
+ _room_name_edit.custom_minimum_size = Vector2(300.0, 42.0)
+ _room_name_edit.max_length = DiscoveryClient.MAX_ROOM_NAME_LENGTH
+ _room_name_edit.placeholder_text = "Player Name's Server"
+ UtilityPageStyle.apply_ocean_line_edit(_room_name_edit)
+ _room_name_edit.text_submitted.connect(
+ func(_value: String) -> void: _commit_room_name()
+ )
+ _room_name_edit.focus_exited.connect(_commit_room_name)
+ row.add_child(_room_name_edit)
+ _online_toggle = _build_host_toggle("online", row)
+ _online_state_label = _online_toggle.get_node("StateBadge/State") as Label
+ _online_toggle.pressed.connect(_on_online_pressed)
+ _discoverable_toggle = _build_host_toggle("discovery", row)
+ _discoverable_state_label = (
+ _discoverable_toggle.get_node("StateBadge/State") as Label
+ )
+ _discoverable_toggle.pressed.connect(_on_discoverable_pressed)
+ _host_discovery_status = Label.new()
+ _host_discovery_status.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ _host_discovery_status.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ _host_discovery_status.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ _host_discovery_status.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ _host_discovery_status.add_theme_font_size_override("font_size", 14)
+ _host_discovery_status.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ row.add_child(_host_discovery_status)
+
+
+func _build_host_toggle(label_text: String, row: HBoxContainer) -> Button:
+ var button := Button.new()
+ button.custom_minimum_size = Vector2(150.0, 46.0)
+ button.text = label_text
+ button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ button.clip_contents = false
+ UtilityPageStyle.apply_ocean_button(button)
+ row.add_child(button)
+ var badge := PanelContainer.new()
+ badge.name = "StateBadge"
+ badge.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ badge.z_index = 2
+ button.add_child(badge)
+ badge.set_anchors_preset(Control.PRESET_CENTER_BOTTOM)
+ badge.offset_left = -39.0
+ badge.offset_top = -12.0
+ badge.offset_right = 39.0
+ badge.offset_bottom = 12.0
+ var state_label := Label.new()
+ state_label.name = "State"
+ state_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ state_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ state_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ state_label.add_theme_font_override("font", UtilityPageStyle.TuffyFont)
+ state_label.add_theme_font_size_override("font_size", 15)
+ state_label.add_theme_color_override("font_color", TOGGLE_STATE_COLOR)
+ badge.add_child(state_label)
+ return button
+
+
+func _set_host_toggle_state(
+ button: Button,
+ state_label: Label,
+ state_text: String,
+ enabled: bool,
+) -> void:
+ state_label.text = state_text
+ var badge := state_label.get_parent() as PanelContainer
+ badge.add_theme_stylebox_override(
+ "panel",
+ UtilityPageStyle.rounded_style(
+ UtilityPageStyle.OCEAN_SELECTED
+ if enabled
+ else UtilityPageStyle.OCEAN_FIELD,
+ 12,
+ ),
+ )
+ button.queue_redraw()
+
+
func _select_tab(index: int) -> void:
- if index == 2 and (_service == null or not _service.is_local_host()):
+ if index == 2 and (_service == null or not _service.is_local_moderator()):
return
_current_tab = index
_refresh()
@@ -91,10 +207,13 @@ func _refresh() -> void:
_count_label.text = "%d / %d connected" % [
_service.get_connected_count(), _service.get_max_players(),
]
+ if _current_tab == 2 and not _service.is_local_moderator():
+ _current_tab = 0
for index: int in _tabs.get_child_count():
var button := _tabs.get_child(index) as Button
button.button_pressed = index == _current_tab
- button.visible = index != 2 or _service.is_local_host()
+ button.visible = index != 2 or _service.is_local_moderator()
+ _refresh_host_settings()
for child: Node in _list.get_children():
child.queue_free()
match _current_tab:
@@ -106,8 +225,114 @@ func _refresh() -> void:
_build_ban_rows()
+func _refresh_host_settings() -> void:
+ if _host_settings_panel == null:
+ return
+ var host_visible: bool = _service.is_local_host() and _current_tab == 0
+ _host_settings_panel.visible = host_visible
+ if not host_visible or _discovery == null:
+ return
+ if not _room_name_edit.has_focus():
+ _room_name_edit.text = _discovery.get_room_name()
+ var is_open: bool = _service.is_open_host()
+ var is_discoverable: bool = _discovery.is_discoverable()
+ _set_host_toggle_state(
+ _online_toggle,
+ _online_state_label,
+ "OPEN" if is_open else "CLOSED",
+ is_open,
+ )
+ _set_host_toggle_state(
+ _discoverable_toggle,
+ _discoverable_state_label,
+ "ON" if is_discoverable else "OFF",
+ is_discoverable,
+ )
+ _online_toggle.disabled = not _service.is_local_host()
+ _online_toggle.tooltip_text = (
+ "Close this game to new connections."
+ if is_open
+ else "Open this game so other players can connect."
+ )
+ var can_publish: bool = (
+ _service.is_local_host()
+ and _discovery.is_configured()
+ and is_open
+ )
+ _discoverable_toggle.disabled = not can_publish
+ _discoverable_toggle.tooltip_text = (
+ "Stop advertising this game in the public room browser."
+ if is_discoverable
+ else "Advertise this open game in the public room browser."
+ if can_publish
+ else "Open the game before enabling discovery."
+ if _discovery.is_configured()
+ else "Room discovery is not configured in this build."
+ )
+ _on_host_status_changed(
+ _discovery.get_host_status_message(),
+ _discovery.host_status_is_error(),
+ )
+
+
+func _commit_room_name() -> void:
+ if _discovery == null:
+ return
+ if not _discovery.set_room_name(_room_name_edit.text):
+ _room_name_edit.text = _discovery.get_room_name()
+ else:
+ _room_name_edit.text = _discovery.get_room_name()
+
+
+func _on_online_pressed() -> void:
+ if _service == null or not _service.is_local_host():
+ return
+ _service.set_host_open(not _service.is_open_host())
+ _refresh_host_settings()
+
+
+func _on_discoverable_pressed() -> void:
+ if _discovery == null:
+ return
+ _discovery.set_discoverable(not _discovery.is_discoverable())
+ _refresh_host_settings()
+
+
+func _on_host_settings_changed(
+ room_name: String,
+ discoverable: bool,
+) -> void:
+ if _room_name_edit != null and not _room_name_edit.has_focus():
+ _room_name_edit.text = room_name
+ if _discoverable_state_label != null:
+ _set_host_toggle_state(
+ _discoverable_toggle,
+ _discoverable_state_label,
+ "ON" if discoverable else "OFF",
+ discoverable,
+ )
+ _refresh_host_settings()
+
+
+func _on_host_status_changed(message: String, is_error: bool) -> void:
+ if _host_discovery_status == null:
+ return
+ var tooltip_only: bool = message in [
+ "Open the game before listing it publicly.",
+ "Open the game before enabling discovery.",
+ ]
+ _host_discovery_status.text = "" if tooltip_only else message
+ _host_discovery_status.visible = not _host_discovery_status.text.is_empty()
+ _host_discovery_status.add_theme_color_override(
+ "font_color",
+ UtilityPageStyle.OCEAN_DANGER
+ if is_error
+ else UtilityPageStyle.OCEAN_TEXT_SECONDARY,
+ )
+
+
func _build_active_rows() -> void:
- if _service.is_local_host():
+ if _service.is_local_moderator():
_build_session_artwork_controls()
var entries := _service.get_entries()
if entries.is_empty():
@@ -116,10 +341,12 @@ func _build_active_rows() -> void:
for entry: PlayerListEntry in entries:
var row := _make_row()
var identity := Label.new()
- identity.custom_minimum_size.x = 515
+ identity.custom_minimum_size.x = 430
var markers: Array[String] = []
if entry.is_host:
markers.append("host")
+ if entry.is_operator:
+ markers.append("operator")
if entry.is_local_player:
markers.append("You")
identity.text = "%s%s · %s\n%s" % [
@@ -128,7 +355,7 @@ func _build_active_rows() -> void:
entry.compact_fingerprint,
entry.continuity_state,
]
- identity.tooltip_text = NetworkIdentityCrypto.format_fingerprint(
+ identity.tooltip_text = "Full identity fingerprint:\n%s" % (
entry.full_fingerprint
)
identity.add_theme_color_override(
@@ -158,6 +385,12 @@ func _build_active_rows() -> void:
block.pressed.connect(_confirm_block.bind(entry))
UtilityPageStyle.apply_ocean_button(block)
row.add_child(block)
+ if entry.can_manage_operator:
+ var operator := Button.new()
+ operator.text = "deop" if entry.is_operator else "op"
+ operator.pressed.connect(_confirm_operator.bind(entry))
+ UtilityPageStyle.apply_ocean_button(operator)
+ row.add_child(operator)
var kick := Button.new()
kick.text = "kick"
kick.disabled = not entry.can_kick
@@ -316,6 +549,24 @@ func _confirm_ban(entry: PlayerListEntry) -> void:
)
+func _confirm_operator(entry: PlayerListEntry) -> void:
+ var enabled: bool = not entry.is_operator
+ _confirm(
+ (
+ "Grant operator access to %s for this room session?"
+ if enabled
+ else "Remove operator access from %s?"
+ ) % entry.display_name,
+ func() -> void:
+ _service.set_operator(
+ entry.peer_id,
+ entry.full_fingerprint,
+ enabled,
+ entry.revision,
+ )
+ )
+
+
func _confirm_unban(fingerprint: String) -> void:
_confirm("Unban %s?" % NetworkIdentityCrypto.compact_suffix(fingerprint), func() -> void:
_service.unban(fingerprint)
@@ -336,7 +587,32 @@ func _confirm(text: String, action: Callable) -> void:
func _focus_first() -> void:
- for child: Node in _tabs.get_children():
- if child is Button and child.visible and not child.disabled:
- child.grab_focus()
- return
+ var candidates: Array[Control] = []
+ _collect_focusable_player_controls(self, candidates)
+ if candidates.is_empty():
+ return
+ candidates.sort_custom(func(first: Control, second: Control) -> bool:
+ if not is_equal_approx(first.global_position.y, second.global_position.y):
+ return first.global_position.y < second.global_position.y
+ return first.global_position.x < second.global_position.x
+ )
+ candidates[0].grab_focus()
+
+
+func _collect_focusable_player_controls(
+ root: Node,
+ output: Array[Control],
+) -> void:
+ for child: Node in root.get_children():
+ if child == _tabs:
+ continue
+ var control := child as Control
+ if control != null and not control.is_visible_in_tree():
+ continue
+ if (
+ control != null
+ and control.focus_mode != Control.FOCUS_NONE
+ and not control is ScrollBar
+ ):
+ output.append(control)
+ _collect_focusable_player_controls(child, output)
diff --git a/ui/profile_page.gd b/ui/profile_page.gd
index a5b030c..3fc9fb4 100644
--- a/ui/profile_page.gd
+++ b/ui/profile_page.gd
@@ -3,9 +3,18 @@ extends Control
const CHECK_DEBOUNCE_SECONDS: float = 0.4
const OPTION_GRID_COLUMNS: int = 6
+const FUR_PALETTE_GRID_COLUMNS: int = 10
+const FUR_CHANNEL_ICON_SIZE: int = 20
+const FEATURE_DRAWER_ANIMATION_SECONDS: float = 0.16
const ControllerMappingManagerType = preload(
"res://settings/controller_mapping_manager.gd"
)
+const AnimaleseVoiceType = preload("res://ui/animalese_voice.gd")
+const TypewriterRevealType = preload("res://ui/typewriter_reveal.gd")
+const VoiceProfilesType = preload(
+ "res://player/animalese_voice_profiles.gd"
+)
+const VOICE_CATEGORY_ID: String = "voice"
var _service: NetworkProfileService
var _experience: PlayerExperience
@@ -13,6 +22,12 @@ var _draft_name: String = ""
var _draft_appearance: Dictionary = {}
var _persisted_name: String = ""
var _persisted_appearance: Dictionary = {}
+var _draft_voice_id: String = VoiceProfilesType.DEFAULT_ID
+var _persisted_voice_id: String = VoiceProfilesType.DEFAULT_ID
+var _draft_speech_speed_id: String = VoiceProfilesType.DEFAULT_SPEED_ID
+var _persisted_speech_speed_id: String = VoiceProfilesType.DEFAULT_SPEED_ID
+var _draft_call_id: String = VoiceProfilesType.DEFAULT_CALL_ID
+var _persisted_call_id: String = VoiceProfilesType.DEFAULT_CALL_ID
var _category_id: String = "species"
var _dirty: bool = false
var _allow_duplicate: bool = false
@@ -35,7 +50,13 @@ var _experience_level: Label
var _experience_progress: ProgressBar
var _experience_value: Label
var _feature_preview_cache: Dictionary = {}
+var _fur_swatch_icon_cache: Dictionary = {}
+var _expanded_feature_drawers: Dictionary = {}
+var _feature_drawer_animation_key: String = ""
var _scale_value_label: Label
+var _voice_preview: AnimaleseVoiceType
+var _voice_preview_tween: Tween
+var _active_fur_color_id: String = "fur_pattern"
func _ready() -> void:
@@ -104,6 +125,8 @@ func activate() -> void:
func deactivate() -> void:
visible = false
_debounce.stop()
+ if _voice_preview_tween != null and _voice_preview_tween.is_valid():
+ _voice_preview_tween.kill()
_preview.reset_view()
@@ -368,15 +391,22 @@ func _build_ui() -> void:
UtilityPageStyle.apply_ocean_button(_keep_editing_button)
confirm_buttons.add_child(_keep_editing_button)
+ _voice_preview = AnimaleseVoiceType.new()
+ _voice_preview.name = "ProfileVoicePreview"
+ add_child(_voice_preview)
_build_categories()
func _build_categories() -> void:
for child: Node in _category_list.get_children():
child.queue_free()
- for category_id: String in CharacterCustomizationCatalog.CATEGORY_IDS:
+ var category_ids: Array[String] = []
+ for appearance_category: String in CharacterCustomizationCatalog.CATEGORY_IDS:
+ category_ids.append(appearance_category)
+ category_ids.append(VOICE_CATEGORY_ID)
+ for category_id: String in category_ids:
var button := Button.new()
- button.text = CharacterCustomizationCatalog.category_label(category_id)
+ button.text = _category_label(category_id)
button.toggle_mode = true
button.custom_minimum_size.x = 120.0
button.button_pressed = category_id == _category_id
@@ -392,7 +422,7 @@ func _select_category(category_id: String) -> void:
var button := child as Button
if button != null:
button.button_pressed = button.text == (
- CharacterCustomizationCatalog.category_label(category_id)
+ _category_label(category_id)
)
_refresh_options()
@@ -401,12 +431,15 @@ func _refresh_options() -> void:
for child: Node in _option_list.get_children():
child.queue_free()
var title := Label.new()
- title.text = CharacterCustomizationCatalog.category_label(_category_id)
+ title.text = _category_label(_category_id)
title.add_theme_font_size_override("font_size", 18)
title.add_theme_color_override(
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
)
_option_list.add_child(title)
+ if _category_id == VOICE_CATEGORY_ID:
+ _build_voice_options()
+ return
if _category_id == CharacterCustomizationCatalog.SCALE_CATEGORY_ID:
_build_scale_option()
return
@@ -440,6 +473,160 @@ func _refresh_options() -> void:
_option_list.add_child(button)
+func _category_label(category_id: String) -> String:
+ return (
+ "voice"
+ if category_id == VOICE_CATEGORY_ID
+ else CharacterCustomizationCatalog.category_label(category_id)
+ )
+
+
+func _build_voice_options() -> void:
+ var description := Label.new()
+ description.text = "Choose how your character sounds in chat."
+ description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ description.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ description.add_theme_font_size_override("font_size", 12)
+ description.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ _option_list.add_child(description)
+ var grid := GridContainer.new()
+ grid.columns = 3
+ grid.add_theme_constant_override("h_separation", 6)
+ grid.add_theme_constant_override("v_separation", 4)
+ grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ _option_list.add_child(grid)
+ for option: Dictionary in VoiceProfilesType.OPTIONS:
+ var option_id := str(option.get("id", ""))
+ var button := Button.new()
+ button.text = str(option.get("label", option_id))
+ button.toggle_mode = true
+ button.custom_minimum_size = Vector2(108.0, 32.0)
+ button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ button.button_pressed = _draft_voice_id == option_id
+ button.pressed.connect(_select_voice_option.bind(option_id))
+ UtilityPageStyle.apply_compact_ocean_button(button)
+ grid.add_child(button)
+ var divider := HSeparator.new()
+ divider.custom_minimum_size.y = 2.0
+ _option_list.add_child(divider)
+ var speed_title := Label.new()
+ speed_title.text = "speech speed"
+ speed_title.add_theme_font_size_override("font_size", 13)
+ speed_title.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+ _option_list.add_child(speed_title)
+ var speed_description := Label.new()
+ speed_description.text = "Controls chat speech on this device only."
+ speed_description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ speed_description.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ speed_description.add_theme_font_size_override("font_size", 12)
+ speed_description.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ _option_list.add_child(speed_description)
+ var speed_grid := GridContainer.new()
+ speed_grid.columns = 3
+ speed_grid.add_theme_constant_override("h_separation", 6)
+ speed_grid.add_theme_constant_override("v_separation", 4)
+ speed_grid.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ _option_list.add_child(speed_grid)
+ for option: Dictionary in VoiceProfilesType.SPEED_OPTIONS:
+ var speed_id := str(option.get("id", ""))
+ var speed_button := Button.new()
+ speed_button.text = str(option.get("label", speed_id))
+ speed_button.tooltip_text = "%d characters per second" % roundi(
+ float(option.get("characters_per_second", 28.0))
+ )
+ speed_button.toggle_mode = true
+ speed_button.custom_minimum_size = Vector2(108.0, 32.0)
+ speed_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ speed_button.button_pressed = _draft_speech_speed_id == speed_id
+ speed_button.pressed.connect(
+ _select_speech_speed_option.bind(speed_id)
+ )
+ UtilityPageStyle.apply_compact_ocean_button(speed_button)
+ speed_grid.add_child(speed_button)
+ var call_divider := HSeparator.new()
+ call_divider.custom_minimum_size.y = 2.0
+ _option_list.add_child(call_divider)
+ var call_title := Label.new()
+ call_title.text = "call"
+ call_title.add_theme_font_size_override("font_size", 13)
+ call_title.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+ _option_list.add_child(call_title)
+ var call_description := Label.new()
+ call_description.text = "Press G to make this sound."
+ call_description.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ call_description.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ call_description.add_theme_font_size_override("font_size", 12)
+ call_description.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ _option_list.add_child(call_description)
+ var call_grid := GridContainer.new()
+ call_grid.columns = 2
+ call_grid.add_theme_constant_override("h_separation", 8)
+ call_grid.add_theme_constant_override("v_separation", 8)
+ _option_list.add_child(call_grid)
+ for option: Dictionary in VoiceProfilesType.CALL_OPTIONS:
+ var call_id := str(option.get("id", ""))
+ var call_button := Button.new()
+ call_button.text = str(option.get("label", call_id))
+ call_button.toggle_mode = true
+ call_button.custom_minimum_size = Vector2(108.0, 32.0)
+ call_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
+ call_button.button_pressed = _draft_call_id == call_id
+ call_button.pressed.connect(_select_call_option.bind(call_id))
+ UtilityPageStyle.apply_compact_ocean_button(call_button)
+ call_grid.add_child(call_button)
+
+
+func _select_voice_option(voice_id: String) -> void:
+ if not VoiceProfilesType.is_valid(voice_id):
+ return
+ _draft_voice_id = voice_id
+ _dirty = _draft_differs()
+ _refresh_options()
+ _refresh_actions()
+ _play_voice_preview()
+
+
+func _select_speech_speed_option(speed_id: String) -> void:
+ if not VoiceProfilesType.is_valid_speed(speed_id):
+ return
+ _draft_speech_speed_id = speed_id
+ _dirty = _draft_differs()
+ _refresh_options()
+ _refresh_actions()
+ _play_voice_preview()
+
+
+func _select_call_option(call_id: String) -> void:
+ if not VoiceProfilesType.is_valid_call(call_id):
+ return
+ _draft_call_id = call_id
+ _dirty = _draft_differs()
+ _refresh_options()
+ _refresh_actions()
+
+
+func _play_voice_preview() -> void:
+ if _voice_preview_tween != null and _voice_preview_tween.is_valid():
+ _voice_preview_tween.kill()
+ _voice_preview_tween = _voice_preview.speak_text(
+ self,
+ "hello there!",
+ "profile-preview",
+ _draft_voice_id,
+ VoiceProfilesType.speed_for(_draft_speech_speed_id),
+ )
+
+
func _build_scale_option() -> void:
var description := Label.new()
description.text = "Adjust your character's visual size."
@@ -506,7 +693,7 @@ func _build_scale_option() -> void:
_option_list.add_child(gameplay_note)
-func _build_feature_preview_options(options: Array) -> void:
+func _build_feature_preview_options(_options: Array) -> void:
var scroll := ScrollContainer.new()
scroll.custom_minimum_size = Vector2(190.0, 0.0)
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
@@ -522,45 +709,153 @@ func _build_feature_preview_options(options: Array) -> void:
var selected_id := CharacterCustomizationCatalog.canonical_option_id(
_category_id, str(_draft_appearance.get(_category_id, ""))
)
- for option: Dictionary in options:
- var option_id := str(option.get("id", ""))
- var button := Button.new()
- var is_none := option_id == "none"
- button.text = "×" if is_none else ""
- button.tooltip_text = "none" if is_none else str(
- option.get("label", option_id)
+ var groups: Array = CharacterCustomizationCatalog.feature_option_groups(
+ _category_id
+ )
+ var expanded_drawer_id := str(
+ _expanded_feature_drawers.get(_category_id, "")
+ )
+ if expanded_drawer_id.is_empty():
+ for group: Dictionary in groups:
+ var group_options: Array = group.get("options", []) as Array
+ if group_options.size() <= 1:
+ continue
+ var representative_id := str(
+ (group_options[0] as Dictionary).get("id", "")
+ )
+ for option: Dictionary in group_options:
+ if (
+ str(option.get("id", "")) == selected_id
+ and selected_id != representative_id
+ ):
+ expanded_drawer_id = str(group.get("id", ""))
+ _expanded_feature_drawers[_category_id] = (
+ expanded_drawer_id
+ )
+ break
+ if not expanded_drawer_id.is_empty():
+ break
+
+ var animation_key := _feature_drawer_animation_key
+ for group: Dictionary in groups:
+ var group_id := str(group.get("id", ""))
+ var group_options: Array = group.get("options", []) as Array
+ if group_options.is_empty():
+ continue
+ var has_variants := group_options.size() > 1
+ var is_expanded := has_variants and group_id == expanded_drawer_id
+ for option_index: int in range(group_options.size()):
+ if option_index > 0 and not is_expanded:
+ continue
+ var option: Dictionary = group_options[option_index] as Dictionary
+ var button := _build_feature_option_button(
+ option,
+ selected_id,
+ group_id,
+ option_index == 0,
+ has_variants,
+ is_expanded,
+ )
+ grid.add_child(button)
+ if (
+ option_index > 0
+ and animation_key == "%s:%s" % [_category_id, group_id]
+ ):
+ _animate_feature_drawer_button(button)
+ _feature_drawer_animation_key = ""
+
+
+func _build_feature_option_button(
+ option: Dictionary,
+ selected_id: String,
+ drawer_id: String,
+ is_representative: bool,
+ has_variants: bool,
+ is_expanded: bool,
+) -> Button:
+ var option_id := str(option.get("id", ""))
+ var button := Button.new()
+ var is_none := option_id == "none"
+ button.text = "×" if is_none else ""
+ button.tooltip_text = "none" if is_none else str(
+ option.get("label", option_id)
+ )
+ if is_representative and has_variants:
+ button.tooltip_text += (
+ " (hide variants)" if is_expanded else " (show variants)"
)
- button.toggle_mode = true
- button.button_pressed = selected_id == option_id
- button.custom_minimum_size = Vector2(84.0, 64.0)
- button.alignment = HORIZONTAL_ALIGNMENT_CENTER
- button.clip_contents = true
+ button.toggle_mode = true
+ button.button_pressed = selected_id == option_id
+ button.custom_minimum_size = Vector2(84.0, 64.0)
+ button.alignment = HORIZONTAL_ALIGNMENT_CENTER
+ button.clip_contents = true
+ if is_representative and has_variants:
+ button.pressed.connect(
+ _select_feature_drawer.bind(_category_id, drawer_id, option_id)
+ )
+ else:
button.pressed.connect(_select_option.bind(_category_id, option_id))
- UtilityPageStyle.apply_compact_ocean_button(button)
- button.custom_minimum_size = Vector2(84.0, 64.0)
- if is_none:
- button.add_theme_font_size_override("font_size", 28)
- else:
- var preview := TextureRect.new()
- preview.texture = _feature_preview_texture(
- _category_id, option_id
- )
- preview.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
- preview.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
- preview.mouse_filter = Control.MOUSE_FILTER_IGNORE
- var preview_height := 50.0
- var preview_width := clampf(
- preview_height * PlayerVisualPresenter.feature_uv_aspect(
- _category_id
- ),
- 32.0,
- 74.0,
- )
- preview.custom_minimum_size = Vector2(preview_width, preview_height)
- preview.size = Vector2(preview_width, preview_height)
- preview.position = Vector2((84.0 - preview_width) * 0.5, 7.0)
- button.add_child(preview)
- grid.add_child(button)
+ UtilityPageStyle.apply_compact_ocean_button(button)
+ button.custom_minimum_size = Vector2(84.0, 64.0)
+ if is_none:
+ button.add_theme_font_size_override("font_size", 28)
+ else:
+ var preview := TextureRect.new()
+ preview.texture = _feature_preview_texture(_category_id, option_id)
+ preview.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
+ preview.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
+ preview.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ var preview_height := 50.0
+ var preview_width := clampf(
+ preview_height * PlayerVisualPresenter.feature_uv_aspect(_category_id),
+ 32.0,
+ 74.0,
+ )
+ preview.custom_minimum_size = Vector2(preview_width, preview_height)
+ preview.size = Vector2(preview_width, preview_height)
+ preview.position = Vector2((84.0 - preview_width) * 0.5, 7.0)
+ button.add_child(preview)
+ if is_representative and has_variants:
+ var indicator := Label.new()
+ indicator.text = "<" if is_expanded else ">"
+ indicator.position = Vector2(66.0, 1.0)
+ indicator.size = Vector2(14.0, 16.0)
+ indicator.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ indicator.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ indicator.add_theme_font_size_override("font_size", 13)
+ indicator.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+ button.add_child(indicator)
+ return button
+
+
+func _select_feature_drawer(
+ category_id: String,
+ drawer_id: String,
+ option_id: String,
+) -> void:
+ if str(_expanded_feature_drawers.get(category_id, "")) == drawer_id:
+ _expanded_feature_drawers.erase(category_id)
+ else:
+ _expanded_feature_drawers[category_id] = drawer_id
+ _feature_drawer_animation_key = "%s:%s" % [category_id, drawer_id]
+ _select_option(category_id, option_id)
+
+
+func _animate_feature_drawer_button(button: Button) -> void:
+ button.scale = Vector2(0.05, 1.0)
+ var faded := button.modulate
+ faded.a = 0.0
+ button.modulate = faded
+ var tween := button.create_tween()
+ tween.set_parallel(true)
+ tween.tween_property(
+ button, "scale", Vector2.ONE, FEATURE_DRAWER_ANIMATION_SECONDS
+ ).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
+ tween.tween_property(
+ button, "modulate:a", 1.0, FEATURE_DRAWER_ANIMATION_SECONDS
+ ).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
func _feature_preview_texture(
@@ -591,30 +886,167 @@ func _feature_preview_texture(
func _build_fur_color_options(options: Array) -> void:
- var grid := GridContainer.new()
- grid.columns = OPTION_GRID_COLUMNS
- grid.add_theme_constant_override("h_separation", 10)
- grid.add_theme_constant_override("v_separation", 10)
- _option_list.add_child(grid)
- var selected_id: String = CharacterCustomizationCatalog.canonical_option_id(
- "fur_pattern", str(_draft_appearance.get("fur_pattern", "white"))
+ var pattern_label := Label.new()
+ pattern_label.text = "pattern"
+ pattern_label.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
)
+ _option_list.add_child(pattern_label)
+ var pattern_row := HBoxContainer.new()
+ pattern_row.add_theme_constant_override("separation", 8)
+ _option_list.add_child(pattern_row)
+ var selected_style_id := str(_draft_appearance.get(
+ CharacterCustomizationCatalog.FUR_STYLE_ID,
+ CharacterCustomizationCatalog.DEFAULT_FUR_STYLE,
+ ))
+ for pattern_option: Dictionary in CharacterCustomizationCatalog.options_for(
+ CharacterCustomizationCatalog.FUR_STYLE_ID
+ ):
+ var pattern_id := str(pattern_option.get("id", ""))
+ var pattern_button := Button.new()
+ pattern_button.text = str(pattern_option.get("label", pattern_id))
+ pattern_button.toggle_mode = true
+ pattern_button.button_pressed = selected_style_id == pattern_id
+ pattern_button.custom_minimum_size = Vector2(118.0, 32.0)
+ pattern_button.pressed.connect(_select_option.bind(
+ CharacterCustomizationCatalog.FUR_STYLE_ID,
+ pattern_id,
+ ))
+ UtilityPageStyle.apply_compact_ocean_button(pattern_button)
+ pattern_row.add_child(pattern_button)
+
+ var channel_label := Label.new()
+ channel_label.text = "color channel"
+ channel_label.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+ _option_list.add_child(channel_label)
+ var channel_grid := GridContainer.new()
+ channel_grid.columns = 2
+ channel_grid.add_theme_constant_override("h_separation", 8)
+ channel_grid.add_theme_constant_override("v_separation", 8)
+ _option_list.add_child(channel_grid)
+ for color_category_id: String in CharacterCustomizationCatalog.FUR_COLOR_IDS:
+ var selected_color_id := str(_draft_appearance.get(
+ color_category_id,
+ "white",
+ ))
+ var selected_color := CharacterCustomizationCatalog.option_color(
+ color_category_id,
+ selected_color_id,
+ )
+ var channel_button := Button.new()
+ channel_button.text = CharacterCustomizationCatalog.fur_color_label(
+ color_category_id
+ )
+ channel_button.icon = _fur_swatch_icon(selected_color)
+ channel_button.icon_alignment = HORIZONTAL_ALIGNMENT_LEFT
+ channel_button.alignment = HORIZONTAL_ALIGNMENT_LEFT
+ channel_button.add_theme_constant_override(
+ "icon_max_width", FUR_CHANNEL_ICON_SIZE
+ )
+ channel_button.add_theme_constant_override("h_separation", 8)
+ channel_button.tooltip_text = "Edit %s: %s" % [
+ CharacterCustomizationCatalog.fur_color_label(color_category_id),
+ _fur_option_label(options, selected_color_id),
+ ]
+ channel_button.toggle_mode = true
+ channel_button.custom_minimum_size = Vector2(140.0, 34.0)
+ channel_button.button_pressed = (
+ _active_fur_color_id == color_category_id
+ )
+ channel_button.pressed.connect(
+ _select_fur_color_slot.bind(color_category_id)
+ )
+ UtilityPageStyle.apply_compact_ocean_button(channel_button)
+ channel_grid.add_child(channel_button)
+
+ _build_fur_palette(_active_fur_color_id, options)
+
+
+func _build_fur_palette(category_id: String, options: Array) -> void:
+ var selected_id: String = CharacterCustomizationCatalog.canonical_option_id(
+ category_id,
+ str(_draft_appearance.get(category_id, "white")),
+ )
+ var label := Label.new()
+ label.text = "%s palette" % CharacterCustomizationCatalog.fur_color_label(
+ category_id
+ )
+ label.add_theme_font_size_override("font_size", 14)
+ label.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+ _option_list.add_child(label)
+
+ var grid := GridContainer.new()
+ grid.columns = FUR_PALETTE_GRID_COLUMNS
+ grid.add_theme_constant_override("h_separation", 6)
+ grid.add_theme_constant_override("v_separation", 6)
+ _option_list.add_child(grid)
for option: Dictionary in options:
var option_id: String = str(option.get("id", ""))
var color: Color = CharacterCustomizationCatalog.option_color(
- "fur_pattern", option_id
+ category_id, option_id
)
var button := Button.new()
button.text = ""
- button.tooltip_text = str(option.get("label", option_id))
+ button.tooltip_text = "%s: %s" % [
+ CharacterCustomizationCatalog.fur_color_label(category_id),
+ str(option.get("label", option_id)),
+ ]
button.toggle_mode = true
- button.custom_minimum_size = Vector2(44.0, 44.0)
+ button.custom_minimum_size = Vector2(30.0, 30.0)
button.button_pressed = selected_id == option_id
- button.pressed.connect(_select_option.bind("fur_pattern", option_id))
+ button.pressed.connect(_select_option.bind(category_id, option_id))
_apply_fur_swatch_style(button, color, button.button_pressed)
grid.add_child(button)
+func _fur_option_label(options: Array, option_id: String) -> String:
+ for option: Dictionary in options:
+ if str(option.get("id", "")) == option_id:
+ return str(option.get("label", option_id))
+ return option_id
+
+
+func _fur_swatch_icon(color: Color) -> Texture2D:
+ var cache_id := color.to_html(true)
+ if _fur_swatch_icon_cache.has(cache_id):
+ return _fur_swatch_icon_cache[cache_id] as Texture2D
+ var image := Image.create(
+ FUR_CHANNEL_ICON_SIZE,
+ FUR_CHANNEL_ICON_SIZE,
+ false,
+ Image.FORMAT_RGBA8,
+ )
+ var center := Vector2.ONE * (float(FUR_CHANNEL_ICON_SIZE) * 0.5)
+ var radius := float(FUR_CHANNEL_ICON_SIZE) * 0.39
+ for y: int in range(FUR_CHANNEL_ICON_SIZE):
+ for x: int in range(FUR_CHANNEL_ICON_SIZE):
+ var sample_position := Vector2(float(x) + 0.5, float(y) + 0.5)
+ var alpha := clampf(
+ radius + 0.8 - sample_position.distance_to(center),
+ 0.0,
+ 1.0,
+ )
+ image.set_pixel(
+ x,
+ y,
+ Color(color.r, color.g, color.b, color.a * alpha),
+ )
+ var texture := ImageTexture.create_from_image(image)
+ _fur_swatch_icon_cache[cache_id] = texture
+ return texture
+
+
+func _select_fur_color_slot(category_id: String) -> void:
+ if category_id not in CharacterCustomizationCatalog.FUR_COLOR_IDS:
+ return
+ _active_fur_color_id = category_id
+ _refresh_options()
+
+
func _apply_fur_swatch_style(
button: Button,
color: Color,
@@ -741,7 +1173,14 @@ func _apply() -> void:
if _service == null:
return
_apply_button.disabled = true
- _service.apply_profile(_draft_name, _draft_appearance, _allow_duplicate)
+ _service.apply_profile(
+ _draft_name,
+ _draft_appearance,
+ _allow_duplicate,
+ _draft_voice_id,
+ _draft_speech_speed_id,
+ _draft_call_id,
+ )
func _on_apply_finished(accepted: bool, message: String) -> void:
@@ -756,8 +1195,19 @@ func _load_persisted() -> void:
return
_persisted_name = _service.get_persisted_name()
_persisted_appearance = _service.get_persisted_appearance()
+ _persisted_voice_id = _service.get_persisted_voice_id()
+ _persisted_speech_speed_id = (
+ _service.get_persisted_speech_speed_id()
+ )
+ _persisted_call_id = _service.get_persisted_call_id()
_draft_name = _persisted_name
_draft_appearance = _persisted_appearance.duplicate(true)
+ _draft_voice_id = _persisted_voice_id
+ _draft_speech_speed_id = _persisted_speech_speed_id
+ _draft_call_id = _persisted_call_id
+ TypewriterRevealType.set_characters_per_second(
+ VoiceProfilesType.speed_for(_persisted_speech_speed_id)
+ )
_name_edit.text = _draft_name
_preview.apply_appearance_profile(_draft_appearance)
_dirty = false
@@ -793,6 +1243,9 @@ func _confirm_pending_action() -> void:
_discard_confirmation.visible = false
if _confirmation_action == "defaults":
_draft_appearance = CharacterCustomizationCatalog.default_snapshot()
+ _draft_voice_id = VoiceProfilesType.DEFAULT_ID
+ _draft_speech_speed_id = VoiceProfilesType.DEFAULT_SPEED_ID
+ _draft_call_id = VoiceProfilesType.DEFAULT_CALL_ID
_preview.apply_appearance_profile(_draft_appearance)
_dirty = _draft_differs()
_refresh_options()
@@ -806,6 +1259,9 @@ func _draft_differs() -> bool:
return (
_draft_name.strip_edges() != _persisted_name
or _draft_appearance != _persisted_appearance
+ or _draft_voice_id != _persisted_voice_id
+ or _draft_speech_speed_id != _persisted_speech_speed_id
+ or _draft_call_id != _persisted_call_id
)
diff --git a/ui/profile_preview.gd b/ui/profile_preview.gd
index 5076cd3..4239ea0 100644
--- a/ui/profile_preview.gd
+++ b/ui/profile_preview.gd
@@ -9,6 +9,7 @@ const UIReferencePresentationType = preload(
)
const FRONT_FACING_YAW: float = PI
const DEFAULT_CAMERA_DISTANCE: float = 1.9
+const DEFAULT_CAMERA_PITCH: float = 0.12
const MIN_CAMERA_DISTANCE: float = 1.05
const MAX_CAMERA_DISTANCE: float = 2.8
const CAMERA_ZOOM_STEP: float = 0.14
@@ -25,7 +26,7 @@ const CAMERA_TARGET_HEIGHT: float = 0.95
var _dragging: bool = false
var _camera_yaw: float = 0.0
-var _camera_pitch: float = 0.0
+var _camera_pitch: float = DEFAULT_CAMERA_PITCH
var _camera_distance: float = DEFAULT_CAMERA_DISTANCE
var _visuals: Node3D
var _controller_mapping_manager: ControllerMappingManagerType
@@ -85,11 +86,9 @@ func apply_appearance_profile(profile: Dictionary) -> void:
func reset_view() -> void:
_preview_root.rotation.y = FRONT_FACING_YAW
_camera_yaw = 0.0
- _camera_pitch = 0.0
+ _camera_pitch = DEFAULT_CAMERA_PITCH
_camera_distance = DEFAULT_CAMERA_DISTANCE
_apply_camera_orbit()
- if _preview_camera != null:
- _preview_camera.position.z = DEFAULT_CAMERA_DISTANCE
func _process(delta: float) -> void:
@@ -144,7 +143,7 @@ func _notification(what: int) -> void:
func _rotate(amount: float) -> void:
- _camera_yaw = fposmod(_camera_yaw + amount, TAU)
+ _camera_yaw = fposmod(_camera_yaw - amount, TAU)
_apply_camera_orbit()
diff --git a/ui/quick_radial_menu.gd b/ui/quick_radial_menu.gd
index 96a9cd5..8ae1720 100644
--- a/ui/quick_radial_menu.gd
+++ b/ui/quick_radial_menu.gd
@@ -9,7 +9,6 @@ const BubbleButtonScene: PackedScene = preload(
const BubbleProfile: BubbleMenuProfile = preload(
"res://ui/components/bubble_menu/bubble_menu_profile.tres"
)
-const SECTOR_COUNT: int = 8
const RING_RADIUS: float = 172.0
const BUBBLE_SIZE: Vector2 = Vector2(92.0, 88.0)
const CONTROLLER_SELECTION_DEADZONE: float = 0.35
@@ -25,6 +24,8 @@ const ACTIONS: Array[StringName] = [
&"online",
&"paint",
&"chat",
+ &"freecam",
+ &"hud",
]
const LABELS: Array[String] = [
"stuff",
@@ -35,13 +36,17 @@ const LABELS: Array[String] = [
"online",
"paint",
"chat",
+ "freecam",
+ "hide hud",
]
+const SECTOR_COUNT: int = 10
var _buttons: Array[BubbleButton] = []
var _is_open: bool = false
var _selected_sector: int = 0
var _controller_selection_mode: bool = false
var _controller_mapping_manager: ControllerMappingManagerType
+var _hud_hidden: bool = false
func setup_controller_mapping(
@@ -58,7 +63,7 @@ func _ready() -> void:
bubble.profile = BubbleProfile
bubble.focus_mode = Control.FOCUS_NONE
bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
- bubble.text = LABELS[sector]
+ bubble.text = _label_for_sector(sector)
add_child(bubble)
_buttons.append(bubble)
_apply_selection_styles()
@@ -88,6 +93,7 @@ func open_menu(controller_selection: bool = false) -> void:
_selected_sector = 0
_controller_selection_mode = controller_selection
visible = true
+ _refresh_labels()
_layout_bubbles()
_apply_selection_styles()
@@ -101,6 +107,22 @@ func is_open() -> bool:
return _is_open
+func set_hud_hidden(hidden: bool) -> void:
+ _hud_hidden = hidden
+ _refresh_labels()
+
+
+func _refresh_labels() -> void:
+ for sector: int in _buttons.size():
+ _buttons[sector].text = _label_for_sector(sector)
+
+
+func _label_for_sector(sector: int) -> String:
+ if ACTIONS[sector] == &"hud":
+ return "show hud" if _hud_hidden else "hide hud"
+ return LABELS[sector]
+
+
func _emit_selected_action(action_id: StringName) -> void:
action_selected.emit(action_id)
@@ -157,7 +179,8 @@ func _update_mouse_selection() -> void:
func _select_sector_from_offset(offset: Vector2) -> void:
- var angle: float = fposmod(offset.angle() + PI * 0.5 + PI / 8.0, TAU)
+ var half_sector: float = TAU / (float(SECTOR_COUNT) * 2.0)
+ var angle: float = fposmod(offset.angle() + PI * 0.5 + half_sector, TAU)
var sector: int = int(floor(angle / (TAU / float(SECTOR_COUNT))))
if sector == _selected_sector:
return
diff --git a/ui/settings/settings_bubble_page.gd b/ui/settings/settings_bubble_page.gd
index 1ccff30..dd01309 100644
--- a/ui/settings/settings_bubble_page.gd
+++ b/ui/settings/settings_bubble_page.gd
@@ -1,6 +1,10 @@
class_name SettingsBubblePage
extends Control
+const ControllerFocusNavigationType = preload(
+ "res://ui/controller_focus_navigation.gd"
+)
+
@export var page_id: StringName
@export var cluster_path: NodePath = ^"BubbleCluster"
@export var bubble_paths: Array[NodePath] = []
@@ -15,7 +19,7 @@ extends Control
var _cluster: BubbleCluster
var _bubbles: Array[BubbleButton] = []
-var _focus_bubbles: Array[BubbleButton] = []
+var _focus_controls: Array[Control] = []
var _transition: Tween
var _transition_generation: int = 0
var _resting_cluster_position: Vector2 = Vector2.ZERO
@@ -29,9 +33,9 @@ func _ready() -> void:
if bubble != null:
_bubbles.append(bubble)
for path: NodePath in focus_paths:
- var bubble := get_node(path) as BubbleButton
- if bubble != null:
- _focus_bubbles.append(bubble)
+ var focus_control := get_node(path) as Control
+ if focus_control != null:
+ _focus_controls.append(focus_control)
_cluster.configure(_bubbles)
_configure_focus_order()
resized.connect(_update_layout)
@@ -169,23 +173,13 @@ func _update_layout() -> void:
_cluster.position = _resting_cluster_position
_cluster.size = field_size
_cluster.apply_layout(field_size, compact)
+ ControllerFocusNavigationType.configure_spatial_neighbors(_focus_controls)
func _configure_focus_order() -> void:
for bubble: BubbleButton in _bubbles:
bubble.focus_mode = Control.FOCUS_NONE
- for index: int in _focus_bubbles.size():
- var bubble: BubbleButton = _focus_bubbles[index]
- if index > 0:
- bubble.focus_neighbor_top = bubble.get_path_to(
- _focus_bubbles[index - 1]
- )
- bubble.focus_neighbor_left = bubble.focus_neighbor_top
- if index + 1 < _focus_bubbles.size():
- bubble.focus_neighbor_bottom = bubble.get_path_to(
- _focus_bubbles[index + 1]
- )
- bubble.focus_neighbor_right = bubble.focus_neighbor_bottom
+ ControllerFocusNavigationType.configure_spatial_neighbors(_focus_controls)
func _set_interactive(interactive: bool) -> void:
@@ -194,11 +188,11 @@ func _set_interactive(interactive: bool) -> void:
if interactive
else Control.MOUSE_FILTER_IGNORE
)
- for bubble: BubbleButton in _focus_bubbles:
- bubble.focus_mode = (
+ for focus_control: Control in _focus_controls:
+ focus_control.focus_mode = (
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
)
- bubble.mouse_filter = (
+ focus_control.mouse_filter = (
Control.MOUSE_FILTER_STOP
if interactive
else Control.MOUSE_FILTER_IGNORE
diff --git a/ui/settings_panel.gd b/ui/settings_panel.gd
index 768980a..4a7ec9b 100644
--- a/ui/settings_panel.gd
+++ b/ui/settings_panel.gd
@@ -5,6 +5,7 @@ const MAX_PANEL_SIZE: Vector2 = Vector2(960.0, 700.0)
const PANEL_EDGE_MARGIN: float = 16.0
const PAGE_ROOT: StringName = &"root"
const PAGE_DISPLAY: StringName = &"display"
+const PAGE_SOUND: StringName = &"sound"
const PAGE_CONTROLS: StringName = &"controls"
const PAGE_ACCESSIBILITY: StringName = &"accessibility"
const PAGE_DATA: StringName = &"data"
@@ -40,6 +41,7 @@ enum PresentationMode {
@onready var _root_page: SettingsBubblePage = %RootPage
@onready var _display_page: SettingsBubblePage = %DisplayPage
+@onready var _sound_page: SettingsBubblePage = %SoundPage
@onready var _controls_page: SettingsBubblePage = %ControlsPage
@onready var _accessibility_page: SettingsBubblePage = %AccessibilityPage
@onready var _data_page: SettingsBubblePage = %DataPage
@@ -50,11 +52,21 @@ enum PresentationMode {
@onready var _chat_dock: BubbleButton = %ChatDock
@onready var _chat_mode: BubbleButton = %ChatMode
@onready var _paint_dock: BubbleButton = %PaintDock
+@onready var _fullscreen_toggle: BubbleButton = %FullscreenToggle
@onready var _mouse_value: BubbleButton = %MouseValue
@onready var _controller_value: BubbleButton = %ControllerValue
@onready var _invert_y_toggle: BubbleButton = %InvertYToggle
+@onready var _on_screen_keyboard_toggle: BubbleButton = %OnScreenKeyboardToggle
@onready var _auto_click_toggle: BubbleButton = %AutoClickToggle
@onready var _auto_click_interval: BubbleButton = %AutoClickIntervalValue
+@onready var _master_volume_slider: HSlider = %MasterVolumeSlider
+@onready var _music_volume_slider: HSlider = %MusicVolumeSlider
+@onready var _effects_volume_slider: HSlider = %EffectsVolumeSlider
+@onready var _environment_volume_slider: HSlider = %EnvironmentVolumeSlider
+@onready var _master_volume_value: Label = %MasterVolumeValue
+@onready var _music_volume_value: Label = %MusicVolumeValue
+@onready var _effects_volume_value: Label = %EffectsVolumeValue
+@onready var _environment_volume_value: Label = %EnvironmentVolumeValue
@onready var _world_options: Array[BubbleButton] = [
%WorldLegible,
@@ -84,6 +96,11 @@ var _auto_click_interval_value: float = 0.20
var _mouse_sensitivity: float = 0.005
var _controller_sensitivity: float = 2.5
var _invert_camera_y: bool = false
+var _on_screen_keyboard_enabled: bool = false
+var _master_volume: float = 1.0
+var _music_volume: float = 1.0
+var _effects_volume: float = 1.0
+var _environment_volume: float = 1.0
var _network_profile: NetworkProfilePreferences
var _network_session: NetworkSession
var _data_root: PlayerDataRoot
@@ -109,11 +126,13 @@ func _ready() -> void:
_pages = {
PAGE_ROOT: _root_page,
PAGE_DISPLAY: _display_page,
+ PAGE_SOUND: _sound_page,
PAGE_CONTROLS: _controls_page,
PAGE_ACCESSIBILITY: _accessibility_page,
PAGE_DATA: _data_page,
}
%DisplayCategory.pressed.connect(_push_page.bind(PAGE_DISPLAY))
+ %SoundCategory.pressed.connect(_push_page.bind(PAGE_SOUND))
%ControlsCategory.pressed.connect(_push_page.bind(PAGE_CONTROLS))
%AccessibilityCategory.pressed.connect(
_push_page.bind(PAGE_ACCESSIBILITY)
@@ -122,12 +141,14 @@ func _ready() -> void:
%ApplySettingsButton.pressed.connect(_apply_settings)
%RootBackButton.pressed.connect(close_panel)
%DisplayBackButton.pressed.connect(handle_back)
+ %SoundBackButton.pressed.connect(handle_back)
%ControlsBackButton.pressed.connect(handle_back)
%ControllerMapping.pressed.connect(_open_controller_mapping)
%AccessibilityBackButton.pressed.connect(handle_back)
%DataBackButton.pressed.connect(handle_back)
%RootBackButton.gui_input.connect(_on_back_bubble_gui_input)
%DisplayBackButton.gui_input.connect(_on_back_bubble_gui_input)
+ %SoundBackButton.gui_input.connect(_on_back_bubble_gui_input)
%ControlsBackButton.gui_input.connect(_on_back_bubble_gui_input)
%AccessibilityBackButton.gui_input.connect(_on_back_bubble_gui_input)
%DataBackButton.gui_input.connect(_on_back_bubble_gui_input)
@@ -135,6 +156,7 @@ func _ready() -> void:
%ChangeDataFolder.pressed.connect(_choose_data_folder)
%ExportPlayerIdentity.pressed.connect(_choose_identity_export.bind("player"))
%ImportPlayerIdentity.pressed.connect(_choose_identity_import.bind("player"))
+ %CopyPlayerFingerprint.pressed.connect(_copy_player_fingerprint)
%ExportHostIdentity.pressed.connect(_choose_identity_export.bind("host"))
%ImportHostIdentity.pressed.connect(_choose_identity_import.bind("host"))
for index: int in _world_options.size():
@@ -148,6 +170,7 @@ func _ready() -> void:
_chat_dock.pressed.connect(_toggle_chat_dock)
_chat_mode.pressed.connect(_toggle_chat_mode)
_paint_dock.pressed.connect(_toggle_paint_dock)
+ _fullscreen_toggle.pressed.connect(_toggle_fullscreen)
%MouseDecrease.pressed.connect(_adjust_mouse_sensitivity.bind(-1))
%MouseIncrease.pressed.connect(_adjust_mouse_sensitivity.bind(1))
_mouse_value.pressed.connect(_adjust_mouse_sensitivity.bind(1))
@@ -161,6 +184,7 @@ func _ready() -> void:
_adjust_controller_sensitivity.bind(1)
)
_invert_y_toggle.pressed.connect(_toggle_invert_y)
+ _on_screen_keyboard_toggle.pressed.connect(_toggle_on_screen_keyboard)
_auto_click_toggle.pressed.connect(_toggle_auto_click)
for control: Control in [_auto_click_toggle, _auto_click_interval]:
control.mouse_entered.connect(
@@ -174,6 +198,18 @@ func _ready() -> void:
_auto_click_interval.pressed.connect(
_adjust_auto_click_interval.bind(1)
)
+ _master_volume_slider.value_changed.connect(
+ _on_audio_volume_changed.bind(&"master")
+ )
+ _music_volume_slider.value_changed.connect(
+ _on_audio_volume_changed.bind(&"music")
+ )
+ _effects_volume_slider.value_changed.connect(
+ _on_audio_volume_changed.bind(&"effects")
+ )
+ _environment_volume_slider.value_changed.connect(
+ _on_audio_volume_changed.bind(&"environment")
+ )
_mouse_value.gui_input.connect(
_on_continuous_value_input.bind(&"mouse")
)
@@ -195,6 +231,7 @@ func _ready() -> void:
_on_controller_mapping_panel_closed
)
_style_data_page()
+ _style_sound_page()
call_deferred("_refresh_panel_size")
@@ -449,6 +486,16 @@ func _refresh_data_page() -> void:
_data_root.override_active
or (_network_session != null and _network_session.is_session_active())
)
+ var fingerprint: String = (
+ _player_identity.fingerprint if _player_identity != null else ""
+ )
+ %CopyPlayerFingerprint.disabled = not NetworkIdentityCrypto.valid_fingerprint(
+ fingerprint
+ )
+ %CopyPlayerFingerprint.text = (
+ "Copy Player Fingerprint · %s"
+ % NetworkIdentityCrypto.compact_suffix(fingerprint)
+ )
func _open_data_folder() -> void:
@@ -456,6 +503,17 @@ func _open_data_folder() -> void:
_feedback.text = "Could not open the data folder."
+func _copy_player_fingerprint() -> void:
+ var fingerprint: String = (
+ _player_identity.fingerprint if _player_identity != null else ""
+ )
+ if not NetworkIdentityCrypto.valid_fingerprint(fingerprint):
+ _feedback.text = "Player identity is unavailable."
+ return
+ DisplayServer.clipboard_set(fingerprint)
+ _feedback.text = "Full player fingerprint copied for server operator setup."
+
+
func _choose_data_folder() -> void:
if _data_root == null or _data_root.override_active:
_feedback.text = "The data folder is externally managed."
@@ -684,7 +742,7 @@ func _identity_operation_allowed() -> bool:
return true
-func _on_identity_operation_finished(success: bool, message: String) -> void:
+func _on_identity_operation_finished(_success: bool, message: String) -> void:
_feedback.text = message
@@ -704,6 +762,11 @@ func _apply_settings() -> void:
edited.mouse_camera_sensitivity = _mouse_sensitivity
edited.controller_camera_sensitivity = _controller_sensitivity
edited.invert_camera_y = _invert_camera_y
+ edited.on_screen_keyboard_enabled = _on_screen_keyboard_enabled
+ edited.master_volume = _master_volume
+ edited.music_volume = _music_volume
+ edited.effects_volume = _effects_volume
+ edited.environment_volume = _environment_volume
if _settings_manager.apply_settings(edited):
if (
_presentation_mode == PresentationMode.TITLE_EMBEDDED
@@ -725,6 +788,18 @@ func _load_controls() -> void:
_mouse_sensitivity = settings.mouse_camera_sensitivity
_controller_sensitivity = settings.controller_camera_sensitivity
_invert_camera_y = settings.invert_camera_y
+ _on_screen_keyboard_enabled = settings.on_screen_keyboard_enabled
+ _master_volume = settings.master_volume
+ _music_volume = settings.music_volume
+ _effects_volume = settings.effects_volume
+ _environment_volume = settings.environment_volume
+ _master_volume_slider.set_value_no_signal(_master_volume * 100.0)
+ _music_volume_slider.set_value_no_signal(_music_volume * 100.0)
+ _effects_volume_slider.set_value_no_signal(_effects_volume * 100.0)
+ _environment_volume_slider.set_value_no_signal(
+ _environment_volume * 100.0
+ )
+ _settings_manager.restore_audio_levels()
_refresh_value_labels()
@@ -747,6 +822,9 @@ func _refresh_value_labels() -> void:
_paint_dock.text = (
"paint dock\n" + ("right" if settings.paint_dock_right else "left")
)
+ _fullscreen_toggle.text = (
+ "fullscreen\n" + ("on" if settings.fullscreen_enabled else "off")
+ )
_mouse_value.text = "mouse\nsensitivity\n%.4f" % _mouse_sensitivity
_controller_value.text = (
"controller\nsensitivity\n%.1f" % _controller_sensitivity
@@ -755,6 +833,10 @@ func _refresh_value_labels() -> void:
"invert\nvertical\ncamera\n"
+ ("on" if _invert_camera_y else "off")
)
+ _on_screen_keyboard_toggle.text = (
+ "on-screen\nkeyboard\n"
+ + ("on" if _on_screen_keyboard_enabled else "off")
+ )
_auto_click_toggle.text = (
"accessibility\nauto-click\n"
+ ("on" if _auto_click_enabled else "off")
@@ -762,6 +844,7 @@ func _refresh_value_labels() -> void:
_auto_click_interval.text = (
"auto-click\ninterval\n%.2f s" % _auto_click_interval_value
)
+ _refresh_audio_value_labels()
for index: int in _world_options.size():
_world_options[index].button_pressed = (
index + 1 == settings.world_pixel_size
@@ -794,6 +877,49 @@ func _style_data_page() -> void:
)
+func _style_sound_page() -> void:
+ UtilityPageStyle.apply_page(_sound_page)
+ var paper := _sound_page.get_node("Paper") as PanelContainer
+ paper.add_theme_stylebox_override(
+ "panel", UtilityPageStyle.panel_style()
+ )
+ var content := _sound_page.get_node("Paper/Content") as VBoxContainer
+ for node: Node in content.find_children("*", "Label", true, false):
+ (node as Label).add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
+ )
+
+
+func _on_audio_volume_changed(value: float, channel: StringName) -> void:
+ var linear_volume: float = clampf(value / 100.0, 0.0, 1.0)
+ match channel:
+ &"master":
+ _master_volume = linear_volume
+ &"music":
+ _music_volume = linear_volume
+ &"effects":
+ _effects_volume = linear_volume
+ &"environment":
+ _environment_volume = linear_volume
+ _refresh_audio_value_labels()
+ if _settings_manager != null:
+ _settings_manager.preview_audio_levels(
+ _master_volume,
+ _music_volume,
+ _effects_volume,
+ _environment_volume,
+ )
+
+
+func _refresh_audio_value_labels() -> void:
+ _master_volume_value.text = "%d%%" % roundi(_master_volume * 100.0)
+ _music_volume_value.text = "%d%%" % roundi(_music_volume * 100.0)
+ _effects_volume_value.text = "%d%%" % roundi(_effects_volume * 100.0)
+ _environment_volume_value.text = (
+ "%d%%" % roundi(_environment_volume * 100.0)
+ )
+
+
func _set_world_pixelation(pixel_size: int) -> void:
if _settings_manager == null:
return
@@ -840,6 +966,17 @@ func _toggle_chat_mode() -> void:
_refresh_value_labels()
+func _toggle_fullscreen() -> void:
+ if _settings_manager == null:
+ return
+ var edited: PlayerSettings = _settings_manager.current_settings.copy()
+ edited.fullscreen_enabled = not edited.fullscreen_enabled
+ if not _settings_manager.apply_settings(edited):
+ _feedback.text = "failed to save fullscreen setting."
+ return
+ _refresh_value_labels()
+
+
func _toggle_paint_dock() -> void:
if _settings_manager == null:
return
@@ -883,6 +1020,11 @@ func _toggle_invert_y() -> void:
_refresh_value_labels()
+func _toggle_on_screen_keyboard() -> void:
+ _on_screen_keyboard_enabled = not _on_screen_keyboard_enabled
+ _refresh_value_labels()
+
+
func _toggle_auto_click() -> void:
_auto_click_enabled = not _auto_click_enabled
_refresh_value_labels()
diff --git a/ui/settings_panel.tscn b/ui/settings_panel.tscn
index e821c82..df2e261 100644
--- a/ui/settings_panel.tscn
+++ b/ui/settings_panel.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=7 format=3]
+[gd_scene load_steps=9 format=3]
[ext_resource type="Script" path="res://ui/settings_panel.gd" id="1_panel"]
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
@@ -6,6 +6,8 @@
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_button.tscn" id="4_bubble"]
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="5_cluster"]
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="6_profile"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/undo_dark.png" id="7_undo_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/check_mark_dark.png" id="8_check_mark_dark"]
[node name="SettingsPanel" type="Control"]
visible = false
@@ -39,8 +41,8 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_page")
page_id = &"root"
-bubble_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/DataCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
-focus_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/DataCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
+bubble_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/SoundCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/DataCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
+focus_paths = Array[NodePath]([NodePath("BubbleCluster/DisplayCategory"), NodePath("BubbleCluster/SoundCategory"), NodePath("BubbleCluster/ControlsCategory"), NodePath("BubbleCluster/AccessibilityCategory"), NodePath("BubbleCluster/DataCategory"), NodePath("BubbleCluster/ApplySettingsButton"), NodePath("BubbleCluster/RootBackButton")])
initial_focus_path = NodePath("BubbleCluster/DisplayCategory")
back_focus_path = NodePath("BubbleCluster/RootBackButton")
compact_maximum_layout_size = Vector2(544, 400)
@@ -86,6 +88,18 @@ minimum_font_size = 17
maximum_font_size = 25
motion_phase = 1.45
+[node name="SoundCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 0)
+text = "sound"
+neutral_size = Vector2(144, 136)
+desktop_anchor = Vector2(100, 180)
+compact_anchor = Vector2(90, 150)
+compact_minimum_size = Vector2(118, 112)
+minimum_font_size = 17
+maximum_font_size = 25
+motion_phase = 2.0
+
[node name="AccessibilityCategory" parent="RootPage/BubbleCluster" instance=ExtResource("4_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
@@ -109,7 +123,9 @@ offset_left = 474.0
offset_top = 308.0
offset_right = 586.0
offset_bottom = 412.0
-text = "apply"
+icon = ExtResource("8_check_mark_dark")
+tooltip_text = "apply"
+accessibility_name = "apply"
neutral_size = Vector2(112, 104)
desktop_anchor = Vector2(511, 332)
compact_anchor = Vector2(470, 330)
@@ -137,7 +153,9 @@ offset_left = 70.0
offset_top = 343.0
offset_right = 170.0
offset_bottom = 437.0
-text = "back"
+icon = ExtResource("7_undo_dark")
+tooltip_text = "back"
+accessibility_name = "back"
neutral_size = Vector2(100, 94)
desktop_anchor = Vector2(220, 300)
compact_anchor = Vector2(155, 275)
@@ -157,8 +175,8 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_page")
page_id = &"display"
-bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/ChatMode"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/DisplayBackButton")])
-focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/ChatMode"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/DisplayBackButton")])
+bubble_paths = Array[NodePath]([NodePath("BubbleCluster/WorldValue"), NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UIValue"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/ChatMode"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/FullscreenToggle"), NodePath("BubbleCluster/DisplayBackButton")])
+focus_paths = Array[NodePath]([NodePath("BubbleCluster/WorldLegible"), NodePath("BubbleCluster/WorldCute"), NodePath("BubbleCluster/WorldRetro"), NodePath("BubbleCluster/WorldHardcore"), NodePath("BubbleCluster/WorldWtf"), NodePath("BubbleCluster/UILegible"), NodePath("BubbleCluster/UICute"), NodePath("BubbleCluster/UIRetro"), NodePath("BubbleCluster/UIHardcore"), NodePath("BubbleCluster/UIWtf"), NodePath("BubbleCluster/ChatDock"), NodePath("BubbleCluster/ChatMode"), NodePath("BubbleCluster/PaintDock"), NodePath("BubbleCluster/FullscreenToggle"), NodePath("BubbleCluster/DisplayBackButton")])
initial_focus_path = NodePath("BubbleCluster/WorldRetro")
back_focus_path = NodePath("BubbleCluster/DisplayBackButton")
compact_maximum_layout_size = Vector2(544, 400)
@@ -337,8 +355,8 @@ unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "chat dock\nleft"
neutral_size = Vector2(96, 96)
-desktop_anchor = Vector2(105, 435)
-compact_anchor = Vector2(76, 378)
+desktop_anchor = Vector2(70, 435)
+compact_anchor = Vector2(55, 378)
compact_minimum_size = Vector2(82, 82)
minimum_font_size = 12
maximum_font_size = 16
@@ -349,8 +367,8 @@ unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "chat mode\ndesktop"
neutral_size = Vector2(96, 96)
-desktop_anchor = Vector2(275, 435)
-compact_anchor = Vector2(225, 378)
+desktop_anchor = Vector2(215, 435)
+compact_anchor = Vector2(180, 378)
compact_minimum_size = Vector2(82, 82)
minimum_font_size = 12
maximum_font_size = 16
@@ -361,24 +379,215 @@ unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "paint dock\nright"
neutral_size = Vector2(96, 96)
-desktop_anchor = Vector2(445, 435)
-compact_anchor = Vector2(380, 378)
+desktop_anchor = Vector2(360, 435)
+compact_anchor = Vector2(305, 378)
compact_minimum_size = Vector2(82, 82)
minimum_font_size = 12
maximum_font_size = 16
motion_phase = 1.7
+[node name="FullscreenToggle" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 0)
+text = "fullscreen\noff"
+neutral_size = Vector2(104, 96)
+desktop_anchor = Vector2(505, 435)
+compact_anchor = Vector2(430, 378)
+compact_minimum_size = Vector2(88, 82)
+minimum_font_size = 11
+maximum_font_size = 15
+motion_phase = 1.85
+
[node name="DisplayBackButton" parent="DisplayPage/BubbleCluster" instance=ExtResource("4_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "back"
neutral_size = Vector2(96, 90)
-desktop_anchor = Vector2(615, 435)
-compact_anchor = Vector2(530, 378)
+desktop_anchor = Vector2(650, 435)
+compact_anchor = Vector2(555, 378)
compact_minimum_size = Vector2(82, 78)
minimum_font_size = 13
maximum_font_size = 16
-motion_phase = 2.0
+motion_phase = 2.15
+
+[node name="SoundPage" type="Control" parent="."]
+unique_name_in_owner = true
+visible = false
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+script = ExtResource("3_page")
+page_id = &"sound"
+bubble_paths = Array[NodePath]([NodePath("BubbleCluster/SoundBackButton")])
+focus_paths = Array[NodePath]([NodePath("Paper/Content/VolumeGrid/MasterVolumeSlider"), NodePath("Paper/Content/VolumeGrid/MusicVolumeSlider"), NodePath("Paper/Content/VolumeGrid/EffectsVolumeSlider"), NodePath("Paper/Content/VolumeGrid/EnvironmentVolumeSlider"), NodePath("BubbleCluster/SoundBackButton")])
+initial_focus_path = NodePath("Paper/Content/VolumeGrid/MasterVolumeSlider")
+back_focus_path = NodePath("BubbleCluster/SoundBackButton")
+compact_maximum_layout_size = Vector2(544, 400)
+
+[node name="BubbleCluster" type="Control" parent="SoundPage"]
+layout_mode = 0
+offset_right = 720.0
+offset_bottom = 520.0
+script = ExtResource("5_cluster")
+profile = ExtResource("6_profile")
+desktop_reference_size = Vector2(720, 520)
+compact_reference_size = Vector2(608, 448)
+
+[node name="Paper" type="PanelContainer" parent="SoundPage"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -310.0
+offset_top = -230.0
+offset_right = 310.0
+offset_bottom = 205.0
+grow_horizontal = 2
+grow_vertical = 2
+z_index = 1
+
+[node name="Content" type="VBoxContainer" parent="SoundPage/Paper"]
+layout_mode = 2
+theme_override_constants/separation = 18
+
+[node name="Heading" type="Label" parent="SoundPage/Paper/Content"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 28
+text = "sound"
+horizontal_alignment = 1
+
+[node name="Helper" type="Label" parent="SoundPage/Paper/Content"]
+layout_mode = 2
+text = "Adjust the mix. Changes are saved when you apply settings."
+horizontal_alignment = 1
+
+[node name="VolumeGrid" type="GridContainer" parent="SoundPage/Paper/Content"]
+layout_mode = 2
+theme_override_constants/h_separation = 16
+theme_override_constants/v_separation = 18
+columns = 3
+
+[node name="MasterLabel" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+custom_minimum_size = Vector2(118, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "master"
+vertical_alignment = 1
+
+[node name="MasterVolumeSlider" type="HSlider" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(350, 42)
+layout_mode = 2
+focus_mode = 2
+tooltip_text = "master volume"
+max_value = 100.0
+step = 1.0
+value = 100.0
+
+[node name="MasterVolumeValue" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(70, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "100%"
+horizontal_alignment = 2
+vertical_alignment = 1
+
+[node name="MusicLabel" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+custom_minimum_size = Vector2(118, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "music"
+vertical_alignment = 1
+
+[node name="MusicVolumeSlider" type="HSlider" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(350, 42)
+layout_mode = 2
+focus_mode = 2
+tooltip_text = "music volume"
+max_value = 100.0
+step = 1.0
+value = 100.0
+
+[node name="MusicVolumeValue" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(70, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "100%"
+horizontal_alignment = 2
+vertical_alignment = 1
+
+[node name="EffectsLabel" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+custom_minimum_size = Vector2(118, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "effects"
+vertical_alignment = 1
+
+[node name="EffectsVolumeSlider" type="HSlider" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(350, 42)
+layout_mode = 2
+focus_mode = 2
+tooltip_text = "effects volume"
+max_value = 100.0
+step = 1.0
+value = 100.0
+
+[node name="EffectsVolumeValue" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(70, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "100%"
+horizontal_alignment = 2
+vertical_alignment = 1
+
+[node name="EnvironmentLabel" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+custom_minimum_size = Vector2(118, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "environment"
+vertical_alignment = 1
+
+[node name="EnvironmentVolumeSlider" type="HSlider" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(350, 42)
+layout_mode = 2
+focus_mode = 2
+tooltip_text = "environment volume"
+max_value = 100.0
+step = 1.0
+value = 100.0
+
+[node name="EnvironmentVolumeValue" type="Label" parent="SoundPage/Paper/Content/VolumeGrid"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(70, 42)
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "100%"
+horizontal_alignment = 2
+vertical_alignment = 1
+
+[node name="SoundBackButton" parent="SoundPage/BubbleCluster" instance=ExtResource("4_bubble")]
+unique_name_in_owner = true
+z_index = 4
+layout_mode = 0
+text = "back"
+neutral_size = Vector2(96, 90)
+desktop_anchor = Vector2(60, 460)
+compact_anchor = Vector2(55, 410)
+compact_minimum_size = Vector2(82, 78)
+minimum_font_size = 13
+maximum_font_size = 16
+motion_phase = 5.0
[node name="ControlsPage" type="Control" parent="."]
unique_name_in_owner = true
@@ -391,8 +600,8 @@ grow_horizontal = 2
grow_vertical = 2
script = ExtResource("3_page")
page_id = &"controls"
-bubble_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControllerMapping"), NodePath("BubbleCluster/ControlsBackButton")])
-focus_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/ControllerMapping"), NodePath("BubbleCluster/ControlsBackButton")])
+bubble_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/OnScreenKeyboardToggle"), NodePath("BubbleCluster/ControllerMapping"), NodePath("BubbleCluster/ControlsBackButton")])
+focus_paths = Array[NodePath]([NodePath("BubbleCluster/MouseDecrease"), NodePath("BubbleCluster/MouseValue"), NodePath("BubbleCluster/MouseIncrease"), NodePath("BubbleCluster/ControllerDecrease"), NodePath("BubbleCluster/ControllerValue"), NodePath("BubbleCluster/ControllerIncrease"), NodePath("BubbleCluster/InvertYToggle"), NodePath("BubbleCluster/OnScreenKeyboardToggle"), NodePath("BubbleCluster/ControllerMapping"), NodePath("BubbleCluster/ControlsBackButton")])
initial_focus_path = NodePath("BubbleCluster/MouseValue")
back_focus_path = NodePath("BubbleCluster/ControlsBackButton")
@@ -485,17 +694,29 @@ neutral_size = Vector2(176, 170)
compact_minimum_size = Vector2(170, 164)
minimum_font_size = 14
maximum_font_size = 24
-desktop_anchor = Vector2(525, 145)
-compact_anchor = Vector2(485, 135)
+desktop_anchor = Vector2(525, 105)
+compact_anchor = Vector2(485, 95)
motion_phase = 4.5
+[node name="OnScreenKeyboardToggle" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(0, 0)
+text = "on-screen\nkeyboard\noff"
+neutral_size = Vector2(170, 150)
+compact_minimum_size = Vector2(154, 136)
+minimum_font_size = 14
+maximum_font_size = 22
+desktop_anchor = Vector2(525, 255)
+compact_anchor = Vector2(485, 235)
+motion_phase = 4.7
+
[node name="ControllerMapping" parent="ControlsPage/BubbleCluster" instance=ExtResource("4_bubble")]
unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "map\ncontroller"
neutral_size = Vector2(160, 150)
-desktop_anchor = Vector2(525, 330)
-compact_anchor = Vector2(485, 300)
+desktop_anchor = Vector2(525, 390)
+compact_anchor = Vector2(485, 355)
compact_minimum_size = Vector2(148, 138)
minimum_font_size = 14
maximum_font_size = 23
@@ -506,8 +727,8 @@ unique_name_in_owner = true
custom_minimum_size = Vector2(0, 0)
text = "back"
neutral_size = Vector2(100, 94)
-desktop_anchor = Vector2(635, 445)
-compact_anchor = Vector2(555, 405)
+desktop_anchor = Vector2(635, 470)
+compact_anchor = Vector2(555, 420)
compact_minimum_size = Vector2(84, 80)
minimum_font_size = 14
maximum_font_size = 17
@@ -692,6 +913,11 @@ layout_mode = 2
text = "Active identity keys stay on this device.\nEncrypted backups can be stored in your synced data folder.\nDo not play the same profile on two devices at the same time."
autowrap_mode = 2
+[node name="CopyPlayerFingerprint" type="Button" parent="DataPage/Paper/Content"]
+unique_name_in_owner = true
+layout_mode = 2
+text = "Copy Player Fingerprint"
+
[node name="IdentityGrid" type="GridContainer" parent="DataPage/Paper/Content"]
layout_mode = 2
columns = 2
diff --git a/ui/surface_drawing_toolbar.gd b/ui/surface_drawing_toolbar.gd
index 0c13705..e6c8efa 100644
--- a/ui/surface_drawing_toolbar.gd
+++ b/ui/surface_drawing_toolbar.gd
@@ -2,7 +2,16 @@ class_name SurfaceDrawingToolbar
extends Control
const UtilityPageStyleType = preload("res://ui/utility_page_style.gd")
-const TOOLBAR_WIDTH: float = 580.0
+const MARKER_MODE_ICON: Texture2D = preload(
+ "res://items/icons/art/art_kit_marker.png"
+)
+const MARKER_MODE_SHADER: Shader = preload(
+ "res://ui/art_kit_marker_icon.gdshader"
+)
+const GRID_MODE_ICON: Texture2D = preload(
+ "res://items/icons/art/art_kit_grid_light.png"
+)
+const TOOLBAR_WIDTH: float = 510.0
const TOOLBAR_HEIGHT: float = 373.0
const COLOR_RAIL_WIDTH: float = 46.0
@@ -17,12 +26,12 @@ const COLOR_RAIL_WIDTH: float = 46.0
@onready var _hide_guide_button: Button = %HideGuideButton
@onready var _restore_guide_button: Button = %RestoreGuideButton
@onready var _finalize_guide_button: Button = %FinalizeGuideButton
-@onready var _close_button: Button = %CloseButton
var _service: NetworkSurfaceDrawingService
var _unlocks: PlayerArtUnlocks
var _color_buttons: Dictionary[StringName, Button] = {}
var _dock_right: bool = true
+var _marker_mode_material: ShaderMaterial
func _ready() -> void:
@@ -38,6 +47,16 @@ func _ready() -> void:
_make_button_round(button, 22)
_mode_button.custom_minimum_size = Vector2(48, 48)
_make_button_round(_mode_button, 24)
+ _enlarge_action_icon(_mode_button)
+ _marker_mode_material = ShaderMaterial.new()
+ _marker_mode_material.shader = MARKER_MODE_SHADER
+ _marker_mode_material.set_shader_parameter(
+ "marker_color",
+ SurfaceDrawingPalette.get_color(SurfaceDrawingPalette.DEFAULT_COLOR_ID),
+ )
+ _mode_button.material = _marker_mode_material
+ for button: Button in _action_buttons():
+ _enlarge_action_icon(button)
_mode_button.pressed.connect(_toggle_mode)
_eraser_button.pressed.connect(_toggle_eraser)
_undo_button.pressed.connect(_undo_last_stroke)
@@ -50,7 +69,6 @@ func _ready() -> void:
_finalize_guide_button.pressed.connect(
_arm_guide_action.bind(NetworkSurfaceDrawingService.GuideAction.FINALIZE)
)
- _close_button.pressed.connect(_close_toolbar)
_brush_option.item_selected.connect(_select_brush)
_grid_option.item_selected.connect(_select_grid)
_build_options()
@@ -75,7 +93,6 @@ func _action_buttons() -> Array[Button]:
_hide_guide_button,
_restore_guide_button,
_finalize_guide_button,
- _close_button,
]
@@ -91,6 +108,25 @@ func _make_button_round(button: Button, radius: int) -> void:
button.add_theme_stylebox_override(style_name, style)
+func _enlarge_action_icon(button: Button) -> void:
+ # The shared ocean button uses generous text padding, leaving only a
+ # 20-pixel icon area in these compact bubbles. Keep the 48x44 control and
+ # hitbox intact while giving icon-only actions a full 40x40 presentation.
+ button.add_theme_constant_override("icon_max_width", 40)
+ for style_name: StringName in [
+ &"normal", &"hover", &"pressed", &"focus", &"disabled",
+ ]:
+ var existing: StyleBox = button.get_theme_stylebox(style_name)
+ var style := existing.duplicate() as StyleBoxFlat
+ if style == null:
+ continue
+ style.content_margin_left = 4.0
+ style.content_margin_right = 4.0
+ style.content_margin_top = 2.0
+ style.content_margin_bottom = 2.0
+ button.add_theme_stylebox_override(style_name, style)
+
+
func setup(
service: NetworkSurfaceDrawingService,
unlocks: PlayerArtUnlocks,
@@ -125,6 +161,8 @@ func _apply_dock_side() -> void:
offset_right = 0.0 if _dock_right else TOOLBAR_WIDTH
offset_top = 0.0
offset_bottom = TOOLBAR_HEIGHT
+ _top_panel.offset_left = 0.0
+ _top_panel.offset_right = TOOLBAR_WIDTH
_color_panel.offset_left = (
TOOLBAR_WIDTH - COLOR_RAIL_WIDTH if _dock_right else 0.0
)
@@ -255,11 +293,6 @@ func _arm_guide_action(action: int) -> void:
_service.arm_guide_action(action)
-func _close_toolbar() -> void:
- if _service != null:
- _service.deactivate()
-
-
func _on_unlocks_changed(_unlock_mask: int) -> void:
_refresh_unlocks()
@@ -268,7 +301,7 @@ func _on_service_state_changed(
is_active: bool,
mode_name: String,
_color_name: String,
- _color_value: Color,
+ color_value: Color,
brush_size: int,
grid_size: int,
_status: String,
@@ -276,7 +309,15 @@ func _on_service_state_changed(
visible = is_active
if not is_active:
return
- _mode_button.text = "▦" if mode_name == "place grid" else "●"
+ _mode_button.icon = (
+ GRID_MODE_ICON if mode_name == "place grid" else MARKER_MODE_ICON
+ )
+ _marker_mode_material.set_shader_parameter("marker_color", color_value)
+ _mode_button.accessibility_name = (
+ "switch to marker mode"
+ if mode_name == "place grid"
+ else "switch to grid mode"
+ )
_mode_button.tooltip_text = (
"Switch to marker mode"
if mode_name == "place grid"
diff --git a/ui/surface_drawing_toolbar.tscn b/ui/surface_drawing_toolbar.tscn
index 61db805..448cae2 100644
--- a/ui/surface_drawing_toolbar.tscn
+++ b/ui/surface_drawing_toolbar.tscn
@@ -1,7 +1,17 @@
-[gd_scene load_steps=3 format=3]
+[gd_scene load_steps=11 format=3]
[ext_resource type="Script" path="res://ui/surface_drawing_toolbar.gd" id="1_script"]
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/undo_light.png" id="3_undo_light"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_eraser.png" id="4_art_kit_eraser"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_marker.png" id="5_art_kit_marker"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_light.png" id="6_grid_light"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_hidden_light.png" id="7_grid_hidden"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_restore_light.png" id="8_grid_restore"]
+[ext_resource type="Texture2D" path="res://items/icons/art/art_kit_grid_finish_light.png" id="9_grid_finish"]
+
+[sub_resource type="ButtonGroup" id="GuideActionGroup"]
+allow_unpress = true
[node name="SurfaceDrawingToolbar" type="Control"]
visible = false
@@ -10,7 +20,7 @@ layout_mode = 0
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
-offset_left = -580.0
+offset_left = -510.0
offset_bottom = 373.0
grow_horizontal = 0
mouse_filter = 2
@@ -20,19 +30,13 @@ script = ExtResource("1_script")
[node name="TopPanel" type="PanelContainer" parent="."]
unique_name_in_owner = true
layout_mode = 0
-offset_right = 580.0
+offset_right = 510.0
offset_bottom = 60.0
[node name="Top" type="HBoxContainer" parent="TopPanel"]
layout_mode = 2
theme_override_constants/separation = 5
-[node name="ModeButton" type="Button" parent="TopPanel/Top"]
-unique_name_in_owner = true
-layout_mode = 2
-tooltip_text = "switch between grid and marker mode"
-text = "▦"
-
[node name="BrushOption" type="OptionButton" parent="TopPanel/Top"]
unique_name_in_owner = true
custom_minimum_size = Vector2(80, 48)
@@ -48,49 +52,70 @@ tooltip_text = "grid size"
[node name="EraserButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
+texture_filter = 1
tooltip_text = "toggle eraser"
toggle_mode = true
-text = "⌫"
+accessibility_name = "toggle eraser"
+icon = ExtResource("4_art_kit_eraser")
+expand_icon = true
[node name="UndoButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
+texture_filter = 1
tooltip_text = "undo last stroke"
-text = "↶"
+accessibility_name = "undo last stroke"
+icon = ExtResource("3_undo_light")
+expand_icon = true
[node name="HideGuideButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
-tooltip_text = "hide grid on next click"
+texture_filter = 1
+tooltip_text = "toggle hide grid mode"
toggle_mode = true
-text = "◌"
+button_group = SubResource("GuideActionGroup")
+accessibility_name = "toggle hide grid mode"
+icon = ExtResource("7_grid_hidden")
+expand_icon = true
[node name="RestoreGuideButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
-tooltip_text = "restore hidden grid on next click"
+texture_filter = 1
+tooltip_text = "toggle show grid mode"
toggle_mode = true
-text = "▤"
+button_group = SubResource("GuideActionGroup")
+accessibility_name = "toggle show grid mode"
+icon = ExtResource("8_grid_restore")
+expand_icon = true
[node name="FinalizeGuideButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
-tooltip_text = "finish grid on next click"
+texture_filter = 1
+tooltip_text = "toggle finalize grid mode"
toggle_mode = true
-text = "✓"
+button_group = SubResource("GuideActionGroup")
+accessibility_name = "toggle finalize grid mode"
+icon = ExtResource("9_grid_finish")
+expand_icon = true
-[node name="CloseButton" type="Button" parent="TopPanel/Top"]
+[node name="ModeButton" type="Button" parent="TopPanel/Top"]
unique_name_in_owner = true
layout_mode = 2
-tooltip_text = "close art tools"
-text = "×"
+texture_filter = 1
+tooltip_text = "switch between grid and marker mode"
+accessibility_name = "switch to grid mode"
+icon = ExtResource("5_art_kit_marker")
+expand_icon = true
[node name="ColorPanel" type="PanelContainer" parent="."]
unique_name_in_owner = true
layout_mode = 0
-offset_left = 534.0
+offset_left = 464.0
offset_top = 54.0
-offset_right = 580.0
+offset_right = 510.0
offset_bottom = 373.0
[node name="ColorList" type="VBoxContainer" parent="ColorPanel"]
diff --git a/ui/the_net_page.gd b/ui/the_net_page.gd
index 3ee735a..ff83a11 100644
--- a/ui/the_net_page.gd
+++ b/ui/the_net_page.gd
@@ -1,6 +1,10 @@
class_name TheNetPage
extends Control
+const CurrencyPresentationType = preload(
+ "res://ui/currency_presentation.gd"
+)
+
enum View {
DAILY,
LIFETIME,
@@ -154,6 +158,8 @@ func _build_laptop() -> void:
)
forecast_stack.add_child(forecast_heading)
_forecast_list = HBoxContainer.new()
+ _forecast_list.custom_minimum_size = Vector2(272.0, 66.0)
+ _forecast_list.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_forecast_list.alignment = BoxContainer.ALIGNMENT_CENTER
_forecast_list.add_theme_constant_override("separation", 6)
forecast_stack.add_child(_forecast_list)
@@ -278,15 +284,11 @@ func _build_job_rows(jobs: Array[Dictionary], empty_text: String) -> void:
)
content.add_child(count)
- var reward := Label.new()
- reward.custom_minimum_size.x = 98.0
- reward.text = "$%d • %d xp" % [
- int(job.get("fish_coin", 0)), int(job.get("experience", 0)),
- ]
- reward.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
- reward.add_theme_color_override(
- "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ var reward := _make_reward_display(
+ int(job.get("fish_coin", 0)),
+ int(job.get("experience", 0)),
)
+ reward.custom_minimum_size.x = 128.0
content.add_child(reward)
var claim := Button.new()
@@ -326,17 +328,19 @@ func _build_payment_rows() -> void:
var content := HBoxContainer.new()
content.add_theme_constant_override("separation", 14)
row.add_child(content)
+ var reward_details := VBoxContainer.new()
+ reward_details.size_flags_horizontal = Control.SIZE_EXPAND_FILL
var label := Label.new()
- label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
- label.text = "%s\n$%d • %d xp" % [
- str(reward.get("title", "completed job")),
- int(reward.get("fish_coin", 0)),
- int(reward.get("experience", 0)),
- ]
+ label.text = str(reward.get("title", "completed job"))
label.add_theme_color_override(
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
)
- content.add_child(label)
+ reward_details.add_child(label)
+ reward_details.add_child(_make_reward_display(
+ int(reward.get("fish_coin", 0)),
+ int(reward.get("experience", 0)),
+ ))
+ content.add_child(reward_details)
var claim := Button.new()
claim.text = "claim"
claim.custom_minimum_size = Vector2(110.0, 42.0)
@@ -363,6 +367,27 @@ func _claim(claim_id: String) -> void:
_refresh()
+func _make_reward_display(fish_coin: int, experience: int) -> HBoxContainer:
+ var reward := HBoxContainer.new()
+ reward.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ reward.add_theme_constant_override("separation", 7)
+ var currency: CurrencyAmount = (
+ CurrencyPresentationType.instantiate_amount(fish_coin, 18.0)
+ )
+ currency.get_amount_label().add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ reward.add_child(currency)
+ var experience_label := Label.new()
+ experience_label.text = "• %d xp" % experience
+ experience_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ experience_label.add_theme_color_override(
+ "font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
+ )
+ reward.add_child(experience_label)
+ return reward
+
+
func _add_empty(message: String) -> void:
var empty := Label.new()
empty.text = message
@@ -407,9 +432,9 @@ func _refresh_forecast(force: bool) -> void:
slot.mouse_filter = Control.MOUSE_FILTER_IGNORE
_forecast_list.add_child(slot)
var icon := WeatherIcon.new()
- icon.position = Vector2(1.0, 7.0)
- icon.size = Vector2(56.0, 56.0)
- icon.custom_minimum_size = Vector2(56.0, 56.0)
+ icon.position = Vector2(10.5, 17.0)
+ icon.size = Vector2(42.0, 42.0)
+ icon.custom_minimum_size = Vector2(42.0, 42.0)
icon.set_weather(weather)
icon.set_nighttime(
WorldTimeService.phase_for_hour(start_hour)
@@ -417,13 +442,13 @@ func _refresh_forecast(force: bool) -> void:
)
slot.add_child(icon)
var time_label := Label.new()
- time_label.position = Vector2(34.0, 0.0)
- time_label.size = Vector2(29.0, 18.0)
+ time_label.position = Vector2(27.0, 0.0)
+ time_label.size = Vector2(36.0, 22.0)
time_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
time_label.text = _forecast_exponent_time(start_hour)
time_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
time_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
- time_label.add_theme_font_size_override("font_size", 10)
+ time_label.add_theme_font_size_override("font_size", 13)
time_label.add_theme_constant_override("outline_size", 3)
time_label.add_theme_color_override(
"font_color", UtilityPageStyle.OCEAN_TEXT_PRIMARY
@@ -478,7 +503,10 @@ func _daily_refresh_text() -> String:
func _add_forecast_empty(message: String) -> void:
var label := Label.new()
label.text = message
- label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
+ label.custom_minimum_size = Vector2(252.0, 66.0)
+ label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ label.autowrap_mode = TextServer.AUTOWRAP_OFF
label.add_theme_color_override(
"font_color", UtilityPageStyle.OCEAN_TEXT_SECONDARY
)
diff --git a/ui/title_credits_page.gd b/ui/title_credits_page.gd
new file mode 100644
index 0000000..f8841ab
--- /dev/null
+++ b/ui/title_credits_page.gd
@@ -0,0 +1,87 @@
+class_name TitleCreditsPage
+extends Control
+
+signal back_requested(restore_navigation_focus: bool)
+
+@onready var _paper: PanelContainer = %Paper
+@onready var _back_button: Button = %CreditsBackButton
+
+var _navigation_focus_active: bool = false
+
+
+func _ready() -> void:
+ UtilityPageStyle.apply_page(self)
+ _paper.add_theme_stylebox_override(
+ "panel", UtilityPageStyle.panel_style()
+ )
+ UtilityPageStyle.apply_ocean_button(_back_button)
+ _back_button.pressed.connect(_request_back)
+ hide()
+
+
+func open_page(use_navigation_focus: bool) -> void:
+ _navigation_focus_active = use_navigation_focus
+ show()
+ UtilityPageStyle.animate_in(self)
+ if use_navigation_focus:
+ call_deferred("_focus_back")
+ else:
+ _release_page_focus()
+
+
+func close_page() -> void:
+ _navigation_focus_active = false
+ _release_page_focus()
+ hide()
+ scale = Vector2.ONE
+ modulate.a = 1.0
+
+
+func handle_input(event: InputEvent) -> bool:
+ if not visible:
+ return false
+ if event is InputEventMouseMotion:
+ _navigation_focus_active = false
+ _release_page_focus()
+ return false
+ if event is InputEventKey and (event as InputEventKey).echo:
+ return false
+ var moves_focus: bool = (
+ event.is_action_pressed("ui_up")
+ or event.is_action_pressed("ui_down")
+ or event.is_action_pressed("ui_left")
+ or event.is_action_pressed("ui_right")
+ )
+ if moves_focus:
+ _navigation_focus_active = true
+ if not _page_has_focus():
+ _back_button.grab_focus()
+ return true
+ if event.is_action_pressed("ui_cancel"):
+ _request_back()
+ return true
+ return false
+
+
+func get_back_button() -> Button:
+ return _back_button
+
+
+func _focus_back() -> void:
+ if visible and _navigation_focus_active:
+ _back_button.grab_focus()
+
+
+func _request_back() -> void:
+ back_requested.emit(_navigation_focus_active)
+
+
+func _page_has_focus() -> bool:
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ return focus_owner != null and is_ancestor_of(focus_owner)
+
+
+func _release_page_focus() -> void:
+ var focus_owner: Control = get_viewport().gui_get_focus_owner()
+ if focus_owner != null and is_ancestor_of(focus_owner):
+ focus_owner.release_focus()
diff --git a/ui/title_credits_page.gd.uid b/ui/title_credits_page.gd.uid
new file mode 100644
index 0000000..1cbdf93
--- /dev/null
+++ b/ui/title_credits_page.gd.uid
@@ -0,0 +1 @@
+uid://c07nehcd5yw6m
diff --git a/ui/title_credits_page.tscn b/ui/title_credits_page.tscn
new file mode 100644
index 0000000..a667465
--- /dev/null
+++ b/ui/title_credits_page.tscn
@@ -0,0 +1,180 @@
+[gd_scene load_steps=3 format=3]
+
+[ext_resource type="Script" path="res://ui/title_credits_page.gd" id="1_script"]
+[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
+
+[node name="TitleCreditsPage" type="Control"]
+visible = false
+layout_mode = 3
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+mouse_filter = 1
+theme = ExtResource("2_theme")
+script = ExtResource("1_script")
+
+[node name="Paper" type="PanelContainer" parent="."]
+unique_name_in_owner = true
+layout_mode = 0
+offset_left = 160.0
+offset_top = 38.0
+offset_right = 1120.0
+offset_bottom = 682.0
+
+[node name="Margin" type="MarginContainer" parent="Paper"]
+layout_mode = 2
+theme_override_constants/margin_left = 52
+theme_override_constants/margin_top = 26
+theme_override_constants/margin_right = 52
+theme_override_constants/margin_bottom = 24
+
+[node name="Layout" type="VBoxContainer" parent="Paper/Margin"]
+layout_mode = 2
+theme_override_constants/separation = 10
+
+[node name="Title" type="Label" parent="Paper/Margin/Layout"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 36
+text = "credits"
+horizontal_alignment = 1
+
+[node name="Subtitle" type="Label" parent="Paper/Margin/Layout"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 18
+text = "NETfishing is created by Woofmeow"
+horizontal_alignment = 1
+
+[node name="Columns" type="HBoxContainer" parent="Paper/Margin/Layout"]
+layout_mode = 2
+size_flags_vertical = 3
+theme_override_constants/separation = 52
+
+[node name="CreativeCredits" type="VBoxContainer" parent="Paper/Margin/Layout/Columns"]
+custom_minimum_size = Vector2(404, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 5
+
+[node name="CreativeHeading" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 23
+text = "creative team"
+
+[node name="VoyagerName" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 18
+text = "Voyager"
+
+[node name="VoyagerRoles" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "co-owner • development • project direction • 3d art • music"
+autowrap_mode = 2
+
+[node name="EndeavourName" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 18
+text = "Endeavour"
+
+[node name="EndeavourRoles" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "co-owner • development • 2d art"
+autowrap_mode = 2
+
+[node name="ContributorSpacer" type="Control" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+custom_minimum_size = Vector2(0, 9)
+layout_mode = 2
+
+[node name="ContributorHeading" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 23
+text = "additional contributors"
+
+[node name="ChillnfillName" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 18
+text = "chillnfill"
+
+[node name="ChillnfillCredit" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "original 3d models for character bodies and arms, ears and tails, and multiple world props and decorative assets including trees and bridges"
+autowrap_mode = 2
+
+[node name="TekgatorName" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 18
+text = "Tekgator"
+
+[node name="TekgatorCredit" type="Label" parent="Paper/Margin/Layout/Columns/CreativeCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "cooler-capacity, reel-speed, and barrier-power shop icon artwork"
+autowrap_mode = 2
+
+[node name="AdditionalCredits" type="VBoxContainer" parent="Paper/Margin/Layout/Columns"]
+custom_minimum_size = Vector2(404, 0)
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 5
+
+[node name="AudioHeading" type="Label" parent="Paper/Margin/Layout/Columns/AdditionalCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 23
+text = "additional audio"
+
+[node name="AudioCredits" type="Label" parent="Paper/Margin/Layout/Columns/AdditionalCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "tosha73 • fishing reel sounds\nkkenny101 • ocean ambience\nqubodup • water impact\nAyton • rain ambience\nivolipa • dog bark\nChristyboy100 • cat meow"
+
+[node name="TechnologySpacer" type="Control" parent="Paper/Margin/Layout/Columns/AdditionalCredits"]
+custom_minimum_size = Vector2(0, 9)
+layout_mode = 2
+
+[node name="TechnologyHeading" type="Label" parent="Paper/Margin/Layout/Columns/AdditionalCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.902, 0.969, 0.969, 1)
+theme_override_font_sizes/font_size = 23
+text = "fonts & technology"
+
+[node name="TechnologyCredits" type="Label" parent="Paper/Margin/Layout/Columns/AdditionalCredits"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 15
+text = "Tuffy • Thatcher Ulrich, Karoly Barta & Michael Evans\nSeattle Avenue • JLH Fonts\nbuilt with Godot Engine"
+autowrap_mode = 2
+
+[node name="Notice" type="Label" parent="Paper/Margin/Layout"]
+layout_mode = 2
+theme_override_colors/font_color = Color(0.624, 0.812, 0.824, 1)
+theme_override_font_sizes/font_size = 13
+text = "complete attribution, licensing, and asset provenance are included with every release"
+horizontal_alignment = 1
+autowrap_mode = 2
+
+[node name="BackCenter" type="CenterContainer" parent="Paper/Margin/Layout"]
+layout_mode = 2
+
+[node name="CreditsBackButton" type="Button" parent="Paper/Margin/Layout/BackCenter"]
+unique_name_in_owner = true
+custom_minimum_size = Vector2(112, 50)
+layout_mode = 2
+text = "back"
diff --git a/ui/title_screen.gd b/ui/title_screen.gd
index 4531b3f..9e17d3e 100644
--- a/ui/title_screen.gd
+++ b/ui/title_screen.gd
@@ -16,9 +16,13 @@ const BubbleClusterType = preload(
const TitleConfirmationBubblePageType = preload(
"res://ui/title_confirmation_bubble_page.gd"
)
+const TitleCreditsPageType = preload("res://ui/title_credits_page.gd")
const NetworkSessionType = preload("res://network/network_session.gd")
const SavedServerStoreType = preload("res://network/saved_server_store.gd")
const JoinGamePageType = preload("res://ui/network/join_game_page.gd")
+const CurrencyPresentationType = preload(
+ "res://ui/currency_presentation.gd"
+)
const DECORATIVE_FISH_TEXTURES: Array[Texture2D] = [
preload("res://fish/species/bass/fish_bass_striped.png"),
preload("res://fish/species/bluegill/fish_bluegill.png"),
@@ -70,7 +74,7 @@ const LOGO_MAX_WIDTH: float = 662.0
const TITLE_HORIZONTAL_MARGIN: float = 48.0
const TITLE_DESKTOP_REFERENCE_SIZE: Vector2 = Vector2(1280.0, 720.0)
const TITLE_COMPACT_REFERENCE_SIZE: Vector2 = Vector2(640.0, 480.0)
-const BUBBLE_FIELD_MAX_WIDTH: float = 396.0
+const BUBBLE_FIELD_MAX_WIDTH: float = 440.0
const BUBBLE_FIELD_DESKTOP_HEIGHT: float = 318.0
const BUBBLE_FIELD_COMPACT_WIDTH: float = 294.0
const BUBBLE_FIELD_COMPACT_HEIGHT: float = 200.0
@@ -99,12 +103,13 @@ enum ConfirmationAction {
@onready var _continue_button: BubbleButtonType = %ContinueButton
@onready var _new_game_button: BubbleButtonType = %NewGameButton
@onready var _settings_button: BubbleButtonType = %SettingsButton
+@onready var _credits_button: BubbleButtonType = %CreditsButton
@onready var _delete_button: BubbleButtonType = %DeleteSaveButton
@onready var _quit_button: BubbleButtonType = %QuitButton
@onready var _join_game_button: BubbleButtonType = %JoinGameButton
@onready var _new_game_label: Label = %NewGameLabel
@onready var _delete_save_label: Label = %DeleteSaveLabel
-@onready var _feedback_label: Label = %FeedbackLabel
+@onready var _feedback_label: RichTextLabel = %FeedbackLabel
@onready var _confirmation_page: TitleConfirmationBubblePageType = (
%ConfirmationPage
)
@@ -134,6 +139,7 @@ enum ConfirmationAction {
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
@onready var _start_prompt_label: Label = %StartPromptLabel
@onready var _join_game_page: JoinGamePageType = %JoinGamePage
+@onready var _credits_page: TitleCreditsPageType = %CreditsPage
var _save_manager: SaveManagerType
var _settings_manager: SettingsManagerType
@@ -200,6 +206,7 @@ func _ready() -> void:
_new_game_button.pressed.connect(_on_new_game_pressed)
_join_game_button.pressed.connect(_open_join_game)
_settings_button.pressed.connect(_open_settings)
+ _credits_button.pressed.connect(_open_credits)
_delete_button.pressed.connect(_on_delete_pressed)
%QuitButton.pressed.connect(_on_quit_pressed)
_confirmation_page.confirmed.connect(_on_confirmation_accepted)
@@ -211,6 +218,7 @@ func _ready() -> void:
_settings_panel.navigation_transition_started.connect(
_emit_navigation_bubble_flurry
)
+ _credits_page.back_requested.connect(_close_credits)
_bubble_field.configure(_get_title_buttons())
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
_decorative_bubble_event_timer.timeout.connect(
@@ -236,10 +244,13 @@ func setup(
network_session: NetworkSessionType,
saved_servers: SavedServerStoreType,
server_trust: ServerTrustStore,
+ discovery: DiscoveryClient,
) -> void:
_save_manager = save_manager
_settings_manager = settings_manager
- _join_game_page.setup(network_session, saved_servers, false, server_trust)
+ _join_game_page.setup(
+ network_session, saved_servers, false, server_trust, discovery
+ )
_join_game_page.join_requested.connect(join_game_requested.emit)
_join_game_page.back_requested.connect(_close_join_game)
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
@@ -258,12 +269,26 @@ func reopen() -> void:
_reset_confirmation()
_settings_panel.hide()
_join_game_page.close_page()
+ _credits_page.close_page()
_refresh_save_inspection()
show()
_start_decorative_presentation()
_start_entry_prompt_animation()
+func reopen_to_menu() -> void:
+ reopen()
+ _awaiting_start_input = false
+ _stop_entry_prompt_animation()
+ _start_prompt_center.hide()
+ _presentation_center.show()
+ _button_center.show()
+ var bubble_field := get_node_or_null("%BubbleField") as Control
+ if bubble_field != null:
+ bubble_field.show()
+ _set_title_bubbles_interactive(true)
+
+
func open_join_game_page(endpoint: String = "") -> void:
_cancel_title_entry_transition()
_awaiting_start_input = false
@@ -271,19 +296,24 @@ func open_join_game_page(endpoint: String = "") -> void:
_presentation_center.hide()
_settings_panel.hide()
_confirmation_page.hide_page()
+ _credits_page.close_page()
_join_game_page.open_page(endpoint)
func report_network_error(message: String) -> void:
_join_game_page.set_status(message)
if not _join_game_page.visible:
- _feedback_label.text = message
+ _feedback_label.text = _center_feedback_text(message)
_feedback_label.show()
_feedback_label.modulate.a = 1.0
func _open_join_game() -> void:
- if _action_in_progress or _is_confirmation_active():
+ if (
+ _action_in_progress
+ or _is_confirmation_active()
+ or _credits_page.visible
+ ):
return
open_join_game_page()
@@ -296,6 +326,39 @@ func _close_join_game() -> void:
_focus_initial_button()
+func _open_credits() -> void:
+ if (
+ _action_in_progress
+ or _is_confirmation_active()
+ or _settings_panel.visible
+ or _join_game_page.visible
+ or _credits_page.visible
+ ):
+ return
+ _hide_continue_stats_context()
+ var restore_navigation_focus: bool = _navigation_focus_active
+ _set_title_bubbles_interactive(false)
+ _release_primary_menu_focus()
+ _presentation_center.hide()
+ _start_prompt_center.hide()
+ _credits_page.open_page(restore_navigation_focus)
+
+
+func _close_credits(restore_navigation_focus: bool) -> void:
+ _credits_page.close_page()
+ _presentation_center.show()
+ _button_center.show()
+ _start_prompt_center.hide()
+ _set_title_bubbles_interactive(true)
+ if restore_navigation_focus:
+ _navigation_focus_active = true
+ _credits_button.grab_focus()
+ else:
+ _navigation_focus_active = false
+ _release_title_focus()
+ _update_continue_stats_visibility()
+
+
func is_awaiting_start_input() -> bool:
return _awaiting_start_input
@@ -400,6 +463,7 @@ func _get_title_buttons() -> Array[BubbleButton]:
_new_game_button,
_join_game_button,
_settings_button,
+ _credits_button,
_delete_button,
_quit_button,
]
@@ -495,6 +559,10 @@ func _input(event: InputEvent) -> void:
and _settings_panel.is_controller_mapping_capturing()
):
return
+ if _credits_page.visible:
+ if _credits_page.handle_input(event):
+ get_viewport().set_input_as_handled()
+ return
if _join_game_page.visible:
if event.is_action_pressed("ui_cancel"):
_close_join_game()
@@ -546,6 +614,7 @@ func _handle_primary_menu_focus_input(event: InputEvent) -> bool:
not _button_center.visible
or _is_confirmation_active()
or _settings_panel.visible
+ or _credits_page.visible
):
return false
if event is InputEventMouseMotion:
@@ -608,6 +677,10 @@ func _prepare_awaiting_start_input() -> void:
_navigation_focus_active = false
_modal_restore_navigation_focus = false
_button_center.show()
+ var bubble_field := get_node_or_null("%BubbleField") as Control
+ if bubble_field != null:
+ bubble_field.hide()
+ call_deferred("set_process", visible)
_feedback_label.show()
_feedback_label.modulate.a = 0.0
_continue_stats_hovered = false
@@ -650,6 +723,10 @@ func _reveal_primary_menu() -> void:
):
return
_awaiting_start_input = false
+ _button_center.show()
+ var bubble_field := get_node_or_null("%BubbleField") as Control
+ if bubble_field != null:
+ bubble_field.show()
_stop_entry_prompt_animation()
_title_entry_generation += 1
_title_entry_transition_active = true
@@ -892,16 +969,23 @@ func _get_continue_stats_text() -> String:
or _inspection.status != SaveInspectionType.Status.VALID_SUPPORTED
):
return ""
- return (
- "%d fish • $%d • %d discovered"
- % [
+ return _center_feedback_text(
+ "%d fish • %s • %d discovered" % [
_inspection.catch_count,
- _inspection.wallet_balance,
+ CurrencyPresentationType.bbcode_amount(
+ _inspection.wallet_balance, 18
+ ),
_inspection.discovered_species_count,
]
)
+func _center_feedback_text(message: String) -> String:
+ if message.begins_with("[center]"):
+ return message
+ return "[center]%s[/center]" % message
+
+
func _on_continue_pressed() -> void:
if (
_action_in_progress
@@ -930,13 +1014,15 @@ func _on_new_game_pressed() -> void:
new_game_requested.emit()
return
if _inspection.status == SaveInspectionType.Status.UNSUPPORTED_VERSION:
- _feedback_label.text = (
+ _feedback_label.text = _center_feedback_text(
"this save is from a newer game version. "
+ "use delete save before starting over."
)
return
if _inspection.status == SaveInspectionType.Status.IO_ERROR:
- _feedback_label.text = "the existing save cannot be accessed safely."
+ _feedback_label.text = _center_feedback_text(
+ "the existing save cannot be accessed safely."
+ )
return
_open_confirmation(
ConfirmationAction.NEW_GAME,
@@ -982,14 +1068,16 @@ func _on_confirmation_accepted() -> void:
_action_in_progress = false
return
if not _save_manager.delete_progression_save():
- _feedback_label.text = "failed to delete saved progression."
+ _feedback_label.text = _center_feedback_text(
+ "failed to delete saved progression."
+ )
_action_in_progress = false
_refresh_save_inspection()
_begin_confirmation_return()
return
_save_manager.initialize_new_game()
_refresh_save_inspection()
- _feedback_label.text = "saved progression deleted."
+ _feedback_label.text = _center_feedback_text("saved progression deleted.")
_begin_confirmation_return()
_action_in_progress = false
@@ -1175,6 +1263,7 @@ func _open_settings() -> void:
_is_confirmation_active()
or _action_in_progress
or _settings_panel.visible
+ or _credits_page.visible
or _title_settings_transition_active
):
return
@@ -1263,8 +1352,9 @@ func _begin_title_cluster_return(feedback_text: String) -> void:
_title_settings_transition_generation += 1
_cancel_title_settings_tween()
_title_settings_transition_active = true
- if _feedback_label.text != feedback_text:
- _feedback_label.text = feedback_text
+ var centered_feedback: String = _center_feedback_text(feedback_text)
+ if _feedback_label.text != centered_feedback:
+ _feedback_label.text = centered_feedback
_feedback_label.visible = _feedback_visible_before_settings
_hide_continue_stats_context()
_set_title_bubbles_interactive(false)
@@ -1372,7 +1462,7 @@ func _refresh_save_inspection() -> void:
_delete_save_label.modulate.a = (
DISABLED_BUBBLE_LABEL_ALPHA if _delete_button.disabled else 1.0
)
- _feedback_label.text = _inspection.message
+ _feedback_label.text = _center_feedback_text(_inspection.message)
if _inspection.status == SaveInspectionType.Status.VALID_SUPPORTED:
_feedback_label.text = _get_continue_stats_text()
if _continue_button.disabled:
@@ -1387,6 +1477,7 @@ func _focus_initial_button() -> void:
or not visible
or _awaiting_start_input
or not _button_center.visible
+ or _credits_page.visible
):
return
if not _continue_button.disabled:
@@ -1402,6 +1493,7 @@ func _on_quit_pressed() -> void:
not _action_in_progress
and not _is_confirmation_active()
and not _settings_panel.visible
+ and not _credits_page.visible
):
_hide_continue_stats_context()
quit_requested.emit()
@@ -1419,6 +1511,7 @@ func _on_title_visibility_changed() -> void:
_navigation_focus_active = false
_modal_restore_navigation_focus = false
_reset_confirmation()
+ _credits_page.close_page()
_stop_decorative_presentation()
diff --git a/ui/title_screen.tscn b/ui/title_screen.tscn
index 7f7d499..ae0c0c6 100644
--- a/ui/title_screen.tscn
+++ b/ui/title_screen.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=14 format=3]
+[gd_scene load_steps=19 format=3]
[ext_resource type="Script" path="res://ui/title_screen.gd" id="1_script"]
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
@@ -11,6 +11,10 @@
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="9_bubble_profile"]
[ext_resource type="PackedScene" path="res://ui/title_confirmation_bubble_page.tscn" id="10_confirmation_page"]
[ext_resource type="PackedScene" path="res://ui/network/join_game_page.tscn" id="11_join_page"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/online_dark.png" id="12_online_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/settings_dark.png" id="13_settings_dark"]
+[ext_resource type="Texture2D" path="res://ui/icons/pictograms/x_dark.png" id="14_x_dark"]
+[ext_resource type="PackedScene" path="res://ui/title_credits_page.tscn" id="15_credits_page"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water"]
shader = ExtResource("4_water_shader")
@@ -18,6 +22,17 @@ shader = ExtResource("4_water_shader")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_logo"]
shader = ExtResource("6_logo_shader")
+[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_continue_stats"]
+content_margin_left = 14.0
+content_margin_top = 6.0
+content_margin_right = 14.0
+content_margin_bottom = 6.0
+bg_color = Color(0.031, 0.122, 0.169, 1)
+corner_radius_top_left = 14
+corner_radius_top_right = 14
+corner_radius_bottom_right = 14
+corner_radius_bottom_left = 14
+
[node name="TitleScreen" type="Control"]
unique_name_in_owner = true
z_index = 200
@@ -206,7 +221,7 @@ unique_name_in_owner = true
layout_mode = 2
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
theme_override_font_sizes/font_size = 22
-text = "v0.5.1-prealpha"
+text = "v0.7.1-alpha"
horizontal_alignment = 1
[node name="Spacer" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
@@ -221,21 +236,21 @@ layout_mode = 2
[node name="BubbleLayoutSlot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter"]
unique_name_in_owner = true
-custom_minimum_size = Vector2(396, 318)
+custom_minimum_size = Vector2(440, 318)
layout_mode = 2
[node name="BubbleMotionRoot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot"]
unique_name_in_owner = true
layout_mode = 0
-offset_right = 396.0
+offset_right = 440.0
offset_bottom = 318.0
mouse_filter = 2
[node name="BubbleField" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot"]
unique_name_in_owner = true
-custom_minimum_size = Vector2(396, 318)
+custom_minimum_size = Vector2(440, 318)
layout_mode = 0
-offset_right = 396.0
+offset_right = 440.0
offset_bottom = 318.0
script = ExtResource("8_bubble_cluster")
profile = ExtResource("9_bubble_profile")
@@ -303,7 +318,10 @@ offset_left = 264.0
offset_top = 17.0
offset_right = 384.0
offset_bottom = 133.0
-text = "settings"
+texture_filter = 1
+icon = ExtResource("13_settings_dark")
+tooltip_text = "settings"
+accessibility_name = "settings"
script = ExtResource("7_bubble_button")
profile = ExtResource("9_bubble_profile")
desktop_anchor = Vector2(324, 75)
@@ -316,13 +334,40 @@ motion_period = 4.9
motion_phase = 2.5
deformation_period = 6.3
+[node name="CreditsButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
+unique_name_in_owner = true
+offset_left = 330.0
+offset_top = 125.0
+offset_right = 414.0
+offset_bottom = 207.0
+text = "credits"
+tooltip_text = "credits"
+accessibility_name = "credits"
+script = ExtResource("7_bubble_button")
+profile = ExtResource("9_bubble_profile")
+neutral_size = Vector2(84, 82)
+desktop_anchor = Vector2(372, 166)
+compact_anchor = Vector2(372, 166)
+compact_minimum_size = Vector2(62, 62)
+minimum_font_size = 12
+maximum_font_size = 17
+horizontal_amplitude = 1.4
+vertical_amplitude = 3.0
+motion_period = 5.0
+motion_phase = 1.8
+deformation_amplitude = 0.015
+deformation_period = 5.6
+
[node name="JoinGameButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
unique_name_in_owner = true
offset_left = 126.0
offset_top = 224.0
offset_right = 248.0
offset_bottom = 342.0
-text = "join\ngame"
+texture_filter = 1
+icon = ExtResource("12_online_dark")
+tooltip_text = "join game"
+accessibility_name = "join game"
script = ExtResource("7_bubble_button")
profile = ExtResource("9_bubble_profile")
neutral_size = Vector2(122, 118)
@@ -380,7 +425,10 @@ offset_left = 275.0
offset_top = 217.0
offset_right = 369.0
offset_bottom = 309.0
-text = "quit"
+texture_filter = 1
+icon = ExtResource("14_x_dark")
+tooltip_text = "quit"
+accessibility_name = "quit"
script = ExtResource("7_bubble_button")
profile = ExtResource("9_bubble_profile")
neutral_size = Vector2(94, 92)
@@ -396,15 +444,18 @@ motion_phase = 4.8
deformation_amplitude = 0.02
deformation_period = 4.8
-[node name="FeedbackLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
+[node name="FeedbackLabel" type="RichTextLabel" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
unique_name_in_owner = true
visible = false
-custom_minimum_size = Vector2(0, 44)
+custom_minimum_size = Vector2(430, 44)
layout_mode = 2
+size_flags_horizontal = 4
text = ""
-horizontal_alignment = 1
-vertical_alignment = 1
+bbcode_enabled = true
+scroll_active = false
autowrap_mode = 2
+vertical_alignment = 1
+theme_override_styles/normal = SubResource("StyleBoxFlat_continue_stats")
[node name="ConfirmationPage" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("10_confirmation_page")]
unique_name_in_owner = true
@@ -432,6 +483,16 @@ offset_bottom = 300.0
grow_horizontal = 2
grow_vertical = 2
+[node name="CreditsPage" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("15_credits_page")]
+unique_name_in_owner = true
+z_index = 220
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+grow_horizontal = 2
+grow_vertical = 2
+
[node name="JoinGamePage" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("11_join_page")]
unique_name_in_owner = true
z_index = 220
diff --git a/ui/typewriter_reveal.gd b/ui/typewriter_reveal.gd
new file mode 100644
index 0000000..aa4f3d6
--- /dev/null
+++ b/ui/typewriter_reveal.gd
@@ -0,0 +1,47 @@
+class_name TypewriterReveal
+extends RefCounted
+
+const DEFAULT_CHARACTERS_PER_SECOND: float = 28.0
+const MIN_CHARACTERS_PER_SECOND: float = 12.0
+const MAX_CHARACTERS_PER_SECOND: float = 60.0
+
+static var _characters_per_second: float = DEFAULT_CHARACTERS_PER_SECOND
+
+
+static func set_characters_per_second(value: float) -> void:
+ _characters_per_second = clampf(
+ value,
+ MIN_CHARACTERS_PER_SECOND,
+ MAX_CHARACTERS_PER_SECOND,
+ )
+
+
+static func get_characters_per_second() -> float:
+ return _characters_per_second
+
+
+static func start(
+ label: Label,
+ characters_per_second: float = -1.0,
+) -> float:
+ if label == null:
+ return 0.0
+ var character_count: int = label.get_total_character_count()
+ if character_count <= 0:
+ label.visible_characters = -1
+ return 0.0
+ label.visible_characters = 0
+ var resolved_characters_per_second := (
+ characters_per_second
+ if characters_per_second > 0.0
+ else _characters_per_second
+ )
+ var duration := float(character_count) / resolved_characters_per_second
+ var reveal_tween := label.create_tween()
+ reveal_tween.tween_property(
+ label,
+ "visible_characters",
+ character_count,
+ duration,
+ ).from(0).set_trans(Tween.TRANS_LINEAR)
+ return duration
diff --git a/ui/typewriter_reveal.gd.uid b/ui/typewriter_reveal.gd.uid
new file mode 100644
index 0000000..2d96fd3
--- /dev/null
+++ b/ui/typewriter_reveal.gd.uid
@@ -0,0 +1 @@
+uid://c1as5qlog6ijy
diff --git a/ui/ui_pixelation_presenter.gd b/ui/ui_pixelation_presenter.gd
index 18481c3..2cc2063 100644
--- a/ui/ui_pixelation_presenter.gd
+++ b/ui/ui_pixelation_presenter.gd
@@ -5,6 +5,13 @@ const MIN_UI_VIEWPORT_SIZE: Vector2i = Vector2i(256, 180)
const UIReferencePresentationType = preload(
"res://ui/ui_reference_presentation.gd"
)
+const ControllerFocusPresentationType = preload(
+ "res://ui/controller_focus_presentation.gd"
+)
+const ControllerFocusRecoveryType = preload(
+ "res://ui/controller_focus_recovery.gd"
+)
+const OnScreenKeyboardType = preload("res://ui/on_screen_keyboard.gd")
signal effective_pixel_size_changed(
requested_pixel_size: int,
@@ -16,6 +23,9 @@ signal effective_pixel_size_changed(
@onready var _canonical_stage: Control = (
$UIViewport/GameUI/UIRoot/CanonicalStage
)
+@onready var _hotbar: HotbarUI = (
+ $UIViewport/GameUI/UIRoot/CanonicalStage/Hotbar
+)
@onready var _chat_ui: ChatUI = $UIViewport/GameUI/UIRoot/ChatUI
@onready var _title_content_stage: Control = (
$UIViewport/GameUI/UIRoot/TitleScreen/ResponsiveTitleStage
@@ -26,14 +36,25 @@ var _effective_pixel_size: int = PlayerSettings.DEFAULT_UI_PIXEL_SIZE
var _gameplay_active: bool = false
var _interactive_ui_open: bool = false
var _passive_pointer_ui_enabled: bool = false
+var _on_screen_keyboard: OnScreenKeyboardType
func _ready() -> void:
+ _on_screen_keyboard = OnScreenKeyboardType.new()
+ _ui_root.add_child(_on_screen_keyboard)
+ var controller_focus_recovery := ControllerFocusRecoveryType.new()
+ _ui_root.add_child(controller_focus_recovery)
+ var controller_focus_presentation := ControllerFocusPresentationType.new()
+ _ui_root.add_child(controller_focus_presentation)
var root_viewport: Viewport = get_viewport()
root_viewport.size_changed.connect(_resize_presentation)
_resize_presentation()
+func set_on_screen_keyboard_enabled(enabled: bool) -> void:
+ _on_screen_keyboard.set_enabled(enabled)
+
+
func set_pixel_size(pixel_size: int) -> void:
_requested_pixel_size = clampi(
pixel_size,
@@ -120,6 +141,7 @@ func _resize_presentation() -> void:
UIReferencePresentationType.get_stage_position(display_size)
)
_canonical_stage.size = UIReferencePresentationType.REFERENCE_SIZE
+ _hotbar.position = Vector2(0.0, _canonical_stage.position.y)
_title_content_stage.set_anchors_preset(Control.PRESET_TOP_LEFT)
_title_content_stage.position = _canonical_stage.position
_title_content_stage.size = UIReferencePresentationType.REFERENCE_SIZE
diff --git a/ui/weather_icon.gd b/ui/weather_icon.gd
index 894e140..b44bc9b 100644
--- a/ui/weather_icon.gd
+++ b/ui/weather_icon.gd
@@ -1,11 +1,21 @@
class_name WeatherIcon
extends Control
-const BUBBLE_COLOR := Color(0.025, 0.13, 0.19, 0.94)
-const ICON_COLOR := Color(0.78, 0.91, 0.95)
-const SUN_COLOR := Color(0.98, 0.82, 0.34)
-const MOON_COLOR := Color(0.78, 0.88, 1.0)
-const RAIN_COLOR := Color(0.28, 0.73, 0.82)
+const CLEAR_DAY_TEXTURE: Texture2D = preload(
+ "res://ui/icons/weather/weather_clear_day.png"
+)
+const CLEAR_NIGHT_TEXTURE: Texture2D = preload(
+ "res://ui/icons/weather/weather_clear_night_full.png"
+)
+const CLOUDY_TEXTURE: Texture2D = preload(
+ "res://ui/icons/weather/weather_cloudy.png"
+)
+const FOG_TEXTURE: Texture2D = preload(
+ "res://ui/icons/weather/weather_fog.png"
+)
+const RAIN_TEXTURE: Texture2D = preload(
+ "res://ui/icons/weather/weather_rain.png"
+)
var _weather: WorldWeatherService.Weather = WorldWeatherService.Weather.SUNNY
var _is_nighttime: bool = false
@@ -14,7 +24,8 @@ var _is_nighttime: bool = false
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_PASS
focus_mode = Control.FOCUS_NONE
- custom_minimum_size = Vector2(34.0, 34.0)
+ texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
+ custom_minimum_size = Vector2(51.0, 51.0)
_update_tooltip()
queue_redraw()
@@ -28,10 +39,10 @@ func set_weather(weather: WorldWeatherService.Weather) -> void:
queue_redraw()
-func set_nighttime(is_nighttime: bool) -> void:
- if _is_nighttime == is_nighttime:
+func set_nighttime(nighttime: bool) -> void:
+ if _is_nighttime == nighttime:
return
- _is_nighttime = is_nighttime
+ _is_nighttime = nighttime
queue_redraw()
@@ -44,55 +55,22 @@ func get_weather() -> WorldWeatherService.Weather:
func _draw() -> void:
- var center: Vector2 = size * 0.5
- var radius: float = minf(size.x, size.y) * 0.5
- draw_circle(center, radius, BUBBLE_COLOR)
+ var icon_size := Vector2.ONE * minf(size.x, size.y)
+ var icon_rect := Rect2((size - icon_size) * 0.5, icon_size)
+ draw_texture_rect(_get_weather_texture(), icon_rect, false)
+
+
+func _get_weather_texture() -> Texture2D:
match _weather:
WorldWeatherService.Weather.SUNNY:
- if _is_nighttime:
- _draw_moon(center)
- else:
- _draw_sun(center)
+ return CLEAR_NIGHT_TEXTURE if _is_nighttime else CLEAR_DAY_TEXTURE
WorldWeatherService.Weather.CLOUDY:
- _draw_cloud(center + Vector2(0.0, 1.0))
+ return CLOUDY_TEXTURE
WorldWeatherService.Weather.RAINY:
- _draw_cloud(center + Vector2(0.0, -2.0))
- for x_offset: float in PackedFloat32Array([-6.0, 0.0, 6.0]):
- draw_line(
- center + Vector2(x_offset + 1.0, 5.0),
- center + Vector2(x_offset - 1.0, 9.0),
- RAIN_COLOR,
- 2.0,
- true,
- )
+ return RAIN_TEXTURE
WorldWeatherService.Weather.FOGGY:
- for y_offset: float in PackedFloat32Array([-6.0, 0.0, 6.0]):
- draw_line(
- center + Vector2(-9.0, y_offset),
- center + Vector2(9.0, y_offset),
- ICON_COLOR,
- 2.0,
- true,
- )
-
-
-func _draw_sun(center: Vector2) -> void:
- draw_circle(center, 5.0, SUN_COLOR)
- for index: int in 8:
- var angle: float = TAU * float(index) / 8.0
- var direction := Vector2(cos(angle), sin(angle))
- draw_line(
- center + direction * 8.0,
- center + direction * 11.0,
- SUN_COLOR,
- 2.0,
- true,
- )
-
-
-func _draw_moon(center: Vector2) -> void:
- draw_circle(center, 8.0, MOON_COLOR)
- draw_circle(center + Vector2(4.0, -2.0), 7.0, BUBBLE_COLOR)
+ return FOG_TEXTURE
+ return CLEAR_DAY_TEXTURE
func _update_tooltip() -> void:
@@ -101,10 +79,3 @@ func _update_tooltip() -> void:
if _weather == WorldWeatherService.Weather.SUNNY
else WorldWeatherService.weather_name(_weather)
)
-
-
-func _draw_cloud(center: Vector2) -> void:
- draw_circle(center + Vector2(-5.0, 0.0), 5.0, ICON_COLOR)
- draw_circle(center + Vector2(0.0, -3.0), 6.0, ICON_COLOR)
- draw_circle(center + Vector2(6.0, 0.0), 5.0, ICON_COLOR)
- draw_rect(Rect2(center + Vector2(-9.0, 0.0), Vector2(18.0, 5.0)), ICON_COLOR)
diff --git a/world/README-WORLD-AUTHORING.md b/world/README-WORLD-AUTHORING.md
deleted file mode 100644
index d596c05..0000000
--- a/world/README-WORLD-AUTHORING.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# World authoring
-
-The active test world uses the human-authored starter island through
-`world/regions/starter_island_region.tscn`.
-
-## Active composition
-
-`world/test_world.tscn` owns the gameplay-wide environment, sun, world bounds,
-and below-world failsafe. `StarterIslandRegion` owns the placed island content:
-
-```text
-StarterIslandRegion
-├── Terrain
-│ ├── Visual
-│ └── Collision
-├── WaterBodies
-│ ├── Pond
-│ │ ├── VisualWater
-│ │ ├── FishingRegion
-│ │ └── RecoveryRegion
-│ └── Ocean
-│ ├── VisualWater
-│ ├── FishingRegions
-│ └── RecoveryRegions
-├── PlayerSpawn
-├── SafeRespawns
-└── Interactables
- ├── FishingShopWorld
- └── PelicanCoolerPerch
-```
-
-Move the meaningful feature root rather than one of its implementation
-children. Child transforms are local offsets owned by that feature.
-
-## Water bodies
-
-Every fishable region must author its `water_type` explicitly. The starter pond
-is `FRESH_WATER`; the starter coast is `SALT_WATER`. Fish species use the same
-central type definition through an allowed-water-type bitmask, so pool contents
-and authoritative selection are both validated against the region. Do not infer
-habitat from node names, pool filenames, coordinates, or water height.
-
-Select `WaterBodies/Pond` to move or resize the pond. Its transform is the
-authoritative surface position. The `surface_size`, fishing padding, recovery
-padding, and recovery depth properties update the visible water and gameplay
-coverage together. Fishing and recovery derive the surface height from the
-owned surface transform.
-
-Select `WaterBodies/Ocean` to move the surrounding water as one feature. Its
-visual, fishing lobes, and recovery lobes use local transforms beneath the
-ocean root. The existing multi-lobe footprint remains intentionally explicit;
-changing that footprint still requires editing its owned lobe children.
-
-## Placed features
-
-- `PlayerSpawn` is the authoritative initial player transform. Its rotation
- controls initial facing.
-- Each marker under `SafeRespawns` is an authoritative recovery destination.
- Recovery preserves the player's current facing; marker rotation is
- intentionally not applied.
-- `Interactables/FishingShopWorld` owns the shop visual, collision,
- interaction area, prompt, and entrance marker.
-- `Interactables/PelicanCoolerPerch` owns the complete Pelican landmark visual.
- Pelican selling remains a Cooler action and has no world interaction area.
-- `Terrain` owns both the imported visual and generated terrain collision.
-- `BelowWorldFailsafe/Coverage` exposes the below-world recovery coverage as a
- saved collision shape in `world/test_world.tscn`.
-
-The active `Environment`, `Sun`, and external starter-island grass material
-remain directly editable through the Inspector. Their tuning is not recreated
-by runtime scripts.
-
-## Reusable world props
-
-Use a single placed `WorldProp` root for trees, rocks, buildings, benches,
-signs, vegetation, and similar landmarks:
-
-```text
-WorldProp
-├── Visual
-└── Collision
- └── CollisionShape3D
-```
-
-Add optional interaction areas, labels, and markers beneath the same root.
-Instance imported GLB visuals beneath `Visual`; keep gameplay collision
-Godot-owned beneath `Collision`. Place and duplicate the complete prop scene,
-not its visual child.
-
-Author reusable assets at scale `(1, 1, 1)`. Uniform root scaling is acceptable
-for provisional props when visual and collision scale together. Avoid
-non-uniform root scaling because it can deform collision and imported geometry
-unpredictably. Make mutable per-instance shapes, meshes, and materials local to
-the scene so editing one prop does not change unrelated instances.
-
-## Shoreline tide ribbons
-
-Each map that uses generated tide ribbons owns a `ShorelineRibbonBaker` node and
-one `ShorelineRibbonConfig` resource per water body. Each fishable water body
-declares the shared `WaterType` value used by fishing, Logbook classification,
-and shoreline presentation. A configuration designates
-only the static terrain `CollisionShape3D` or `MeshInstance3D` to intersect, the
-water height, explicit generation bounds, water-facing reference, optional
-smoothing overrides, and the generated `.tres` output path. Props, docks,
-players, bobbers, and gameplay areas are not scanned unless a map author
-explicitly selects one as the terrain source. The baker reports every configured
-body but intentionally generates ribbons only for `SALT_WATER`; freshwater uses
-the shared depth-tinted shader without tide marks or an advancing wash.
-
-To rebuild in the editor, select the map's `ShorelineRibbonBaker` node and press
-**Rebuild Shoreline Ribbons** in the Inspector. The equivalent validation/CI
-command for the starter map is:
-
-```sh
-godot --headless --path . --script scripts/bake_shoreline_ribbons.gd
-```
-
-Set the baker's `debug_path_stage` to Raw, Simplified, or Smoothed before an
-editor rebuild to compare the extraction stages. Keep it Off in the finished
-scene; the temporary editor-only line preview is never saved as gameplay data.
-
-Rebuild a saltwater ribbon only when its terrain at the waterline, configured
-water height, or generation bounds change. Freshwater terrain changes do not
-require a ribbon rebuild because freshwater bodies have no ribbon. Adding or
-moving unrelated props, fishing areas, recovery volumes, or other gameplay
-nodes does not require a rebuild. Normal gameplay loads the committed generated
-saltwater meshes and never runs the extraction step.
diff --git a/world/environment/local_storm_cloud.gdshader b/world/environment/local_storm_cloud.gdshader
new file mode 100644
index 0000000..b5ec03b
--- /dev/null
+++ b/world/environment/local_storm_cloud.gdshader
@@ -0,0 +1,37 @@
+shader_type spatial;
+render_mode blend_mix, depth_prepass_alpha, cull_disabled, unshaded, fog_disabled, shadows_disabled;
+
+uniform vec4 cloud_color : source_color = vec4(0.07, 0.10, 0.12, 1.0);
+uniform float weather_opacity : hint_range(0.0, 1.0, 0.01) = 0.0;
+uniform float maximum_opacity : hint_range(0.0, 1.0, 0.01) = 0.5;
+uniform float distance_fade_start : hint_range(50.0, 500.0, 1.0) = 240.0;
+uniform float distance_fade_end : hint_range(50.0, 500.0, 1.0) = 300.0;
+
+varying float world_normal_height;
+varying float camera_distance;
+
+
+void vertex() {
+ world_normal_height = normalize(MODEL_NORMAL_MATRIX * NORMAL).y;
+ vec3 world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
+ camera_distance = distance(
+ world_position.xz,
+ CAMERA_POSITION_WORLD.xz
+ );
+}
+
+
+void fragment() {
+ float facet_light = mix(
+ 0.68,
+ 1.06,
+ clamp(world_normal_height * 0.5 + 0.5, 0.0, 1.0)
+ );
+ ALBEDO = cloud_color.rgb * facet_light;
+ float distance_fade = 1.0 - smoothstep(
+ distance_fade_start,
+ distance_fade_end,
+ camera_distance
+ );
+ ALPHA = weather_opacity * maximum_opacity * distance_fade * cloud_color.a;
+}
diff --git a/world/environment/local_storm_cloud.gdshader.uid b/world/environment/local_storm_cloud.gdshader.uid
new file mode 100644
index 0000000..b07fd92
--- /dev/null
+++ b/world/environment/local_storm_cloud.gdshader.uid
@@ -0,0 +1 @@
+uid://c20wlon7hc48g
diff --git a/world/environment/local_storm_cloud_layer.gd b/world/environment/local_storm_cloud_layer.gd
new file mode 100644
index 0000000..2ec0008
--- /dev/null
+++ b/world/environment/local_storm_cloud_layer.gd
@@ -0,0 +1,228 @@
+class_name LocalStormCloudLayer
+extends Node3D
+
+const CLOUD_SHADER: Shader = preload(
+ "res://world/environment/local_storm_cloud.gdshader"
+)
+const MIN_CLOUD_ALTITUDE: float = 15.0
+const MAX_CLOUD_ALTITUDE: float = 23.0
+const GRID_AXIS_COUNT: int = 9
+const GRID_SPACING: float = 70.0
+const FIELD_HALF_EXTENT: float = GRID_AXIS_COUNT * GRID_SPACING * 0.5
+const DISTANCE_FADE_START: float = 240.0
+const DISTANCE_FADE_END: float = 300.0
+const WRAP_RADIUS: float = FIELD_HALF_EXTENT
+const MAXIMUM_OPACITY: float = 1.0
+const BASE_VELOCITY := Vector2(0.825, -0.45)
+const BODY_OUTLINE: Array[Vector2] = [
+ Vector2(-6.9, -0.8),
+ Vector2(-6.6, -2.0),
+ Vector2(-5.7, -3.0),
+ Vector2(-4.5, -3.5),
+ Vector2(-3.0, -3.7),
+ Vector2(-1.8, -4.2),
+ Vector2(-0.5, -4.3),
+ Vector2(0.7, -4.0),
+ Vector2(2.0, -4.1),
+ Vector2(3.0, -3.5),
+ Vector2(4.6, -3.3),
+ Vector2(5.8, -2.5),
+ Vector2(6.6, -1.5),
+ Vector2(7.0, -0.2),
+ Vector2(6.8, 1.0),
+ Vector2(6.1, 1.9),
+ Vector2(6.0, 2.9),
+ Vector2(5.1, 3.7),
+ Vector2(3.8, 4.0),
+ Vector2(2.7, 4.7),
+ Vector2(1.4, 4.9),
+ Vector2(0.2, 5.3),
+ Vector2(-1.2, 5.0),
+ Vector2(-2.1, 4.4),
+ Vector2(-3.6, 4.2),
+ Vector2(-4.9, 3.5),
+ Vector2(-5.4, 2.5),
+ Vector2(-6.3, 1.7),
+ Vector2(-6.8, 0.6),
+]
+
+var _target: Node3D
+var _material: ShaderMaterial
+var _multimesh: MultiMesh
+var _cloud_mesh: MultiMeshInstance3D
+var _drift_offset := Vector2.ZERO
+var _storm_amount: float = 0.0
+
+
+func setup(target: Node3D) -> void:
+ _target = target
+ _build_cloud_field()
+ _update_cloud_transforms()
+ set_process(true)
+
+
+func set_storm_amount(amount: float, color: Color) -> void:
+ _storm_amount = clampf(amount, 0.0, 1.0)
+ var should_be_visible: bool = _storm_amount > 0.001
+ if should_be_visible and not visible:
+ _update_cloud_transforms()
+ visible = should_be_visible
+ if _material == null:
+ return
+ _material.set_shader_parameter("weather_opacity", _storm_amount)
+ _material.set_shader_parameter("cloud_color", color)
+
+
+func get_storm_amount() -> float:
+ return _storm_amount
+
+
+func get_patch_count() -> int:
+ return GRID_AXIS_COUNT * GRID_AXIS_COUNT
+
+
+func _process(delta: float) -> void:
+ if not visible or _target == null or not is_instance_valid(_target):
+ return
+ _drift_offset += BASE_VELOCITY * delta
+ _drift_offset = Vector2(
+ _wrap_axis(_drift_offset.x),
+ _wrap_axis(_drift_offset.y),
+ )
+ _update_cloud_transforms()
+
+
+func _build_cloud_field() -> void:
+ _material = ShaderMaterial.new()
+ _material.shader = CLOUD_SHADER
+ _material.set_shader_parameter("weather_opacity", 0.0)
+ _material.set_shader_parameter("maximum_opacity", MAXIMUM_OPACITY)
+ _material.set_shader_parameter("distance_fade_start", DISTANCE_FADE_START)
+ _material.set_shader_parameter("distance_fade_end", DISTANCE_FADE_END)
+
+ var cloud_body_mesh: ArrayMesh = _build_cloud_body_mesh()
+ cloud_body_mesh.surface_set_material(0, _material)
+
+ _multimesh = MultiMesh.new()
+ _multimesh.transform_format = MultiMesh.TRANSFORM_3D
+ _multimesh.mesh = cloud_body_mesh
+ _multimesh.instance_count = get_patch_count()
+ _multimesh.custom_aabb = AABB(
+ Vector3(
+ -FIELD_HALF_EXTENT - 60.0,
+ MIN_CLOUD_ALTITUDE - 5.0,
+ -FIELD_HALF_EXTENT - 60.0,
+ ),
+ Vector3(
+ (FIELD_HALF_EXTENT + 60.0) * 2.0,
+ MAX_CLOUD_ALTITUDE - MIN_CLOUD_ALTITUDE + 10.0,
+ (FIELD_HALF_EXTENT + 60.0) * 2.0,
+ ),
+ )
+
+ _cloud_mesh = MultiMeshInstance3D.new()
+ _cloud_mesh.name = "CloudField"
+ _cloud_mesh.multimesh = _multimesh
+ _cloud_mesh.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
+ add_child(_cloud_mesh)
+ visible = false
+
+
+func _build_cloud_body_mesh() -> ArrayMesh:
+ var outline := PackedVector2Array(BODY_OUTLINE)
+ var surface_tool := SurfaceTool.new()
+ surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
+ var face_indices: PackedInt32Array = Geometry2D.triangulate_polygon(
+ outline
+ )
+ for triangle_offset: int in range(0, face_indices.size(), 3):
+ var point_a: Vector2 = outline[face_indices[triangle_offset]]
+ var point_b: Vector2 = outline[face_indices[triangle_offset + 1]]
+ var point_c: Vector2 = outline[face_indices[triangle_offset + 2]]
+ _add_oriented_triangle(
+ surface_tool,
+ _to_cloud_vertex(point_a),
+ _to_cloud_vertex(point_b),
+ _to_cloud_vertex(point_c),
+ Vector3.DOWN,
+ )
+ surface_tool.index()
+ return surface_tool.commit()
+
+
+func _to_cloud_vertex(point: Vector2) -> Vector3:
+ return Vector3(point.x, 0.0, point.y)
+
+
+func _add_oriented_triangle(
+ surface_tool: SurfaceTool,
+ point_a: Vector3,
+ point_b: Vector3,
+ point_c: Vector3,
+ expected_normal: Vector3,
+) -> void:
+ if (point_b - point_a).cross(point_c - point_a).dot(expected_normal) < 0.0:
+ var swap: Vector3 = point_b
+ point_b = point_c
+ point_c = swap
+ for point: Vector3 in [point_a, point_b, point_c]:
+ surface_tool.set_normal(expected_normal)
+ surface_tool.add_vertex(point)
+
+
+func _update_cloud_transforms() -> void:
+ if _target == null or _multimesh == null:
+ return
+ global_position = _target.global_position
+ var target_xz := Vector2(
+ _target.global_position.x,
+ _target.global_position.z,
+ )
+ var grid_center: float = float(GRID_AXIS_COUNT - 1) * 0.5
+ var instance_index: int = 0
+ for grid_z: int in GRID_AXIS_COUNT:
+ for grid_x: int in GRID_AXIS_COUNT:
+ var patch_index: int = grid_z * GRID_AXIS_COUNT + grid_x
+ var world_offset := Vector2(
+ (float(grid_x) - grid_center) * GRID_SPACING,
+ (float(grid_z) - grid_center) * GRID_SPACING,
+ ) + _drift_offset
+ var relative := Vector2(
+ _wrap_axis(world_offset.x - target_xz.x),
+ _wrap_axis(world_offset.y - target_xz.y),
+ )
+ var altitude: float = lerpf(
+ MIN_CLOUD_ALTITUDE,
+ MAX_CLOUD_ALTITUDE,
+ float(patch_index % 4) / 3.0,
+ )
+ var patch_scale: float = 2.20 + float(
+ (patch_index * 7) % 10
+ ) * 0.10
+ var width_variation: float = 0.90 + float(
+ (patch_index * 5) % 7
+ ) * 0.04
+ var depth_variation: float = 0.90 + float(
+ (patch_index * 3 + 2) % 7
+ ) * 0.04
+ var patch_basis := Basis(
+ Vector3.UP,
+ deg_to_rad(float(patch_index * 17 % 41) - 20.0),
+ ).scaled(Vector3(
+ patch_scale * 2.35 * width_variation,
+ patch_scale * 0.34,
+ patch_scale * 2.65 * depth_variation,
+ ))
+ _multimesh.set_instance_transform(
+ instance_index,
+ Transform3D(
+ patch_basis,
+ Vector3(relative.x, altitude, relative.y),
+ ),
+ )
+ instance_index += 1
+
+
+func _wrap_axis(value: float) -> float:
+ return fposmod(value + FIELD_HALF_EXTENT, FIELD_HALF_EXTENT * 2.0) \
+ - FIELD_HALF_EXTENT
diff --git a/world/environment/local_storm_cloud_layer.gd.uid b/world/environment/local_storm_cloud_layer.gd.uid
new file mode 100644
index 0000000..d274b64
--- /dev/null
+++ b/world/environment/local_storm_cloud_layer.gd.uid
@@ -0,0 +1 @@
+uid://krinusur24lh
diff --git a/world/environment/netfishing_environment.tres b/world/environment/netfishing_environment.tres
index 747d3ce..4f625e4 100644
--- a/world/environment/netfishing_environment.tres
+++ b/world/environment/netfishing_environment.tres
@@ -10,7 +10,7 @@ ambient_light_source = 2
ambient_light_color = Color(0.82, 0.9, 0.92, 1)
ambient_light_energy = 1.08
reflected_light_source = 2
-fog_enabled = true
+fog_enabled = false
fog_mode = 1
fog_light_color = Color(0.54902, 0.74902, 0.764706, 1)
fog_light_energy = 0.82
diff --git a/world/environment/netfishing_sky.gdshader b/world/environment/netfishing_sky.gdshader
index bff5c56..07d3c53 100644
--- a/world/environment/netfishing_sky.gdshader
+++ b/world/environment/netfishing_sky.gdshader
@@ -1,10 +1,14 @@
shader_type sky;
+#include "res://world/environment/netfishing_sky_clouds.gdshaderinc"
+
uniform vec4 sky_top_color : source_color = vec4(0.204, 0.498, 0.643, 1.0);
uniform vec4 sky_horizon_color : source_color = vec4(0.663, 0.843, 0.847, 1.0);
uniform vec4 ground_bottom_color : source_color = vec4(0.157, 0.361, 0.439, 1.0);
uniform vec4 ground_horizon_color : source_color = vec4(0.549, 0.749, 0.765, 1.0);
uniform float horizon_blend_width : hint_range(0.005, 0.15, 0.005) = 0.01;
+uniform vec4 fog_horizon_color : source_color = vec4(0.13, 0.21, 0.32, 1.0);
+uniform float fog_horizon_occlusion : hint_range(0.0, 1.0) = 0.0;
uniform vec3 sun_direction = vec3(0.0, 1.0, 0.0);
uniform vec4 sun_color : source_color = vec4(1.0, 0.86, 0.46, 1.0);
@@ -83,6 +87,15 @@ void sky() {
base_color = mix(
base_color, moon_color.rgb, moon_disc * moon_visible_strength
);
+ base_color = apply_weather_clouds(base_color, view_direction);
+ // Compatibility fog does not fully erase the color split between a custom
+ // sky's upper and lower hemispheres. Dense low-light fog supplies one
+ // uniform sky color here so that split cannot masquerade as an ocean edge.
+ base_color = mix(
+ base_color,
+ fog_horizon_color.rgb,
+ fog_horizon_occlusion
+ );
COLOR = base_color;
}
diff --git a/world/environment/netfishing_sky.tres b/world/environment/netfishing_sky.tres
index 7e84c45..f94a6e4 100644
--- a/world/environment/netfishing_sky.tres
+++ b/world/environment/netfishing_sky.tres
@@ -4,11 +4,19 @@
[sub_resource type="ShaderMaterial" id="ShaderMaterial_netfishing"]
shader = ExtResource("1_sky_shader")
+shader_parameter/cloud_coverage = 0.0
+shader_parameter/cloud_opacity = 0.0
+shader_parameter/cloud_light_color = Color(0.7, 0.76, 0.77, 1)
+shader_parameter/cloud_shadow_color = Color(0.31, 0.38, 0.4, 1)
+shader_parameter/cloud_wind = Vector2(0.01, -0.006)
+shader_parameter/cloud_scale = 0.72
shader_parameter/sky_top_color = Color(0.204, 0.498, 0.643, 1)
shader_parameter/sky_horizon_color = Color(0.663, 0.843, 0.847, 1)
shader_parameter/ground_bottom_color = Color(0.157, 0.361, 0.439, 1)
shader_parameter/ground_horizon_color = Color(0.549, 0.749, 0.765, 1)
shader_parameter/horizon_blend_width = 0.01
+shader_parameter/fog_horizon_color = Color(0.13, 0.21, 0.32, 1)
+shader_parameter/fog_horizon_occlusion = 0.0
shader_parameter/sun_direction = Vector3(0, 1, 0)
shader_parameter/sun_color = Color(1, 0.86, 0.46, 1)
shader_parameter/sun_visibility = 1.0
diff --git a/world/environment/netfishing_sky_clouds.gdshaderinc b/world/environment/netfishing_sky_clouds.gdshaderinc
new file mode 100644
index 0000000..d0cbbfb
--- /dev/null
+++ b/world/environment/netfishing_sky_clouds.gdshaderinc
@@ -0,0 +1,70 @@
+uniform float cloud_coverage : hint_range(0.0, 1.0, 0.01) = 0.0;
+uniform float cloud_opacity : hint_range(0.0, 1.0, 0.01) = 0.0;
+uniform vec4 cloud_light_color : source_color = vec4(0.70, 0.76, 0.77, 1.0);
+uniform vec4 cloud_shadow_color : source_color = vec4(0.31, 0.38, 0.40, 1.0);
+uniform vec2 cloud_wind = vec2(0.010, -0.006);
+uniform float cloud_scale : hint_range(0.1, 3.0, 0.05) = 0.72;
+
+
+float cloud_hash(vec2 point) {
+ return fract(sin(dot(point, vec2(127.1, 311.7))) * 43758.5453);
+}
+
+
+float cloud_value_noise(vec2 point) {
+ vec2 cell = floor(point);
+ vec2 local = fract(point);
+ vec2 blend = local * local * (3.0 - 2.0 * local);
+ float bottom = mix(
+ cloud_hash(cell),
+ cloud_hash(cell + vec2(1.0, 0.0)),
+ blend.x
+ );
+ float top = mix(
+ cloud_hash(cell + vec2(0.0, 1.0)),
+ cloud_hash(cell + vec2(1.0, 1.0)),
+ blend.x
+ );
+ return mix(bottom, top, blend.y);
+}
+
+
+float cloud_shape(vec2 point) {
+ vec2 broad_point = floor(point * 5.0) / 5.0;
+ vec2 detail_point = floor(point * 13.0) / 13.0;
+ float broad = cloud_value_noise(broad_point * 0.62);
+ float detail = cloud_value_noise(detail_point * 1.55 + vec2(17.3, 9.1));
+ float combined = broad * 0.72 + detail * 0.28;
+ return floor(combined * 7.0 + 0.5) / 7.0;
+}
+
+
+vec3 apply_weather_clouds(vec3 base_color, vec3 view_direction) {
+ if (cloud_opacity <= 0.001 || view_direction.y <= 0.0) {
+ return base_color;
+ }
+ float safe_height = max(view_direction.y, 0.08);
+ vec2 cloud_plane = view_direction.xz / safe_height;
+ vec2 cloud_point = (
+ cloud_plane + cloud_wind * TIME
+ ) * cloud_scale;
+ float shape = cloud_shape(cloud_point);
+ float threshold = mix(0.82, 0.27, cloud_coverage);
+ float mask = smoothstep(threshold - 0.08, threshold + 0.08, shape);
+ mask = floor(mask * 4.0 + 0.5) / 4.0;
+ mask *= smoothstep(0.025, 0.14, view_direction.y);
+ mask *= cloud_opacity;
+ float body_depth = smoothstep(threshold, 1.0, shape);
+ float underside = clamp(
+ (1.0 - smoothstep(0.08, 0.72, view_direction.y)) * 0.35
+ + body_depth * 0.65,
+ 0.0,
+ 1.0
+ );
+ vec3 cloud_color = mix(
+ cloud_light_color.rgb,
+ cloud_shadow_color.rgb,
+ underside
+ );
+ return mix(base_color, cloud_color, mask);
+}
diff --git a/world/environment/netfishing_sky_clouds.gdshaderinc.uid b/world/environment/netfishing_sky_clouds.gdshaderinc.uid
new file mode 100644
index 0000000..cf79ca0
--- /dev/null
+++ b/world/environment/netfishing_sky_clouds.gdshaderinc.uid
@@ -0,0 +1 @@
+uid://cuqo54hgbjcrf
diff --git a/world/fishing_shop_interaction.gd b/world/fishing_shop_interaction.gd
index 880b78a..d912eca 100644
--- a/world/fishing_shop_interaction.gd
+++ b/world/fishing_shop_interaction.gd
@@ -3,17 +3,25 @@ extends Area3D
signal local_player_range_changed(in_range: bool)
+@export_node_path("Node3D") var look_character_path: NodePath = ^"../Shopkeeper"
+
var _local_player: Player
var _local_player_in_range: bool = false
+var _look_character: WorldCharacterDisplay
func _ready() -> void:
+ _look_character = get_node_or_null(
+ look_character_path
+ ) as WorldCharacterDisplay
body_entered.connect(_on_body_entered)
body_exited.connect(_on_body_exited)
func setup_local_player(player: Player) -> void:
_local_player = player
+ if _look_character != null:
+ _look_character.set_head_look_target(player)
_refresh_overlaps()
@@ -29,6 +37,12 @@ func is_avatar_in_range(avatar: Player) -> bool:
)
+func get_prompt_anchor_position() -> Vector3:
+ if _look_character != null:
+ return _look_character.get_head_anchor_position()
+ return global_position + Vector3.UP * 1.25
+
+
func _refresh_overlaps() -> void:
var is_overlapping: bool = (
_local_player != null
@@ -49,6 +63,8 @@ func _on_body_exited(body: Node3D) -> void:
func _set_local_player_in_range(in_range: bool) -> void:
+ if _look_character != null:
+ _look_character.set_head_look_active(in_range)
if _local_player_in_range == in_range:
return
_local_player_in_range = in_range
diff --git a/world/generated/shorelines/starter_ocean_shoreline.tres b/world/generated/shorelines/starter_ocean_shoreline.tres
index 2481c43..627b08e 100644
--- a/world/generated/shorelines/starter_ocean_shoreline.tres
+++ b/world/generated/shorelines/starter_ocean_shoreline.tres
@@ -1,14 +1,14 @@
-[gd_resource type="ArrayMesh" format=4]
+[gd_resource type="ArrayMesh" format=4 uid="uid://dmgps6rhbdjlw"]
[resource]
_surfaces = [{
-"aabb": AABB(-28.317474, -0.432, -27.355175, 55.825676, 1e-05, 52.391964),
-"attribute_data": PackedByteArray("AAAAAAAAAAAAAAAAAACAP65fYT4AAAAArl9hPgAAgD+QX+E+AAAAAJBf4T4AAIA/swcpPwAAAACzByk/AACAP5BfYT8AAAAAkF9hPwAAgD8o2Yw/AAAAACjZjD8AAIA/HAWpPwAAAAAcBak/AACAPw8xxT8AAAAADzHFPwAAgD/CW+E/AAAAAMJb4T8AAIA/sof9PwAAAACyh/0/AACAP87ZDEAAAAAAztkMQAAAgD/M7BpAAAAAAMzsGkAAAIA/xwIpQAAAAADHAilAAACAP8EYN0AAAAAAwRg3QAAAgD+UIEVAAAAAAJQgRUAAAIA/mvxSQAAAAACa/FJAAACAP5ESYUAAAAAAkRJhQAAAgD+Ps25AAAAAAI+zbkAAAIA/icl8QAAAAACJyXxAAACAP1ZfhUAAAAAAVl+FQAAAgD9RaoxAAAAAAFFqjEAAAIA/T3WTQAAAAABPdZNAAACAP0J7mkAAAAAAQnuaQAAAgD8+hqFAAAAAAD6GoUAAAIA/OpGoQAAAAAA6kahAAACAPzacr0AAAAAANpyvQAAAgD+JlLZAAAAAAImUtkAAAIA/g5+9QAAAAACDn71AAACAP4CqxEAAAAAAgKrEQAAAgD+WjstAAAAAAJaOy0AAAIA/k5nSQAAAAACTmdJAAACAP5ye2UAAAAAAnJ7ZQAAAgD+WqeBAAAAAAJap4EAAAIA/k7TnQAAAAACTtOdAAACAP/y87kAAAAAA/LzuQAAAgD/4x/VAAAAAAPjH9UAAAIA/9NL8QAAAAAD00vxAAACAP/juAUEAAAAA+O4BQQAAgD+scgVBAAAAAKxyBUEAAIA/K/gIQQAAAAAr+AhBAACAP6h9DEEAAAAAqH0MQQAAgD9r+w9BAAAAAGv7D0EAAIA/6YATQQAAAADpgBNBAACAP8/vFkEAAAAAz+8WQQAAgD9NdRpBAAAAAE11GkEAAIA/jdIdQQAAAACN0h1BAACAPwtYIUEAAAAAC1ghQQAAgD9u3CRBAAAAAG7cJEEAAIA/7GEoQQAAAADsYShBAACAP9vlK0EAAAAA2+UrQQAAgD9Yay9BAAAAAFhrL0EAAIA/1vAyQQAAAADW8DJBAACAP8d1NkEAAAAAx3U2QQAAgD9F+zlBAAAAAEX7OUEAAIA/woA9QQAAAADCgD1BAACAPxYGQUEAAAAAFgZBQQAAgD+Ui0RBAAAAAJSLREEAAIA/FBFIQQAAAAAUEUhBAACAP5GWS0EAAAAAkZZLQQAAgD8QHE9BAAAAABAcT0EAAIA/gYZSQQAAAACBhlJBAACAPwAMVkEAAAAAAAxWQQAAgD9+kVlBAAAAAH6RWUEAAIA//RZdQQAAAAD9Fl1BAACAP3qcYEEAAAAAepxgQQAAgD/4IWRBAAAAAPghZEEAAIA/d6dnQQAAAAB3p2dBAACAP/Qsa0EAAAAA9CxrQQAAgD9zsm5BAAAAAHOybkEAAIA/VDRyQQAAAABUNHJBAACAP9O5dUEAAAAA07l1QQAAgD9RP3lBAAAAAFE/eUEAAIA/z8R8QQAAAADPxHxBAACAPyYlgEEAAAAAJiWAQQAAgD/l54FBAAAAAOXngUEAAIA/pKqDQQAAAACkqoNBAACAP2RthUEAAAAAZG2FQQAAgD8jMIdBAAAAACMwh0EAAIA/4vKIQQAAAADi8ohBAACAP6G1ikEAAAAAobWKQQAAgD9geIxBAAAAAGB4jEEAAIA/HzuOQQAAAAAfO45BAACAP979j0EAAAAA3v2PQQAAgD+dwJFBAAAAAJ3AkUEAAIA/XIOTQQAAAABcg5NBAACAPxtGlUEAAAAAG0aVQQAAgD/MCJdBAAAAAMwIl0EAAIA/jMuYQQAAAACMy5hBAACAP0uOmkEAAAAAS46aQQAAgD8KUZxBAAAAAApRnEEAAIA/yROeQQAAAADJE55BAACAP4jWn0EAAAAAiNafQQAAgD9HmaFBAAAAAEeZoUEAAIA/BlyjQQAAAAAGXKNBAACAP8UepUEAAAAAxR6lQQAAgD+E4aZBAAAAAIThpkEAAIA/Q6SoQQAAAABDpKhBAACAPwNnqkEAAAAAA2eqQQAAgD/CKaxBAAAAAMIprEEAAIA/geytQQAAAACB7K1BAACAPz+vr0EAAAAAP6+vQQAAgD/+cbFBAAAAAP5xsUEAAIA/vjSzQQAAAAC+NLNBAACAP333tEEAAAAAffe0QQAAgD88urZBAAAAADy6tkEAAIA/+3y4QQAAAAD7fLhBAACAP7o/ukEAAAAAuj+6QQAAgD95ArxBAAAAAHkCvEEAAIA/OMW9QQAAAAA4xb1BAACAP+CHv0EAAAAA4Ie/QQAAgD+fSsFBAAAAAJ9KwUEAAIA/Xg3DQQAAAABeDcNBAACAPx3QxEEAAAAAHdDEQQAAgD/cksZBAAAAANySxkEAAIA/m1XIQQAAAACbVchBAACAP1oYykEAAAAAWhjKQQAAgD8Z28tBAAAAABnby0EAAIA/2J3NQQAAAADYnc1BAACAP5dgz0EAAAAAl2DPQQAAgD9WI9FBAAAAAFYj0UEAAIA/FebSQQAAAAAV5tJBAACAP9So1EEAAAAA1KjUQQAAgD+Ta9ZBAAAAAJNr1kEAAIA/Ui7YQQAAAABSLthBAACAPxLx2UEAAAAAEvHZQQAAgD/Rs9tBAAAAANGz20EAAIA/kHbdQQAAAACQdt1BAACAP08530EAAAAATznfQQAAgD8O/OBBAAAAAA784EEAAIA/zb7iQQAAAADNvuJBAACAP4yB5EEAAAAAjIHkQQAAgD9LROZBAAAAAEtE5kEAAIA/CgfoQQAAAAAKB+hBAACAP8nJ6UEAAAAAycnpQQAAgD+IjOtBAAAAAIiM60EAAIA/R0/tQQAAAABHT+1BAACAPwYS70EAAAAABhLvQQAAgD/F1PBBAAAAAMXU8EEAAIA/hJfyQQAAAACEl/JBAACAP0Ra9EEAAAAARFr0QQAAgD/+HPZBAAAAAP4c9kEAAIA/vd/3QQAAAAC93/dBAACAP3yi+UEAAAAAfKL5QQAAgD87ZftBAAAAADtl+0EAAIA/+if9QQAAAAD6J/1BAACAP7nq/kEAAAAAuer+QQAAgD+8VgBCAAAAALxWAEIAAIA/HDgBQgAAAAAcOAFCAACAP3sZAkIAAAAAexkCQgAAgD/b+gJCAAAAANv6AkIAAIA/OtwDQgAAAAA63ANCAACAP5q9BEIAAAAAmr0EQgAAgD/5ngVCAAAAAPmeBUIAAIA/WYAGQgAAAABZgAZCAACAP7hhB0IAAAAAuGEHQgAAgD8YQwhCAAAAABhDCEIAAIA/dyQJQgAAAAB3JAlCAACAP9cFCkIAAAAA1wUKQgAAgD825wpCAAAAADbnCkIAAIA/lsgLQgAAAACWyAtCAACAP/WpDEIAAAAA9akMQgAAgD9Viw1CAAAAAFWLDUIAAIA/tGwOQgAAAAC0bA5CAACAPwZOD0IAAAAABk4PQgAAgD9lLxBCAAAAAGUvEEIAAIA/xRARQgAAAADFEBFCAACAPyTyEUIAAAAAJPIRQgAAgD+E0xJCAAAAAITTEkIAAIA/47QTQgAAAADjtBNCAACAP0OWFEIAAAAAQ5YUQgAAgD+idxVCAAAAAKJ3FUIAAIA/AlkWQgAAAAACWRZCAACAP2E6F0IAAAAAYToXQgAAgD/BGxhCAAAAAMEbGEIAAIA/IP0YQgAAAAAg/RhCAACAP4DeGUIAAAAAgN4ZQgAAgD/gvxpCAAAAAOC/GkIAAIA/P6EbQgAAAAA/oRtCAACAP56CHEIAAAAAnoIcQgAAgD+lYx1CAAAAAKVjHUIAAIA/BUUeQgAAAAAFRR5CAACAP2QmH0IAAAAAZCYfQgAAgD/EByBCAAAAAMQHIEIAAIA/I+kgQgAAAAAj6SBCAACAP4PKIUIAAAAAg8ohQgAAgD/iqyJCAAAAAOKrIkIAAIA/Qo0jQgAAAABCjSNCAACAP6FuJEIAAAAAoW4kQgAAgD9tPyVCAAAAAG0/JUIAAIA/zSAmQgAAAADNICZCAACAPywCJ0IAAAAALAInQgAAgD9N4SdCAAAAAE3hJ0IAAIA/rcIoQgAAAACtwihCAACAPwykKUIAAAAADKQpQgAAgD9shSpCAAAAAGyFKkIAAIA/O2YrQgAAAAA7ZitCAACAP5tHLEIAAAAAm0csQgAAgD/6KC1CAAAAAPooLUIAAIA/WgouQgAAAABaCi5CAACAP7nrLkIAAAAAuesuQgAAgD8ZzS9CAAAAABnNL0IAAIA/ZK4wQgAAAABkrjBCAACAP8OPMUIAAAAAw48xQgAAgD8jcTJCAAAAACNxMkIAAIA/g1IzQgAAAACDUjNCAACAP+IzNEIAAAAA4jM0QgAAgD9BFTVCAAAAAEEVNUIAAIA/ofY1QgAAAACh9jVCAACAP+/XNkIAAAAA79c2QgAAgD9PuTdCAAAAAE+5N0IAAIA/rpo4QgAAAACumjhCAACAPw58OUIAAAAADnw5QgAAgD9tXTpCAAAAAG1dOkIAAIA/zT47QgAAAADNPjtCAACAPywgPEIAAAAALCA8QgAAgD+MAT1CAAAAAIwBPUIAAIA/6+I9QgAAAADr4j1CAACAPyzEPkIAAAAALMQ+QgAAgD+MpT9CAAAAAIylP0IAAIA/7IZAQgAAAADshkBCAACAP0toQUIAAAAAS2hBQgAAgD+rSUJCAAAAAKtJQkIAAIA/CitDQgAAAAAKK0NCAACAP2oMREIAAAAAagxEQgAAgD+27URCAAAAALbtREIAAIA/Fc9FQgAAAAAVz0VCAACAP3WwRkIAAAAAdbBGQgAAgD/UkUdCAAAAANSRR0IAAIA/NHNIQgAAAAA0c0hCAACAP5NUSUIAAAAAk1RJQgAAgD91NEpCAAAAAHU0SkIAAIA/1RVLQgAAAADVFUtCAACAPzT3S0IAAAAANPdLQgAAgD/X0ExCAAAAANfQTEIAAIA/N7JNQgAAAAA3sk1CAACAP5aTTkIAAAAAlpNOQgAAgD95dE9CAAAAAHl0T0IAAIA/2VVQQgAAAADZVVBCAACAPyk3UUIAAAAAKTdRQgAAgD+JGFJCAAAAAIkYUkIAAIA/6PlSQgAAAADo+VJCAACAP0jbU0IAAAAASNtTQgAAgD+ivFRCAAAAAKK8VEIAAIA/AZ5VQgAAAAABnlVCAACAP2F/VkIAAAAAYX9WQgAAgD+SYFdCAAAAAJJgV0IAAIA/8UFYQgAAAADxQVhCAACAP1EjWUIAAAAAUSNZQgAAgD+wBFpCAAAAALAEWkIAAIA/4OVaQgAAAADg5VpCAACAP0DHW0IAAAAAQMdbQgAAgD+fqFxCAAAAAJ+oXEIAAIA/qoldQgAAAACqiV1CAACAPwprXkIAAAAACmteQgAAgD8DS19CAAAAAANLX0IAAIA/jBpgQgAAAACMGmBCAACAPyb4YEIAAAAAJvhgQgAAgD+F1mFCAAAAAIXWYUIAAIA/v7ZiQgAAAAC/tmJCAACAPx+YY0IAAAAAH5hjQgAAgD/keGRCAAAAAOR4ZEIAAIA/RFplQgAAAABEWmVCAACAP5U7ZkIAAAAAlTtmQgAAgD/dG2dCAAAAAN0bZ0IAAIA/bfpnQgAAAABt+mdCAACAP8fVaEIAAAAAx9VoQgAAgD9TsWlCAAAAAFOxaUIAAIA/F5FqQgAAAAAXkWpCAACAP3Zya0IAAAAAdnJrQgAAgD/MU2xCAAAAAMxTbEIAAIA/LDVtQgAAAAAsNW1CAACAP3QWbkIAAAAAdBZuQgAAgD/U925CAAAAANT3bkIAAIA/FdlvQgAAAAAV2W9CAACAP3S6cEIAAAAAdLpwQgAAgD/Um3FCAAAAANSbcUIAAIA/33xyQgAAAADffHJCAACAPz5ec0IAAAAAPl5zQgAAgD/0PnRCAAAAAPQ+dEIAAIA/VCB1QgAAAABUIHVCAACAP1QBdkIAAAAAVAF2QgAAgD8r4HZCAAAAACvgdkIAAIA/i8F3QgAAAACLwXdCAACAP0aheEIAAAAARqF4QgAAgD+mgnlCAAAAAKaCeUIAAIA/KWN6QgAAAAApY3pCAACAP4hEe0IAAAAAiER7QgAAgD/AJXxCAAAAAMAlfEIAAIA/Hwd9QgAAAAAfB31CAACAP3/ofUIAAAAAf+h9QgAAgD+XyX5CAAAAAJfJfkIAAIA/96p/QgAAAAD3qn9CAACAPytGgEIAAAAAK0aAQgAAgD/PtoBCAAAAAM+2gEIAAIA/fyeBQgAAAAB/J4FCAACAPy6YgUIAAAAALpiBQgAAgD/eCIJCAAAAAN4IgkIAAIA/d3mCQgAAAAB3eYJCAACAPyfqgkIAAAAAJ+qCQgAAgD/XWoNCAAAAANdag0IAAIA/h8uDQgAAAACHy4NCAACAPzI8hEIAAAAAMjyEQgAAgD/irIRCAAAAAOKshEIAAIA/kh2FQgAAAACSHYVCAACAP0GOhUIAAAAAQY6FQgAAgD+g/oVCAAAAAKD+hUIAAIA/UG+GQgAAAABQb4ZCAACAPwDghkIAAAAAAOCGQgAAgD+wUIdCAAAAALBQh0IAAIA/X8GHQgAAAABfwYdCAACAPw8yiEIAAAAADzKIQgAAgD+/oohCAAAAAL+iiEIAAIA/bxOJQgAAAABvE4lCAACAPxSEiUIAAAAAFISJQgAAgD/E9IlCAAAAAMT0iUIAAIA/dGWKQgAAAAB0ZYpCAACAPyPWikIAAAAAI9aKQgAAgD/TRotCAAAAANNGi0IAAIA/g7eLQgAAAACDt4tCAACAPzMojEIAAAAAMyiMQgAAgD/imIxCAAAAAOKYjEIAAIA/kgmNQgAAAACSCY1CAACAP0J6jUIAAAAAQnqNQgAAgD/y6o1CAAAAAPLqjUIAAIA/oVuOQgAAAAChW45CAACAP1HMjkIAAAAAUcyOQgAAgD8BPY9CAAAAAAE9j0IAAIA/r62PQgAAAACvrY9CAACAP18ekEIAAAAAXx6QQgAAgD8Pj5BCAAAAAA+PkEIAAIA/vv+QQgAAAAC+/5BCAACAP25wkUIAAAAAbnCRQgAAgD8e4ZFCAAAAAB7hkUIAAIA/zlGSQgAAAADOUZJCAACAP33CkkIAAAAAfcKSQgAAgD8tM5NCAAAAAC0zk0IAAIA/3aOTQgAAAADdo5NCAACAP40UlEIAAAAAjRSUQgAAgD89hZRCAAAAAD2FlEIAAIA/7PWUQgAAAADs9ZRCAACAP5xmlUIAAAAAnGaVQgAAgD9M15VCAAAAAEzXlUIAAIA//EeWQgAAAAD8R5ZCAACAP6u4lkIAAAAAq7iWQgAAgD9bKZdCAAAAAFspl0IAAIA/CpqXQgAAAAAKmpdCAACAP7oKmEIAAAAAugqYQgAAgD9qe5hCAAAAAGp7mEIAAIA/GeyYQgAAAAAZ7JhCAACAP8lcmUIAAAAAyVyZQgAAgD95zZlCAAAAAHnNmUIAAIA/KT6aQgAAAAApPppCAACAP9mumkIAAAAA2a6aQgAAgD+IH5tCAAAAAIgfm0IAAIA/OJCbQgAAAAA4kJtCAACAP+gAnEIAAAAA6ACcQgAAgD+YcZxCAAAAAJhxnEIAAIA/R+KcQgAAAABH4pxCAACAP/dSnUIAAAAA91KdQgAAgD+nw51CAAAAAKfDnUIAAIA/VzSeQgAAAABXNJ5CAACAPwalnkIAAAAABqWeQgAAgD+2FZ9CAAAAALYVn0IAAIA/ZoafQgAAAABmhp9CAACAPxb3n0IAAAAAFvefQgAAgD/FZ6BCAAAAAMVnoEIAAIA/ddigQgAAAAB12KBCAACAPyVJoUIAAAAAJUmhQgAAgD/VuaFCAAAAANW5oUIAAIA/hCqiQgAAAACEKqJCAACAPzSbokIAAAAANJuiQgAAgD/kC6NCAAAAAOQLo0IAAIA/lHyjQgAAAACUfKNCAACAP0Tto0IAAAAARO2jQgAAgD/zXaRCAAAAAPNdpEIAAIA/o86kQgAAAACjzqRCAACAP1M/pUIAAAAAUz+lQgAAgD8DsKVCAAAAAAOwpUIAAIA/siCmQgAAAACyIKZCAACAP2KRpkIAAAAAYpGmQgAAgD8SAqdCAAAAABICp0IAAIA/wnKnQgAAAADCcqdCAACAP3Ljp0IAAAAAcuOnQgAAgD8hVKhCAAAAACFUqEIAAIA/0cSoQgAAAADRxKhCAACAP4E1qUIAAAAAgTWpQgAAgD8wpqlCAAAAADCmqUIAAIA/4BaqQgAAAADgFqpCAACAP5CHqkIAAAAAkIeqQgAAgD9A+KpCAAAAAED4qkIAAIA/8GirQgAAAADwaKtCAACAP5/Zq0IAAAAAn9mrQgAAgD9PSqxCAAAAAE9KrEIAAIA//7qsQgAAAAD/uqxCAACAP68rrUIAAAAAryutQgAAgD9enK1CAAAAAF6crUIAAIA/Dg2uQgAAAAAODa5CAACAP759rkIAAAAAvn2uQgAAgD9u7q5CAAAAAG7urkIAAIA/HF+vQgAAAAAcX69CAACAP8zPr0IAAAAAzM+vQgAAgD97QLBCAAAAAHtAsEIAAIA/K7GwQgAAAAArsbBCAACAP9shsUIAAAAA2yGxQgAAgD+LkrFCAAAAAIuSsUIAAIA/OgOyQgAAAAA6A7JCAACAP+pzskIAAAAA6nOyQgAAgD+S5LJCAAAAAJLkskIAAIA/QVWzQgAAAABBVbNCAACAP/HFs0IAAAAA8cWzQgAAgD+hNrRCAAAAAKE2tEIAAIA/TKe0QgAAAABMp7RCAACAP/sXtUIAAAAA+xe1QgAAgD+riLVCAAAAAKuItUIAAIA/W/m1QgAAAABb+bVCAACAPwtqtkIAAAAAC2q2QgAAgD+42rZCAAAAALjatkIAAIA/Z0u3QgAAAABnS7dCAACAPxe8t0IAAAAAF7y3QgAAgD/HLLhCAAAAAMcsuEIAAIA/d524QgAAAAB3nbhCAACAPyYOuUIAAAAAJg65QgAAgD/VfrlCAAAAANV+uUIAAIA/he+5QgAAAACF77lCAACAPzRgukIAAAAANGC6QgAAgD/k0LpCAAAAAOTQukIAAIA/lEG7QgAAAACUQbtCAACAP0Syu0IAAAAARLK7QgAAgD/0IrxCAAAAAPQivEIAAIA/o5O8QgAAAACjk7xCAACAP1MEvUIAAAAAUwS9QgAAgD8Cdb1CAAAAAAJ1vUIAAIA/suW9QgAAAACy5b1CAACAP2JWvkIAAAAAYla+QgAAgD8Rx75CAAAAABHHvkIAAIA/wTe/QgAAAADBN79CAACAP3Gov0IAAAAAcai/QgAAgD/aF8BCAAAAANoXwEIAAIA/iojAQgAAAACKiMBCAACAPzr5wEIAAAAAOvnAQgAAgD/qacFCAAAAAOppwUIAAIA/mdrBQgAAAACZ2sFCAACAP0lLwkIAAAAASUvCQgAAgD8iu8JCAAAAACK7wkIAAIA/0ivDQgAAAADSK8NCAACAP4Gcw0IAAAAAgZzDQgAAgD8xDcRCAAAAADENxEIAAIA/4X3EQgAAAADhfcRCAACAP5HuxEIAAAAAke7EQgAAgD8pXMVCAAAAAClcxUIAAIA/2czFQgAAAADZzMVCAACAP4k9xkIAAAAAiT3GQgAAgD85rsZCAAAAADmuxkIAAIA/6B7HQgAAAADoHsdCAACAP5iPx0IAAAAAmI/HQgAAgD+y/sdCAAAAALL+x0IAAIA/Ym/IQgAAAABib8hCAACAPxLgyEIAAAAAEuDIQgAAgD/CUMlCAAAAAMJQyUIAAIA/ccHJQgAAAABxwclCAACAPyEyykIAAAAAITLKQgAAgD/RospCAAAAANGiykIAAIA/gRPLQgAAAACBE8tCAACAPwaEy0IAAAAABoTLQgAAgD+19MtCAAAAALX0y0IAAIA/ZWXMQgAAAABlZcxCAACAPxXWzEIAAAAAFdbMQgAAgD/FRs1CAAAAAMVGzUIAAIA/dLfNQgAAAAB0t81CAACAPyIozkIAAAAAIijOQgAAgD/SmM5CAAAAANKYzkIAAIA/ggnPQgAAAACCCc9CAACAPzF6z0IAAAAAMXrPQgAAgD/h6s9CAAAAAOHqz0IAAIA/kVvQQgAAAACRW9BCAACAP0HM0EIAAAAAQczQQgAAgD91PNFCAAAAAHU80UIAAIA/JK3RQgAAAAAkrdFCAACAP9Qd0kIAAAAA1B3SQgAAgD+EjtJCAAAAAISO0kIAAIA/NP/SQgAAAAA0/9JCAACAP+Rv00IAAAAA5G/TQgAAgD8d4NNCAAAAAB3g00IAAIA/zVDUQgAAAADNUNRCAACAP33B1EIAAAAAfcHUQgAAgD8tMtVCAAAAAC0y1UIAAIA/3KLVQgAAAADcotVCAACAP4wT1kIAAAAAjBPWQgAAgD8ohNZCAAAAACiE1kIAAIA/2PTWQgAAAADY9NZCAACAP4hl10IAAAAAiGXXQgAAgD841tdCAAAAADjW10IAAIA/50bYQgAAAADnRthCAACAP1C32EIAAAAAULfYQgAAgD8AKNlCAAAAAAAo2UIAAIA/sJjZQgAAAACwmNlCAACAP18J2kIAAAAAXwnaQgAAgD/PedpCAAAAAM952kIAAIA/f+raQgAAAAB/6tpCAACAPy9b20IAAAAAL1vbQgAAgD/ey9tCAAAAAN7L20IAAIA/bjzcQgAAAABuPNxCAACAPx6t3EIAAAAAHq3cQgAAgD/OHd1CAAAAAM4d3UIAAIA/fo7dQgAAAAB+jt1CAACAPyr/3UIAAAAAKv/dQgAAgD/ab95CAAAAANpv3kIAAIA/ieDeQgAAAACJ4N5CAACAPzlR30IAAAAAOVHfQgAAgD/pwd9CAAAAAOnB30IAAIA/lzLgQgAAAACXMuBCAACAP0aj4EIAAAAARqPgQgAAgD/2E+FCAAAAAPYT4UIAAIA/poThQgAAAACmhOFCAACAP1b14UIAAAAAVvXhQgAAgD8FZuJCAAAAAAVm4kIAAIA/tNbiQgAAAAC01uJCAACAP2RH40IAAAAAZEfjQgAAgD8UuONCAAAAABS440IAAIA/xCjkQgAAAADEKORCAACAP3OZ5EIAAAAAc5nkQgAAgD8jCuVCAAAAACMK5UIAAIA/03rlQgAAAADTeuVCAACAP4Lr5UIAAAAAguvlQgAAgD8yXOZCAAAAADJc5kIAAIA/4szmQgAAAADizOZCAACAP5I950IAAAAAkj3nQgAAgD9BrudCAAAAAEGu50IAAIA/8R7oQgAAAADxHuhCAACAP6GP6EIAAAAAoY/oQgAAgD9CAOlCAAAAAEIA6UIAAIA/8XDpQgAAAADxcOlCAACAP6Hh6UIAAAAAoeHpQgAAgD9RUupCAAAAAFFS6kIAAIA/AcPqQgAAAAABw+pCAACAP7Az60IAAAAAsDPrQgAAgD9BpOtCAAAAAEGk60IAAIA/8RTsQgAAAADxFOxCAACAP6CF7EIAAAAAoIXsQgAAgD9Q9uxCAAAAAFD27EIAAIA/AGftQgAAAAAAZ+1CAACAP0fX7UIAAAAAR9ftQgAAgD/3R+5CAAAAAPdH7kIAAIA/prjuQgAAAACmuO5CAACAP1Yp70IAAAAAVinvQgAAgD/vmO9CAAAAAO+Y70IAAIA/ngnwQgAAAACeCfBCAACAP0h68EIAAAAASHrwQgAAgD/46vBCAAAAAPjq8EIAAIA/p1vxQgAAAACnW/FCAACAP0rM8UIAAAAASszxQgAAgD/6PPJCAAAAAPo88kIAAIA/kK3yQgAAAACQrfJCAACAP0Ae80IAAAAAQB7zQgAAgD/LjvNCAAAAAMuO80IAAIA/e//zQgAAAAB7//NCAACAPyNw9EIAAAAAI3D0QgAAgD+94PRCAAAAAL3g9EIAAIA/bVH1QgAAAABtUfVCAACAP/zB9UIAAAAA/MH1QgAAgD+sMvZCAAAAAKwy9kIAAIA/U6P2QgAAAABTo/ZCAACAP4gT90IAAAAAiBP3QgAAgD84hPdCAAAAADiE90IAAIA/lPT3QgAAAACU9PdCAACAP0Rl+EIAAAAARGX4QgAAgD/H1fhCAAAAAMfV+EIAAIA/d0b5QgAAAAB3RvlCAACAPye3+UIAAAAAJ7f5QgAAgD/OJ/pCAAAAAM4n+kIAAIA/fpj6QgAAAAB+mPpCAACAPyoJ+0IAAAAAKgn7QgAAgD/ZeftCAAAAANl5+0IAAIA/ier7QgAAAACJ6vtCAACAPzJb/EIAAAAAMlv8QgAAgD/hy/xCAAAAAOHL/EIAAIA/kTz9QgAAAACRPP1CAACAPzqt/UIAAAAAOq39QgAAgD/qHf5CAAAAAOod/kIAAIA/mY7+QgAAAACZjv5CAACAP0b//kIAAAAARv/+QgAAgD/2b/9CAAAAAPZv/0IAAIA/auD/QgAAAABq4P9CAACAP40oAEMAAAAAjSgAQwAAgD/lYABDAAAAAOVgAEMAAIA/PZkAQwAAAAA9mQBDAACAP5XRAEMAAAAAldEAQwAAgD/nCQFDAAAAAOcJAUMAAIA/P0IBQwAAAAA/QgFDAACAP5d6AUMAAAAAl3oBQwAAgD/vsgFDAAAAAO+yAUMAAIA/R+sBQwAAAABH6wFDAACAP5sjAkMAAAAAmyMCQwAAgD/zWwJDAAAAAPNbAkMAAIA/S5QCQwAAAABLlAJDAACAP6PMAkMAAAAAo8wCQwAAgD/6BANDAAAAAPoEA0MAAIA/Uj0DQwAAAABSPQNDAACAP6p1A0MAAAAAqnUDQwAAgD8CrgNDAAAAAAKuA0MAAIA/WeYDQwAAAABZ5gNDAACAP7EeBEMAAAAAsR4EQwAAgD8JVwRDAAAAAAlXBEMAAIA/YY8EQwAAAABhjwRDAACAP7nHBEMAAAAAuccEQwAAgD8RAAVDAAAAABEABUMAAIA/aTgFQwAAAABpOAVDAACAP8FwBUMAAAAAwXAFQwAAgD8IqQVDAAAAAAipBUMAAIA/YOEFQwAAAABg4QVDAACAP7gZBkMAAAAAuBkGQwAAgD8QUgZDAAAAABBSBkMAAIA/aIoGQwAAAABoigZDAACAP7/CBkMAAAAAv8IGQwAAgD8X+wZDAAAAABf7BkMAAIA/bzMHQwAAAABvMwdDAACAP4ZrB0MAAAAAhmsHQwAAgD/eowdDAAAAAN6jB0MAAIA/NtwHQwAAAAA23AdDAACAP44UCEMAAAAAjhQIQwAAgD/mTAhDAAAAAOZMCEMAAIA/PoUIQwAAAAA+hQhDAACAP5W9CEMAAAAAlb0IQwAAgD+d9QhDAAAAAJ31CEMAAIA/9C0JQwAAAAD0LQlDAACAP0xmCUMAAAAATGYJQwAAgD+knglDAAAAAKSeCUMAAIA//NYJQwAAAAD81glDAACAP1QPCkMAAAAAVA8KQwAAgD8uRwpDAAAAAC5HCkMAAIA/hn8KQwAAAACGfwpDAACAP923CkMAAAAA3bcKQwAAgD818ApDAAAAADXwCkMAAIA/jSgLQwAAAACNKAtDAACAP+VgC0MAAAAA5WALQwAAgD8qmQtDAAAAACqZC0MAAIA/gtELQwAAAACC0QtDAACAP9oJDEMAAAAA2gkMQwAAgD8xQgxDAAAAADFCDEMAAIA/iXoMQwAAAACJegxDAACAP7iyDEMAAAAAuLIMQwAAgD8Q6wxDAAAAABDrDEMAAIA/aCMNQwAAAABoIw1DAACAP8BbDUMAAAAAwFsNQwAAgD8YlA1DAAAAABiUDUMAAIA/ZcwNQwAAAABlzA1DAACAP70EDkMAAAAAvQQOQwAAgD8VPQ5DAAAAABU9DkMAAIA/bHUOQwAAAABsdQ5DAACAP4+tDkMAAAAAj60OQwAAgD/n5Q5DAAAAAOflDkMAAIA/Px4PQwAAAAA/Hg9DAACAP5ZWD0MAAAAAllYPQwAAgD/ujg9DAAAAAO6OD0MAAIA/RscPQwAAAABGxw9DAACAP57/D0MAAAAAnv8PQwAAgD/qNxBDAAAAAOo3EEMAAIA/QnAQQwAAAABCcBBDAACAP5qoEEMAAAAAmqgQQwAAgD/i4BBDAAAAAOLgEEMAAIA/OhkRQwAAAAA6GRFDAACAP5JREUMAAAAAklERQwAAgD/PiRFDAAAAAM+JEUMAAIA/J8IRQwAAAAAnwhFDAACAP3/6EUMAAAAAf/oRQwAAgD/QMhJDAAAAANAyEkMAAIA/KGsSQwAAAAAoaxJDAACAPxmjEkMAAAAAGaMSQwAAgD9x2xJDAAAAAHHbEkMAAIA/wBMTQwAAAADAExNDAACAPxhME0MAAAAAGEwTQwAAgD9vhBNDAAAAAG+EE0MAAIA/kbwTQwAAAACRvBNDAACAP+n0E0MAAAAA6fQTQwAAgD9BLRRDAAAAAEEtFEMAAIA/l2UUQwAAAACXZRRDAACAP++dFEMAAAAA750UQwAAgD9H1hRDAAAAAEfWFEMAAIA/ng4VQwAAAACeDhVDAACAP+tGFUMAAAAA60YVQwAAgD9DfxVDAAAAAEN/FUMAAIA/Z7cVQwAAAABntxVDAACAP7fvFUMAAAAAt+8VQwAAgD8LKBZDAAAAAAsoFkMAAIA/YmAWQwAAAABiYBZDAACAP7qYFkMAAAAAupgWQwAAgD8E0RZDAAAAAATRFkMAAIA/XAkXQwAAAABcCRdDAACAP7RBF0MAAAAAtEEXQwAAgD8MehdDAAAAAAx6F0MAAIA/Y7IXQwAAAABjshdDAACAP7vqF0MAAAAAu+oXQwAAgD8RIxhDAAAAABEjGEMAAIA/aFsYQwAAAABoWxhDAACAP8CTGEMAAAAAwJMYQwAAgD8NzBhDAAAAAA3MGEMAAIA/ZAQZQwAAAABkBBlDAACAP7w8GUMAAAAAvDwZQwAAgD8IdRlDAAAAAAh1GUMAAIA/YK0ZQwAAAABgrRlDAACAP7flGUMAAAAAt+UZQwAAgD8PHhpDAAAAAA8eGkMAAIA/YlYaQwAAAABiVhpDAACAP7mOGkMAAAAAuY4aQwAAgD8RxxpDAAAAABHHGkMAAIA/af8aQwAAAABp/xpDAACAP8E3G0MAAAAAwTcbQwAAgD8WcBtDAAAAABZwG0MAAIA/bqgbQwAAAABuqBtDAACAP8XgG0MAAAAAxeAbQwAAgD8dGRxDAAAAAB0ZHEMAAIA/dVEcQwAAAAB1URxDAACAP82JHEMAAAAAzYkcQwAAgD/1wRxDAAAAAPXBHEMAAIA/TfocQwAAAABN+hxDAACAP6UyHUMAAAAApTIdQwAAgD/9ah1DAAAAAP1qHUMAAIA/eKIdQwAAAAB4oh1DAACAP8/aHUMAAAAAz9odQwAAgD8nEx5DAAAAACcTHkMAAIA/f0seQwAAAAB/Sx5DAACAP16DHkMAAAAAXoMeQwAAgD+2ux5DAAAAALa7HkMAAIA/DvQeQwAAAAAO9B5DAACAPyQrH0MAAAAAJCsfQwAAgD98Yx9DAAAAAHxjH0MAAIA/1JsfQwAAAADUmx9DAACAPyvUH0MAAAAAK9QfQwAAgD8wDCBDAAAAADAMIEMAAIA/iEQgQwAAAACIRCBDAACAP+B8IEMAAAAA4HwgQwAAgD9wtCBDAAAAAHC0IEMAAIA/yOwgQwAAAADI7CBDAACAP3MkIUMAAAAAcyQhQwAAgD/LXCFDAAAAAMtcIUMAAIA/IpUhQwAAAAAilSFDAACAP/jMIUMAAAAA+MwhQwAAgD9PBSJDAAAAAE8FIkMAAIA/pz0iQwAAAACnPSJDAACAP/91IkMAAAAA/3UiQwAAgD8mriJDAAAAACauIkMAAIA/fuYiQwAAAAB+5iJDAACAP9UeI0MAAAAA1R4jQwAAgD/LViNDAAAAAMtWI0MAAIA/I48jQwAAAAAjjyNDAACAPy7GI0MAAAAALsYjQwAAgD+C/SNDAAAAAIL9I0MAAIA/2jUkQwAAAADaNSRDAACAP+RtJEMAAAAA5G0kQwAAgD88piRDAAAAADymJEMAAIA/Td4kQwAAAABN3iRDAACAP6UWJUMAAAAApRYlQwAAgD/QTiVDAAAAANBOJUMAAIA/KIclQwAAAAAohyVDAACAP3+/JUMAAAAAf78lQwAAgD/X9yVDAAAAANf3JUMAAIA/LzAmQwAAAAAvMCZDAACAPwdoJkMAAAAAB2gmQwAAgD9foCZDAAAAAF+gJkMAAIA/t9gmQwAAAAC32CZDAACAP78QJ0MAAAAAvxAnQwAAgD8XSSdDAAAAABdJJ0MAAIA/boEnQwAAAABugSdDAACAP5O5J0MAAAAAk7knQwAAgD/q8SdDAAAAAOrxJ0MAAIA/QiooQwAAAABCKihDAACAP4diKEMAAAAAh2IoQwAAgD/fmihDAAAAAN+aKEMAAIA/N9MoQwAAAAA30yhDAACAP44LKUMAAAAAjgspQwAAgD/RQylDAAAAANFDKUMAAIA/KXwpQwAAAAApfClDAACAP4G0KUMAAAAAgbQpQwAAgD/Z7ClDAAAAANnsKUMAAIA/+yQqQwAAAAD7JCpDAACAP1NdKkMAAAAAU10qQwAAgD+rlSpDAAAAAKuVKkMAAIA/ps0qQwAAAACmzSpDAACAP/4FK0MAAAAA/gUrQwAAgD9WPitDAAAAAFY+K0MAAIA/iHYrQwAAAACIditDAACAP+CuK0MAAAAA4K4rQwAAgD+M5itDAAAAAIzmK0MAAIA/5B4sQwAAAADkHixDAACAPzxXLEMAAAAAPFcsQwAAgD9ujyxDAAAAAG6PLEMAAIA/xccsQwAAAADFxyxDAACAPx0ALUMAAAAAHQAtQwAAgD91OC1DAAAAAHU4LUMAAIA/unAtQwAAAAC6cC1DAACAPxGpLUMAAAAAEaktQwAAgD9p4S1DAAAAAGnhLUMAAIA/wRkuQwAAAADBGS5DAACAPxlSLkMAAAAAGVIuQwAAgD9jii5DAAAAAGOKLkMAAIA/u8IuQwAAAAC7wi5DAACAPxP7LkMAAAAAE/suQwAAgD9rMy9DAAAAAGszL0MAAIA/w2svQwAAAADDay9DAACAPxukL0MAAAAAG6QvQwAAgD9Z3C9DAAAAAFncL0MAAIA/sBQwQwAAAACwFDBDAACAPwhNMEMAAAAACE0wQwAAgD9ghTBDAAAAAGCFMEMAAIA/uL0wQwAAAAC4vTBDAACAPxD2MEMAAAAAEPYwQwAAgD9PLjFDAAAAAE8uMUMAAIA/p2YxQwAAAACnZjFDAACAP/+eMUMAAAAA/54xQwAAgD9X1zFDAAAAAFfXMUMAAIA/rw8yQwAAAACvDzJDAACAP/hHMkMAAAAA+EcyQwAAgD9QgDJDAAAAAFCAMkMAAIA/qLgyQwAAAACouDJDAACAPwDxMkMAAAAAAPEyQwAAgD9XKTNDAAAAAFcpM0MAAIA/r2EzQwAAAACvYTNDAACAP+mZM0MAAAAA6ZkzQwAAgD9B0jNDAAAAAEHSM0MAAIA/mQo0QwAAAACZCjRDAACAP/FCNEMAAAAA8UI0QwAAgD9JezRDAAAAAEl7NEMAAIA/obM0QwAAAAChszRDAACAPzLrNEMAAAAAMus0QwAAgD+KIzVDAAAAAIojNUMAAIA/4ls1QwAAAADiWzVDAACAPzqUNUMAAAAAOpQ1QwAAgD+SzDVDAAAAAJLMNUMAAIA/6gQ2QwAAAADqBDZDAACAPxI9NkMAAAAAEj02QwAAgD9qdTZDAAAAAGp1NkMAAIA/wq02QwAAAADCrTZDAACAPxrmNkMAAAAAGuY2QwAAgD9yHjdDAAAAAHIeN0MAAIA/ylY3QwAAAADKVjdDAACAPyKPN0MAAAAAIo83QwAAgD96xzdDAAAAAHrHN0MAAIA/0v83QwAAAADS/zdDAACAPyk4OEMAAAAAKTg4QwAAgD9rcDhDAAAAAGtwOEMAAIA/w6g4QwAAAADDqDhDAACAPxvhOEMAAAAAG+E4QwAAgD9zGTlDAAAAAHMZOUMAAIA/ylE5QwAAAADKUTlDAACAPyKKOUMAAAAAIoo5QwAAgD96wjlDAAAAAHrCOUMAAIA/0vo5QwAAAADS+jlDAACAPyozOkMAAAAAKjM6QwAAgD+CazpDAAAAAIJrOkMAAIA/2qM6QwAAAADaozpDAACAPzLcOkMAAAAAMtw6QwAAgD99FDtDAAAAAH0UO0MAAIA/1Uw7QwAAAADVTDtDAACAPy2FO0MAAAAALYU7QwAAgD+FvTtDAAAAAIW9O0MAAIA/3fU7QwAAAADd9TtDAACAPzUuPEMAAAAANS48QwAAgD+MZjxDAAAAAIxmPEMAAIA/5J48QwAAAADknjxDAACAPzzXPEMAAAAAPNc8QwAAgD+UDz1DAAAAAJQPPUMAAIA/7Ec9QwAAAADsRz1DAACAP0SAPUMAAAAARIA9QwAAgD+cuD1DAAAAAJy4PUMAAIA/9PA9QwAAAAD08D1DAACAP0spPkMAAAAASyk+QwAAgD+jYT5DAAAAAKNhPkMAAIA/+5k+QwAAAAD7mT5DAACAP1PSPkMAAAAAU9I+QwAAgD+rCj9DAAAAAKsKP0MAAIA/A0M/QwAAAAADQz9DAACAP1t7P0MAAAAAW3s/QwAAgD+zsz9DAAAAALOzP0MAAIA/Cuw/QwAAAAAK7D9DAACAP2IkQEMAAAAAYiRAQwAAgD+6XEBDAAAAALpcQEMAAIA/EpVAQwAAAAASlUBDAACAP2rNQEMAAAAAas1AQwAAgD/CBUFDAAAAAMIFQUMAAIA/Gj5BQwAAAAAaPkFDAACAP3F2QUMAAAAAcXZBQwAAgD/JrkFDAAAAAMmuQUMAAIA/IedBQwAAAAAh50FDAACAP3kfQkMAAAAAeR9CQwAAgD/RV0JDAAAAANFXQkMAAIA/KZBCQwAAAAApkEJDAACAP4HIQkMAAAAAgchCQwAAgD/ZAENDAAAAANkAQ0MAAIA/LzlDQwAAAAAvOUNDAACAP4dxQ0MAAAAAh3FDQwAAgD/fqUNDAAAAAN+pQ0MAAIA/N+JDQwAAAAA34kNDAACAP48aREMAAAAAjxpEQwAAgD/nUkRDAAAAAOdSREMAAIA/P4tEQwAAAAA/i0RDAACAP5HDREMAAAAAkcNEQwAAgD/p+0RDAAAAAOn7REMAAIA/QTRFQwAAAABBNEVDAACAP5lsRUMAAAAAmWxFQwAAgD8ipEVDAAAAACKkRUMAAIA/etxFQwAAAAB63EVDAACAP9IURkMAAAAA0hRGQwAAgD8/SkZDAAAAAD9KRkMAAIA/l4JGQwAAAACXgkZDAACAP3i4RkMAAAAAeLhGQwAAgD/Q8EZDAAAAANDwRkMAAIA/"),
+"aabb": AABB(-27.86245, -0.432, -26.431866, 54.402885, 1e-05, 51.728455),
+"attribute_data": PackedByteArray("AAAAAAAAAAAAAAAAAACAP0HfIz4AAAAAQd8jPgAAgD8S36M+AAAAABLfoz4AAIA/s871PgAAAACzzvU+AACAPyrfIz8AAAAAKt8jPwAAgD/61kw/AAAAAPrWTD8AAIA/s851PwAAAACzznU/AACAP0Jjjz8AAAAAQmOPPwAAgD/F3qM/AAAAAMXeoz8AAIA/uFq4PwAAAAC4Wrg/AACAP5TWzD8AAAAAlNbMPwAAgD97UuE/AAAAAHtS4T8AAIA/Y871PwAAAABjzvU/AACAPyUlBUAAAAAAJSUFQAAAgD8CYw9AAAAAAAJjD0AAAIA/+aAZQAAAAAD5oBlAAACAP+TeI0AAAAAA5N4jQAAAgD/bHC5AAAAAANscLkAAAIA/0Vo4QAAAAADRWjhAAACAP72YQkAAAAAAvZhCQAAAgD+z1kxAAAAAALPWTEAAAIA/PBRXQAAAAAA8FFdAAACAPytSYUAAAAAAK1JhQAAAgD8ekGtAAAAAAB6Qa0AAAIA/Dc51QAAAAAANznVAAACAPwEGgEAAAAAAAQaAQAAAgD/4JIVAAAAAAPgkhUAAAIA/tEOKQAAAAAC0Q4pAAACAP65ij0AAAAAArmKPQAAAgD+mgZRAAAAAAKaBlEAAAIA/oaCZQAAAAAChoJlAAACAP5i/nkAAAAAAmL+eQAAAgD9K3qNAAAAAAEreo0AAAIA/Q/2oQAAAAABD/ahAAACAPzscrkAAAAAAOxyuQAAAgD83O7NAAAAAADc7s0AAAIA/L1q4QAAAAAAvWrhAAACAPxh5vUAAAAAAGHm9QAAAgD8QmMJAAAAAABCYwkAAAIA/C7fHQAAAAAALt8dAAACAPwPWzEAAAAAAA9bMQAAAgD/99NFAAAAAAP300UAAAIA/ahPXQAAAAABqE9dAAACAP2My3EAAAAAAYzLcQAAAgD9cUeFAAAAAAFxR4UAAAIA/VnDmQAAAAABWcOZAAACAP06P60AAAAAATo/rQAAAgD+CrfBAAAAAAIKt8EAAAIA/e8z1QAAAAAB7zPVAAACAP3Tr+kAAAAAAdOv6QAAAgD83BQBBAAAAADcFAEEAAIA/jpQCQQAAAACOlAJBAACAPwskBUEAAAAACyQFQQAAgD+IswdBAAAAAIizB0EAAIA/BUMKQQAAAAAFQwpBAACAP17SDEEAAAAAXtIMQQAAgD/aYQ9BAAAAANphD0EAAIA/WPERQQAAAABY8RFBAACAP9SAFEEAAAAA1IAUQQAAgD9FEBdBAAAAAEUQF0EAAIA/wZ8ZQQAAAADBnxlBAACAPz8vHEEAAAAAPy8cQQAAgD+7vh5BAAAAALu+HkEAAIA/OE4hQQAAAAA4TiFBAACAP5vdI0EAAAAAm90jQQAAgD8XbSZBAAAAABdtJkEAAIA/lPwoQQAAAACU/ChBAACAPxCMK0EAAAAAEIwrQQAAgD97Gy5BAAAAAHsbLkEAAIA/+KowQQAAAAD4qjBBAACAP3Q6M0EAAAAAdDozQQAAgD/xyTVBAAAAAPHJNUEAAIA/bVk4QQAAAABtWThBAACAP9LoOkEAAAAA0ug6QQAAgD9PeD1BAAAAAE94PUEAAIA/ywdAQQAAAADLB0BBAACAP0iXQkEAAAAASJdCQQAAgD/FJkVBAAAAAMUmRUEAAIA/N7ZHQQAAAAA3tkdBAACAP7RFSkEAAAAAtEVKQQAAgD8w1UxBAAAAADDVTEEAAIA/rWRPQQAAAACtZE9BAACAPyb0UUEAAAAAJvRRQQAAgD+jg1RBAAAAAKODVEEAAIA/IBNXQQAAAAAgE1dBAACAP5yiWUEAAAAAnKJZQQAAgD8ZMlxBAAAAABkyXEEAAIA/ksFeQQAAAACSwV5BAACAPw5RYUEAAAAADlFhQQAAgD+L4GNBAAAAAIvgY0EAAIA/CHBmQQAAAAAIcGZBAACAP4T/aEEAAAAAhP9oQQAAgD/3jmtBAAAAAPeOa0EAAIA/dB5uQQAAAAB0Hm5BAACAP/GtcEEAAAAA8a1wQQAAgD9tPXNBAAAAAG09c0EAAIA/6sx1QQAAAADqzHVBAACAP1hceEEAAAAAWFx4QQAAgD/V63pBAAAAANXrekEAAIA/Unt9QQAAAABSe31BAACAP2cFgEEAAAAAZwWAQQAAgD8lTYFBAAAAACVNgUEAAIA/4JSCQQAAAADglIJBAACAP57cg0EAAAAAntyDQQAAgD9cJIVBAAAAAFwkhUEAAIA/G2yGQQAAAAAbbIZBAACAP9Kzh0EAAAAA0rOHQQAAgD+Q+4hBAAAAAJD7iEEAAIA/TkOKQQAAAABOQ4pBAACAPw2Li0EAAAAADYuLQQAAgD/L0oxBAAAAAMvSjEEAAIA/hBqOQQAAAACEGo5BAACAP0Nij0EAAAAAQ2KPQQAAgD8BqpBBAAAAAAGqkEEAAIA/v/GRQQAAAAC/8ZFBAACAP3Q5k0EAAAAAdDmTQQAAgD8ygZRBAAAAADKBlEEAAIA/8MiVQQAAAADwyJVBAACAP68Ql0EAAAAArxCXQQAAgD9nWJhBAAAAAGdYmEEAAIA/JaCZQQAAAAAloJlBAACAP+PnmkEAAAAA4+eaQQAAgD+iL5xBAAAAAKIvnEEAAIA/YHedQQAAAABgd51BAACAPx6/nkEAAAAAHr+eQQAAgD/dBqBBAAAAAN0GoEEAAIA/m06hQQAAAACbTqFBAACAP1mWokEAAAAAWZaiQQAAgD8Y3qNBAAAAABjeo0EAAIA/1iWlQQAAAADWJaVBAACAP5RtpkEAAAAAlG2mQQAAgD9TtadBAAAAAFO1p0EAAIA/Ef2oQQAAAAAR/ahBAACAP89EqkEAAAAAz0SqQQAAgD+OjKtBAAAAAI6Mq0EAAIA/TNSsQQAAAABM1KxBAACAPwocrkEAAAAAChyuQQAAgD/JY69BAAAAAMljr0EAAIA//KqwQQAAAAD8qrBBAACAP7nxsUEAAAAAufGxQQAAgD93ObNBAAAAAHc5s0EAAIA/NYG0QQAAAAA1gbRBAACAP/TItUEAAAAA9Mi1QQAAgD+yELdBAAAAALIQt0EAAIA/cFi4QQAAAABwWLhBAACAPy+guUEAAAAAL6C5QQAAgD/t57pBAAAAAO3nukEAAIA/qy+8QQAAAACrL7xBAACAP2l3vUEAAAAAaXe9QQAAgD8ov75BAAAAACi/vkEAAIA/5gbAQQAAAADmBsBBAACAP6ROwUEAAAAApE7BQQAAgD9ilsJBAAAAAGKWwkEAAIA/F97DQQAAAAAX3sNBAACAP8slxUEAAAAAyyXFQQAAgD98bcZBAAAAAHxtxkEAAIA/LbXHQQAAAAAttcdBAACAP9z8yEEAAAAA3PzIQQAAgD+JRMpBAAAAAIlEykEAAIA/OIzLQQAAAAA4jMtBAACAP+fTzEEAAAAA59PMQQAAgD+UG85BAAAAAJQbzkEAAIA/QWPPQQAAAABBY89BAACAP/Kq0EEAAAAA8qrQQQAAgD+j8tFBAAAAAKPy0UEAAIA/VTrTQQAAAABVOtNBAACAPwiC1EEAAAAACILUQQAAgD/CydVBAAAAAMLJ1UEAAIA/gBHXQQAAAACAEddBAACAPz5Z2EEAAAAAPlnYQQAAgD/9oNlBAAAAAP2g2UEAAIA/u+jaQQAAAAC76NpBAACAP3kw3EEAAAAAeTDcQQAAgD83eN1BAAAAADd43UEAAIA/9r/eQQAAAAD2v95BAACAP7QH4EEAAAAAtAfgQQAAgD9vT+FBAAAAAG9P4UEAAIA/LZfiQQAAAAAtl+JBAACAP+fe40EAAAAA597jQQAAgD+lJuVBAAAAAKUm5UEAAIA/XW7mQQAAAABdbuZBAACAPxu250EAAAAAG7bnQQAAgD/Z/ehBAAAAANn96EEAAIA/lkXqQQAAAACWRepBAACAP1SN60EAAAAAVI3rQQAAgD8S1exBAAAAABLV7EEAAIA/0BzuQQAAAADQHO5BAACAP45k70EAAAAAjmTvQQAAgD9NrPBBAAAAAE2s8EEAAIA/CfTxQQAAAAAJ9PFBAACAP8g780EAAAAAyDvzQQAAgD+Gg/RBAAAAAIaD9EEAAIA/RMv1QQAAAABEy/VBAACAPwIT90EAAAAAAhP3QQAAgD/BWvhBAAAAAMFa+EEAAIA/f6L5QQAAAAB/ovlBAACAPzzq+kEAAAAAPOr6QQAAgD/7MfxBAAAAAPsx/EEAAIA/uXn9QQAAAAC5ef1BAACAP3fB/kEAAAAAd8H+QQAAgD+YBABCAAAAAJgEAEIAAIA/d6gAQgAAAAB3qABCAACAP1ZMAUIAAAAAVkwBQgAAgD828AFCAAAAADbwAUIAAIA/EpQCQgAAAAASlAJCAACAP/E3A0IAAAAA8TcDQgAAgD/Q2wNCAAAAANDbA0IAAIA/r38EQgAAAACvfwRCAACAP4kjBUIAAAAAiSMFQgAAgD9oxwVCAAAAAGjHBUIAAIA/R2sGQgAAAABHawZCAACAPyYPB0IAAAAAJg8HQgAAgD//sgdCAAAAAP+yB0IAAIA/3lYIQgAAAADeVghCAACAP736CEIAAAAAvfoIQgAAgD+bnglCAAAAAJueCUIAAIA/e0IKQgAAAAB7QgpCAACAP1rmCkIAAAAAWuYKQgAAgD85igtCAAAAADmKC0IAAIA/Dy4MQgAAAAAPLgxCAACAP+7RDEIAAAAA7tEMQgAAgD/NdQ1CAAAAAM11DUIAAIA/pBkOQgAAAACkGQ5CAACAP4O9DkIAAAAAg70OQgAAgD9jYQ9CAAAAAGNhD0IAAIA/PwUQQgAAAAA/BRBCAACAPx6pEEIAAAAAHqkQQgAAgD/9TBFCAAAAAP1MEUIAAIA/3fARQgAAAADd8BFCAACAP7yUEkIAAAAAvJQSQgAAgD+bOBNCAAAAAJs4E0IAAIA/etwTQgAAAAB63BNCAACAP1mAFEIAAAAAWYAUQgAAgD84JBVCAAAAADgkFUIAAIA/GMgVQgAAAAAYyBVCAACAP/drFkIAAAAA92sWQgAAgD/WDxdCAAAAANYPF0IAAIA/tbMXQgAAAAC1sxdCAACAP5RXGEIAAAAAlFcYQgAAgD9z+xhCAAAAAHP7GEIAAIA/UZ8ZQgAAAABRnxlCAACAPypDGkIAAAAAKkMaQgAAgD8C5xpCAAAAAALnGkIAAIA/2oobQgAAAADaihtCAACAP7EuHEIAAAAAsS4cQgAAgD+H0hxCAAAAAIfSHEIAAIA/XXYdQgAAAABddh1CAACAPzMaHkIAAAAAMxoeQgAAgD8Jvh5CAAAAAAm+HkIAAIA/32EfQgAAAADfYR9CAACAP7cFIEIAAAAAtwUgQgAAgD+PqSBCAAAAAI+pIEIAAIA/aE0hQgAAAABoTSFCAACAP0PxIUIAAAAAQ/EhQgAAgD8ilSJCAAAAACKVIkIAAIA/ATkjQgAAAAABOSNCAACAP+DcI0IAAAAA4NwjQgAAgD+/gCRCAAAAAL+AJEIAAIA/niQlQgAAAACeJCVCAACAP33IJUIAAAAAfcglQgAAgD9cbCZCAAAAAFxsJkIAAIA/PBAnQgAAAAA8ECdCAACAPxu0J0IAAAAAG7QnQgAAgD/6VyhCAAAAAPpXKEIAAIA/2fsoQgAAAADZ+yhCAACAP7ifKUIAAAAAuJ8pQgAAgD+YQypCAAAAAJhDKkIAAIA/d+cqQgAAAAB35ypCAACAP1aLK0IAAAAAVosrQgAAgD81LyxCAAAAADUvLEIAAIA/FNMsQgAAAAAU0yxCAACAP/N2LUIAAAAA83YtQgAAgD/SGi5CAAAAANIaLkIAAIA/Tb0uQgAAAABNvS5CAACAPy1hL0IAAAAALWEvQgAAgD8MBTBCAAAAAAwFMEIAAIA/66gwQgAAAADrqDBCAACAP8pMMUIAAAAAykwxQgAAgD+p8DFCAAAAAKnwMUIAAIA/iJQyQgAAAACIlDJCAACAP2g4M0IAAAAAaDgzQgAAgD9H3DNCAAAAAEfcM0IAAIA/JoA0QgAAAAAmgDRCAACAPwUkNUIAAAAABSQ1QgAAgD/kxzVCAAAAAOTHNUIAAIA/w2s2QgAAAADDazZCAACAP6IPN0IAAAAAog83QgAAgD+CszdCAAAAAIKzN0IAAIA/TVc4QgAAAABNVzhCAACAPyz7OEIAAAAALPs4QgAAgD8MnzlCAAAAAAyfOUIAAIA/5EI6QgAAAADkQjpCAACAP8TmOkIAAAAAxOY6QgAAgD+jijtCAAAAAKOKO0IAAIA/gi48QgAAAACCLjxCAACAP1XSPEIAAAAAVdI8QgAAgD80dj1CAAAAADR2PUIAAIA/FBo+QgAAAAAUGj5CAACAP/O9PkIAAAAA870+QgAAgD/JYT9CAAAAAMlhP0IAAIA/qAVAQgAAAACoBUBCAACAP4epQEIAAAAAh6lAQgAAgD9mTUFCAAAAAGZNQUIAAIA/P/FBQgAAAAA/8UFCAACAPx6VQkIAAAAAHpVCQgAAgD/9OENCAAAAAP04Q0IAAIA/3NxDQgAAAADc3ENCAACAP7yAREIAAAAAvIBEQgAAgD+ZJEVCAAAAAJkkRUIAAIA/eMhFQgAAAAB4yEVCAACAP1dsRkIAAAAAV2xGQgAAgD82EEdCAAAAADYQR0IAAIA/ErRHQgAAAAAStEdCAACAP/FXSEIAAAAA8VdIQgAAgD/R+0hCAAAAANH7SEIAAIA/sJ9JQgAAAACwn0lCAACAP49DSkIAAAAAj0NKQgAAgD9r50pCAAAAAGvnSkIAAIA/SotLQgAAAABKi0tCAACAPyovTEIAAAAAKi9MQgAAgD8J00xCAAAAAAnTTEIAAIA/6HZNQgAAAADodk1CAACAP8caTkIAAAAAxxpOQgAAgD+mvk5CAAAAAKa+TkIAAIA/hWJPQgAAAACFYk9CAACAP2UGUEIAAAAAZQZQQgAAgD9EqlBCAAAAAESqUEIAAIA/I05RQgAAAAAjTlFCAACAPwLyUUIAAAAAAvJRQgAAgD/hlVJCAAAAAOGVUkIAAIA/wDlTQgAAAADAOVNCAACAP6DdU0IAAAAAoN1TQgAAgD9/gVRCAAAAAH+BVEIAAIA/XiVVQgAAAABeJVVCAACAPz3JVUIAAAAAPclVQgAAgD8cbVZCAAAAABxtVkIAAIA/+xBXQgAAAAD7EFdCAACAP9q0V0IAAAAA2rRXQgAAgD+6WFhCAAAAALpYWEIAAIA/mfxYQgAAAACZ/FhCAACAP3igWUIAAAAAeKBZQgAAgD9BRFpCAAAAAEFEWkIAAIA/8OdaQgAAAADw51pCAACAP5uLW0IAAAAAm4tbQgAAgD8ZL1xCAAAAABkvXEIAAIA/+NJcQgAAAAD40lxCAACAP9h2XUIAAAAA2HZdQgAAgD+3Gl5CAAAAALcaXkIAAIA/lr5eQgAAAACWvl5CAACAP3ViX0IAAAAAdWJfQgAAgD9UBmBCAAAAAFQGYEIAAIA/M6pgQgAAAAAzqmBCAACAPxNOYUIAAAAAE05hQgAAgD/y8WFCAAAAAPLxYUIAAIA/0ZViQgAAAADRlWJCAACAP7A5Y0IAAAAAsDljQgAAgD+P3WNCAAAAAI/dY0IAAIA/boFkQgAAAABugWRCAACAP04lZUIAAAAATiVlQgAAgD8tyWVCAAAAAC3JZUIAAIA/DG1mQgAAAAAMbWZCAACAP+sQZ0IAAAAA6xBnQgAAgD/KtGdCAAAAAMq0Z0IAAIA/qVhoQgAAAACpWGhCAACAP4n8aEIAAAAAifxoQgAAgD9ooGlCAAAAAGigaUIAAIA/R0RqQgAAAABHRGpCAACAPyboakIAAAAAJuhqQgAAgD8FjGtCAAAAAAWMa0IAAIA/5C9sQgAAAADkL2xCAACAP8TTbEIAAAAAxNNsQgAAgD+jd21CAAAAAKN3bUIAAIA/ghtuQgAAAACCG25CAACAP2G/bkIAAAAAYb9uQgAAgD9AY29CAAAAAEBjb0IAAIA/HwdwQgAAAAAfB3BCAACAP/+qcEIAAAAA/6pwQgAAgD/eTnFCAAAAAN5OcUIAAIA/vfJxQgAAAAC98nFCAACAP5yWckIAAAAAnJZyQgAAgD97OnNCAAAAAHs6c0IAAIA/Wt5zQgAAAABa3nNCAACAPzqCdEIAAAAAOoJ0QgAAgD8ZJnVCAAAAABkmdUIAAIA/+Ml1QgAAAAD4yXVCAACAP9dtdkIAAAAA1212QgAAgD+2EXdCAAAAALYRd0IAAIA/lbV3QgAAAACVtXdCAACAP3VZeEIAAAAAdVl4QgAAgD9U/XhCAAAAAFT9eEIAAIA/M6F5QgAAAAAzoXlCAACAPxJFekIAAAAAEkV6QgAAgD/x6HpCAAAAAPHoekIAAIA/0Ix7QgAAAADQjHtCAACAP7AwfEIAAAAAsDB8QgAAgD+P1HxCAAAAAI/UfEIAAIA/bnh9QgAAAABueH1CAACAP00cfkIAAAAATRx+QgAAgD8swH5CAAAAACzAfkIAAIA/DGR/QgAAAAAMZH9CAACAP/UDgEIAAAAA9QOAQgAAgD/lVYBCAAAAAOVVgEIAAIA/1KeAQgAAAADUp4BCAACAP8T5gEIAAAAAxPmAQgAAgD+0S4FCAAAAALRLgUIAAIA/o52BQgAAAACjnYFCAACAP5PvgUIAAAAAk++BQgAAgD+CQYJCAAAAAIJBgkIAAIA/cpOCQgAAAAByk4JCAACAP2LlgkIAAAAAYuWCQgAAgD9RN4NCAAAAAFE3g0IAAIA/QYmDQgAAAABBiYNCAACAPzDbg0IAAAAAMNuDQgAAgD8gLYRCAAAAACAthEIAAIA/D3+EQgAAAAAPf4RCAACAP//QhEIAAAAA/9CEQgAAgD/vIoVCAAAAAO8ihUIAAIA/3nSFQgAAAADedIVCAACAP87GhUIAAAAAzsaFQgAAgD+9GIZCAAAAAL0YhkIAAIA/rWqGQgAAAACtaoZCAACAP528hkIAAAAAnbyGQgAAgD+MDodCAAAAAIwOh0IAAIA/fGCHQgAAAAB8YIdCAACAP2uyh0IAAAAAa7KHQgAAgD9bBIhCAAAAAFsEiEIAAIA/S1aIQgAAAABLVohCAACAPzqoiEIAAAAAOqiIQgAAgD8q+ohCAAAAACr6iEIAAIA/GUyJQgAAAAAZTIlCAACAPwmeiUIAAAAACZ6JQgAAgD/474lCAAAAAPjviUIAAIA/6EGKQgAAAADoQYpCAACAP9iTikIAAAAA2JOKQgAAgD/H5YpCAAAAAMflikIAAIA/tzeLQgAAAAC3N4tCAACAP6aJi0IAAAAApomLQgAAgD+W24tCAAAAAJbbi0IAAIA/hi2MQgAAAACGLYxCAACAP3V/jEIAAAAAdX+MQgAAgD9l0YxCAAAAAGXRjEIAAIA/VCONQgAAAABUI41CAACAP0R1jUIAAAAARHWNQgAAgD8zx41CAAAAADPHjUIAAIA/IxmOQgAAAAAjGY5CAACAPxNrjkIAAAAAE2uOQgAAgD8CvY5CAAAAAAK9jkIAAIA/8g6PQgAAAADyDo9CAACAP+Fgj0IAAAAA4WCPQgAAgD/Rso9CAAAAANGyj0IAAIA/wASQQgAAAADABJBCAACAP7BWkEIAAAAAsFaQQgAAgD+gqJBCAAAAAKCokEIAAIA/j/qQQgAAAACP+pBCAACAP39MkUIAAAAAf0yRQgAAgD9vnpFCAAAAAG+ekUIAAIA/XvCRQgAAAABe8JFCAACAP05CkkIAAAAATkKSQgAAgD89lJJCAAAAAD2UkkIAAIA/LeaSQgAAAAAt5pJCAACAPxw4k0IAAAAAHDiTQgAAgD8MipNCAAAAAAyKk0IAAIA//NuTQgAAAAD825NCAACAP+stlEIAAAAA6y2UQgAAgD/bf5RCAAAAANt/lEIAAIA/ytGUQgAAAADK0ZRCAACAP7ojlUIAAAAAuiOVQgAAgD+pdZVCAAAAAKl1lUIAAIA/mceVQgAAAACZx5VCAACAP4kZlkIAAAAAiRmWQgAAgD94a5ZCAAAAAHhrlkIAAIA/aL2WQgAAAABovZZCAACAP1cPl0IAAAAAVw+XQgAAgD9HYZdCAAAAAEdhl0IAAIA/N7OXQgAAAAA3s5dCAACAPyYFmEIAAAAAJgWYQgAAgD8WV5hCAAAAABZXmEIAAIA/BamYQgAAAAAFqZhCAACAP/X6mEIAAAAA9fqYQgAAgD/kTJlCAAAAAORMmUIAAIA/1J6ZQgAAAADUnplCAACAP8TwmUIAAAAAxPCZQgAAgD+zQppCAAAAALNCmkIAAIA/o5SaQgAAAACjlJpCAACAP5LmmkIAAAAAkuaaQgAAgD+COJtCAAAAAII4m0IAAIA/coqbQgAAAAByiptCAACAP2Hcm0IAAAAAYdybQgAAgD9RLpxCAAAAAFEunEIAAIA/M4CcQgAAAAAzgJxCAACAPx7SnEIAAAAAHtKcQgAAgD8JJJ1CAAAAAAkknUIAAIA/83WdQgAAAADzdZ1CAACAP93HnUIAAAAA3cedQgAAgD/HGZ5CAAAAAMcZnkIAAIA/sWueQgAAAACxa55CAACAP5y9nkIAAAAAnL2eQgAAgD+GD59CAAAAAIYPn0IAAIA/cWGfQgAAAABxYZ9CAACAP2Gzn0IAAAAAYbOfQgAAgD9QBaBCAAAAAFAFoEIAAIA/QFegQgAAAABAV6BCAACAPzCpoEIAAAAAMKmgQgAAgD8f+6BCAAAAAB/7oEIAAIA/D02hQgAAAAAPTaFCAACAP/6eoUIAAAAA/p6hQgAAgD/u8KFCAAAAAO7woUIAAIA/3kKiQgAAAADeQqJCAACAP82UokIAAAAAzZSiQgAAgD+95qJCAAAAAL3mokIAAIA/rDijQgAAAACsOKNCAACAP5yKo0IAAAAAnIqjQgAAgD+M3KNCAAAAAIzco0IAAIA/ey6kQgAAAAB7LqRCAACAP2uApEIAAAAAa4CkQgAAgD9a0qRCAAAAAFrSpEIAAIA/SiSlQgAAAABKJKVCAACAPzl2pUIAAAAAOXalQgAAgD8pyKVCAAAAACnIpUIAAIA/GBqmQgAAAAAYGqZCAACAPwhspkIAAAAACGymQgAAgD/4vaZCAAAAAPi9pkIAAIA/5w+nQgAAAADnD6dCAACAP9dhp0IAAAAA12GnQgAAgD/Gs6dCAAAAAMazp0IAAIA/tgWoQgAAAAC2BahCAACAP6ZXqEIAAAAApleoQgAAgD+VqahCAAAAAJWpqEIAAIA/hfuoQgAAAACF+6hCAACAP3RNqUIAAAAAdE2pQgAAgD9kn6lCAAAAAGSfqUIAAIA/VPGpQgAAAABU8alCAACAP0NDqkIAAAAAQ0OqQgAAgD8zlapCAAAAADOVqkIAAIA/IueqQgAAAAAi56pCAACAPxI5q0IAAAAAEjmrQgAAgD8Bi6tCAAAAAAGLq0IAAIA/8dyrQgAAAADx3KtCAACAP+EurEIAAAAA4S6sQgAAgD/QgKxCAAAAANCArEIAAIA/wNKsQgAAAADA0qxCAACAP68krUIAAAAAryStQgAAgD+fdq1CAAAAAJ92rUIAAIA/j8itQgAAAACPyK1CAACAP34arkIAAAAAfhquQgAAgD9ubK5CAAAAAG5srkIAAIA/Xb6uQgAAAABdvq5CAACAP00Qr0IAAAAATRCvQgAAgD89Yq9CAAAAAD1ir0IAAIA/LLSvQgAAAAAstK9CAACAPxwGsEIAAAAAHAawQgAAgD8LWLBCAAAAAAtYsEIAAIA/+6mwQgAAAAD7qbBCAACAP+r7sEIAAAAA6vuwQgAAgD/aTbFCAAAAANpNsUIAAIA/yp+xQgAAAADKn7FCAACAP7nxsUIAAAAAufGxQgAAgD+pQ7JCAAAAAKlDskIAAIA/mJWyQgAAAACYlbJCAACAP4jnskIAAAAAiOeyQgAAgD93ObNCAAAAAHc5s0IAAIA/Z4uzQgAAAABni7NCAACAP1fds0IAAAAAV92zQgAAgD9GL7RCAAAAAEYvtEIAAIA/NoG0QgAAAAA2gbRCAACAPyXTtEIAAAAAJdO0QgAAgD8VJbVCAAAAABUltUIAAIA/BXe1QgAAAAAFd7VCAACAP/TItUIAAAAA9Mi1QgAAgD/kGrZCAAAAAOQatkIAAIA/02y2QgAAAADTbLZCAACAP8O+tkIAAAAAw762QgAAgD+yELdCAAAAALIQt0IAAIA/f2K3QgAAAAB/YrdCAACAP2K0t0IAAAAAYrS3QgAAgD9DBrhCAAAAAEMGuEIAAIA/Jli4QgAAAAAmWLhCAACAP/WpuEIAAAAA9am4QgAAgD/l+7hCAAAAAOX7uEIAAIA/1E25QgAAAADUTblCAACAP8SfuUIAAAAAxJ+5QgAAgD+z8blCAAAAALPxuUIAAIA/o0O6QgAAAACjQ7pCAACAP5OVukIAAAAAk5W6QgAAgD+C57pCAAAAAILnukIAAIA/cjm7QgAAAAByObtCAACAP2GLu0IAAAAAYYu7QgAAgD9R3btCAAAAAFHdu0IAAIA/QC+8QgAAAABAL7xCAACAPzCBvEIAAAAAMIG8QgAAgD8f07xCAAAAAB/TvEIAAIA/DyW9QgAAAAAPJb1CAACAP/92vUIAAAAA/3a9QgAAgD/uyL1CAAAAAO7IvUIAAIA/3hq+QgAAAADeGr5CAACAP81svkIAAAAAzWy+QgAAgD+9vr5CAAAAAL2+vkIAAIA/rRC/QgAAAACtEL9CAACAP5xiv0IAAAAAnGK/QgAAgD+MtL9CAAAAAIy0v0IAAIA/ewbAQgAAAAB7BsBCAACAP2tYwEIAAAAAa1jAQgAAgD9bqsBCAAAAAFuqwEIAAIA/SvzAQgAAAABK/MBCAACAPzpOwUIAAAAAOk7BQgAAgD8poMFCAAAAACmgwUIAAIA/GfLBQgAAAAAZ8sFCAACAPwhEwkIAAAAACETCQgAAgD/4lcJCAAAAAPiVwkIAAIA/6OfCQgAAAADo58JCAACAP9c5w0IAAAAA1znDQgAAgD/Hi8NCAAAAAMeLw0IAAIA/tt3DQgAAAAC23cNCAACAP6YvxEIAAAAApi/EQgAAgD+VgcRCAAAAAJWBxEIAAIA/hdPEQgAAAACF08RCAACAP3UlxUIAAAAAdSXFQgAAgD9kd8VCAAAAAGR3xUIAAIA/VMnFQgAAAABUycVCAACAP0MbxkIAAAAAQxvGQgAAgD8ybcZCAAAAADJtxkIAAIA/Ir/GQgAAAAAiv8ZCAACAPxERx0IAAAAAERHHQgAAgD8BY8dCAAAAAAFjx0IAAIA/8LTHQgAAAADwtMdCAACAP+AGyEIAAAAA4AbIQgAAgD/QWMhCAAAAANBYyEIAAIA/v6rIQgAAAAC/qshCAACAP6/8yEIAAAAAr/zIQgAAgD+eTslCAAAAAJ5OyUIAAIA/jqDJQgAAAACOoMlCAACAP37yyUIAAAAAfvLJQgAAgD9sRMpCAAAAAGxEykIAAIA/W5bKQgAAAABblspCAACAP0voykIAAAAAS+jKQgAAgD86OstCAAAAADo6y0IAAIA/KozLQgAAAAAqjMtCAACAPxney0IAAAAAGd7LQgAAgD8IMMxCAAAAAAgwzEIAAIA/94HMQgAAAAD3gcxCAACAP+fTzEIAAAAA59PMQgAAgD/XJc1CAAAAANclzUIAAIA/xnfNQgAAAADGd81CAACAP7bJzUIAAAAAtsnNQgAAgD+kG85CAAAAAKQbzkIAAIA/k23OQgAAAACTbc5CAACAP4O/zkIAAAAAg7/OQgAAgD9yEc9CAAAAAHIRz0IAAIA/YmPPQgAAAABiY89CAACAP1G1z0IAAAAAUbXPQgAAgD8+B9BCAAAAAD4H0EIAAIA/LlnQQgAAAAAuWdBCAACAPx2r0EIAAAAAHavQQgAAgD8N/dBCAAAAAA390EIAAIA//U7RQgAAAAD9TtFCAACAP+qg0UIAAAAA6qDRQgAAgD/a8tFCAAAAANry0UIAAIA/yUTSQgAAAADJRNJCAACAP7mW0kIAAAAAuZbSQgAAgD+o6NJCAAAAAKjo0kIAAIA/ljrTQgAAAACWOtNCAACAP4aM00IAAAAAhozTQgAAgD913tNCAAAAAHXe00IAAIA/ZTDUQgAAAABlMNRCAACAP1WC1EIAAAAAVYLUQgAAgD9E1NRCAAAAAETU1EIAAIA/MSbVQgAAAAAxJtVCAACAPyF41UIAAAAAIXjVQgAAgD8QytVCAAAAABDK1UIAAIA/ABzWQgAAAAAAHNZCAACAP/Bt1kIAAAAA8G3WQgAAgD/cv9ZCAAAAANy/1kIAAIA/yxHXQgAAAADLEddCAACAP7tj10IAAAAAu2PXQgAAgD+qtddCAAAAAKq110IAAIA/mgfYQgAAAACaB9hCAACAP4pZ2EIAAAAAilnYQgAAgD93q9hCAAAAAHer2EIAAIA/Zv3YQgAAAABm/dhCAACAP1ZP2UIAAAAAVk/ZQgAAgD9FodlCAAAAAEWh2UIAAIA/NfPZQgAAAAA189lCAACAPyVF2kIAAAAAJUXaQgAAgD8Tl9pCAAAAABOX2kIAAIA/A+naQgAAAAAD6dpCAACAP/I620IAAAAA8jrbQgAAgD/ijNtCAAAAAOKM20IAAIA/0t7bQgAAAADS3ttCAACAP8Ew3EIAAAAAwTDcQgAAgD+wgtxCAAAAALCC3EIAAIA/oNTcQgAAAACg1NxCAACAP48m3UIAAAAAjybdQgAAgD9/eN1CAAAAAH943UIAAIA/bsrdQgAAAABuyt1CAACAP14c3kIAAAAAXhzeQgAAgD9Mbt5CAAAAAExu3kIAAIA/O8DeQgAAAAA7wN5CAACAPysS30IAAAAAKxLfQgAAgD8bZN9CAAAAABtk30IAAIA/CrbfQgAAAAAKtt9CAACAP/oH4EIAAAAA+gfgQgAAgD/oWeBCAAAAAOhZ4EIAAIA/16vgQgAAAADXq+BCAACAP8f94EIAAAAAx/3gQgAAgD+2T+FCAAAAALZP4UIAAIA/pqHhQgAAAACmoeFCAACAP5bz4UIAAAAAlvPhQgAAgD+FReJCAAAAAIVF4kIAAIA/dZfiQgAAAAB1l+JCAACAP2Tp4kIAAAAAZOniQgAAgD9UO+NCAAAAAFQ740IAAIA/Q43jQgAAAABDjeNCAACAPzPf40IAAAAAM9/jQgAAgD8jMeRCAAAAACMx5EIAAIA/EoPkQgAAAAASg+RCAACAPwLV5EIAAAAAAtXkQgAAgD/xJuVCAAAAAPEm5UIAAIA/4XjlQgAAAADheOVCAACAP9HK5UIAAAAA0crlQgAAgD/AHOZCAAAAAMAc5kIAAIA/sG7mQgAAAACwbuZCAACAP5/A5kIAAAAAn8DmQgAAgD+PEudCAAAAAI8S50IAAIA/fmTnQgAAAAB+ZOdCAACAP26250IAAAAAbrbnQgAAgD9eCOhCAAAAAF4I6EIAAIA/TVroQgAAAABNWuhCAACAPz2s6EIAAAAAPazoQgAAgD8s/uhCAAAAACz+6EIAAIA/HFDpQgAAAAAcUOlCAACAPwyi6UIAAAAADKLpQgAAgD/78+lCAAAAAPvz6UIAAIA/5kXqQgAAAADmRepCAACAP9SX6kIAAAAA1JfqQgAAgD/B6epCAAAAAMHp6kIAAIA/rzvrQgAAAACvO+tCAACAP5yN60IAAAAAnI3rQgAAgD+J3+tCAAAAAInf60IAAIA/djHsQgAAAAB2MexCAACAP2KD7EIAAAAAYoPsQgAAgD9O1exCAAAAAE7V7EIAAIA/OiftQgAAAAA6J+1CAACAPyd57UIAAAAAJ3ntQgAAgD8Ty+1CAAAAABPL7UIAAIA/AB3uQgAAAAAAHe5CAACAP+xu7kIAAAAA7G7uQgAAgD/ZwO5CAAAAANnA7kIAAIA/xhLvQgAAAADGEu9CAACAP7Rk70IAAAAAtGTvQgAAgD+htu9CAAAAAKG270IAAIA/jwjwQgAAAACPCPBCAACAP3pa8EIAAAAAelrwQgAAgD9prPBCAAAAAGms8EIAAIA/Wf7wQgAAAABZ/vBCAACAP0hQ8UIAAAAASFDxQgAAgD84ovFCAAAAADii8UIAAIA/KPTxQgAAAAAo9PFCAACAPxdG8kIAAAAAF0byQgAAgD8HmPJCAAAAAAeY8kIAAIA/9unyQgAAAAD26fJCAACAP+Y780IAAAAA5jvzQgAAgD/WjfNCAAAAANaN80IAAIA/xd/zQgAAAADF3/NCAACAP7Ux9EIAAAAAtTH0QgAAgD+kg/RCAAAAAKSD9EIAAIA/lNX0QgAAAACU1fRCAACAP4Qn9UIAAAAAhCf1QgAAgD9zefVCAAAAAHN59UIAAIA/Y8v1QgAAAABjy/VCAACAP1Id9kIAAAAAUh32QgAAgD9Cb/ZCAAAAAEJv9kIAAIA/McH2QgAAAAAxwfZCAACAPyET90IAAAAAIRP3QgAAgD8RZfdCAAAAABFl90IAAIA/ALf3QgAAAAAAt/dCAACAP/AI+EIAAAAA8Aj4QgAAgD/fWvhCAAAAAN9a+EIAAIA/z6z4QgAAAADPrPhCAACAP7/++EIAAAAAv/74QgAAgD+uUPlCAAAAAK5Q+UIAAIA/nqL5QgAAAACeovlCAACAP430+UIAAAAAjfT5QgAAgD98RvpCAAAAAHxG+kIAAIA/bJj6QgAAAABsmPpCAACAP1vq+kIAAAAAW+r6QgAAgD9LPPtCAAAAAEs8+0IAAIA/O477QgAAAAA7jvtCAACAPyrg+0IAAAAAKuD7QgAAgD8ZMvxCAAAAABky/EIAAIA/CYT8QgAAAAAJhPxCAACAP/jV/EIAAAAA+NX8QgAAgD/oJ/1CAAAAAOgn/UIAAIA/13n9QgAAAADXef1CAACAP8fL/UIAAAAAx8v9QgAAgD+2Hf5CAAAAALYd/kIAAIA/pW/+QgAAAAClb/5CAACAP5XB/kIAAAAAlcH+QgAAgD+EE/9CAAAAAIQT/0IAAIA/dGX/QgAAAAB0Zf9CAACAP2O3/0IAAAAAY7f/QgAAgD+pBABDAAAAAKkEAEMAAIA/oS0AQwAAAAChLQBDAACAP5lWAEMAAAAAmVYAQwAAgD+RfwBDAAAAAJF/AEMAAIA/iKgAQwAAAACIqABDAACAP4DRAEMAAAAAgNEAQwAAgD94+gBDAAAAAHj6AEMAAIA/byMBQwAAAABvIwFDAACAP2dMAUMAAAAAZ0wBQwAAgD9edQFDAAAAAF51AUMAAIA/Vp4BQwAAAABWngFDAACAP03HAUMAAAAATccBQwAAgD9F8AFDAAAAAEXwAUMAAIA/OxkCQwAAAAA7GQJDAACAPzNCAkMAAAAAM0ICQwAAgD8rawJDAAAAACtrAkMAAIA/I5QCQwAAAAAjlAJDAACAPxi9AkMAAAAAGL0CQwAAgD8Q5gJDAAAAABDmAkMAAIA/Bw8DQwAAAAAHDwNDAACAP/83A0MAAAAA/zcDQwAAgD/3YANDAAAAAPdgA0MAAIA/74kDQwAAAADviQNDAACAP+eyA0MAAAAA57IDQwAAgD/e2wNDAAAAAN7bA0MAAIA/1gQEQwAAAADWBARDAACAP84tBEMAAAAAzi0EQwAAgD/GVgRDAAAAAMZWBEMAAIA/vX8EQwAAAAC9fwRDAACAP7WoBEMAAAAAtagEQwAAgD+t0QRDAAAAAK3RBEMAAIA/pfoEQwAAAACl+gRDAACAP50jBUMAAAAAnSMFQwAAgD8aTAVDAAAAABpMBUMAAIA/EXUFQwAAAAARdQVDAACAPwmeBUMAAAAACZ4FQwAAgD8BxwVDAAAAAAHHBUMAAIA/+e8FQwAAAAD57wVDAACAP/AYBkMAAAAA8BgGQwAAgD/oQQZDAAAAAOhBBkMAAIA/4GoGQwAAAADgagZDAACAP9iTBkMAAAAA2JMGQwAAgD/QvAZDAAAAANC8BkMAAIA/x+UGQwAAAADH5QZDAACAP78OB0MAAAAAvw4HQwAAgD+2NwdDAAAAALY3B0MAAIA/rmAHQwAAAACuYAdDAACAP6aJB0MAAAAApokHQwAAgD+csgdDAAAAAJyyB0MAAIA/k9sHQwAAAACT2wdDAACAP4sECEMAAAAAiwQIQwAAgD+CLQhDAAAAAIItCEMAAIA/elYIQwAAAAB6VghDAACAP3B/CEMAAAAAcH8IQwAAgD9nqAhDAAAAAGeoCEMAAIA/X9EIQwAAAABf0QhDAACAP1X6CEMAAAAAVfoIQwAAgD9NIwlDAAAAAE0jCUMAAIA/Q0wJQwAAAABDTAlDAACAPzp1CUMAAAAAOnUJQwAAgD8ynglDAAAAADKeCUMAAIA/KMcJQwAAAAAoxwlDAACAPyDwCUMAAAAAIPAJQwAAgD8VGQpDAAAAABUZCkMAAIA/DUIKQwAAAAANQgpDAACAPwVrCkMAAAAABWsKQwAAgD/9kwpDAAAAAP2TCkMAAIA/9LwKQwAAAAD0vApDAACAP+rlCkMAAAAA6uUKQwAAgD/iDgtDAAAAAOIOC0MAAIA/2jcLQwAAAADaNwtDAACAP9FgC0MAAAAA0WALQwAAgD/JiQtDAAAAAMmJC0MAAIA/wLILQwAAAADAsgtDAACAP7fbC0MAAAAAt9sLQwAAgD+vBAxDAAAAAK8EDEMAAIA/pi0MQwAAAACmLQxDAACAP51WDEMAAAAAnVYMQwAAgD+VfwxDAAAAAJV/DEMAAIA/jKgMQwAAAACMqAxDAACAP4TRDEMAAAAAhNEMQwAAgD98+gxDAAAAAHz6DEMAAIA/ciMNQwAAAAByIw1DAACAP2pMDUMAAAAAakwNQwAAgD9idQ1DAAAAAGJ1DUMAAIA/WZ4NQwAAAABZng1DAACAP1HHDUMAAAAAUccNQwAAgD9J8A1DAAAAAEnwDUMAAIA/QBkOQwAAAABAGQ5DAACAPzhCDkMAAAAAOEIOQwAAgD8waw5DAAAAADBrDkMAAIA/KJQOQwAAAAAolA5DAACAPyC9DkMAAAAAIL0OQwAAgD8X5g5DAAAAABfmDkMAAIA/Dw8PQwAAAAAPDw9DAACAPwc4D0MAAAAABzgPQwAAgD//YA9DAAAAAP9gD0MAAIA/9okPQwAAAAD2iQ9DAACAP+6yD0MAAAAA7rIPQwAAgD/m2w9DAAAAAObbD0MAAIA/1wQQQwAAAADXBBBDAACAP8ktEEMAAAAAyS0QQwAAgD+7VhBDAAAAALtWEEMAAIA/rH8QQwAAAACsfxBDAACAP56oEEMAAAAAnqgQQwAAgD+S0RBDAAAAAJLREEMAAIA/ivoQQwAAAACK+hBDAACAP4EjEUMAAAAAgSMRQwAAgD95TBFDAAAAAHlMEUMAAIA/cXURQwAAAABxdRFDAACAP2meEUMAAAAAaZ4RQwAAgD9gxxFDAAAAAGDHEUMAAIA/WPARQwAAAABY8BFDAACAP1AZEkMAAAAAUBkSQwAAgD9IQhJDAAAAAEhCEkMAAIA/QGsSQwAAAABAaxJDAACAPzeUEkMAAAAAN5QSQwAAgD8vvRJDAAAAAC+9EkMAAIA/JOYSQwAAAAAk5hJDAACAPxkPE0MAAAAAGQ8TQwAAgD8OOBNDAAAAAA44E0MAAIA/A2ETQwAAAAADYRNDAACAP/iJE0MAAAAA+IkTQwAAgD/sshNDAAAAAOyyE0MAAIA/4dsTQwAAAADh2xNDAACAP9YEFEMAAAAA1gQUQwAAgD/LLRRDAAAAAMstFEMAAIA/wVYUQwAAAADBVhRDAACAP7h/FEMAAAAAuH8UQwAAgD+vqBRDAAAAAK+oFEMAAIA/ptEUQwAAAACm0RRDAACAP536FEMAAAAAnfoUQwAAgD+TIxVDAAAAAJMjFUMAAIA/iUwVQwAAAACJTBVDAACAP351FUMAAAAAfnUVQwAAgD9znhVDAAAAAHOeFUMAAIA/aMcVQwAAAABoxxVDAACAP13wFUMAAAAAXfAVQwAAgD9SGRZDAAAAAFIZFkMAAIA/R0IWQwAAAABHQhZDAACAPzxrFkMAAAAAPGsWQwAAgD8xlBZDAAAAADGUFkMAAIA/KL0WQwAAAAAovRZDAACAPyDmFkMAAAAAIOYWQwAAgD8YDxdDAAAAABgPF0MAAIA/DzgXQwAAAAAPOBdDAACAPwdhF0MAAAAAB2EXQwAAgD//iRdDAAAAAP+JF0MAAIA/97IXQwAAAAD3shdDAACAP+/bF0MAAAAA79sXQwAAgD/mBBhDAAAAAOYEGEMAAIA/3i0YQwAAAADeLRhDAACAP9ZWGEMAAAAA1lYYQwAAgD/OfxhDAAAAAM5/GEMAAIA/xqgYQwAAAADGqBhDAACAP73RGEMAAAAAvdEYQwAAgD+1+hhDAAAAALX6GEMAAIA/nSMZQwAAAACdIxlDAACAP4ZMGUMAAAAAhkwZQwAAgD9vdRlDAAAAAG91GUMAAIA/Zp4ZQwAAAABmnhlDAACAP17HGUMAAAAAXscZQwAAgD9W8BlDAAAAAFbwGUMAAIA/TRkaQwAAAABNGRpDAACAP0VCGkMAAAAARUIaQwAAgD89axpDAAAAAD1rGkMAAIA/NZQaQwAAAAA1lBpDAACAPy29GkMAAAAALb0aQwAAgD8k5hpDAAAAACTmGkMAAIA/HA8bQwAAAAAcDxtDAACAPxQ4G0MAAAAAFDgbQwAAgD8MYRtDAAAAAAxhG0MAAIA/BIobQwAAAAAEihtDAACAP/uyG0MAAAAA+7IbQwAAgD/z2xtDAAAAAPPbG0MAAIA/6wQcQwAAAADrBBxDAACAP+MtHEMAAAAA4y0cQwAAgD/bVhxDAAAAANtWHEMAAIA/0n8cQwAAAADSfxxDAACAP8qoHEMAAAAAyqgcQwAAgD+/0RxDAAAAAL/RHEMAAIA/tPocQwAAAAC0+hxDAACAP6kjHUMAAAAAqSMdQwAAgD+eTB1DAAAAAJ5MHUMAAIA/k3UdQwAAAACTdR1DAACAP4ieHUMAAAAAiJ4dQwAAgD98xx1DAAAAAHzHHUMAAIA/cfAdQwAAAABx8B1DAACAP2cZHkMAAAAAZxkeQwAAgD9aQh5DAAAAAFpCHkMAAIA/UWseQwAAAABRax5DAACAP0mUHkMAAAAASZQeQwAAgD9BvR5DAAAAAEG9HkMAAIA/OeYeQwAAAAA55h5DAACAPzEPH0MAAAAAMQ8fQwAAgD8oOB9DAAAAACg4H0MAAIA/IGEfQwAAAAAgYR9DAACAPxiKH0MAAAAAGIofQwAAgD8Qsx9DAAAAABCzH0MAAIA/CNwfQwAAAAAI3B9DAACAP/8EIEMAAAAA/wQgQwAAgD/3LSBDAAAAAPctIEMAAIA/71YgQwAAAADvViBDAACAP+d/IEMAAAAA538gQwAAgD/fqCBDAAAAAN+oIEMAAIA/1dEgQwAAAADV0SBDAACAP836IEMAAAAAzfogQwAAgD/FIyFDAAAAAMUjIUMAAIA/vUwhQwAAAAC9TCFDAACAP7R1IUMAAAAAtHUhQwAAgD+sniFDAAAAAKyeIUMAAIA/pMchQwAAAACkxyFDAACAP5rwIUMAAAAAmvAhQwAAgD+SGSJDAAAAAJIZIkMAAIA/ikIiQwAAAACKQiJDAACAP4JrIkMAAAAAgmsiQwAAgD95lCJDAAAAAHmUIkMAAIA/cb0iQwAAAABxvSJDAACAP2nmIkMAAAAAaeYiQwAAgD9gDyNDAAAAAGAPI0MAAIA/WDgjQwAAAABYOCNDAACAP09hI0MAAAAAT2EjQwAAgD9HiiNDAAAAAEeKI0MAAIA/PrMjQwAAAAA+syNDAACAPzbcI0MAAAAANtwjQwAAgD8uBSRDAAAAAC4FJEMAAIA/Ji4kQwAAAAAmLiRDAACAPx1XJEMAAAAAHVckQwAAgD8VgCRDAAAAABWAJEMAAIA/DakkQwAAAAANqSRDAACAPwTSJEMAAAAABNIkQwAAgD/8+iRDAAAAAPz6JEMAAIA/9CMlQwAAAAD0IyVDAACAP+xMJUMAAAAA7EwlQwAAgD/kdSVDAAAAAOR1JUMAAIA/254lQwAAAADbniVDAACAP9PHJUMAAAAA08clQwAAgD/L8CVDAAAAAMvwJUMAAIA/wxkmQwAAAADDGSZDAACAP7pCJkMAAAAAukImQwAAgD+yayZDAAAAALJrJkMAAIA/qpQmQwAAAACqlCZDAACAP6K9JkMAAAAAor0mQwAAgD+a5iZDAAAAAJrmJkMAAIA/kQ8nQwAAAACRDydDAACAP4k4J0MAAAAAiTgnQwAAgD+BYSdDAAAAAIFhJ0MAAIA/eYonQwAAAAB5iidDAACAP86yJ0MAAAAAzrInQwAAgD/F2ydDAAAAAMXbJ0MAAIA/vQQoQwAAAAC9BChDAACAP7UtKEMAAAAAtS0oQwAAgD+tVihDAAAAAK1WKEMAAIA/pH8oQwAAAACkfyhDAACAP5yoKEMAAAAAnKgoQwAAgD+U0ShDAAAAAJTRKEMAAIA/jPooQwAAAACM+ihDAACAP4QjKUMAAAAAhCMpQwAAgD97TClDAAAAAHtMKUMAAIA/c3UpQwAAAABzdSlDAACAP2ueKUMAAAAAa54pQwAAgD9jxylDAAAAAGPHKUMAAIA/V/ApQwAAAABX8ClDAACAP08ZKkMAAAAATxkqQwAAgD9HQipDAAAAAEdCKkMAAIA/PmsqQwAAAAA+aypDAACAPzCUKkMAAAAAMJQqQwAAgD8ovSpDAAAAACi9KkMAAIA/IOYqQwAAAAAg5ipDAACAPxcPK0MAAAAAFw8rQwAAgD8MOCtDAAAAAAw4K0MAAIA/BGErQwAAAAAEYStDAACAP/yJK0MAAAAA/IkrQwAAgD/zsitDAAAAAPOyK0MAAIA/69srQwAAAADr2ytDAACAP+EELEMAAAAA4QQsQwAAgD/YLSxDAAAAANgtLEMAAIA/0FYsQwAAAADQVixDAACAP8h/LEMAAAAAyH8sQwAAgD/AqCxDAAAAAMCoLEMAAIA/ttEsQwAAAAC20SxDAACAP636LEMAAAAArfosQwAAgD+lIy1DAAAAAKUjLUMAAIA/nUwtQwAAAACdTC1DAACAP5V1LUMAAAAAlXUtQwAAgD+Nni1DAAAAAI2eLUMAAIA/hMctQwAAAACExy1DAACAP3vwLUMAAAAAe/AtQwAAgD9zGS5DAAAAAHMZLkMAAIA/a0IuQwAAAABrQi5DAACAP2NrLkMAAAAAY2suQwAAgD9blC5DAAAAAFuULkMAAIA/Ur0uQwAAAABSvS5DAACAP0nmLkMAAAAASeYuQwAAgD9BDy9DAAAAAEEPL0MAAIA/OTgvQwAAAAA5OC9DAACAPzFhL0MAAAAAMWEvQwAAgD8pii9DAAAAACmKL0MAAIA/"),
"format": 34359742487,
-"index_count": 5436,
-"index_data": PackedByteArray("AAACAAEAAQACAAMAAgAEAAMAAwAEAAUABAAGAAUABQAGAAcABgAIAAcABwAIAAkACAAKAAkACQAKAAsACgAMAAsACwAMAA0ADAAOAA0ADQAOAA8ADgAQAA8ADwAQABEAEAASABEAEQASABMAEgAUABMAEwAUABUAFAAWABUAFQAWABcAFgAYABcAFwAYABkAGAAaABkAGQAaABsAGgAcABsAGwAcAB0AHAAeAB0AHQAeAB8AHgAgAB8AHwAgACEAIAAiACEAIQAiACMAIgAkACMAIwAkACUAJAAmACUAJQAmACcAJgAoACcAJwAoACkAKAAqACkAKQAqACsAKgAsACsAKwAsAC0ALAAuAC0ALQAuAC8ALgAwAC8ALwAwADEAMAAyADEAMQAyADMAMgA0ADMAMwA0ADUANAA2ADUANQA2ADcANgA4ADcANwA4ADkAOAA6ADkAOQA6ADsAOgA8ADsAOwA8AD0APAA+AD0APQA+AD8APgBAAD8APwBAAEEAQABCAEEAQQBCAEMAQgBEAEMAQwBEAEUARABGAEUARQBGAEcARgBIAEcARwBIAEkASABKAEkASQBKAEsASgBMAEsASwBMAE0ATABOAE0ATQBOAE8ATgBQAE8ATwBQAFEAUABSAFEAUQBSAFMAUgBUAFMAUwBUAFUAVABWAFUAVQBWAFcAVgBYAFcAVwBYAFkAWABaAFkAWQBaAFsAWgBcAFsAWwBcAF0AXABeAF0AXQBeAF8AXgBgAF8AXwBgAGEAYABiAGEAYQBiAGMAYgBkAGMAYwBkAGUAZABmAGUAZQBmAGcAZgBoAGcAZwBoAGkAaABqAGkAaQBqAGsAagBsAGsAawBsAG0AbABuAG0AbQBuAG8AbgBwAG8AbwBwAHEAcAByAHEAcQByAHMAcgB0AHMAcwB0AHUAdAB2AHUAdQB2AHcAdgB4AHcAdwB4AHkAeAB6AHkAeQB6AHsAegB8AHsAewB8AH0AfAB+AH0AfQB+AH8AfgCAAH8AfwCAAIEAgACCAIEAgQCCAIMAggCEAIMAgwCEAIUAhACGAIUAhQCGAIcAhgCIAIcAhwCIAIkAiACKAIkAiQCKAIsAigCMAIsAiwCMAI0AjACOAI0AjQCOAI8AjgCQAI8AjwCQAJEAkACSAJEAkQCSAJMAkgCUAJMAkwCUAJUAlACWAJUAlQCWAJcAlgCYAJcAlwCYAJkAmACaAJkAmQCaAJsAmgCcAJsAmwCcAJ0AnACeAJ0AnQCeAJ8AngCgAJ8AnwCgAKEAoACiAKEAoQCiAKMAogCkAKMAowCkAKUApACmAKUApQCmAKcApgCoAKcApwCoAKkAqACqAKkAqQCqAKsAqgCsAKsAqwCsAK0ArACuAK0ArQCuAK8ArgCwAK8ArwCwALEAsACyALEAsQCyALMAsgC0ALMAswC0ALUAtAC2ALUAtQC2ALcAtgC4ALcAtwC4ALkAuAC6ALkAuQC6ALsAugC8ALsAuwC8AL0AvAC+AL0AvQC+AL8AvgDAAL8AvwDAAMEAwADCAMEAwQDCAMMAwgDEAMMAwwDEAMUAxADGAMUAxQDGAMcAxgDIAMcAxwDIAMkAyADKAMkAyQDKAMsAygDMAMsAywDMAM0AzADOAM0AzQDOAM8AzgDQAM8AzwDQANEA0ADSANEA0QDSANMA0gDUANMA0wDUANUA1ADWANUA1QDWANcA1gDYANcA1wDYANkA2ADaANkA2QDaANsA2gDcANsA2wDcAN0A3ADeAN0A3QDeAN8A3gDgAN8A3wDgAOEA4ADiAOEA4QDiAOMA4gDkAOMA4wDkAOUA5ADmAOUA5QDmAOcA5gDoAOcA5wDoAOkA6ADqAOkA6QDqAOsA6gDsAOsA6wDsAO0A7ADuAO0A7QDuAO8A7gDwAO8A7wDwAPEA8ADyAPEA8QDyAPMA8gD0APMA8wD0APUA9AD2APUA9QD2APcA9gD4APcA9wD4APkA+AD6APkA+QD6APsA+gD8APsA+wD8AP0A/AD+AP0A/QD+AP8A/gAAAf8A/wAAAQEBAAECAQEBAQECAQMBAgEEAQMBAwEEAQUBBAEGAQUBBQEGAQcBBgEIAQcBBwEIAQkBCAEKAQkBCQEKAQsBCgEMAQsBCwEMAQ0BDAEOAQ0BDQEOAQ8BDgEQAQ8BDwEQAREBEAESAREBEQESARMBEgEUARMBEwEUARUBFAEWARUBFQEWARcBFgEYARcBFwEYARkBGAEaARkBGQEaARsBGgEcARsBGwEcAR0BHAEeAR0BHQEeAR8BHgEgAR8BHwEgASEBIAEiASEBIQEiASMBIgEkASMBIwEkASUBJAEmASUBJQEmAScBJgEoAScBJwEoASkBKAEqASkBKQEqASsBKgEsASsBKwEsAS0BLAEuAS0BLQEuAS8BLgEwAS8BLwEwATEBMAEyATEBMQEyATMBMgE0ATMBMwE0ATUBNAE2ATUBNQE2ATcBNgE4ATcBNwE4ATkBOAE6ATkBOQE6ATsBOgE8ATsBOwE8AT0BPAE+AT0BPQE+AT8BPgFAAT8BPwFAAUEBQAFCAUEBQQFCAUMBQgFEAUMBQwFEAUUBRAFGAUUBRQFGAUcBRgFIAUcBRwFIAUkBSAFKAUkBSQFKAUsBSgFMAUsBSwFMAU0BTAFOAU0BTQFOAU8BTgFQAU8BTwFQAVEBUAFSAVEBUQFSAVMBUgFUAVMBUwFUAVUBVAFWAVUBVQFWAVcBVgFYAVcBVwFYAVkBWAFaAVkBWQFaAVsBWgFcAVsBWwFcAV0BXAFeAV0BXQFeAV8BXgFgAV8BXwFgAWEBYAFiAWEBYQFiAWMBYgFkAWMBYwFkAWUBZAFmAWUBZQFmAWcBZgFoAWcBZwFoAWkBaAFqAWkBaQFqAWsBagFsAWsBawFsAW0BbAFuAW0BbQFuAW8BbgFwAW8BbwFwAXEBcAFyAXEBcQFyAXMBcgF0AXMBcwF0AXUBdAF2AXUBdQF2AXcBdgF4AXcBdwF4AXkBeAF6AXkBeQF6AXsBegF8AXsBewF8AX0BfAF+AX0BfQF+AX8BfgGAAX8BfwGAAYEBgAGCAYEBgQGCAYMBggGEAYMBgwGEAYUBhAGGAYUBhQGGAYcBhgGIAYcBhwGIAYkBiAGKAYkBiQGKAYsBigGMAYsBiwGMAY0BjAGOAY0BjQGOAY8BjgGQAY8BjwGQAZEBkAGSAZEBkQGSAZMBkgGUAZMBkwGUAZUBlAGWAZUBlQGWAZcBlgGYAZcBlwGYAZkBmAGaAZkBmQGaAZsBmgGcAZsBmwGcAZ0BnAGeAZ0BnQGeAZ8BngGgAZ8BnwGgAaEBoAGiAaEBoQGiAaMBogGkAaMBowGkAaUBpAGmAaUBpQGmAacBpgGoAacBpwGoAakBqAGqAakBqQGqAasBqgGsAasBqwGsAa0BrAGuAa0BrQGuAa8BrgGwAa8BrwGwAbEBsAGyAbEBsQGyAbMBsgG0AbMBswG0AbUBtAG2AbUBtQG2AbcBtgG4AbcBtwG4AbkBuAG6AbkBuQG6AbsBugG8AbsBuwG8Ab0BvAG+Ab0BvQG+Ab8BvgHAAb8BvwHAAcEBwAHCAcEBwQHCAcMBwgHEAcMBwwHEAcUBxAHGAcUBxQHGAccBxgHIAccBxwHIAckByAHKAckByQHKAcsBygHMAcsBywHMAc0BzAHOAc0BzQHOAc8BzgHQAc8BzwHQAdEB0AHSAdEB0QHSAdMB0gHUAdMB0wHUAdUB1AHWAdUB1QHWAdcB1gHYAdcB1wHYAdkB2AHaAdkB2QHaAdsB2gHcAdsB2wHcAd0B3AHeAd0B3QHeAd8B3gHgAd8B3wHgAeEB4AHiAeEB4QHiAeMB4gHkAeMB4wHkAeUB5AHmAeUB5QHmAecB5gHoAecB5wHoAekB6AHqAekB6QHqAesB6gHsAesB6wHsAe0B7AHuAe0B7QHuAe8B7gHwAe8B7wHwAfEB8AHyAfEB8QHyAfMB8gH0AfMB8wH0AfUB9AH2AfUB9QH2AfcB9gH4AfcB9wH4AfkB+AH6AfkB+QH6AfsB+gH8AfsB+wH8Af0B/AH+Af0B/QH+Af8B/gEAAv8B/wEAAgECAAICAgECAQICAgMCAgIEAgMCAwIEAgUCBAIGAgUCBQIGAgcCBgIIAgcCBwIIAgkCCAIKAgkCCQIKAgsCCgIMAgsCCwIMAg0CDAIOAg0CDQIOAg8CDgIQAg8CDwIQAhECEAISAhECEQISAhMCEgIUAhMCEwIUAhUCFAIWAhUCFQIWAhcCFgIYAhcCFwIYAhkCGAIaAhkCGQIaAhsCGgIcAhsCGwIcAh0CHAIeAh0CHQIeAh8CHgIgAh8CHwIgAiECIAIiAiECIQIiAiMCIgIkAiMCIwIkAiUCJAImAiUCJQImAicCJgIoAicCJwIoAikCKAIqAikCKQIqAisCKgIsAisCKwIsAi0CLAIuAi0CLQIuAi8CLgIwAi8CLwIwAjECMAIyAjECMQIyAjMCMgI0AjMCMwI0AjUCNAI2AjUCNQI2AjcCNgI4AjcCNwI4AjkCOAI6AjkCOQI6AjsCOgI8AjsCOwI8Aj0CPAI+Aj0CPQI+Aj8CPgJAAj8CPwJAAkECQAJCAkECQQJCAkMCQgJEAkMCQwJEAkUCRAJGAkUCRQJGAkcCRgJIAkcCRwJIAkkCSAJKAkkCSQJKAksCSgJMAksCSwJMAk0CTAJOAk0CTQJOAk8CTgJQAk8CTwJQAlECUAJSAlECUQJSAlMCUgJUAlMCUwJUAlUCVAJWAlUCVQJWAlcCVgJYAlcCVwJYAlkCWAJaAlkCWQJaAlsCWgJcAlsCWwJcAl0CXAJeAl0CXQJeAl8CXgJgAl8CXwJgAmECYAJiAmECYQJiAmMCYgJkAmMCYwJkAmUCZAJmAmUCZQJmAmcCZgJoAmcCZwJoAmkCaAJqAmkCaQJqAmsCagJsAmsCawJsAm0CbAJuAm0CbQJuAm8CbgJwAm8CbwJwAnECcAJyAnECcQJyAnMCcgJ0AnMCcwJ0AnUCdAJ2AnUCdQJ2AncCdgJ4AncCdwJ4AnkCeAJ6AnkCeQJ6AnsCegJ8AnsCewJ8An0CfAJ+An0CfQJ+An8CfgKAAn8CfwKAAoECgAKCAoECgQKCAoMCggKEAoMCgwKEAoUChAKGAoUChQKGAocChgKIAocChwKIAokCiAKKAokCiQKKAosCigKMAosCiwKMAo0CjAKOAo0CjQKOAo8CjgKQAo8CjwKQApECkAKSApECkQKSApMCkgKUApMCkwKUApUClAKWApUClQKWApcClgKYApcClwKYApkCmAKaApkCmQKaApsCmgKcApsCmwKcAp0CnAKeAp0CnQKeAp8CngKgAp8CnwKgAqECoAKiAqECoQKiAqMCogKkAqMCowKkAqUCpAKmAqUCpQKmAqcCpgKoAqcCpwKoAqkCqAKqAqkCqQKqAqsCqgKsAqsCqwKsAq0CrAKuAq0CrQKuAq8CrgKwAq8CrwKwArECsAKyArECsQKyArMCsgK0ArMCswK0ArUCtAK2ArUCtQK2ArcCtgK4ArcCtwK4ArkCuAK6ArkCuQK6ArsCugK8ArsCuwK8Ar0CvAK+Ar0CvQK+Ar8CvgLAAr8CvwLAAsECwALCAsECwQLCAsMCwgLEAsMCwwLEAsUCxALGAsUCxQLGAscCxgLIAscCxwLIAskCyALKAskCyQLKAssCygLMAssCywLMAs0CzALOAs0CzQLOAs8CzgLQAs8CzwLQAtEC0ALSAtEC0QLSAtMC0gLUAtMC0wLUAtUC1ALWAtUC1QLWAtcC1gLYAtcC1wLYAtkC2ALaAtkC2QLaAtsC2gLcAtsC2wLcAt0C3ALeAt0C3QLeAt8C3gLgAt8C3wLgAuEC4ALiAuEC4QLiAuMC4gLkAuMC4wLkAuUC5ALmAuUC5QLmAucC5gLoAucC5wLoAukC6ALqAukC6QLqAusC6gLsAusC6wLsAu0C7ALuAu0C7QLuAu8C7gLwAu8C7wLwAvEC8ALyAvEC8QLyAvMC8gL0AvMC8wL0AvUC9AL2AvUC9QL2AvcC9gL4AvcC9wL4AvkC+AL6AvkC+QL6AvsC+gL8AvsC+wL8Av0C/AL+Av0C/QL+Av8C/gIAA/8C/wIAAwEDAAMCAwEDAQMCAwMDAgMEAwMDAwMEAwUDBAMGAwUDBQMGAwcDBgMIAwcDBwMIAwkDCAMKAwkDCQMKAwsDCgMMAwsDCwMMAw0DDAMOAw0DDQMOAw8DDgMQAw8DDwMQAxEDEAMSAxEDEQMSAxMDEgMUAxMDEwMUAxUDFAMWAxUDFQMWAxcDFgMYAxcDFwMYAxkDGAMaAxkDGQMaAxsDGgMcAxsDGwMcAx0DHAMeAx0DHQMeAx8DHgMgAx8DHwMgAyEDIAMiAyEDIQMiAyMDIgMkAyMDIwMkAyUDJAMmAyUDJQMmAycDJgMoAycDJwMoAykDKAMqAykDKQMqAysDKgMsAysDKwMsAy0DLAMuAy0DLQMuAy8DLgMwAy8DLwMwAzEDMAMyAzEDMQMyAzMDMgM0AzMDMwM0AzUDNAM2AzUDNQM2AzcDNgM4AzcDNwM4AzkDOAM6AzkDOQM6AzsDOgM8AzsDOwM8Az0DPAM+Az0DPQM+Az8DPgNAAz8DPwNAA0EDQANCA0EDQQNCA0MDQgNEA0MDQwNEA0UDRANGA0UDRQNGA0cDRgNIA0cDRwNIA0kDSANKA0kDSQNKA0sDSgNMA0sDSwNMA00DTANOA00DTQNOA08DTgNQA08DTwNQA1EDUANSA1EDUQNSA1MDUgNUA1MDUwNUA1UDVANWA1UDVQNWA1cDVgNYA1cDVwNYA1kDWANaA1kDWQNaA1sDWgNcA1sDWwNcA10DXANeA10DXQNeA18DXgNgA18DXwNgA2EDYANiA2EDYQNiA2MDYgNkA2MDYwNkA2UDZANmA2UDZQNmA2cDZgNoA2cDZwNoA2kDaANqA2kDaQNqA2sDagNsA2sDawNsA20DbANuA20DbQNuA28DbgNwA28DbwNwA3EDcANyA3EDcQNyA3MDcgN0A3MDcwN0A3UDdAN2A3UDdQN2A3cDdgN4A3cDdwN4A3kDeAN6A3kDeQN6A3sDegN8A3sDewN8A30DfAN+A30DfQN+A38DfgOAA38DfwOAA4EDgAOCA4EDgQOCA4MDggOEA4MDgwOEA4UDhAOGA4UDhQOGA4cDhgOIA4cDhwOIA4kDiAOKA4kDiQOKA4sDigOMA4sDiwOMA40DjAOOA40DjQOOA48DjgOQA48DjwOQA5EDkAOSA5EDkQOSA5MDkgOUA5MDkwOUA5UDlAOWA5UDlQOWA5cDlgOYA5cDlwOYA5kDmAOaA5kDmQOaA5sDmgOcA5sDmwOcA50DnAOeA50DnQOeA58DngOgA58DnwOgA6EDoAOiA6EDoQOiA6MDogOkA6MDowOkA6UDpAOmA6UDpQOmA6cDpgOoA6cDpwOoA6kDqAOqA6kDqQOqA6sDqgOsA6sDqwOsA60DrAOuA60DrQOuA68DrgOwA68DrwOwA7EDsAOyA7EDsQOyA7MDsgO0A7MDswO0A7UDtAO2A7UDtQO2A7cDtgO4A7cDtwO4A7kDuAO6A7kDuQO6A7sDugO8A7sDuwO8A70DvAO+A70DvQO+A78DvgPAA78DvwPAA8EDwAPCA8EDwQPCA8MDwgPEA8MDwwPEA8UDxAPGA8UDxQPGA8cDxgPIA8cDxwPIA8kDyAPKA8kDyQPKA8sDygPMA8sDywPMA80DzAPOA80DzQPOA88DzgPQA88DzwPQA9ED0APSA9ED0QPSA9MD0gPUA9MD0wPUA9UD1APWA9UD1QPWA9cD1gPYA9cD1wPYA9kD2APaA9kD2QPaA9sD2gPcA9sD2wPcA90D3APeA90D3QPeA98D3gPgA98D3wPgA+ED4APiA+ED4QPiA+MD4gPkA+MD4wPkA+UD5APmA+UD5QPmA+cD5gPoA+cD5wPoA+kD6APqA+kD6QPqA+sD6gPsA+sD6wPsA+0D7APuA+0D7QPuA+8D7gPwA+8D7wPwA/ED8APyA/ED8QPyA/MD8gP0A/MD8wP0A/UD9AP2A/UD9QP2A/cD9gP4A/cD9wP4A/kD+AP6A/kD+QP6A/sD+gP8A/sD+wP8A/0D/AP+A/0D/QP+A/8D/gMABP8D/wMABAEEAAQCBAEEAQQCBAMEAgQEBAMEAwQEBAUEBAQGBAUEBQQGBAcEBgQIBAcEBwQIBAkECAQKBAkECQQKBAsECgQMBAsECwQMBA0EDAQOBA0EDQQOBA8EDgQQBA8EDwQQBBEEEAQSBBEEEQQSBBMEEgQUBBMEEwQUBBUEFAQWBBUEFQQWBBcEFgQYBBcEFwQYBBkEGAQaBBkEGQQaBBsEGgQcBBsEGwQcBB0EHAQeBB0EHQQeBB8EHgQgBB8EHwQgBCEEIAQiBCEEIQQiBCMEIgQkBCMEIwQkBCUEJAQmBCUEJQQmBCcEJgQoBCcEJwQoBCkEKAQqBCkEKQQqBCsEKgQsBCsEKwQsBC0ELAQuBC0ELQQuBC8ELgQwBC8ELwQwBDEEMAQyBDEEMQQyBDMEMgQ0BDMEMwQ0BDUENAQ2BDUENQQ2BDcENgQ4BDcENwQ4BDkEOAQ6BDkEOQQ6BDsEOgQ8BDsEOwQ8BD0EPAQ+BD0EPQQ+BD8EPgRABD8EPwRABEEEQARCBEEEQQRCBEMEQgREBEMEQwREBEUERARGBEUERQRGBEcERgRIBEcERwRIBEkESARKBEkESQRKBEsESgRMBEsESwRMBE0ETAROBE0ETQROBE8ETgRQBE8ETwRQBFEEUARSBFEEUQRSBFMEUgRUBFMEUwRUBFUEVARWBFUEVQRWBFcEVgRYBFcEVwRYBFkEWARaBFkEWQRaBFsEWgRcBFsEWwRcBF0EXAReBF0EXQReBF8EXgRgBF8EXwRgBGEEYARiBGEEYQRiBGMEYgRkBGMEYwRkBGUEZARmBGUEZQRmBGcEZgRoBGcEZwRoBGkEaARqBGkEaQRqBGsEagRsBGsEawRsBG0EbARuBG0EbQRuBG8EbgRwBG8EbwRwBHEEcARyBHEEcQRyBHMEcgR0BHMEcwR0BHUEdAR2BHUEdQR2BHcEdgR4BHcEdwR4BHkEeAR6BHkEeQR6BHsEegR8BHsEewR8BH0EfAR+BH0EfQR+BH8EfgSABH8EfwSABIEEgASCBIEEgQSCBIMEggSEBIMEgwSEBIUEhASGBIUEhQSGBIcEhgSIBIcEhwSIBIkEiASKBIkEiQSKBIsEigSMBIsEiwSMBI0EjASOBI0EjQSOBI8EjgSQBI8EjwSQBJEEkASSBJEEkQSSBJMEkgSUBJMEkwSUBJUElASWBJUElQSWBJcElgSYBJcElwSYBJkEmASaBJkEmQSaBJsEmgScBJsEmwScBJ0EnASeBJ0EnQSeBJ8EngSgBJ8EnwSgBKEEoASiBKEEoQSiBKMEogSkBKMEowSkBKUEpASmBKUEpQSmBKcEpgSoBKcEpwSoBKkEqASqBKkEqQSqBKsEqgSsBKsEqwSsBK0ErASuBK0ErQSuBK8ErgSwBK8ErwSwBLEEsASyBLEEsQSyBLMEsgS0BLMEswS0BLUEtAS2BLUEtQS2BLcEtgS4BLcEtwS4BLkEuAS6BLkEuQS6BLsEugS8BLsEuwS8BL0EvAS+BL0EvQS+BL8EvgTABL8EvwTABMEEwATCBMEEwQTCBMMEwgTEBMMEwwTEBMUExATGBMUExQTGBMcExgTIBMcExwTIBMkEyATKBMkEyQTKBMsEygTMBMsEywTMBM0EzATOBM0EzQTOBM8EzgTQBM8EzwTQBNEE0ATSBNEE0QTSBNME0gTUBNME0wTUBNUE1ATWBNUE1QTWBNcE1gTYBNcE1wTYBNkE2ATaBNkE2QTaBNsE2gTcBNsE2wTcBN0E3ATeBN0E3QTeBN8E3gTgBN8E3wTgBOEE4ATiBOEE4QTiBOME4gTkBOME4wTkBOUE5ATmBOUE5QTmBOcE5gToBOcE5wToBOkE6ATqBOkE6QTqBOsE6gTsBOsE6wTsBO0E7ATuBO0E7QTuBO8E7gTwBO8E7wTwBPEE8ATyBPEE8QTyBPME8gT0BPME8wT0BPUE9AT2BPUE9QT2BPcE9gT4BPcE9wT4BPkE+AT6BPkE+QT6BPsE+gT8BPsE+wT8BP0E/AT+BP0E/QT+BP8E/gQABf8E/wQABQEFAAUCBQEFAQUCBQMFAgUEBQMFAwUEBQUFBAUGBQUFBQUGBQcFBgUIBQcFBwUIBQkFCAUKBQkFCQUKBQsFCgUMBQsFCwUMBQ0FDAUOBQ0FDQUOBQ8FDgUQBQ8FDwUQBREFEAUSBREFEQUSBRMFEgUUBRMFEwUUBRUFFAUWBRUFFQUWBRcFFgUYBRcFFwUYBRkFGAUaBRkFGQUaBRsFGgUcBRsFGwUcBR0FHAUeBR0FHQUeBR8FHgUgBR8FHwUgBSEFIAUiBSEFIQUiBSMFIgUkBSMFIwUkBSUFJAUmBSUFJQUmBScFJgUoBScFJwUoBSkFKAUqBSkFKQUqBSsFKgUsBSsFKwUsBS0FLAUuBS0FLQUuBS8FLgUwBS8FLwUwBTEFMAUyBTEFMQUyBTMFMgU0BTMFMwU0BTUFNAU2BTUFNQU2BTcFNgU4BTcFNwU4BTkFOAU6BTkFOQU6BTsFOgU8BTsFOwU8BT0FPAU+BT0FPQU+BT8FPgVABT8FPwVABUEFQAVCBUEFQQVCBUMFQgVEBUMFQwVEBUUFRAVGBUUFRQVGBUcFRgVIBUcFRwVIBUkFSAVKBUkFSQVKBUsFSgVMBUsFSwVMBU0FTAVOBU0FTQVOBU8FTgVQBU8FTwVQBVEFUAVSBVEFUQVSBVMFUgVUBVMFUwVUBVUFVAVWBVUFVQVWBVcFVgVYBVcFVwVYBVkFWAVaBVkFWQVaBVsFWgVcBVsFWwVcBV0FXAVeBV0FXQVeBV8FXgVgBV8FXwVgBWEFYAViBWEFYQViBWMFYgVkBWMFYwVkBWUFZAVmBWUFZQVmBWcFZgVoBWcFZwVoBWkFaAVqBWkFaQVqBWsFagVsBWsFawVsBW0FbAVuBW0FbQVuBW8FbgVwBW8FbwVwBXEFcAVyBXEFcQVyBXMFcgV0BXMFcwV0BXUFdAV2BXUFdQV2BXcFdgV4BXcFdwV4BXkFeAV6BXkFeQV6BXsFegV8BXsFewV8BX0FfAV+BX0FfQV+BX8FfgWABX8FfwWABYEFgAWCBYEFgQWCBYMFggWEBYMFgwWEBYUFhAWGBYUFhQWGBYcFhgWIBYcFhwWIBYkFiAWKBYkFiQWKBYsFigWMBYsFiwWMBY0FjAWOBY0FjQWOBY8FjgWQBY8FjwWQBZEFkAWSBZEFkQWSBZMFkgWUBZMFkwWUBZUFlAWWBZUFlQWWBZcFlgWYBZcFlwWYBZkFmAWaBZkFmQWaBZsFmgWcBZsFmwWcBZ0FnAWeBZ0FnQWeBZ8FngWgBZ8FnwWgBaEFoAWiBaEFoQWiBaMFogWkBaMFowWkBaUFpAWmBaUFpQWmBacFpgWoBacFpwWoBakFqAWqBakFqQWqBasFqgWsBasFqwWsBa0FrAWuBa0FrQWuBa8FrgWwBa8FrwWwBbEFsAWyBbEFsQWyBbMFsgW0BbMFswW0BbUFtAW2BbUFtQW2BbcFtgW4BbcFtwW4BbkFuAW6BbkFuQW6BbsFugW8BbsFuwW8Bb0FvAW+Bb0FvQW+Bb8FvgXABb8FvwXABcEFwAXCBcEFwQXCBcMFwgXEBcMFwwXEBcUFxAXGBcUFxQXGBccFxgXIBccFxwXIBckFyAXKBckFyQXKBcsFygXMBcsFywXMBc0FzAXOBc0FzQXOBc8FzgXQBc8FzwXQBdEF0AXSBdEF0QXSBdMF0gXUBdMF0wXUBdUF1AXWBdUF1QXWBdcF1gXYBdcF1wXYBdkF2AXaBdkF2QXaBdsF2gXcBdsF2wXcBd0F3AXeBd0F3QXeBd8F3gXgBd8F3wXgBeEF4AXiBeEF4QXiBeMF4gXkBeMF4wXkBeUF5AXmBeUF5QXmBecF5gXoBecF5wXoBekF6AXqBekF6QXqBesF6gXsBesF6wXsBe0F7AXuBe0F7QXuBe8F7gXwBe8F7wXwBfEF8AXyBfEF8QXyBfMF8gX0BfMF8wX0BfUF9AX2BfUF9QX2BfcF9gX4BfcF9wX4BfkF+AX6BfkF+QX6BfsF+gX8BfsF+wX8Bf0F/AX+Bf0F/QX+Bf8F/gUABv8F/wUABgEGAAYCBgEGAQYCBgMGAgYEBgMGAwYEBgUGBAYGBgUGBQYGBgcGBgYIBgcGBwYIBgkGCAYKBgkGCQYKBgsGCgYMBgsGCwYMBg0GDAYOBg0GDQYOBg8GDgYQBg8GDwYQBhEGEAYSBhEGEQYSBhMGEgYUBhMGEwYUBhUGFAYWBhUGFQYWBhcGFgYYBhcGFwYYBhkGGAYaBhkGGQYaBhsGGgYcBhsGGwYcBh0GHAYeBh0GHQYeBh8GHgYgBh8GHwYgBiEGIAYiBiEGIQYiBiMGIgYkBiMGIwYkBiUGJAYmBiUGJQYmBicGJgYoBicGJwYoBikGKAYqBikGKQYqBisGKgYsBisGKwYsBi0GLAYuBi0GLQYuBi8GLgYwBi8GLwYwBjEGMAYyBjEGMQYyBjMGMgY0BjMGMwY0BjUGNAY2BjUGNQY2BjcGNgY4BjcGNwY4BjkGOAY6BjkGOQY6BjsGOgY8BjsGOwY8Bj0GPAY+Bj0GPQY+Bj8GPgZABj8GPwZABkEGQAZCBkEGQQZCBkMGQgZEBkMGQwZEBkUGRAZGBkUGRQZGBkcGRgZIBkcGRwZIBkkGSAZKBkkGSQZKBksGSgZMBksGSwZMBk0GTAZOBk0GTQZOBk8GTgZQBk8GTwZQBlEGUAZSBlEGUQZSBlMGUgZUBlMGUwZUBlUGVAZWBlUGVQZWBlcGVgZYBlcGVwZYBlkGWAZaBlkGWQZaBlsGWgZcBlsGWwZcBl0GXAZeBl0GXQZeBl8GXgZgBl8GXwZgBmEGYAZiBmEGYQZiBmMGYgZkBmMGYwZkBmUGZAZmBmUGZQZmBmcGZgZoBmcGZwZoBmkGaAZqBmkGaQZqBmsGagZsBmsGawZsBm0GbAZuBm0GbQZuBm8GbgZwBm8GbwZwBnEGcAZyBnEGcQZyBnMGcgZ0BnMGcwZ0BnUGdAZ2BnUGdQZ2BncGdgZ4BncGdwZ4BnkGeAZ6BnkGeQZ6BnsGegZ8BnsGewZ8Bn0GfAZ+Bn0GfQZ+Bn8GfgaABn8GfwaABoEGgAaCBoEGgQaCBoMGggaEBoMGgwaEBoUGhAaGBoUGhQaGBocGhgaIBocGhwaIBokGiAaKBokGiQaKBosGigaMBosGiwaMBo0GjAaOBo0GjQaOBo8GjgaQBo8GjwaQBpEGkAaSBpEGkQaSBpMGkgaUBpMGkwaUBpUGlAaWBpUGlQaWBpcGlgaYBpcGlwaYBpkGmAaaBpkGmQaaBpsGmgacBpsGmwacBp0GnAaeBp0GnQaeBp8GngagBp8GnwagBqEGoAaiBqEGoQaiBqMGogakBqMGowakBqUGpAamBqUGpQamBqcGpgaoBqcGpwaoBqkGqAaqBqkGqQaqBqsGqgasBqsGqwasBq0GrAauBq0GrQauBq8GrgawBq8GrwawBrEGsAayBrEGsQayBrMGsga0BrMGswa0BrUGtAa2BrUGtQa2BrcGtga4BrcGtwa4BrkGuAa6BrkGuQa6BrsGuga8BrsGuwa8Br0GvAa+Br0GvQa+Br8GvgbABr8GvwbABsEGwAbCBsEGwQbCBsMGwgbEBsMGwwbEBsUGxAbGBsUGxQbGBscGxgbIBscGxwbIBskGyAbKBskGyQbKBssGygbMBssGywbMBs0GzAbOBs0GzQbOBs8GzgbQBs8GzwbQBtEG0AbSBtEG0QbSBtMG0gbUBtMG0wbUBtUG1AbWBtUG1QbWBtcG1gbYBtcG1wbYBtkG2AbaBtkG2QbaBtsG2gbcBtsG2wbcBt0G3AbeBt0G3QbeBt8G3gbgBt8G3wbgBuEG4AbiBuEG4QbiBuMG4gbkBuMG4wbkBuUG5AbmBuUG5QbmBucG5gboBucG5wboBukG6AbqBukG6QbqBusG6gbsBusG6wbsBu0G7AbuBu0G7QbuBu8G7gbwBu8G7wbwBvEG8AbyBvEG8QbyBvMG8gb0BvMG8wb0BvUG9Ab2BvUG9Qb2BvcG9gb4BvcG9wb4BvkG+Ab6BvkG+Qb6BvsG+gb8BvsG+wb8Bv0G/Ab+Bv0G/Qb+Bv8G/gYAB/8G/wYABwEHAAcCBwEHAQcCBwMHAgcEBwMHAwcEBwUHBAcGBwUHBQcGBwcHBgcIBwcHBwcIBwkHCAcKBwkHCQcKBwsHCgcMBwsHCwcMBw0HDAcOBw0HDQcOBw8HDgcQBw8HDwcQBxEHEAcSBxEHEQcSBxMHEgcAABMHEwcAAAEA"),
+"index_count": 6588,
+"index_data": PackedByteArray("AAACAAEAAQACAAMAAgAEAAMAAwAEAAUABAAGAAUABQAGAAcABgAIAAcABwAIAAkACAAKAAkACQAKAAsACgAMAAsACwAMAA0ADAAOAA0ADQAOAA8ADgAQAA8ADwAQABEAEAASABEAEQASABMAEgAUABMAEwAUABUAFAAWABUAFQAWABcAFgAYABcAFwAYABkAGAAaABkAGQAaABsAGgAcABsAGwAcAB0AHAAeAB0AHQAeAB8AHgAgAB8AHwAgACEAIAAiACEAIQAiACMAIgAkACMAIwAkACUAJAAmACUAJQAmACcAJgAoACcAJwAoACkAKAAqACkAKQAqACsAKgAsACsAKwAsAC0ALAAuAC0ALQAuAC8ALgAwAC8ALwAwADEAMAAyADEAMQAyADMAMgA0ADMAMwA0ADUANAA2ADUANQA2ADcANgA4ADcANwA4ADkAOAA6ADkAOQA6ADsAOgA8ADsAOwA8AD0APAA+AD0APQA+AD8APgBAAD8APwBAAEEAQABCAEEAQQBCAEMAQgBEAEMAQwBEAEUARABGAEUARQBGAEcARgBIAEcARwBIAEkASABKAEkASQBKAEsASgBMAEsASwBMAE0ATABOAE0ATQBOAE8ATgBQAE8ATwBQAFEAUABSAFEAUQBSAFMAUgBUAFMAUwBUAFUAVABWAFUAVQBWAFcAVgBYAFcAVwBYAFkAWABaAFkAWQBaAFsAWgBcAFsAWwBcAF0AXABeAF0AXQBeAF8AXgBgAF8AXwBgAGEAYABiAGEAYQBiAGMAYgBkAGMAYwBkAGUAZABmAGUAZQBmAGcAZgBoAGcAZwBoAGkAaABqAGkAaQBqAGsAagBsAGsAawBsAG0AbABuAG0AbQBuAG8AbgBwAG8AbwBwAHEAcAByAHEAcQByAHMAcgB0AHMAcwB0AHUAdAB2AHUAdQB2AHcAdgB4AHcAdwB4AHkAeAB6AHkAeQB6AHsAegB8AHsAewB8AH0AfAB+AH0AfQB+AH8AfgCAAH8AfwCAAIEAgACCAIEAgQCCAIMAggCEAIMAgwCEAIUAhACGAIUAhQCGAIcAhgCIAIcAhwCIAIkAiACKAIkAiQCKAIsAigCMAIsAiwCMAI0AjACOAI0AjQCOAI8AjgCQAI8AjwCQAJEAkACSAJEAkQCSAJMAkgCUAJMAkwCUAJUAlACWAJUAlQCWAJcAlgCYAJcAlwCYAJkAmACaAJkAmQCaAJsAmgCcAJsAmwCcAJ0AnACeAJ0AnQCeAJ8AngCgAJ8AnwCgAKEAoACiAKEAoQCiAKMAogCkAKMAowCkAKUApACmAKUApQCmAKcApgCoAKcApwCoAKkAqACqAKkAqQCqAKsAqgCsAKsAqwCsAK0ArACuAK0ArQCuAK8ArgCwAK8ArwCwALEAsACyALEAsQCyALMAsgC0ALMAswC0ALUAtAC2ALUAtQC2ALcAtgC4ALcAtwC4ALkAuAC6ALkAuQC6ALsAugC8ALsAuwC8AL0AvAC+AL0AvQC+AL8AvgDAAL8AvwDAAMEAwADCAMEAwQDCAMMAwgDEAMMAwwDEAMUAxADGAMUAxQDGAMcAxgDIAMcAxwDIAMkAyADKAMkAyQDKAMsAygDMAMsAywDMAM0AzADOAM0AzQDOAM8AzgDQAM8AzwDQANEA0ADSANEA0QDSANMA0gDUANMA0wDUANUA1ADWANUA1QDWANcA1gDYANcA1wDYANkA2ADaANkA2QDaANsA2gDcANsA2wDcAN0A3ADeAN0A3QDeAN8A3gDgAN8A3wDgAOEA4ADiAOEA4QDiAOMA4gDkAOMA4wDkAOUA5ADmAOUA5QDmAOcA5gDoAOcA5wDoAOkA6ADqAOkA6QDqAOsA6gDsAOsA6wDsAO0A7ADuAO0A7QDuAO8A7gDwAO8A7wDwAPEA8ADyAPEA8QDyAPMA8gD0APMA8wD0APUA9AD2APUA9QD2APcA9gD4APcA9wD4APkA+AD6APkA+QD6APsA+gD8APsA+wD8AP0A/AD+AP0A/QD+AP8A/gAAAf8A/wAAAQEBAAECAQEBAQECAQMBAgEEAQMBAwEEAQUBBAEGAQUBBQEGAQcBBgEIAQcBBwEIAQkBCAEKAQkBCQEKAQsBCgEMAQsBCwEMAQ0BDAEOAQ0BDQEOAQ8BDgEQAQ8BDwEQAREBEAESAREBEQESARMBEgEUARMBEwEUARUBFAEWARUBFQEWARcBFgEYARcBFwEYARkBGAEaARkBGQEaARsBGgEcARsBGwEcAR0BHAEeAR0BHQEeAR8BHgEgAR8BHwEgASEBIAEiASEBIQEiASMBIgEkASMBIwEkASUBJAEmASUBJQEmAScBJgEoAScBJwEoASkBKAEqASkBKQEqASsBKgEsASsBKwEsAS0BLAEuAS0BLQEuAS8BLgEwAS8BLwEwATEBMAEyATEBMQEyATMBMgE0ATMBMwE0ATUBNAE2ATUBNQE2ATcBNgE4ATcBNwE4ATkBOAE6ATkBOQE6ATsBOgE8ATsBOwE8AT0BPAE+AT0BPQE+AT8BPgFAAT8BPwFAAUEBQAFCAUEBQQFCAUMBQgFEAUMBQwFEAUUBRAFGAUUBRQFGAUcBRgFIAUcBRwFIAUkBSAFKAUkBSQFKAUsBSgFMAUsBSwFMAU0BTAFOAU0BTQFOAU8BTgFQAU8BTwFQAVEBUAFSAVEBUQFSAVMBUgFUAVMBUwFUAVUBVAFWAVUBVQFWAVcBVgFYAVcBVwFYAVkBWAFaAVkBWQFaAVsBWgFcAVsBWwFcAV0BXAFeAV0BXQFeAV8BXgFgAV8BXwFgAWEBYAFiAWEBYQFiAWMBYgFkAWMBYwFkAWUBZAFmAWUBZQFmAWcBZgFoAWcBZwFoAWkBaAFqAWkBaQFqAWsBagFsAWsBawFsAW0BbAFuAW0BbQFuAW8BbgFwAW8BbwFwAXEBcAFyAXEBcQFyAXMBcgF0AXMBcwF0AXUBdAF2AXUBdQF2AXcBdgF4AXcBdwF4AXkBeAF6AXkBeQF6AXsBegF8AXsBewF8AX0BfAF+AX0BfQF+AX8BfgGAAX8BfwGAAYEBgAGCAYEBgQGCAYMBggGEAYMBgwGEAYUBhAGGAYUBhQGGAYcBhgGIAYcBhwGIAYkBiAGKAYkBiQGKAYsBigGMAYsBiwGMAY0BjAGOAY0BjQGOAY8BjgGQAY8BjwGQAZEBkAGSAZEBkQGSAZMBkgGUAZMBkwGUAZUBlAGWAZUBlQGWAZcBlgGYAZcBlwGYAZkBmAGaAZkBmQGaAZsBmgGcAZsBmwGcAZ0BnAGeAZ0BnQGeAZ8BngGgAZ8BnwGgAaEBoAGiAaEBoQGiAaMBogGkAaMBowGkAaUBpAGmAaUBpQGmAacBpgGoAacBpwGoAakBqAGqAakBqQGqAasBqgGsAasBqwGsAa0BrAGuAa0BrQGuAa8BrgGwAa8BrwGwAbEBsAGyAbEBsQGyAbMBsgG0AbMBswG0AbUBtAG2AbUBtQG2AbcBtgG4AbcBtwG4AbkBuAG6AbkBuQG6AbsBugG8AbsBuwG8Ab0BvAG+Ab0BvQG+Ab8BvgHAAb8BvwHAAcEBwAHCAcEBwQHCAcMBwgHEAcMBwwHEAcUBxAHGAcUBxQHGAccBxgHIAccBxwHIAckByAHKAckByQHKAcsBygHMAcsBywHMAc0BzAHOAc0BzQHOAc8BzgHQAc8BzwHQAdEB0AHSAdEB0QHSAdMB0gHUAdMB0wHUAdUB1AHWAdUB1QHWAdcB1gHYAdcB1wHYAdkB2AHaAdkB2QHaAdsB2gHcAdsB2wHcAd0B3AHeAd0B3QHeAd8B3gHgAd8B3wHgAeEB4AHiAeEB4QHiAeMB4gHkAeMB4wHkAeUB5AHmAeUB5QHmAecB5gHoAecB5wHoAekB6AHqAekB6QHqAesB6gHsAesB6wHsAe0B7AHuAe0B7QHuAe8B7gHwAe8B7wHwAfEB8AHyAfEB8QHyAfMB8gH0AfMB8wH0AfUB9AH2AfUB9QH2AfcB9gH4AfcB9wH4AfkB+AH6AfkB+QH6AfsB+gH8AfsB+wH8Af0B/AH+Af0B/QH+Af8B/gEAAv8B/wEAAgECAAICAgECAQICAgMCAgIEAgMCAwIEAgUCBAIGAgUCBQIGAgcCBgIIAgcCBwIIAgkCCAIKAgkCCQIKAgsCCgIMAgsCCwIMAg0CDAIOAg0CDQIOAg8CDgIQAg8CDwIQAhECEAISAhECEQISAhMCEgIUAhMCEwIUAhUCFAIWAhUCFQIWAhcCFgIYAhcCFwIYAhkCGAIaAhkCGQIaAhsCGgIcAhsCGwIcAh0CHAIeAh0CHQIeAh8CHgIgAh8CHwIgAiECIAIiAiECIQIiAiMCIgIkAiMCIwIkAiUCJAImAiUCJQImAicCJgIoAicCJwIoAikCKAIqAikCKQIqAisCKgIsAisCKwIsAi0CLAIuAi0CLQIuAi8CLgIwAi8CLwIwAjECMAIyAjECMQIyAjMCMgI0AjMCMwI0AjUCNAI2AjUCNQI2AjcCNgI4AjcCNwI4AjkCOAI6AjkCOQI6AjsCOgI8AjsCOwI8Aj0CPAI+Aj0CPQI+Aj8CPgJAAj8CPwJAAkECQAJCAkECQQJCAkMCQgJEAkMCQwJEAkUCRAJGAkUCRQJGAkcCRgJIAkcCRwJIAkkCSAJKAkkCSQJKAksCSgJMAksCSwJMAk0CTAJOAk0CTQJOAk8CTgJQAk8CTwJQAlECUAJSAlECUQJSAlMCUgJUAlMCUwJUAlUCVAJWAlUCVQJWAlcCVgJYAlcCVwJYAlkCWAJaAlkCWQJaAlsCWgJcAlsCWwJcAl0CXAJeAl0CXQJeAl8CXgJgAl8CXwJgAmECYAJiAmECYQJiAmMCYgJkAmMCYwJkAmUCZAJmAmUCZQJmAmcCZgJoAmcCZwJoAmkCaAJqAmkCaQJqAmsCagJsAmsCawJsAm0CbAJuAm0CbQJuAm8CbgJwAm8CbwJwAnECcAJyAnECcQJyAnMCcgJ0AnMCcwJ0AnUCdAJ2AnUCdQJ2AncCdgJ4AncCdwJ4AnkCeAJ6AnkCeQJ6AnsCegJ8AnsCewJ8An0CfAJ+An0CfQJ+An8CfgKAAn8CfwKAAoECgAKCAoECgQKCAoMCggKEAoMCgwKEAoUChAKGAoUChQKGAocChgKIAocChwKIAokCiAKKAokCiQKKAosCigKMAosCiwKMAo0CjAKOAo0CjQKOAo8CjgKQAo8CjwKQApECkAKSApECkQKSApMCkgKUApMCkwKUApUClAKWApUClQKWApcClgKYApcClwKYApkCmAKaApkCmQKaApsCmgKcApsCmwKcAp0CnAKeAp0CnQKeAp8CngKgAp8CnwKgAqECoAKiAqECoQKiAqMCogKkAqMCowKkAqUCpAKmAqUCpQKmAqcCpgKoAqcCpwKoAqkCqAKqAqkCqQKqAqsCqgKsAqsCqwKsAq0CrAKuAq0CrQKuAq8CrgKwAq8CrwKwArECsAKyArECsQKyArMCsgK0ArMCswK0ArUCtAK2ArUCtQK2ArcCtgK4ArcCtwK4ArkCuAK6ArkCuQK6ArsCugK8ArsCuwK8Ar0CvAK+Ar0CvQK+Ar8CvgLAAr8CvwLAAsECwALCAsECwQLCAsMCwgLEAsMCwwLEAsUCxALGAsUCxQLGAscCxgLIAscCxwLIAskCyALKAskCyQLKAssCygLMAssCywLMAs0CzALOAs0CzQLOAs8CzgLQAs8CzwLQAtEC0ALSAtEC0QLSAtMC0gLUAtMC0wLUAtUC1ALWAtUC1QLWAtcC1gLYAtcC1wLYAtkC2ALaAtkC2QLaAtsC2gLcAtsC2wLcAt0C3ALeAt0C3QLeAt8C3gLgAt8C3wLgAuEC4ALiAuEC4QLiAuMC4gLkAuMC4wLkAuUC5ALmAuUC5QLmAucC5gLoAucC5wLoAukC6ALqAukC6QLqAusC6gLsAusC6wLsAu0C7ALuAu0C7QLuAu8C7gLwAu8C7wLwAvEC8ALyAvEC8QLyAvMC8gL0AvMC8wL0AvUC9AL2AvUC9QL2AvcC9gL4AvcC9wL4AvkC+AL6AvkC+QL6AvsC+gL8AvsC+wL8Av0C/AL+Av0C/QL+Av8C/gIAA/8C/wIAAwEDAAMCAwEDAQMCAwMDAgMEAwMDAwMEAwUDBAMGAwUDBQMGAwcDBgMIAwcDBwMIAwkDCAMKAwkDCQMKAwsDCgMMAwsDCwMMAw0DDAMOAw0DDQMOAw8DDgMQAw8DDwMQAxEDEAMSAxEDEQMSAxMDEgMUAxMDEwMUAxUDFAMWAxUDFQMWAxcDFgMYAxcDFwMYAxkDGAMaAxkDGQMaAxsDGgMcAxsDGwMcAx0DHAMeAx0DHQMeAx8DHgMgAx8DHwMgAyEDIAMiAyEDIQMiAyMDIgMkAyMDIwMkAyUDJAMmAyUDJQMmAycDJgMoAycDJwMoAykDKAMqAykDKQMqAysDKgMsAysDKwMsAy0DLAMuAy0DLQMuAy8DLgMwAy8DLwMwAzEDMAMyAzEDMQMyAzMDMgM0AzMDMwM0AzUDNAM2AzUDNQM2AzcDNgM4AzcDNwM4AzkDOAM6AzkDOQM6AzsDOgM8AzsDOwM8Az0DPAM+Az0DPQM+Az8DPgNAAz8DPwNAA0EDQANCA0EDQQNCA0MDQgNEA0MDQwNEA0UDRANGA0UDRQNGA0cDRgNIA0cDRwNIA0kDSANKA0kDSQNKA0sDSgNMA0sDSwNMA00DTANOA00DTQNOA08DTgNQA08DTwNQA1EDUANSA1EDUQNSA1MDUgNUA1MDUwNUA1UDVANWA1UDVQNWA1cDVgNYA1cDVwNYA1kDWANaA1kDWQNaA1sDWgNcA1sDWwNcA10DXANeA10DXQNeA18DXgNgA18DXwNgA2EDYANiA2EDYQNiA2MDYgNkA2MDYwNkA2UDZANmA2UDZQNmA2cDZgNoA2cDZwNoA2kDaANqA2kDaQNqA2sDagNsA2sDawNsA20DbANuA20DbQNuA28DbgNwA28DbwNwA3EDcANyA3EDcQNyA3MDcgN0A3MDcwN0A3UDdAN2A3UDdQN2A3cDdgN4A3cDdwN4A3kDeAN6A3kDeQN6A3sDegN8A3sDewN8A30DfAN+A30DfQN+A38DfgOAA38DfwOAA4EDgAOCA4EDgQOCA4MDggOEA4MDgwOEA4UDhAOGA4UDhQOGA4cDhgOIA4cDhwOIA4kDiAOKA4kDiQOKA4sDigOMA4sDiwOMA40DjAOOA40DjQOOA48DjgOQA48DjwOQA5EDkAOSA5EDkQOSA5MDkgOUA5MDkwOUA5UDlAOWA5UDlQOWA5cDlgOYA5cDlwOYA5kDmAOaA5kDmQOaA5sDmgOcA5sDmwOcA50DnAOeA50DnQOeA58DngOgA58DnwOgA6EDoAOiA6EDoQOiA6MDogOkA6MDowOkA6UDpAOmA6UDpQOmA6cDpgOoA6cDpwOoA6kDqAOqA6kDqQOqA6sDqgOsA6sDqwOsA60DrAOuA60DrQOuA68DrgOwA68DrwOwA7EDsAOyA7EDsQOyA7MDsgO0A7MDswO0A7UDtAO2A7UDtQO2A7cDtgO4A7cDtwO4A7kDuAO6A7kDuQO6A7sDugO8A7sDuwO8A70DvAO+A70DvQO+A78DvgPAA78DvwPAA8EDwAPCA8EDwQPCA8MDwgPEA8MDwwPEA8UDxAPGA8UDxQPGA8cDxgPIA8cDxwPIA8kDyAPKA8kDyQPKA8sDygPMA8sDywPMA80DzAPOA80DzQPOA88DzgPQA88DzwPQA9ED0APSA9ED0QPSA9MD0gPUA9MD0wPUA9UD1APWA9UD1QPWA9cD1gPYA9cD1wPYA9kD2APaA9kD2QPaA9sD2gPcA9sD2wPcA90D3APeA90D3QPeA98D3gPgA98D3wPgA+ED4APiA+ED4QPiA+MD4gPkA+MD4wPkA+UD5APmA+UD5QPmA+cD5gPoA+cD5wPoA+kD6APqA+kD6QPqA+sD6gPsA+sD6wPsA+0D7APuA+0D7QPuA+8D7gPwA+8D7wPwA/ED8APyA/ED8QPyA/MD8gP0A/MD8wP0A/UD9AP2A/UD9QP2A/cD9gP4A/cD9wP4A/kD+AP6A/kD+QP6A/sD+gP8A/sD+wP8A/0D/AP+A/0D/QP+A/8D/gMABP8D/wMABAEEAAQCBAEEAQQCBAMEAgQEBAMEAwQEBAUEBAQGBAUEBQQGBAcEBgQIBAcEBwQIBAkECAQKBAkECQQKBAsECgQMBAsECwQMBA0EDAQOBA0EDQQOBA8EDgQQBA8EDwQQBBEEEAQSBBEEEQQSBBMEEgQUBBMEEwQUBBUEFAQWBBUEFQQWBBcEFgQYBBcEFwQYBBkEGAQaBBkEGQQaBBsEGgQcBBsEGwQcBB0EHAQeBB0EHQQeBB8EHgQgBB8EHwQgBCEEIAQiBCEEIQQiBCMEIgQkBCMEIwQkBCUEJAQmBCUEJQQmBCcEJgQoBCcEJwQoBCkEKAQqBCkEKQQqBCsEKgQsBCsEKwQsBC0ELAQuBC0ELQQuBC8ELgQwBC8ELwQwBDEEMAQyBDEEMQQyBDMEMgQ0BDMEMwQ0BDUENAQ2BDUENQQ2BDcENgQ4BDcENwQ4BDkEOAQ6BDkEOQQ6BDsEOgQ8BDsEOwQ8BD0EPAQ+BD0EPQQ+BD8EPgRABD8EPwRABEEEQARCBEEEQQRCBEMEQgREBEMEQwREBEUERARGBEUERQRGBEcERgRIBEcERwRIBEkESARKBEkESQRKBEsESgRMBEsESwRMBE0ETAROBE0ETQROBE8ETgRQBE8ETwRQBFEEUARSBFEEUQRSBFMEUgRUBFMEUwRUBFUEVARWBFUEVQRWBFcEVgRYBFcEVwRYBFkEWARaBFkEWQRaBFsEWgRcBFsEWwRcBF0EXAReBF0EXQReBF8EXgRgBF8EXwRgBGEEYARiBGEEYQRiBGMEYgRkBGMEYwRkBGUEZARmBGUEZQRmBGcEZgRoBGcEZwRoBGkEaARqBGkEaQRqBGsEagRsBGsEawRsBG0EbARuBG0EbQRuBG8EbgRwBG8EbwRwBHEEcARyBHEEcQRyBHMEcgR0BHMEcwR0BHUEdAR2BHUEdQR2BHcEdgR4BHcEdwR4BHkEeAR6BHkEeQR6BHsEegR8BHsEewR8BH0EfAR+BH0EfQR+BH8EfgSABH8EfwSABIEEgASCBIEEgQSCBIMEggSEBIMEgwSEBIUEhASGBIUEhQSGBIcEhgSIBIcEhwSIBIkEiASKBIkEiQSKBIsEigSMBIsEiwSMBI0EjASOBI0EjQSOBI8EjgSQBI8EjwSQBJEEkASSBJEEkQSSBJMEkgSUBJMEkwSUBJUElASWBJUElQSWBJcElgSYBJcElwSYBJkEmASaBJkEmQSaBJsEmgScBJsEmwScBJ0EnASeBJ0EnQSeBJ8EngSgBJ8EnwSgBKEEoASiBKEEoQSiBKMEogSkBKMEowSkBKUEpASmBKUEpQSmBKcEpgSoBKcEpwSoBKkEqASqBKkEqQSqBKsEqgSsBKsEqwSsBK0ErASuBK0ErQSuBK8ErgSwBK8ErwSwBLEEsASyBLEEsQSyBLMEsgS0BLMEswS0BLUEtAS2BLUEtQS2BLcEtgS4BLcEtwS4BLkEuAS6BLkEuQS6BLsEugS8BLsEuwS8BL0EvAS+BL0EvQS+BL8EvgTABL8EvwTABMEEwATCBMEEwQTCBMMEwgTEBMMEwwTEBMUExATGBMUExQTGBMcExgTIBMcExwTIBMkEyATKBMkEyQTKBMsEygTMBMsEywTMBM0EzATOBM0EzQTOBM8EzgTQBM8EzwTQBNEE0ATSBNEE0QTSBNME0gTUBNME0wTUBNUE1ATWBNUE1QTWBNcE1gTYBNcE1wTYBNkE2ATaBNkE2QTaBNsE2gTcBNsE2wTcBN0E3ATeBN0E3QTeBN8E3gTgBN8E3wTgBOEE4ATiBOEE4QTiBOME4gTkBOME4wTkBOUE5ATmBOUE5QTmBOcE5gToBOcE5wToBOkE6ATqBOkE6QTqBOsE6gTsBOsE6wTsBO0E7ATuBO0E7QTuBO8E7gTwBO8E7wTwBPEE8ATyBPEE8QTyBPME8gT0BPME8wT0BPUE9AT2BPUE9QT2BPcE9gT4BPcE9wT4BPkE+AT6BPkE+QT6BPsE+gT8BPsE+wT8BP0E/AT+BP0E/QT+BP8E/gQABf8E/wQABQEFAAUCBQEFAQUCBQMFAgUEBQMFAwUEBQUFBAUGBQUFBQUGBQcFBgUIBQcFBwUIBQkFCAUKBQkFCQUKBQsFCgUMBQsFCwUMBQ0FDAUOBQ0FDQUOBQ8FDgUQBQ8FDwUQBREFEAUSBREFEQUSBRMFEgUUBRMFEwUUBRUFFAUWBRUFFQUWBRcFFgUYBRcFFwUYBRkFGAUaBRkFGQUaBRsFGgUcBRsFGwUcBR0FHAUeBR0FHQUeBR8FHgUgBR8FHwUgBSEFIAUiBSEFIQUiBSMFIgUkBSMFIwUkBSUFJAUmBSUFJQUmBScFJgUoBScFJwUoBSkFKAUqBSkFKQUqBSsFKgUsBSsFKwUsBS0FLAUuBS0FLQUuBS8FLgUwBS8FLwUwBTEFMAUyBTEFMQUyBTMFMgU0BTMFMwU0BTUFNAU2BTUFNQU2BTcFNgU4BTcFNwU4BTkFOAU6BTkFOQU6BTsFOgU8BTsFOwU8BT0FPAU+BT0FPQU+BT8FPgVABT8FPwVABUEFQAVCBUEFQQVCBUMFQgVEBUMFQwVEBUUFRAVGBUUFRQVGBUcFRgVIBUcFRwVIBUkFSAVKBUkFSQVKBUsFSgVMBUsFSwVMBU0FTAVOBU0FTQVOBU8FTgVQBU8FTwVQBVEFUAVSBVEFUQVSBVMFUgVUBVMFUwVUBVUFVAVWBVUFVQVWBVcFVgVYBVcFVwVYBVkFWAVaBVkFWQVaBVsFWgVcBVsFWwVcBV0FXAVeBV0FXQVeBV8FXgVgBV8FXwVgBWEFYAViBWEFYQViBWMFYgVkBWMFYwVkBWUFZAVmBWUFZQVmBWcFZgVoBWcFZwVoBWkFaAVqBWkFaQVqBWsFagVsBWsFawVsBW0FbAVuBW0FbQVuBW8FbgVwBW8FbwVwBXEFcAVyBXEFcQVyBXMFcgV0BXMFcwV0BXUFdAV2BXUFdQV2BXcFdgV4BXcFdwV4BXkFeAV6BXkFeQV6BXsFegV8BXsFewV8BX0FfAV+BX0FfQV+BX8FfgWABX8FfwWABYEFgAWCBYEFgQWCBYMFggWEBYMFgwWEBYUFhAWGBYUFhQWGBYcFhgWIBYcFhwWIBYkFiAWKBYkFiQWKBYsFigWMBYsFiwWMBY0FjAWOBY0FjQWOBY8FjgWQBY8FjwWQBZEFkAWSBZEFkQWSBZMFkgWUBZMFkwWUBZUFlAWWBZUFlQWWBZcFlgWYBZcFlwWYBZkFmAWaBZkFmQWaBZsFmgWcBZsFmwWcBZ0FnAWeBZ0FnQWeBZ8FngWgBZ8FnwWgBaEFoAWiBaEFoQWiBaMFogWkBaMFowWkBaUFpAWmBaUFpQWmBacFpgWoBacFpwWoBakFqAWqBakFqQWqBasFqgWsBasFqwWsBa0FrAWuBa0FrQWuBa8FrgWwBa8FrwWwBbEFsAWyBbEFsQWyBbMFsgW0BbMFswW0BbUFtAW2BbUFtQW2BbcFtgW4BbcFtwW4BbkFuAW6BbkFuQW6BbsFugW8BbsFuwW8Bb0FvAW+Bb0FvQW+Bb8FvgXABb8FvwXABcEFwAXCBcEFwQXCBcMFwgXEBcMFwwXEBcUFxAXGBcUFxQXGBccFxgXIBccFxwXIBckFyAXKBckFyQXKBcsFygXMBcsFywXMBc0FzAXOBc0FzQXOBc8FzgXQBc8FzwXQBdEF0AXSBdEF0QXSBdMF0gXUBdMF0wXUBdUF1AXWBdUF1QXWBdcF1gXYBdcF1wXYBdkF2AXaBdkF2QXaBdsF2gXcBdsF2wXcBd0F3AXeBd0F3QXeBd8F3gXgBd8F3wXgBeEF4AXiBeEF4QXiBeMF4gXkBeMF4wXkBeUF5AXmBeUF5QXmBecF5gXoBecF5wXoBekF6AXqBekF6QXqBesF6gXsBesF6wXsBe0F7AXuBe0F7QXuBe8F7gXwBe8F7wXwBfEF8AXyBfEF8QXyBfMF8gX0BfMF8wX0BfUF9AX2BfUF9QX2BfcF9gX4BfcF9wX4BfkF+AX6BfkF+QX6BfsF+gX8BfsF+wX8Bf0F/AX+Bf0F/QX+Bf8F/gUABv8F/wUABgEGAAYCBgEGAQYCBgMGAgYEBgMGAwYEBgUGBAYGBgUGBQYGBgcGBgYIBgcGBwYIBgkGCAYKBgkGCQYKBgsGCgYMBgsGCwYMBg0GDAYOBg0GDQYOBg8GDgYQBg8GDwYQBhEGEAYSBhEGEQYSBhMGEgYUBhMGEwYUBhUGFAYWBhUGFQYWBhcGFgYYBhcGFwYYBhkGGAYaBhkGGQYaBhsGGgYcBhsGGwYcBh0GHAYeBh0GHQYeBh8GHgYgBh8GHwYgBiEGIAYiBiEGIQYiBiMGIgYkBiMGIwYkBiUGJAYmBiUGJQYmBicGJgYoBicGJwYoBikGKAYqBikGKQYqBisGKgYsBisGKwYsBi0GLAYuBi0GLQYuBi8GLgYwBi8GLwYwBjEGMAYyBjEGMQYyBjMGMgY0BjMGMwY0BjUGNAY2BjUGNQY2BjcGNgY4BjcGNwY4BjkGOAY6BjkGOQY6BjsGOgY8BjsGOwY8Bj0GPAY+Bj0GPQY+Bj8GPgZABj8GPwZABkEGQAZCBkEGQQZCBkMGQgZEBkMGQwZEBkUGRAZGBkUGRQZGBkcGRgZIBkcGRwZIBkkGSAZKBkkGSQZKBksGSgZMBksGSwZMBk0GTAZOBk0GTQZOBk8GTgZQBk8GTwZQBlEGUAZSBlEGUQZSBlMGUgZUBlMGUwZUBlUGVAZWBlUGVQZWBlcGVgZYBlcGVwZYBlkGWAZaBlkGWQZaBlsGWgZcBlsGWwZcBl0GXAZeBl0GXQZeBl8GXgZgBl8GXwZgBmEGYAZiBmEGYQZiBmMGYgZkBmMGYwZkBmUGZAZmBmUGZQZmBmcGZgZoBmcGZwZoBmkGaAZqBmkGaQZqBmsGagZsBmsGawZsBm0GbAZuBm0GbQZuBm8GbgZwBm8GbwZwBnEGcAZyBnEGcQZyBnMGcgZ0BnMGcwZ0BnUGdAZ2BnUGdQZ2BncGdgZ4BncGdwZ4BnkGeAZ6BnkGeQZ6BnsGegZ8BnsGewZ8Bn0GfAZ+Bn0GfQZ+Bn8GfgaABn8GfwaABoEGgAaCBoEGgQaCBoMGggaEBoMGgwaEBoUGhAaGBoUGhQaGBocGhgaIBocGhwaIBokGiAaKBokGiQaKBosGigaMBosGiwaMBo0GjAaOBo0GjQaOBo8GjgaQBo8GjwaQBpEGkAaSBpEGkQaSBpMGkgaUBpMGkwaUBpUGlAaWBpUGlQaWBpcGlgaYBpcGlwaYBpkGmAaaBpkGmQaaBpsGmgacBpsGmwacBp0GnAaeBp0GnQaeBp8GngagBp8GnwagBqEGoAaiBqEGoQaiBqMGogakBqMGowakBqUGpAamBqUGpQamBqcGpgaoBqcGpwaoBqkGqAaqBqkGqQaqBqsGqgasBqsGqwasBq0GrAauBq0GrQauBq8GrgawBq8GrwawBrEGsAayBrEGsQayBrMGsga0BrMGswa0BrUGtAa2BrUGtQa2BrcGtga4BrcGtwa4BrkGuAa6BrkGuQa6BrsGuga8BrsGuwa8Br0GvAa+Br0GvQa+Br8GvgbABr8GvwbABsEGwAbCBsEGwQbCBsMGwgbEBsMGwwbEBsUGxAbGBsUGxQbGBscGxgbIBscGxwbIBskGyAbKBskGyQbKBssGygbMBssGywbMBs0GzAbOBs0GzQbOBs8GzgbQBs8GzwbQBtEG0AbSBtEG0QbSBtMG0gbUBtMG0wbUBtUG1AbWBtUG1QbWBtcG1gbYBtcG1wbYBtkG2AbaBtkG2QbaBtsG2gbcBtsG2wbcBt0G3AbeBt0G3QbeBt8G3gbgBt8G3wbgBuEG4AbiBuEG4QbiBuMG4gbkBuMG4wbkBuUG5AbmBuUG5QbmBucG5gboBucG5wboBukG6AbqBukG6QbqBusG6gbsBusG6wbsBu0G7AbuBu0G7QbuBu8G7gbwBu8G7wbwBvEG8AbyBvEG8QbyBvMG8gb0BvMG8wb0BvUG9Ab2BvUG9Qb2BvcG9gb4BvcG9wb4BvkG+Ab6BvkG+Qb6BvsG+gb8BvsG+wb8Bv0G/Ab+Bv0G/Qb+Bv8G/gYAB/8G/wYABwEHAAcCBwEHAQcCBwMHAgcEBwMHAwcEBwUHBAcGBwUHBQcGBwcHBgcIBwcHBwcIBwkHCAcKBwkHCQcKBwsHCgcMBwsHCwcMBw0HDAcOBw0HDQcOBw8HDgcQBw8HDwcQBxEHEAcSBxEHEQcSBxMHEgcUBxMHEwcUBxUHFAcWBxUHFQcWBxcHFgcYBxcHFwcYBxkHGAcaBxkHGQcaBxsHGgccBxsHGwccBx0HHAceBx0HHQceBx8HHgcgBx8HHwcgByEHIAciByEHIQciByMHIgckByMHIwckByUHJAcmByUHJQcmBycHJgcoBycHJwcoBykHKAcqBykHKQcqBysHKgcsBysHKwcsBy0HLAcuBy0HLQcuBy8HLgcwBy8HLwcwBzEHMAcyBzEHMQcyBzMHMgc0BzMHMwc0BzUHNAc2BzUHNQc2BzcHNgc4BzcHNwc4BzkHOAc6BzkHOQc6BzsHOgc8BzsHOwc8Bz0HPAc+Bz0HPQc+Bz8HPgdABz8HPwdAB0EHQAdCB0EHQQdCB0MHQgdEB0MHQwdEB0UHRAdGB0UHRQdGB0cHRgdIB0cHRwdIB0kHSAdKB0kHSQdKB0sHSgdMB0sHSwdMB00HTAdOB00HTQdOB08HTgdQB08HTwdQB1EHUAdSB1EHUQdSB1MHUgdUB1MHUwdUB1UHVAdWB1UHVQdWB1cHVgdYB1cHVwdYB1kHWAdaB1kHWQdaB1sHWgdcB1sHWwdcB10HXAdeB10HXQdeB18HXgdgB18HXwdgB2EHYAdiB2EHYQdiB2MHYgdkB2MHYwdkB2UHZAdmB2UHZQdmB2cHZgdoB2cHZwdoB2kHaAdqB2kHaQdqB2sHagdsB2sHawdsB20HbAduB20HbQduB28HbgdwB28HbwdwB3EHcAdyB3EHcQdyB3MHcgd0B3MHcwd0B3UHdAd2B3UHdQd2B3cHdgd4B3cHdwd4B3kHeAd6B3kHeQd6B3sHegd8B3sHewd8B30HfAd+B30HfQd+B38HfgeAB38HfweAB4EHgAeCB4EHgQeCB4MHggeEB4MHgweEB4UHhAeGB4UHhQeGB4cHhgeIB4cHhweIB4kHiAeKB4kHiQeKB4sHigeMB4sHiweMB40HjAeOB40HjQeOB48HjgeQB48HjweQB5EHkAeSB5EHkQeSB5MHkgeUB5MHkweUB5UHlAeWB5UHlQeWB5cHlgeYB5cHlweYB5kHmAeaB5kHmQeaB5sHmgecB5sHmwecB50HnAeeB50HnQeeB58HngegB58HnwegB6EHoAeiB6EHoQeiB6MHogekB6MHowekB6UHpAemB6UHpQemB6cHpgeoB6cHpweoB6kHqAeqB6kHqQeqB6sHqgesB6sHqwesB60HrAeuB60HrQeuB68HrgewB68HrwewB7EHsAeyB7EHsQeyB7MHsge0B7MHswe0B7UHtAe2B7UHtQe2B7cHtge4B7cHtwe4B7kHuAe6B7kHuQe6B7sHuge8B7sHuwe8B70HvAe+B70HvQe+B78HvgfAB78HvwfAB8EHwAfCB8EHwQfCB8MHwgfEB8MHwwfEB8UHxAfGB8UHxQfGB8cHxgfIB8cHxwfIB8kHyAfKB8kHyQfKB8sHygfMB8sHywfMB80HzAfOB80HzQfOB88HzgfQB88HzwfQB9EH0AfSB9EH0QfSB9MH0gfUB9MH0wfUB9UH1AfWB9UH1QfWB9cH1gfYB9cH1wfYB9kH2AfaB9kH2QfaB9sH2gfcB9sH2wfcB90H3AfeB90H3QfeB98H3gfgB98H3wfgB+EH4AfiB+EH4QfiB+MH4gfkB+MH4wfkB+UH5AfmB+UH5QfmB+cH5gfoB+cH5wfoB+kH6AfqB+kH6QfqB+sH6gfsB+sH6wfsB+0H7AfuB+0H7QfuB+8H7gfwB+8H7wfwB/EH8AfyB/EH8QfyB/MH8gf0B/MH8wf0B/UH9Af2B/UH9Qf2B/cH9gf4B/cH9wf4B/kH+Af6B/kH+Qf6B/sH+gf8B/sH+wf8B/0H/Af+B/0H/Qf+B/8H/gcACP8H/wcACAEIAAgCCAEIAQgCCAMIAggECAMIAwgECAUIBAgGCAUIBQgGCAcIBggICAcIBwgICAkICAgKCAkICQgKCAsICggMCAsICwgMCA0IDAgOCA0IDQgOCA8IDggQCA8IDwgQCBEIEAgSCBEIEQgSCBMIEggUCBMIEwgUCBUIFAgWCBUIFQgWCBcIFggYCBcIFwgYCBkIGAgaCBkIGQgaCBsIGggcCBsIGwgcCB0IHAgeCB0IHQgeCB8IHgggCB8IHwggCCEIIAgiCCEIIQgiCCMIIggkCCMIIwgkCCUIJAgmCCUIJQgmCCcIJggoCCcIJwgoCCkIKAgqCCkIKQgqCCsIKggsCCsIKwgsCC0ILAguCC0ILQguCC8ILggwCC8ILwgwCDEIMAgyCDEIMQgyCDMIMgg0CDMIMwg0CDUINAg2CDUINQg2CDcINgg4CDcINwg4CDkIOAg6CDkIOQg6CDsIOgg8CDsIOwg8CD0IPAg+CD0IPQg+CD8IPghACD8IPwhACEEIQAhCCEEIQQhCCEMIQghECEMIQwhECEUIRAhGCEUIRQhGCEcIRghICEcIRwhICEkISAhKCEkISQhKCEsISghMCEsISwhMCE0ITAhOCE0ITQhOCE8ITghQCE8ITwhQCFEIUAhSCFEIUQhSCFMIUghUCFMIUwhUCFUIVAhWCFUIVQhWCFcIVghYCFcIVwhYCFkIWAhaCFkIWQhaCFsIWghcCFsIWwhcCF0IXAheCF0IXQheCF8IXghgCF8IXwhgCGEIYAhiCGEIYQhiCGMIYghkCGMIYwhkCGUIZAhmCGUIZQhmCGcIZghoCGcIZwhoCGkIaAhqCGkIaQhqCGsIaghsCGsIawhsCG0IbAhuCG0IbQhuCG8IbghwCG8IbwhwCHEIcAhyCHEIcQhyCHMIcgh0CHMIcwh0CHUIdAh2CHUIdQh2CHcIdgh4CHcIdwh4CHkIeAh6CHkIeQh6CHsIegh8CHsIewh8CH0IfAh+CH0IfQh+CH8IfgiACH8IfwiACIEIgAiCCIEIgQiCCIMIggiECIMIgwiECIUIhAiGCIUIhQiGCIcIhgiICIcIhwiICIkIiAiKCIkIiQiKCIsIigiMCIsIiwiMCI0IjAiOCI0IjQiOCI8IjgiQCI8IjwiQCJEIkAiSCJEIkQiSCJMIkggAAJMIkwgAAAEA"),
"primitive": 3,
"uv_scale": Vector4(0, 0, 0, 0),
-"vertex_count": 1812,
-"vertex_data": PackedByteArray("Rr6cQRsv3b5fSszBPiejQRsv3b5WBcrBc/SbQRsv3b5g28rBy+6hQRsv3b6qncfBnR2bQRsv3b4fT8nB9RehQRsv3b5pEcbBxkaaQRsv3b7ewsfBHkGgQRsv3b4ohcTBGW6ZQRsv3b4kM8bBFHifQRsv3b7vEsPBGaSYQRsv3b7nmcTBF8SeQRsv3b68pcHBNOOXQRsv3b50AMPBAgqeQRsv3b6VGsDB6iKXQRsv3b5IaMHBW0udQRsv3b7jhb7BNmGWQRsv3b74x7/B8qacQRsv3b6nJ73BpMCVQRsv3b4wGr7Bjh+cQRsv3b6AubvBiSKVQRsv3b6KcrzBtIWbQRsv3b5gHbrB1YaUQRsv3b6mvbrBpQ2bQRsv3b4B1bjBzR6UQRsv3b7E+rjBVr+aQRsv3b6wdLfBcbaTQRsv3b4SMbfBgHOaQRsv3b58R7bBYKGTQRsv3b7rU7XBJm6aQRsv3b5PXbXBmcWTQRsv3b6MVLPBtyqaQRsv3b5apLXBo/yUQRsv3b6GorHBsO2ZQRsv3b5dTrbBAHeWQRsv3b58bLDBfwqaQRsv3b4dNbbBSjOYQRsv3b7Yoa/BtaiaQRsv3b7f+LXBFfeZQRsv3b5hD6/BwYabQRsv3b6trbXBPsWbQRsv3b7yyK7B+8icQRsv3b5CgrXB3YqdQRsv3b6ohK7BUUueQRsv3b7JRrXBglqfQRsv3b5WY67BzpifQRsv3b4FL7XBlSShQRsv3b40Y67BlSShQRsv3b4BMLXBVOeiQRsv3b40Y67BVOeiQRsv3b4BMLXBaJKkQRsv3b6TZK7BklulQRsv3b63JbXBASSmQRsv3b4bBK7B9QCoQRsv3b5LjrTB+ManQRsv3b4+eK3BdO2pQRsv3b6267PBdlOpQRsv3b4I96zBgIKsQRsv3b4++bLBa4mqQRsv3b4XBazBZgevQRsv3b74H7HBlb2rQRsv3b5Z0KrBXpWwQRsv3b5clq/BddmsQRsv3b6Ks6nBMKmyQRsv3b5xO63BvFStQRsv3b6BMajBNMizQRsv3b79V6rB+uKtQRsv3b7FhqbB7li0QRsv3b6+pajBs2WuQRsv3b6B+qTBTR21QRsv3b5XCabBNGOuQRsv3b6fV6PBATC1QRsv3b6fV6PBNGOuQRsv3b7glKHBATC1QRsv3b7glKHBPGOuQRsv3b6ezp/Bxy+1QRsv3b527J/BgnOuQRsv3b61/Z3B7ji1QRsv3b7QnZ7BMLiuQRsv3b5INJzBgHG1QRsv3b4FOJ3BIP2uQRsv3b79bJrBJKi1QRsv3b5JwpvBG3GvQRsv3b4yoJjBzNy1QRsv3b583ZrBszewQRsv3b6Q6JbBYje2QRsv3b5bHJrB0D6xQRsv3b6VSJXBlDm2QRsv3b4P6pnBsuqyQRsv3b57DpTBn721QRsv3b4SPprBjs+0QRsv3b54opPBiYO1QRsv3b7xZZrBM5O2QRsv3b5hopPBjj+3QRsv3b6gZprBNze4QRsv3b7iTJPB95i5QRsv3b5c9ZnBwOa5QRsv3b618JLBAJe7QRsv3b79hpnBoYm7QRsv3b4Sc5LBLaG9QRsv3b5x65jBPS+9QRsv3b6Y4JHBW2q/QRsv3b4LTZjBgtO+QRsv3b65TpHBnT3BQRsv3b4YqpfBXWzAQRsv3b7CpZDBJhbDQRsv3b5+55bBLwfCQRsv3b6r8Y/BDsLEQRsv3b4FLJbBQqPDQRsv3b4JPY/BemTGQRsv3b6YdJXBhjnFQRsv3b4kh47BhyXIQRsv3b4Lq5TBuMfGQRsv3b40vo3Bx9fJQRsv3b5v0JPBKVrIQRsv3b4v84zBOGrLQRsv3b5qBZPBmezJQRsv3b4rKIzBqfzMQRsv3b5mOpLBZUXLQRsv3b5wiIvBaT/QQRsv3b64KpDBbb7LQRsv3b7AOYrBmyXSQRsv3b7Pg4zBiULMQRsv3b5Yk4jBx7/SQRsv3b6Zm4rBP8nMQRsv3b4z5YbBfUbTQRsv3b517YjB9U/NQRsv3b4NN4XBM83TQRsv3b5OP4fBqtbNQRsv3b7oiIPB6FPUQRsv3b4pkYXBYF3OQRsv3b7D2oHBntrUQRsv3b4F44PBFuTOQRsv3b6dLIDBVGHVQRsv3b7eNILBy2rPQRsv3b7w/HzBCejVQRsv3b65hoDBmO/PQRsv3b6crXnBGH3WQRsv3b7tT33B5VTQQRsv3b5hanbBnAbXQRsv3b4oznjBU4fQQRsv3b53A3PBZUjXQRsv3b71lnTBkLvQQRsv3b4MhG/BonzXQRsv3b6KF3HBze/QQRsv3b6hBGzB37DXQRsv3b4fmG3BCiTRQRsv3b42hWjBHOXXQRsv3b60GGrBR1jRQRsv3b7LBWXBWRnYQRsv3b5JmWbBhIzRQRsv3b5ghmHBlk3YQRsv3b7eGWPBwcDRQRsv3b71Bl7B04HYQRsv3b5zml/B/vTRQRsv3b6Kh1rBELbYQRsv3b4IG1zBOynSQRsv3b4fCFfBTerYQRsv3b6dm1jBeF3SQRsv3b60iFPBih7ZQRsv3b4yHFXBtZHSQRsv3b5JCVDBx1LZQRsv3b7HnFHB8sXSQRsv3b7eiUzBBIfZQRsv3b5cHU7BL/rSQRsv3b5zCknBQbvZQRsv3b7xnUrBbC7TQRsv3b4Ii0XBfu/ZQRsv3b6GHkfBqWLTQRsv3b6dC0LBuyPaQRsv3b4bn0PBLZbTQRsv3b73mj7Ba13aQRsv3b7qsD/BYqnTQRsv3b7pJTvBpHTaQRsv3b5UuDvBmbvTQRsv3b7QoTfB+YbaQRsv3b6kLjjB1c3TQRsv3b4PHTTBNZnaQRsv3b7jqTTBEODTQRsv3b5OmDDBcKvaQRsv3b4iJTHBTPLTQRsv3b6NEy3BrL3aQRsv3b5hoC3BhwTUQRsv3b7LjinB58/aQRsv3b6bGyrBwhbUQRsv3b4KCibBIuLaQRsv3b7elibB/ijUQRsv3b5JhSLBXvTaQRsv3b4dEiPBOTvUQRsv3b6HAB/BmQbbQRsv3b5bjR/BdU3UQRsv3b7GexvB1RjbQRsv3b6aCBzBsF/UQRsv3b4F9xfBECvbQRsv3b7VgxjB63HUQRsv3b5DchTBSz3bQRsv3b4X/xTBJ4TUQRsv3b6C7RDBh0/bQRsv3b5WehHBYpbUQRsv3b7BaA3BwmHbQRsv3b6V9Q3BnqjUQRsv3b4A5AnB/nPbQRsv3b7UcArB2brUQRsv3b4/XwbBOYbbQRsv3b4P7AbBFM3UQRsv3b592gLBdJjbQRsv3b5RZwPBUN/UQRsv3b53q/7AsKrbQRsv3b4fxf/Ai/HUQRsv3b71offA67zbQRsv3b6du/jAxwPVQRsv3b5ymPDAJ8/bQRsv3b4asvHAAhbVQRsv3b7wjunAYuHbQRsv3b6YqOrAPijVQRsv3b5theLAnvPbQRsv3b4Vn+PAZzrVQRsv3b6ug9vAXgbcQRsv3b5bW9zAAUTVQRsv3b4MitTAtBDcQRsv3b7j1NTA/kPVQRsv3b7eh83AyxDcQRsv3b7eh83A/kPVQRsv3b7ifMbAyxDcQRsv3b7ifMbA/kPVQRsv3b7lcb/AyxDcQRsv3b7lcb/A/kPVQRsv3b7pZrjAyxDcQRsv3b7pZrjA/kPVQRsv3b7tW7HAyxDcQRsv3b7tW7HA/kPVQRsv3b7wUKrAyxDcQRsv3b7wUKrA/kPVQRsv3b70RaPAyxDcQRsv3b70RaPA/kPVQRsv3b74OpzAyxDcQRsv3b74OpzA/kPVQRsv3b78L5XAyxDcQRsv3b78L5XA/kPVQRsv3b4AJY7AyxDcQRsv3b4AJY7A/kPVQRsv3b4EGofAyxDcQRsv3b4EGofA/kPVQRsv3b4HD4DAyxDcQRsv3b4HD4DA/kPVQRsv3b4WCHLAyxDcQRsv3b4WCHLA/kPVQRsv3b4d8mPAyxDcQRsv3b4d8mPA/kPVQRsv3b4k3FXAyxDcQRsv3b4k3FXA/kPVQRsv3b4sxkfAyxDcQRsv3b4sxkfA/kPVQRsv3b4zsDnAyxDcQRsv3b4zsDnA/kPVQRsv3b46mivAyxDcQRsv3b46mivA/kPVQRsv3b5EhB3AyxDcQRsv3b5EhB3A/kPVQRsv3b5Kbg/AyxDcQRsv3b5Kbg/A/kPVQRsv3b5SWAHAyxDcQRsv3b5SWAHA/kPVQRsv3b60hOa/yxDcQRsv3b60hOa//kPVQRsv3b7EWMq/yxDcQRsv3b7EWMq//kPVQRsv3b7QLK6/yxDcQRsv3b7QLK6//kPVQRsv3b7gAJK/yxDcQRsv3b7gAJK//kPVQRsv3b7gqWu/yxDcQRsv3b7gqWu//kPVQRsv3b74UTO/yxDcQRsv3b74UTO//kPVQRsv3b4w9PW+yxDcQRsv3b4w9PW+/kPVQRsv3b5wRIW+yxDcQRsv3b5wRIW+AUTVQRsv3b6mlii9uRDcQRsv3b6fEAe9XDvVQRsv3b7n9jU+wwfcQRsv3b5UoUg+uDDVQRsv3b6Khss+CP3bQRsv3b4Bz9U+EibVQRsv3b4gFx4/YvLbQRsv3b5bOyM/axvVQRsv3b70alY/u+fbQRsv3b5tj1s/xBDVQRsv3b5rX4c/FN3bQRsv3b6J8Yk/HgbVQRsv3b5YiaM/btLbQRsv3b52G6Y/d/vUQRsv3b5Cs78/x8fbQRsv3b5/RcI/0PDUQRsv3b403ds/IL3bQRsv3b5Sb94/KubUQRsv3b4gB/g/erLbQRsv3b4+mfo/g9vUQRsv3b6GGApA06fbQRsv3b6kYQtA3NDUQRsv3b58LRhALJ3bQRsv3b6adhlANcbUQRsv3b51QiZAhZLbQRsv3b6DiydAj7vUQRsv3b5sVzRA34fbQRsv3b56oDVA6LDUQRsv3b5gbEJAOH3bQRsv3b5+tUNAQabUQRsv3b5ZgVBAkXLbQRsv3b5nylFAm5vUQRsv3b5Qll5A62fbQRsv3b5e319A9JDUQRsv3b5Fq2xARF3bQRsv3b5j9G1ATYbUQRsv3b4+wHpAnVLbQRsv3b5MCXxAp3vUQRsv3b6aaoRA90fbQRsv3b4hD4VAAHHUQRsv3b4UdYtAUD3bQRsv3b6jGYxAWWbUQRsv3b6Qf5JAqTLbQRsv3b4fJJNAslvUQRsv3b4MiplAAijbQRsv3b6TLppAG1HUQRsv3b5WjKBA7BzbQRsv3b58dqFApz3UQRsv3b7AgqdAtgfbQRsv3b5ZCalA6h7UQRsv3b5Lf65AnufaQRsv3b6eXLBABADUQRsv3b4IhrVAuMjaQRsv3b5jY7dAHeHTQRsv3b7GjLxA0anaQRsv3b4har5AN8LTQRsv3b6Gk8NA64raQRsv3b7ZcMVAUaPTQRsv3b5DmspABWzaQRsv3b6ed8xAaoTTQRsv3b4CodFAHk3aQRsv3b5dftNAhGXTQRsv3b7Bp9hAOC7aQRsv3b4UhdpAnkbTQRsv3b5/rt9AUg/aQRsv3b7ai+FAtyfTQRsv3b49teZAa/DZQRsv3b6YkuhA0QjTQRsv3b78u+1AhdHZQRsv3b5Pme9A6+nSQRsv3b66wvRAn7LZQRsv3b4VoPZABMvSQRsv3b55yftAuJPZQRsv3b7Upv1AHqzSQRsv3b4caAFB0nTZQRsv3b7GVgJBOI3SQRsv3b576wRB7FXZQRsv3b4o2gVBoW7SQRsv3b7VZghBqDTZQRsv3b6qmQlBlD/SQRsv3b64zQtBjfnYQRsv3b5fzA1BXe3RQRsv3b6/Mw9B/5vYQRsv3b4VuRFB0ZnRQRsv3b6eqRJBc0jYQRsv3b70LhVBREbRQRsv3b59HxZB5vTXQRsv3b7XpBhBt/LQQRsv3b5blRlBWaHXQRsv3b62GhxBKp/QQRsv3b46Cx1BzE3XQRsv3b6QkB9BnkvQQRsv3b4agSBBQPrWQRsv3b5wBiNBEfjPQRsv3b739iNBs6bWQRsv3b5SfCZBVazPQRsv3b4yMidBghjWQRsv3b7/qStB5RDPQRsv3b7/gSlBZxDUQRsv3b63ujJBSb/NQRsv3b4TPStB7o3RQRsv3b7UgTZBM17MQRsv3b6SHS1Bkn/PQRsv3b5TMDlB7NrKQRsv3b64Py5B5PvMQRsv3b5RKjtBjDHJQRsv3b4xMC9BvwvLQRsv3b4hRjxB2H/HQRsv3b7DJTBBC1rJQRsv3b6zOz1BGdfFQRsv3b6yFjFBNmXHQRsv3b4HVD5B1yvEQRsv3b7CtjFBZz3FQRsv3b4aJT9BgXLCQRsv3b4vKjJBhlTDQRsv3b5Qpj9Bk7PAQRsv3b47nzJBmJXBQRsv3b5cG0BBpPS+QRsv3b5HFDNBqda/QRsv3b5okEBBtjW9QRsv3b5TiTNBuxe+QRsv3b50BUFB5H27QRsv3b7D/DNBdyO8QRsv3b6UhkFBTsS5QRsv3b7VMTRBVCS6QRsv3b4ixkFBKwO4QRsv3b7aXjRBUVq4QRsv3b4W9EFB/UC2QRsv3b77izRBIpi2QRsv3b43IUJBzn60QRsv3b4cuTRB9NW0QRsv3b5YTkJBoLyyQRsv3b4+5jRBxhOzQRsv3b56e0JBcvqwQRsv3b5fEzVBl1GxQRsv3b6bqEJBaDqvQRsv3b5PQDVBVX+vQRsv3b4t10JBHn2tQRsv3b5GWjVBdpatQRsv3b6B80JBWr2rQRsv3b46WjVBWr2rQRsv3b7U80JBm/qpQRsv3b46WjVBm/qpQRsv3b7U80JB3DeoQRsv3b46WjVB3DeoQRsv3b7U80JBHXWmQRsv3b46WjVBHXWmQRsv3b7U80JBXrKkQRsv3b46WjVBXrKkQRsv3b7U80JBn++iQRsv3b46WjVBn++iQRsv3b7U80JB4CyhQRsv3b46WjVB4CyhQRsv3b7U80JBVGifQRsv3b4+WjVBoHefQRsv3b6280JBBZ6dQRsv3b6FajVBNPCdQRsv3b49AENBi9abQRsv3b5/sDVBN1ycQRsv3b7RP0NBIRWaQRsv3b649TVBzZqaQRsv3b4KhUNBt1OYQRsv3b7xOjZBY9mYQRsv3b5DykNBTJKWQRsv3b4qgDZB+BeXQRsv3b58D0RB4tCUQRsv3b5jxTZBjlaVQRsv3b61VERB7w6TQRsv3b6yCjdBKpmTQRsv3b5NmURBLUCRQRsv3b65VzdBrz6SQRsv3b7qy0RBcXqPQRsv3b6FGThBk+eQQRsv3b6sZUVBucGNQRsv3b6c1jhB2y6PQRsv3b7DIkZBAQmMQRsv3b6ykzlBI3aNQRsv3b7Z30ZBSVCKQRsv3b7JUDpBa72LQRsv3b7wnEdBeIKIQRsv3b5OGTtB5qKKQRsv3b5CBEhBatCGQRsv3b5qoDxB0M+JQRsv3b531UhBhTyFQRsv3b49TD5BmWuIQRsv3b6fUEpBt6GDQRsv3b7CAEBBNzuHQRsv3b6MiktBrhGCQRsv3b6xVkJB5keHQRsv3b77EktB5S2BQRsv3b7wzEVB7EKHQRsv3b7q4UtBKl+AQRsv3b6JCUlBCKCGQRsv3b4tYU5B3YN/QRsv3b5cdkxBQDOGQRsv3b4m0FBBSnB+QRsv3b5d2U9BWLSFQRsv3b6A8FNBIFx9QRsv3b5NTlNB60eFQRsv3b5vklZB7rN8QRsv3b5F3VZBFgqFQRsv3b6dUllB+RB8QRsv3b7qU1pBnLiEQRsv3b5CyVxB2Wp7QRsv3b6L3l1BAXOEQRsv3b73qV9B/B17QRsv3b5gdWFB9FWEQRsv3b5ckmJBCdV6QRsv3b5Q+GRBnTGEQRsv3b7qEWZBeIt6QRsv3b4/hGhBnA+EQRsv3b7+TWlBWWt6QRsv3b4KGWxBNQKEQRsv3b7jVWxBSWt6QRsv3b6xpW9BcgKEQRsv3b6xpW9BSWt6QRsv3b4vK3NBcgKEQRsv3b4vK3NBkmt6QRsv3b55oXZBYwGEQRsv3b6xIndB8Cl6QRsv3b79D3pBbNuDQRsv3b4OOXtBbtN5QRsv3b68jH1BZ66DQRsv3b5w3H5BSIF5QRsv3b7ndYBBBXGDQRsv3b4xr4FBu514QRsv3b6iFYJBqNqCQRsv3b7r7INB68F3QRsv3b6anoNBvOWBQRsv3b7KyIZBEhB2QRsv3b5croRBxKV9QRsv3b5MU4pB53NzQRsv3b45AoVBQLJ2QRsv3b7KnItBKOBvQRsv3b6jZYVBXLt0QRsv3b6sv4tBeXtsQRsv3b6jXYZBKJF0QRsv3b501YtB7KxpQRsv3b6LrIdBQtpzQRsv3b5KL4xBM3JnQRsv3b7mMYlBYudyQRsv3b6324xB76xlQRsv3b7syYpBKLVxQRsv3b5d9Y1BeCFkQRsv3b4gVoxBX+hvQRsv3b6+vI9BZ0piQRsv3b59uo1BTjZtQRsv3b7Zx5FB/TlgQRsv3b4L+o5BzKhpQRsv3b4P4JNBK+VdQRsv3b5F449BSrFjQRsv3b79CZZBM8RaQRsv3b7GOZBBcr9eQRsv3b5PupZBOEBXQRsv3b5+6pBBtfBdQRsv3b4n1pZBeTpUQRsv3b5CEZJB7whdQRsv3b7PP5dBAohRQRsv3b5sVZNBq29bQRsv3b5Q/pdBKTdPQRsv3b75uZRBMLFZQRsv3b71D5lB2vBMQRsv3b7SGpZBPrJXQRsv3b47RJpBztZKQRsv3b7ijZdB6OZVQRsv3b5lgptBKMxIQRsv3b5RAJlBpPVTQRsv3b7Y4pxBFsNGQRsv3b77e5pB1UlSQRsv3b7rF55BefxEQRsv3b42C5xBt85QQRsv3b7wZ59BOzVDQRsv3b7bm51BPVhPQRsv3b5braBB57tBQRsv3b7lQp9BIT1OQRsv3b5P76FB1FpAQRsv3b5Z8qBBBzpNQRsv3b5QJKNB6GI/QRsv3b5ltKJBjpVMQRsv3b6XWKRBT5U+QRsv3b6jhaRBrxZMQRsv3b6hUqVBg4Q+QRsv3b47U6ZBqRdMQRsv3b4pvaZBxy4+QRsv3b6v76dBC3pLQRsv3b7gXqlBZCo9QRsv3b5BealBI79JQRsv3b5fDqxBvbE7QRsv3b4y86pBvotHQRsv3b4PSa5BoeU5QRsv3b5iX6xBxApFQRsv3b4HRbBBt9Y3QRsv3b6PtK1B+kFCQRsv3b5oE7JBeIQ1QRsv3b6z+q5BbYQ/QRsv3b6MlrNBny8zQRsv3b7nOrBBApg8QRsv3b4BJLVBwpMwQRsv3b5WWLFB2Ws5QRsv3b7IgrZBDOstQRsv3b62e7JBA6A2QRsv3b79tLdBIkMrQRsv3b7Dj7NB41MzQRsv3b5mCblByWQoQRsv3b5fhLRBi/AvQRsv3b6iLLpBWnglQRsv3b7zfbVBzvYsQRsv3b6gKrtBoZciQRsv3b4Eb7ZBL4EpQRsv3b4zSrxBd4sfQRsv3b6CPbdB0eklQRsv3b6mP71B7G4cQRsv3b6VELhBQ80iQRsv3b65Er5BvFwZQRsv3b4A4bhBDWMfQRsv3b6s+b5BzzkWQRsv3b5MmblB87obQRsv3b4k0b9BrwETQRsv3b7mSLpBwFYYQRsv3b5RisBBX8QPQRsv3b6h+bpBcxkVQRsv3b4LO8FBpZMMQRsv3b7Np7tBwH0RQRsv3b74/sFBd04JQRsv3b4hOrxB48QNQRsv3b6LpsJBF/sFQRsv3b7wzLxBMmoKQRsv3b6eOsNB2qYCQRsv3b7lX71B9RUHQRsv3b6TzcNBd+7+QBsv3b567b1BIK8CQRsv3b7ViMRBylL4QBsv3b6NKr5Bsdz7QBsv3b6O6MRB+F/xQBsv3b4iXr5BnIL0QBsv3b5UH8VBAWHqQBsv3b4Xkr5BpYPtQBsv3b5JU8VBCWLjQBsv3b4Mxr5BrYTmQBsv3b4+h8VBEmPcQBsv3b4B+r5BtoXfQBsv3b4zu8VBGWTVQBsv3b72Lb9BxYbYQBsv3b4o78VBIWXOQBsv3b7sYb9BzYfRQBsv3b4eI8ZB6mvHQBsv3b63lb9BvV3KQBsv3b5JWMZBpIXAQBsv3b63wr9BqpPCQBsv3b6KisZB+5G5QBsv3b7V2L9ByOy6QBsv3b55o8ZBPImyQBsv3b5I779BCeSzQBsv3b7sucZBfICrQBsv3b67BcBBSdusQBsv3b5f0MZBvXekQBsv3b4uHMBBitKlQBsv3b7S5sZB/W6dQBsv3b6hMsBBysmeQBsv3b5F/cZBPmaWQBsv3b4UScBBC8GXQBsv3b64E8dBfl2PQBsv3b6HX8BBU7iQQBsv3b4rKsdBvlSIQBsv3b77dcBBkq+JQBsv3b6fQMdB/0uBQBsv3b5ujMBBzKaCQBsv3b4SV8dBgIZ0QBsv3b7hosBBGjx3QBsv3b6FbcdBAnVmQBsv3b5UucBBnCppQBsv3b74g8dBg2NYQBsv3b7Hz8BBHRlbQBsv3b5rmsdBgmhKQBsv3b4b5sBB8F5MQBsv3b7GscdBXm08QBsv3b4W8MBBDok9QBsv3b6GvMdBP1suQBsv3b5f+MBBaFsvQBsv3b7gxMdB5UUgQBsv3b6pAMFB/0UhQBsv3b4rzcdBhzASQBsv3b7zCMFBsDATQBsv3b501cdBKhsEQBsv3b4+EcFBUxsFQBsv3b7A3cdBoAvsPxsv3b6IGcFB1AvuPxsv3b4K5sdB4+DPPxsv3b7SIcFBNuHRPxsv3b5U7sdBK7azPxsv3b4dKsFBfra1Pxsv3b6e9sdBdouXPxsv3b5nMsFBqouZPxsv3b7p/sdBdMF2Pxsv3b6xOsFBGsJ6Pxsv3b4yB8hBBGw+Pxsv3b78QsFBqmxCPxsv3b5+D8hBlxYGPxsv3b5GS8FB/xYKPxsv3b7IF8hBQIKbPhsv3b6QU8FBjIOjPhsv3b4SIMhBgF2rPRsv3b7bW8FBrmLLPRsv3b5cKMhB86YLvhsv3b4lZMFBpkr3vRsv3b6nMMhBaH62vhsv3b5vbMFBHX2uvhsv3b7wOMhBqJQTvxsv3b66dMFBApQPvxsv3b48QchBK7lLvxsv3b7+fMFBZFhJvxsv3b6wSchBKuqBvxsv3b6LfsFB47mBvxsv3b5XS8hBbBCevxsv3b6LfsFBbBCevxsv3b5YS8hBXjy6vxsv3b6LfsFBXjy6vxsv3b5YS8hBTmjWvxsv3b6LfsFBTmjWvxsv3b5YS8hBP5Tyvxsv3b6LfsFBP5Tyvxsv3b5YS8hBGGAHwBsv3b6LfsFBGGAHwBsv3b5YS8hBEHYVwBsv3b6LfsFBEHYVwBsv3b5YS8hBCowjwBsv3b6LfsFBCowjwBsv3b5YS8hBAqIxwBsv3b6LfsFBAqIxwBsv3b5YS8hB+rc/wBsv3b6LfsFB+rc/wBsv3b5YS8hB881NwBsv3b6LfsFB881NwBsv3b5YS8hB6+NbwBsv3b6LfsFB6+NbwBsv3b5YS8hB5PlpwBsv3b6LfsFB5PlpwBsv3b5YS8hB3A94wBsv3b6LfsFB3A94wBsv3b5YS8hB6hKDwBsv3b6LfsFB6hKDwBsv3b5YS8hB5h2KwBsv3b6LfsFB5h2KwBsv3b5YS8hB4iiRwBsv3b6LfsFB4iiRwBsv3b5YS8hB3zOYwBsv3b6LfsFB3zOYwBsv3b5YS8hB2z6fwBsv3b6LfsFB2z6fwBsv3b5YS8hB10mmwBsv3b6LfsFB10mmwBsv3b5YS8hB1FStwBsv3b6LfsFB1FStwBsv3b5YS8hBxl+0wBsv3b6LfsFBG2C0wBsv3b5YS8hBTGi7wBsv3b6AfsFBin27wBsv3b5LS8hB1XDCwBsv3b7Me8FBpprCwBsv3b6RSMhByXvJwBsv3b4XecFBk6XJwBsv3b7cRchBvYbQwBsv3b5jdsFBh7DQwBsv3b4oQ8hBsZHXwBsv3b6uc8FBgrvXwBsv3b5zQMhBpZzewBsv3b75cMFBb8bewBsv3b6+PchBmaflwBsv3b5FbsFBY9HlwBsv3b4KO8hBjbLswBsv3b6Qa8FBV9zswBsv3b5VOMhBgb3zwBsv3b7caMFBS+fzwBsv3b6hNchBdcj6wBsv3b4nZsFBRvL6wBsv3b7sMshBtekAwRsv3b5yY8FBmv4AwRsv3b43MMhBL28EwRsv3b6+YMFBFIQEwRsv3b6DLchBqfQHwRsv3b4JXsFBjgkIwRsv3b7OKshBI3oLwRsv3b5VW8FBCI8LwRsv3b4aKMhBnP8OwRsv3b6gWMFBhRQPwRsv3b5lJchBF4USwRsv3b7rVcFB/JkSwRsv3b6wIshBkQoWwRsv3b43U8FBdh8WwRsv3b78H8hBC5AZwRsv3b6CUMFB8KQZwRsv3b5HHchBeBMdwRsv3b7QTcFBvjkdwRsv3b6CGshBvpYgwRsv3b6fRsFB7M4gwRsv3b4yE8hBDRwkwRsv3b5IP8FBwlQkwRsv3b7aC8hBbaEnwRsv3b7wN8FBJtonwRsv3b6CBMhBzCYrwRsv3b6YMMFBhV8rwRsv3b4q/cdBLKwuwRsv3b5AKcFB4eQuwRsv3b7S9cdBizEywRsv3b7pIcFBQGoywRsv3b577sdB67Y1wRsv3b6RGsFBpO81wRsv3b4j58dBSjw5wRsv3b45E8FB/3Q5wRsv3b7L38dBqsE8wRsv3b7iC8FBX/o8wRsv3b502MdBCUdAwRsv3b6KBMFBwn9AwRsv3b4c0cdBacxDwRsv3b4y/cBBIgVEwRsv3b7EycdByFFHwRsv3b7a9cBBfYpHwRsv3b5swsdBLNRKwRsv3b6L7sBBPyZLwRsv3b7cusdBvlROwRsv3b6y4MBBmMxOwRsv3b53rMdBINhRwRsv3b6az8BBYlxSwRsv3b4lm8dB+FxVwRsv3b56vsBBOuFVwRsv3b4FisdBz+FYwRsv3b5brcBBEWZZwRsv3b7meMdBp2ZcwRsv3b47nMBB6epcwRsv3b7GZ8dBf+tfwRsv3b4ci8BBwW9gwRsv3b6nVsdBVnBjwRsv3b78ecBBmPRjwRsv3b6HRcdBXvNmwRsv3b7maMBBAodnwRsv3b4iNMdBKWhqwRsv3b5GVMBBF39rwRsv3b56G8dBQdptwRsv3b7dIcBBvmRvwRsv3b5048ZB8FlxwRsv3b7K7r9BcORywRsv3b5hsMZBGtx0wRsv3b6Uu79BiVF2wRsv3b5WfsZBRGV4wRsv3b6Ojb9B0pJ5wRsv3b7QU8ZBZu57wRsv3b7cbL9BGul8wRsv3b4kNcZBjXF/wRsv3b5nTL9BIDaAwRsv3b6vFMZBWnqBwRsv3b7yK79Bs/eBwRsv3b469MVBEj2DwRsv3b5pC79BuLCDwRsv3b5d1MVBrQGFwRsv3b7R775BF16FwRsv3b4qusVBjMWGwRsv3b5Q275BbxSHwRsv3b5TpsVB1YeIwRsv3b7jxr5BudaIwRsv3b7mkcVBHUqKwRsv3b51sr5BAZmKwRsv3b54fcVBZgyMwRsv3b4Inr5BSVuMwRsv3b4LacVBm8+NwRsv3b6Rib5BoBaOwRsv3b7rVMVB8pOPwRsv3b4leb5BwcqPwRsv3b4VRcVBhFeRwRsv3b4Wbb5B+4WRwRsv3b5EOcVBGRqTwRsv3b4OYb5BkEiTwRsv3b48LcVBr9yUwRsv3b4GVb5BJguVwRsv3b40IcVBRZ+WwRsv3b7+SL5BvM2WwRsv3b4sFcVB22GYwRsv3b72PL5BUpCYwRsv3b4kCcVBIiWawRsv3b7pML5Bt02awRsv3b49/cRBMOmbwRsv3b7mJ75B0gWcwRsv3b539MRBm6ydwRsv3b4MIr5BLcOdwRsv3b6z7sRBUG+fwRsv3b40HL5B5IWfwRsv3b7b6MRBBjKhwRsv3b5bFr5BmkihwRsv3b4C48RBu/SiwRsv3b6DEL5BTQujwRsv3b4q3cRBcLekwRsv3b6rCr5BAs6kwRsv3b5S18RBJnqmwRsv3b7TBL5BupCmwRsv3b560cRBVi+owRsv3b6Z/71B0riowRsv3b72xsRBZ8mpwRsv3b6kw71BFFmrwRsv3b7wYcRBDmWrwRsv3b4RPL1ByIKtwRsv3b5ussNBaxGtwRsv3b7Mr7xBJS+vwRsv3b4pJsNByb2uwRsv3b6HI7xBg9uwwRsv3b7kmcJBJmqwwRsv3b5Cl7tB4IeywRsv3b6fDcJBCxOywRsv3b4qDLtBUE60wRsv3b6PeMFBmo2zwRsv3b6HhbpBJii3wRsv3b7FScBBVLK0wRsv3b6mZ7lBi2W5wRsv3b6wUb5BEvi1wRsv3b4aMLhBSau6wRsv3b4kGr1B0T23wRsv3b6N+LZBCPG7wRsv3b6X4rtBj4O4wRsv3b4BwbVBxja9wRsv3b4Lq7pB17i5wRsv3b4um7RBA/i+wRsv3b6N7rhBYYq6wRsv3b6KUrNBx6jAwRsv3b4ASrZBAhe7wRsv3b65vrFBNIHBwRsv3b5JALRBj6y7wRsv3b6CFbBBwRbCwRsv3b4SV7JBG0K8wRsv3b5LbK5BTqzCwRsv3b7arbBBp9e8wRsv3b4Uw6xB2kHDwRsv3b6jBK9Bs2i9wRsv3b5aKKtBJfnDwRsv3b7D7qxB+LW9wRsv3b4ilqlBHXvEwRsv3b4vOapBEbW9wRsv3b6S5qdB3oHEwRsv3b6S5qdBEbW9wRsv3b7SI6ZB3oHEwRsv3b7SI6ZBEbW9wRsv3b4TYaRB3oHEwRsv3b4TYaRBEbW9wRsv3b5UnqJB3oHEwRsv3b5UnqJBEbW9wRsv3b6V26BB3oHEwRsv3b6V26BBEbW9wRsv3b7WGJ9B3oHEwRsv3b7WGJ9BerW9wRsv3b4lSZ1BzH7EwRsv3b4vt51B2u+9wRsv3b5ge5tBBqzEwRsv3b5la5xBkDO+wRsv3b5Su5lB0OzEwRsv3b5/v5pB7na+wRsv3b6j/ZdBLjDFwRsv3b7QAZlBTLq+wRsv3b70P5ZBjHPFwRsv3b4hRJdBqv2+wRsv3b5FgpRB6rbFwRsv3b5yhpVBC0G/wRsv3b6CxJJBMPrFwRsv3b5byZNBY4i/wRsv3b6f9JBBrCLGwRsv3b7vlJJBoCDAwRsv3b61OI9BRY7GwRsv3b5gcJFBnLPAwRsv3b6Zjo1BQSHHwRsv3b5Exo9BmUbBwRsv3b5+5ItBPrTHwRsv3b4pHI5BldnBwRsv3b5iOopBOkfIwRsv3b4NcoxBkmzCwRsv3b5HkIhBN9rIwRsv3b7yx4pBRgXDwRsv3b5014ZBTELJwRsv3b40jIlBzeDDwRsv3b56N4VBOczJwRsv3b4lkIhBPszEwRsv3b57sINBY5/KwRsv3b6+ModB1bTFwRsv3b5gLoJB+ofLwRsv3b6jsIVBa53GwRsv3b5GrIBBkHDMwRsv3b6KLoRBAobHwRsv3b5ZVH5BJ1nNwRsv3b5wrIJBnHjIwRsv3b79MXtBn/bNwRsv3b5om4FB6q7JwRsv3b40a3hBg7HOwRsv3b6azoBBeerKwRsv3b5W2nVBoNHPwRsv3b7JRn9BzSLMwRsv3b5XUHNB9AnRwRsv3b7KvHxBIVvNwRsv3b5ZxnBBR0LSwRsv3b7MMnpBdZPOwRsv3b5aPG5Bm3rTwRsv3b7PqHdBeMTPwRsv3b5swmtB1OnUwRsv3b5WpnRBuNDQwRsv3b5NDWlBczfWwRsv3b5vUHFBdd/RwRsv3b7VP2ZB80zXwRsv3b4ncW5B/e7SwRsv3b5DcGNBe1zYwRsv3b6XoWtBhf7TwRsv3b6zoGBBA2zZwRsv3b4H0mhBnQfVwRsv3b4x411B06vawRsv3b4Je2VBv+XVwRsv3b7U+VpBfNDbwRsv3b6TrWFBq7jWwRsv3b6p51dBfrbcwRsv3b4vVl5B1o3XwRsv3b5ZzVRBqYvdwRsv3b7gO1tBwWHYwRsv3b7Dt1FBL2rewRsv3b4p/ldBrCPZwRsv3b7OuE5BNXPfwRsv3b6cyVNB1KHZwRsv3b54e0tBZiLgwRsv3b52dk9BwCXawRsv3b50HUhBUqbgwRsv3b5yGExBY6nawRsv3b5ZwURBayzhwRsv3b4drEhBYyPbwRsv3b6tkEFBzNXhwRsv3b6Z7ENBYzzbwRsv3b7BOj5B5QXiwRsv3b7bED9BG1jbwRsv3b73tjpBnSHiwRsv3b4RjTtBxnPbwRsv3b70NDdBuj3iwRsv3b74+zdBZ4vbwRsv3b5guDNB5VbiwRsv3b49PzRBapbbwRsv3b7vODBBsGLiwRsv3b62jjBBhaHbwRsv3b63syxBy23iwRsv3b5+CS1BoKzbwRsv3b5/LilB5njiwRsv3b5GhClBtLfbwRsv3b65qyVBNITiwRsv3b607CVBZL3bwRsv3b5rKyJBKIriwRsv3b6BQSJBY73bwRsv3b6GqB5BMIriwRsv3b6GqB5BY73bwRsv3b4IIxtBMIriwRsv3b4IIxtBY73bwRsv3b6KnRdBMIriwRsv3b6KnRdBY73bwRsv3b4MGBRBMIriwRsv3b4MGBRBZL3bwRsv3b5klRBBJ4riwRsv3b5MfRBBLbfbwRsv3b6bEw1BwoPiwRsv3b7j3AxBQK/bwRsv3b4GjwlByHviwRsv3b7CUQlBUafbwRsv3b6tCQZB2XPiwRsv3b5lzAVBYp/bwRsv3b5ShAJB6mviwRsv3b4KRwJBc5fbwRsv3b7v/f1A+2PiwRsv3b5gg/1AhY/bwRsv3b738/ZABlziwRsv3b4hc/ZAzobbwRsv3b6+7u9ADlPiwRsv3b78P+9A9XjbwRsv3b5G6ehA70TiwRsv3b7fEuhAFGvbwRsv3b4l3+FADjfiwRsv3b6+COFAM13bwRsv3b4D1dpALSniwRsv3b6c/tlAUk/bwRsv3b7iytNATBviwRsv3b579NJAcUHbwRsv3b7BwMxAaw3iwRsv3b5a6stAkDPbwRsv3b6ftsVAiv/hwRsv3b444MRA0yXbwRsv3b64ur5Am/DhwRsv3b5ma71AvQjbwRsv3b4kz7dA38/hwRsv3b7ZnbVA493awRsv3b7F2LBAs6LhwRsv3b6KPq5AwrLawRsv3b4O1qlAknfhwRsv3b7TO6dAoofawRsv3b5W06JAckzhwRsv3b4jOaBAglzawRsv3b6h0JtAUiHhwRsv3b5mNplAtTHawRsv3b6K2pRAu/PgwRsv3b4E1ZFAK/rZwRsv3b4DCY5ANbDgwRsv3b6rpolAQqPZwRsv3b4bPYdAa07gwRsv3b7G6oFAEkvZwRsv3b73VIBAO/bfwRsv3b5DBXZA4vLYwRsv3b6n2XJAC57fwRsv3b77NGhAQJzYwRsv3b5cQmVANDrfwRsv3b5KuVhADirYwRsv3b6tQlhA4p7ewRsv3b6gL0dAiYrXwRsv3b40b0tAeuHdwRsv3b4VwjdAgefWwRsv3b5dTT5Acj7dwRsv3b5LoCpAN0/WwRsv3b6h5TFA1krcwRsv3b66ChhArF3VwRsv3b4CcSdAi7zawRsv3b7lEgZAIUDUwRsv3b7v0hxAE3rZwRsv3b7oCvQ/lR3TwRsv3b6e0BFAk3fYwRsv3b4EgeA/Tw3SwRsv3b7VYwZAnYHXwRsv3b56zss/1/zQwRsv3b4i5vU/H43WwRsv3b6nV7c/6v/PwRsv3b4iDN4/5LLVwRsv3b4+sqI/TwnPwRsv3b6v7sU/o9zUwRsv3b55z40/CSfOwRsv3b4a9Kw/FSDUwRsv3b725HE/SVHNwRsv3b5iYpM/NHTTwRsv3b6cAkk/tJnMwRsv3b6S4nE/p+LSwRsv3b7uzx4/s/DLwRsv3b5MDTw/hF3SwRsv3b61luk+MWvLwRsv3b5JywQ/nPTRwRsv3b5orZE+i/LKwRsv3b6leJo+qZHRwRsv3b4Ctd09JJnKwRsv3b5e7qI92k3RwRsv3b7AVHu9S1nKwRsv3b6wWBK+4hnRwRsv3b7XQHm+FSzKwRsv3b6JtLy+hfbQwRsv3b5GY9O+ASnKwRsv3b5Bthi/J/XQwRsv3b5nxBK/G0bKwRsv3b5dWFO/FwTRwRsv3b4QBDe/ZqPKwRsv3b7MmYa/SEDRwRsv3b4qf1q/3x/LwRsv3b6vnKK/q5jRwRsv3b7mOIG/47/LwRsv3b5Iyb2/1xTSwRsv3b6QHZa/I3HMwRsv3b4Rc9i/cJ7SwRsv3b499Kq/U0DNwRsv3b4VA/K//VDTwRsv3b5/0MC/HRDOwRsv3b5OzQXAEf/TwRsv3b5ldNa/3wDPwRsv3b6KChLAesjUwRsv3b7awuq/k+/PwRsv3b52/B3Am7fVwRsv3b7QWAHA8djQwRsv3b6s3CnAs7XWwRsv3b7eSw7A3LPRwRsv3b6rCDbAUaHXwRsv3b40YBvAzY/SwRsv3b51QkLAQoXYwRsv3b4dDSjA7WLTwRsv3b57iE7AVmvZwRsv3b6cbjXALCzUwRsv3b4jClvAYD/awRsv3b4WmULAVPXUwRsv3b6PiWfAHhTbwRsv3b5K1E/AmLHVwRsv3b5xK3TAbeHbwRsv3b48mF3As2jWwRsv3b4XfoDAPZ7cwRsv3b4jzmrA0R7XwRsv3b4f3YbAd2LdwRsv3b4YkHjA6MPXwRsv3b5+Vo3AnRbewRsv3b6tVIPAqGfYwRsv3b772ZPAK8PewRsv3b4KM4rAE/zYwRsv3b7DJJrAio3fwRsv3b5EGpPAkEXZwRsv3b6azaDAfvjfwRsv3b6MIZzA/JLZwRsv3b7KvafA6kXgwRsv3b68EaPAaeDZwRsv3b77ra7AVpPgwRsv3b7lAarAeizawRsv3b47erXA+urgwRsv3b6e/7HAL1HawRsv3b5+VrzAexjhwRsv3b5LLbrA+nLawRsv3b7YWMPA3DrhwRsv3b64TcHA15TawRsv3b68XsrAuVzhwRsv3b6cU8jAtLbawRsv3b6fZNHAln7hwRsv3b5/Wc/AfNjawRsv3b4BZtjAEKHhwRsv3b44gdbADvXawRsv3b7GVd/AXMDhwRsv3b76NN7AZv3awRsv3b7hTebA5MnhwRsv3b7QyuXA4gXbwRsv3b6MWO3AYNLhwRsv3b571ezAXg7bwRsv3b42Y/TA3NrhwRsv3b4l4PPA2hbbwRsv3b7hbfvAWOPhwRsv3b7Q6vrAVh/bwRsv3b5GPAHB1OvhwRsv3b69+gDB0ifbwRsv3b6bwQTBUPThwRsv3b4SgATBRTDbwRsv3b7qPwjBEf3hwRsv3b4QOgjBVCnbwRsv3b7JvQvB5PXhwRsv3b6J9wvBWSHbwRsv3b6tQg/B4O3hwRsv3b5VgA/BXhnbwRsv3b4HyBLB5eXhwRsv3b6vBRPBYhHbwRsv3b5hTRbB6d3hwRsv3b4NixbBZgnbwRsv3b670hnB7dXhwRsv3b5nEBrBagHbwRsv3b4VWB3B8c3hwRsv3b69lR3Bb/nawRsv3b5v3SDB9sXhwRsv3b4XGyHBfvHawRsv3b4jXyTBrb3hwRsv3b7OuyTBbuLawRsv3b5mxSfBrqbhwRsv3b7/HSnBIJvawRsv3b4yJSvB8lDhwRsv3b4NWS3BIFLawRsv3b7Jni7B8gfhwRsv3b6k0jDBIAnawRsv3b5hGDLB8r7gwRsv3b48TDTBIMDZwRsv3b74kTXB8nXgwRsv3b7UxTfBIHfZwRsv3b6OCznB8izgwRsv3b5uPzvBHy7ZwRsv3b4mhTzB8ePfwRsv3b4GuT7BxObYwRsv3b4h7T/BnY7fwRsv3b6wtkLBg3zYwRsv3b7ALEPBl/rewRsv3b7lN0fB/OPXwRsv3b61ZkbBVkXewRsv3b70GkvBE0jXwRsv3b6OtEnBbandwRsv3b7NaE7BK6zWwRsv3b5nAk3BhQ3dwRsv3b6mtlHBQhDWwRsv3b5AUFDBnHHcwRsv3b5/BFXBWnTVwRsv3b4ZnlPBtNXbwRsv3b5YUljBbt/UwRsv3b6lylbBYwXbwRsv3b78mVzBpwjUwRsv3b7WpFnB38nZwRsv3b6S42DBJRDTwRsv3b5phVzBYrPYwRsv3b4mIGTBHBTSwRsv3b7OcF/BWbfXwRsv3b6MC2fBExjRwRsv3b4zXGLBULvWwRsv3b7w9mnBChzQwRsv3b6YR2XBRr/VwRsv3b5Z4mzBnCrPwRsv3b5PFmjBrHPUwRsv3b7XpHDBWgfOwRsv3b55b2rBvKzSwRsv3b63XXTB6rbMwRsv3b5TqGzBkRvRwRsv3b7NCXfB3V7LwRsv3b697m7BhMPPwRsv3b43UHnB0AbKwRsv3b4mNXHBdmvOwRsv3b6ilnvBwq7IwRsv3b6Qe3PBaBPNwRsv3b4M3X3BvF3HwRsv3b6ZtnXBpobLwRsv3b5hPIDBpPfFwRsv3b4Pr3fBGs3JwRsv3b5HdYHBJILEwRsv3b6enHnB2UHIwRsv3b6reoLBFArDwRsv3b6djXvByMnGwRsv3b4rc4PBBZLBwRsv3b6bfn3Bu1HFwRsv3b6pa4TBNiHAwRsv3b5zZn/BR6PDwRsv3b59hoXBc6S+wRsv3b4xg4DBZbLBwRsv3b59lobBXBG9wRsv3b7KPIHB2Om/wRsv3b7UaYfB+3e7wRsv3b5r+YHBd1C+wRsv3b52JojBmd65wRsv3b4LtoLBFbe8wRsv3b4W44jBp1a4wRsv3b6Xa4PB8Jq6wRsv3b7T1InB1LS2wRsv3b5u1IPBHlm4wRsv3b67bYrByP+0wRsv3b5PP4TBTp22wRsv3b5I2orB70mzwRsv3b5iqoTBdee0wRsv3b5aRYvBPaexwRsv3b67EYXB+qGywRsv3b5hzIvBKv6vwRsv3b6gJYXBczGwwRsv3b6r8YvBaD+uwRsv3b4cKoXBBFGuwRsv3b7S9ovBr3yswRsv3b6rLoXBSo6swRsv3b5h+4vBcLOqwRsv3b5lM4XBgPyqwRsv3b6q/ovBTuuowRsv3b4KVYXBtWypwRsv3b4GHYzBtimnwRsv3b7NdoXBE6ynwRsv3b63PozBN2SlwRsv3b7nmIXBswimwRsv3b7qXYzBsZyjwRsv3b4zzYXB0oWkwRsv3b5SiozBP9uhwRsv3b4TE4bB1uaiwRsv3b4wy4zBYhqgwRsv3b7vWIbBfkOhwRsv3b4yDI3BSFaewRsv3b5br4bBDtOfwRsv3b4AUo3BepucwRsv3b5lIYfBAk6ewRsv3b4Xt43BuuCawRsv3b6hk4fBk8icwRsv3b6sGo7BQCmZwRsv3b49I4jBjXWbwRsv3b6eiY7BEICXwRsv3b7NyYjBUPuZwRsv3b6NHo/B7MaVwRsv3b4reInBv/iYwRsv3b7neI/BtD+UwRsv3b7ThIrBViCYwRsv3b7iGpDBP8OSwRsv3b6djovBCv+WwRsv3b7i4JDBKmWRwRsv3b5ay4zBRTyWwRsv3b4OkpHBzzKQwRsv3b5DJo7BzE+VwRsv3b7WoZLBE/2OwRsv3b5ni4/BII+UwRsv3b7IcZPBmBeOwRsv3b5YKJHBRwuUwRsv3b47cpTBoDqNwRsv3b55uJLBpkeTwRsv3b7E0pXBeXKMwRsv3b5HX5TBlcGSwRsv3b696JbBgt+LwRsv3b5mFpbBv1KSwRsv3b6SPZjBLFGLwRsv3b7TwJfBLcGRwRsv3b6a8ZnBmL6KwRsv3b6DZ5nBUyWRwRsv3b7WspvB3yKKwRsv3b5BDJvBc4OQwRsv3b52aJ3BUoiJwRsv3b4KrpzBvNiPwRsv3b5BNJ/BCNmIwRsv3b5zRZ7BthGPwRsv3b4hBKHB/yOIwRsv3b4S1p/BeTWOwRsv3b6g56LBR1uHwRsv3b5dP6HBg8OMwRsv3b71XqXBkDeGwRsv3b7nXKLBPrKKwRsv3b6teqfBpuGEwRsv3b63ZaPBmeSIwRsv3b5V46jBGHaDwRsv3b6bX6TB5DaHwRsv3b4/C6rBm/+BwRsv3b4STqXBDZCFwRsv3b6UGKvBDYWAwRsv3b5CL6bB+cmDwRsv3b6tJazBbfd9wRsv3b5H9abBfPWBwRsv3b6NEq3B7th6wRsv3b73sKfBQhyAwRsv3b4h8K3B/Z13wRsv3b60UqjBHpN8wRsv3b65p67Bal90wRsv3b5U9ajB+gh5wRsv3b6kWK/B7hJxwRsv3b5ahKnBim11wRsv3b6I9a/BJsFtwRsv3b6NE6rBa/VxwRsv3b4Wi7DBFGxqwRsv3b4hmarBLWRuwRsv3b4kGrHBzg5nwRsv3b4TGavBbe5qwRsv3b7GnbHBGsVjwRsv3b53lqvB2+VmwRsv3b6YNLLBzGdgwRsv3b5n4qvBd65iwRsv3b6mlrLB2vBcwRsv3b5tKqzBCR9fwRsv3b624LLBRn9ZwRsv3b4RcqzBTmdbwRsv3b6uLbPBEhJWwRsv3b4Qp6zBlWlXwRsv3b5ea7PBAphSwRsv3b6LyazBUKVTwRsv3b4hkbPBOBVPwRsv3b5o7KzBhiJQwRsv3b7+s7PBqpZLwRsv3b4fD63B9H9MwRsv3b4C2LPB3x5IwRsv3b5VKK3B/KJIwRsv3b7h87PBNaFEwRsv3b7lMK3BMOREwRsv3b5f/bPB4htBwRsv3b6ROa3B3V5BwRsv3b4LBrTBj5Y9wRsv3b49Qq3Bitk9wRsv3b63DrTBXhU6wRsv3b7hSq3BLTU6wRsv3b6cF7TBzZg2wRsv3b5zSq3Bem42wRsv3b4fF7TBIhgzwRsv3b74P63B5cYywRsv3b5MDLTB4pIvwRsv3b50Na3BqUEvwRsv3b7IAbTBow0swRsv3b7wKq3BZrwrwRsv3b5E97PBZIgowRsv3b5rIK3BJzcowRsv3b6/7LPB8SclwRsv3b4qF63B650jwRsv3b7I2LPB9eMhwRsv3b71v6zBn+QewRsv3b70YbPBv38ewRsv3b5sVazBNUIbwRsv3b4X8LLBOBQbwRsv3b4H6qvBrtYXwRsv3b6yhLLBVsYXwRsv3b7dgqvByIwTwRsv3b6K+bHBONUUwRsv3b6N56rBRGEOwRsv3b7r47DBvg0SwRsv3b6e9anBwW4KwRsv3b5sl6/BFyMPwRsv3b4I+ajBHIQHwRsv3b7Wmq7B/30MwRsv3b4mGqjBuI8CwRsv3b6Ev6zBn/cKwRsv3b4GwKbBJiv+wBsv3b61DqrBS1MJwRsv3b6HNaXBVqX6wBsv3b4kaKjBWsAEwRsv3b42TaTBVY0RwRsv3b43AaLBX/8DwRsv3b4kcKLBSYARwRsv3b42oaHBW9UDwRsv3b52nqDBnGsRwRsv3b4sUqDB2a0DwRsv3b4m3J7BGkQRwRsv3b7cj57BFowDwRsv3b4uNJ3BhvEQwRsv3b74B5zBko8CwRsv3b6+ppvBEHIPwRsv3b6heZnBRV8BwRsv3b5CA5rBXSgOwRsv3b7hsZfBEA8DwRsv3b6urpfB/JvuwBsv3b5TGpvBwpYAwRsv3b4TOZbBWjrtwBsv3b5e2JrBZgv8wBsv3b548JTBjmXpwBsv3b7E45nBRUD2wBsv3b4urZPB+ZPowBsv3b4MjpnBQwXvwBsv3b4jCpPB3C/mwBsv3b6UeJnBJ0HowBsv3b6TdZLBClDgwBsv3b6E9pjBZf7gwBsv3b7n+pHBo3bdwBsv3b76uJjBFonZwBsv3b4r+ZHBFonZwBsv3b74xZjBGn7SwBsv3b4r+ZHBGn7SwBsv3b74xZjBxprLwBsv3b5p+ZHBr0nKwBsv3b4rxJjB5OLEwBsv3b5yz5HBuUvBwBsv3b4DjZjBug2+wBsv3b5RhZHB64O5wBsv3b63OZjBEX63wBsv3b7UP5HBzbKvwBsv3b6hw5fB1oqxwBsv3b6rlpDBFeelwBsv3b4GvJbB6eGrwBsv3b5T44/BufiawBsv3b7INpXBHSGowBsv3b4hvY7B/beRwBsv3b6nl5LBSQKfwBsv3b6W4o3BD1e5wBsv3b4cLozBiuiewBsv3b4V84vBIhi6wBsv3b4Lu4vBYn2ewBsv3b5VS4rBTmS5wBsv3b5gSonBp/ScwBsv3b7brIjB0yy3wBsv3b6m3YbBLeagwBsv3b5XgIbBrpCHwBsv3b4A+ojBocydwBsv3b4P14TB2naFwBsv3b634IfBUl6awBsv3b4QO4PB2CiDwBsv3b7XxobBxT2WwBsv3b7WvoHBKNd/wBsv3b6koYXBghWSwBsv3b7hQYDBEr95wBsv3b6mg4TB+iuNwBsv3b6P133BbFNywBsv3b79hoPBT0aIwBsv3b7QL3vByK1qwBsv3b6geYLBy6mCwBsv3b6Nw3jBBhZlwBsv3b7q24HBAfR4wBsv3b6C1XbBVjhcwBsv3b7sMIHBw4xswBsv3b5D6XTBJZRTwBsv3b4yf4DB2fVewBsv3b6Se3PBWrBLwBsv3b6xGYDBO2pRwBsv3b7FVHLBFuo/wBsv3b5KNX/BELhDwBsv3b6yK3HB90Q1wBsv3b47SH7BAW81wBsv3b5YaHDB67orwBsv3b4cyn3BlE8nwBsv3b6i4G/Bpz4fwBsv3b7AU33B6E0ZwBsv3b5DWm/BPeMRwBsv3b5b03zBbeoKwBsv3b50527BXSkHwBsv3b7BeHzBvfP4vxsv3b5U2m7BMHv3vxsv3b6cc3zBdMjcvxsv3b4kzm7B50/bvxsv3b5sZ3zBZnTAvxsv3b7qwW7BclbAvxsv3b6EW3zBVGmjvxsv3b4vzW7BEBKrvxsv3b4lXnzBcrmGvxsv3b70Q2/BdcSUvxsv3b5uwHzBq5NVvxsv3b5OuG/BlKlxvxsv3b7JNH3BwAccvxsv3b4PMXDBgllGvxsv3b4uiH3B8e3Gvhsv3b5CI3HBGMchvxsv3b4NK37BRBQ1vhsv3b76QHLBdM/ivhsv3b6AK3/BDYYiPRsv3b7AZnPB1Y2Uvhsv3b6P73/BpGx6Phsv3b53GXXBXmk1vhsv3b4sdIDBXX/ePhsv3b7z/3bBMO6EvBsv3b7LQ4HB17EhPxsv3b7h/HjBCCm8PRsv3b49v4HBdLtKPxsv3b7Ys3vBWDIqPhsv3b4odILB2nJxPxsv3b7zY37BbJORPhsv3b7kfYPBCHCKPxsv3b6stYDBrKWuPhsv3b6WDITB2e2VPxsv3b62a4LB2OvFPhsv3b6PCIXBX9GgPxsv3b5lDoTBxEbvPhsv3b6xlYbB5V6rPxsv3b6Lx4XBX/8EPxsv3b4Vl4fBdnWwPxsv3b4xl4fBxIQKPxsv3b6vwIjB7EW1Pxsv3b5PU4nBriUUPxsv3b7MfIrBcxy6Pxsv3b6wEYvBq2sdPxsv3b73J4zBWWm+Pxsv3b5y3YzBGBMkPxsv3b5Od43B2aWlPxsv3b7Mt47B+DMJQBsv3b6Eh47B3m2mPxsv3b5fepDB+pcJQBsv3b4XSpDB4jWnPxsv3b7yPJLB/PsJQBsv3b6rDJLB/PynPxsv3b7T/JPBaWMKQBsv3b5u45PB0QioPxsv3b42tZXByGIKQBsv3b5P8JXBYRumPxsv3b6lb5fBqFIJQBsv3b4y6JfB9yekPxsv3b5PMZnB9FgIQBsv3b7cqZnBjDSiPxsv3b758prBPl8HQBsv3b6Ga5vBIkGgPxsv3b6jtJzBiWUGQBsv3b4wLZ3BI0mePxsv3b5Re57BAn0FQBsv3b4/yZ7BzrSdPxsv3b7GSaDB0j4FQBsv3b5qLKDBfT2fPxsv3b5yE6LB7/AFQBsv3b6ytaHB4sGgPxsv3b6J1aPBIbMGQBsv3b7Jd6PBR0aiPxsv3b6hl6XBVHUHQBsv3b7hOaXBrMqjPxsv3b64WafBhjcIQBsv3b74+6bBbNO+Pxsv3b5E/KjBdiUlPxsv3b6nqqnBBtXCPxsv3b47rKrBDQcvPxsv3b6KyqvBw+7HPxsv3b63Y6zBY+s5Pxsv3b5noa3B5hLNPxsv3b7lHq7BqTNEPxsv3b6UXK/BCTfSPxsv3b4S2q/B8HtOPxsv3b7CF7HBtFXXPxsv3b5zk7HBPRZZPxsv3b5o4LLBeMbcPxsv3b50P7PBai5nPxsv3b57/LTB6E/lPxsv3b674LTBNMV7Pxsv3b4G/bbBSA7uPxsv3b44jbbB+qCGPxsv3b6DqbjBp8z2Pxsv3b60ObjBWF+PPxsv3b7/VbrBB4v/Pxsv3b4x5rnBuR2YPxsv3b58ArzBRxEEQBsv3b6si7vBdv+hPxsv3b6A473B8zoJQBsv3b6vH73B/vmuPxsv3b574L/BTjkPQBsv3b4Vsb7BBEW8Pxsv3b5Ln8HBVEsVQBsv3b7TR8DBFGnIPxsv3b4KNsPBWV0bQBsv3b6Q3sHBHI3UPxsv3b7HzMTBXm8hQBsv3b5OdcPBIrHgPxsv3b6EY8bBbrYmQBsv3b7E48TBp7n4Pxsv3b5iKMnBX34wQBsv3b6YzcXBCJUQQBsv3b5rT8vBx/s7QBsv3b4KyMbBf1kdQBsv3b6XZszBqJ9HQBsv3b7excfBX/0oQBsv3b5rZM3BiENTQBsv3b6xw8jBSqE0QBsv3b4/Ys7BaedeQBsv3b6EwcnBK0VAQBsv3b4SYM/BOHxqQBsv3b4SvsrBEFpMQBsv3b5oZ9DBXWB1QBsv3b4Eo8vB0MBeQBsv3b4k0tHBVQOBQBsv3b4nFszBw95yQBsv3b4HntLB7saHQBsv3b67k8zBAjOAQBsv3b6cG9PBiIqOQBsv3b5OEc3BnPaGQBsv3b4vmdPBI06VQBsv3b7ijs3BMLqNQBsv3b7CFtTBvRGcQBsv3b52DM7Byn2UQBsv3b5WlNTBVtWiQBsv3b4Kis7BakGbQBsv3b7rEdXB8JipQBsv3b6dB8/BBAWiQBsv3b5+j9XBi1ywQBsv3b4xhc/BmMioQBsv3b4RDdbBBeK2QBsv3b7q/s/BIl6xQBsv3b6Op9bBrpS9QBsv3b6NNNDBsG66QBsv3b6m9dbBeo3EQBsv3b4TZNDB1KvBQBsv3b4UJ9fBUo7LQBsv3b7Tk9DBrKzIQBsv3b7UVtfBKI/SQBsv3b6Tw9DBiq3PQBsv3b6VhtfB/4/ZQBsv3b5S89DBYa7WQBsv3b5UttfB15DgQBsv3b4SI9HBMa/dQBsv3b4T5tfBrpHnQBsv3b7SUtHBCLDkQBsv3b7TFdjBhZLuQBsv3b6SgtHB37DrQBsv3b6TRdjBXJP1QBsv3b5SstHBtrHyQBsv3b5TddjBM5T8QBsv3b4S4tHBlbL5QBsv3b4UpdjBhcoBQRsv3b7REdLBtVkAQRsv3b7T1NjBYjkFQRsv3b7TQNLBz10EQRsv3b4oCtnBMKgIQRsv3b50SdLBToUIQRsv3b4qFtnBlCkMQRsv3b5xSdLBlCkMQRsv3b4+FtnBEq8PQRsv3b5xSdLBEq8PQRsv3b4+FtnBkDQTQRsv3b5xSdLBkDQTQRsv3b4+FtnBDroWQRsv3b5xSdLBDroWQRsv3b4+FtnBjD8aQRsv3b5xSdLBjD8aQRsv3b4+FtnBCsUdQRsv3b5xSdLBCsUdQRsv3b4+FtnBiEohQRsv3b5xSdLBiEohQRsv3b4+FtnBBtAkQRsv3b5xSdLBBtAkQRsv3b4+FtnBhFUoQRsv3b5xSdLBhFUoQRsv3b4+FtnBA9srQRsv3b5xSdLBA9srQRsv3b4+FtnBgWAvQRsv3b5xSdLBgWAvQRsv3b4+FtnB/+UyQRsv3b5xSdLB/+UyQRsv3b4+FtnBfWs2QRsv3b5xSdLBfWs2QRsv3b4+FtnBDPI5QRsv3b5xSdLB++g5QRsv3b49FtnBQnk9QRsv3b7LS9LBbGE9QRsv3b6OGNnBZP9AQRsv3b6fT9LB2uFAQRsv3b5cHNnB2YREQRsv3b5yU9LBU2dEQRsv3b4vINnBTwpIQRsv3b5EV9LByexHQRsv3b4BJNnBxY9LQRsv3b4XW9LBO3JLQRsv3b7UJ9nBOhVPQRsv3b7qXtLBtPdOQRsv3b6nK9nBsJpSQRsv3b68YtLBKn1SQRsv3b55L9nBJyBWQRsv3b6PZtLBnQJWQRsv3b5MM9nBnaVZQRsv3b5iatLBE4hZQRsv3b4fN9nBEStdQRsv3b41btLBiw1dQRsv3b7yOtnBh7BgQRsv3b4HctLBAZNgQRsv3b7EPtnBfDZkQRsv3b7bddLBvRRkQRsv3b6TQtnBpL5nQRsv3b7JetLBtIVnQRsv3b5aR9nBKEZrQRsv3b6jhNLBOvpqQRsv3b4GUdnBb8tuQRsv3b54jtLBfn9uQRsv3b7aWtnBtlByQRsv3b5NmNLByARyQRsv3b6wZNnB/dV1QRsv3b4hotLBD4p1QRsv3b6EbtnBRVt5QRsv3b72q9LBVw95QRsv3b5YeNnBjOB8QRsv3b7KtdLBnpR8QRsv3b4sgtnB6jKAQRsv3b6fv9LB8QyAQRsv3b4BjNnBjfWBQRsv3b50ydLBl8+BQRsv3b7WldnBcrmDQRsv3b5Q09LB0IiDQRsv3b5un9nBWn6FQRsv3b7A4tLB2ziFQRsv3b4qrtnB00GHQRsv3b5v99LBJPKGQRsv3b5pwtnBGQSJQRsv3b4RDNPBarSIQRsv3b4L19nBX8aKQRsv3b6zINPBsHaKQRsv3b6t69nBpYiMQRsv3b5VNdPB9DiMQRsv3b5PANrB7EqOQRsv3b74SdPBO/uNQRsv3b7yFNrBnhCQQRsv3b7KXtPB1qOPQRsv3b4wKNrBedeRQRsv3b7ogtPBSjqRQRsv3b6ZSNrBK5qTQRsv3b7SsNPBr+mSQRsv3b6ndNrBl1qVQRsv3b6F3tPBG6qUQRsv3b5aotrBzQuXQRsv3b48C9TBpNyWQRsv3b5m19rBdKSYQRsv3b7K99PBxp+ZQRsv3b5bstrBMUeaQRsv3b5nkNPB2OSbQRsv3b5XK9rB78SbQRsv3b5APNPBYz+fQRsv3b4SFNnBgKKcQRsv3b6lMdLBTB2iQRsv3b5yONbBKm6dQRsv3b6P9dDBeP6jQRsv3b5/vNLBkFidQRsv3b4uk8/BfRqkQRsv3b7o0M7BWwidQRsv3b6a5s3B1rejQRsv3b51qMzB/3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+/")
+"vertex_count": 2196,
+"vertex_data": PackedByteArray("zGaeQRsv3b6BEqPBRTmmQRsv3b7dhKrBNkSfQRsv3b6dJKLB8yunQRsv3b5igKnBhCOgQRsv3b64NKHBQQuoQRsv3b5+kKjB0gKhQRsv3b7SRKDBkeqoQRsv3b6WoKfBIOKhQRsv3b7sVJ/B38mpQRsv3b6wsKbBbsGiQRsv3b4GZZ7BK6mqQRsv3b7MwKXBvKCjQRsv3b4hdZ3BeYirQRsv3b7m0KTB9n2kQRsv3b59h5zBFH2sQRsv3b7VyaPBrVSlQRsv3b7qlJvBCnCtQRsv3b6pt6LBECymQRsv3b7PnprBm0yuQRsv3b6mu6HB6AOnQRsv3b4uqJnBcSSvQRsv3b4HxaDBwdunQRsv3b6NsZjBTPyvQRsv3b5kzp/BmbOoQRsv3b7rupfBJNSwQRsv3b7C157BToupQRsv3b5zxJbBb62xQRsv3b56353B71+qQRsv3b6v0JXBTaGyQRsv3b5Tx5zBhCyrQRsv3b7U1ZTB84qzQRsv3b5tqZvBrfurQRsv3b7d15PBHFq0QRsv3b52q5rB18qsQRsv3b7l2ZLBRim1QRsv3b5+rZnBAZqtQRsv3b7t25HBcPi1QRsv3b6Gr5jBKmmuQRsv3b723ZDBmce2QRsv3b6PsZfBNDavQRsv3b6j4o/Bjay3QRsv3b6AmJbBRfuvQRsv3b7r4o7BF5O4QRsv3b60bZXBX7+wQRsv3b4k3o3BFGG5QRsv3b7cW5TBW4SxQRsv3b4z2IzBECa6QRsv3b7rVZPBVkmyQRsv3b5C0ovBC+u6QRsv3b76T5LBUg6zQRsv3b5RzIrBB7C7QRsv3b4JSpHB0dCzQRsv3b68yYnBdY68QRsv3b6lIZDBiom0QRsv3b7TwYjBQ2u9QRsv3b7R5o7BukG1QRsv3b5itIfBLCy+QRsv3b6xzI3BsPq1QRsv3b7SpYbBIuW+QRsv3b4hvozBprO2QRsv3b5Bl4XBGJ6/QRsv3b6Qr4vB42u3QRsv3b7BiYTBcV7AQRsv3b4jlorBeR64QRsv3b6pfoPBcTjBQRsv3b4ST4nBcsa4QRsv3b4wa4LByP7BQRsv3b71CojBHnG5QRsv3b5kU4HBdanCQRsv3b4n84bByhu6QRsv3b6XO4DBIVTDQRsv3b5a24XBWca6QRsv3b72R37B+P/DQRsv3b6lwYTBxmy7QRsv3b5+JHzBctDEQRsv3b5waIPB7AK8QRsv3b767XnBU43FQRsv3b6rBoLBhJy8QRsv3b7sqnfB6ybGQRsv3b4k5YDBGza9QRsv3b7fZ3XBgsDGQRsv3b48h3/Bz869QRsv3b40KHPBNmPHQRsv3b6DIX3BAWC+QRsv3b7773DBTh/IQRsv3b4+PXrBVeK+QRsv3b4JpW7B3MDIQRsv3b65anfBb2e/QRsv3b4LTmzB+EXJQRsv3b6yE3XBiey/QRsv3b4L92nBEsvJQRsv3b6yvHLBrG7AQRsv3b71rWfBjm7KQRsv3b4Z12/Bet3AQRsv3b6ZWmXBawXLQRsv3b52s2zBNEnBQRsv3b6H9GLBDHrLQRsv3b5wG2rBubXBQRsv3b4EimDBkebLQRsv3b7tsGfBKyHCQRsv3b7GJV7BIF7MQRsv3b4fBmXBo4PCQRsv3b7tv1vBF9PMQRsv3b4FLmLBCOLCQRsv3b5wUFnBKzjNQRsv3b4Fk1/BBEHDQRsv3b4W3VbBKJfNQRsv3b6jH13BaZ/DQRsv3b6ubVTBLvzNQRsv3b7Mg1rBtffDQRsv3b4+AVLBK2TOQRsv3b4zqFfBuEjEQRsv3b5xjE/BBr7OQRsv3b6H8FTBhJrEQRsv3b6yEU3B0g/PQRsv3b7IdVLBM+zEQRsv3b7fl0rB1GLPQRsv3b6p8U/BmTvFQRsv3b4eJkjBa7/PQRsv3b46FE3Bon/FQRsv3b4FrkXBcg7QQRsv3b5dOkrBpcTFQRsv3b46LUPBdVPQQRsv3b6SuUfBqAnGQRsv3b5wrEDBeJjQQRsv3b7IOEXB/03GQRsv3b4WMj7BXeTQQRsv3b7zdULBgonGQRsv3b4xtzvB2SnRQRsv3b7gkj/B7sHGQRsv3b5iNDnBFmXRQRsv3b6B8DzBmfrGQRsv3b7FrjbBwZ3RQRsv3b7kajrBHjPHQRsv3b7tKjTBANjRQRsv3b4i0zfBsmjHQRsv3b53rTHBtBXSQRsv3b6c8TTB+pTHQRsv3b5EKy/B00fSQRsv3b4iHzLBx8HHQRsv3b7voSzBoHTSQRsv3b7NlS/BlO7HQRsv3b6ZGCrBbaHSQRsv3b53DC3BCxvIQRsv3b5XlCfBrdHSQRsv3b4eTyrBj0DIQRsv3b7oESXB4vzSQRsv3b60bCfBzmHIQRsv3b5KiSLBMCDTQRsv3b4+vSTBOoPIQRsv3b45/R/BnUHTQRsv3b4tMSLBqKTIQRsv3b4ncR3BCmPTQRsv3b4apR/BvcXIQRsv3b5A7BrB9YfTQRsv3b6QzxzBRt3IQRsv3b6zZhjBIqPTQRsv3b5B7hnBzPPIQRsv3b6/2RXBC7rTQRsv3b5AVhfBWQrJQRsv3b7RSxPBmNDTQRsv3b5KyBTB4iDJQRsv3b4+vhDBRefTQRsv3b6yNhLBuTbJQRsv3b4IOA7Bv//TQRsv3b4HWQ/BvULJQRsv3b5rsAvBoQ3UQRsv3b7pfQzB607JQRsv3b5hIQnBzxnUQRsv3b7o7gnBGlvJQRsv3b5ZkgbB/iXUQRsv3b7gXwfBRWfJQRsv3b7ZAwTBRTLUQRsv3b5ZywTBp3LJQRsv3b6zegHBpz7UQRsv3b6T/wHB4nbJQRsv3b5R4f3AckPUQRsv3b7Zcf7AK3vJQRsv3b5zwvjAu0fUQRsv3b4LU/nAdH/JQRsv3b6Xo/PABEzUQRsv3b4fNPTAuoPJQRsv3b6zh+7AY1DUQRsv3b7S9u7ABYbJQRsv3b4zdenAz1LUQRsv3b4xWenAEoLJQRsv3b65X+TAq07UQRsv3b7w2ePAG37JQRsv3b7YQN/AtErUQRsv3b4Pu97AJHrJQRsv3b74IdrAvUbUQRsv3b4vnNnAM3bJQRsv3b5zCdXAhkLUQRsv3b4jPNTAFG7JQRsv3b7l98/AfTnUQRsv3b51mc7AkmHJQRsv3b5w4MrAVizUQRsv3b5WOMnAAFXJQRsv3b5twsXAxB/UQRsv3b5TGsTAb0jJQRsv3b5rpMDAMxPUQRsv3b5R/L7A/TvJQRsv3b7HkbvAVwXUQRsv3b7FabnACSjJQRsv3b7LgrbAPe/TQRsv3b6Aw7PAhxLJQRsv3b68aLHAWtnTQRsv3b4Akq7A/vzIQRsv3b6XTKzA0sPTQRsv3b7rdanAh+fIQRsv3b6RNKfAka3TQRsv3b6WL6TAhc/IQRsv3b5MJ6LAhZLTQRsv3b7lhJ7A4bDIQRsv3b4EGJ3AZXHTQRsv3b6VBpnABJLIQRsv3b7f/pfAiFLTQRsv3b5w7ZPAJ3PIQRsv3b675ZLAqjPTQRsv3b471I7AmFTIQRsv3b692I3AqBHTQRsv3b58PonADC7IQRsv3b6p0YjAbubSQRsv3b4NlIPAkQXIQRsv3b4nv4PAHr3SQRsv3b5EzXzAAt3HQRsv3b6DVH3Aj5TSQRsv3b54o3LArrTHQRsv3b7GOHPAsWnSQRsv3b6Q6WfA+IfHQRsv3b5gMmnADTfSQRsv3b4dkFzArFXHQRsv3b7uI1/AUgHSQRsv3b78zFHAEiPHQRsv3b5sBVXAuM7RQRsv3b56rkfAlfDGQRsv3b6Y7ErA+JrRQRsv3b61VT3AvrzGQRsv3b7k70DAyF/RQRsv3b4Q+jHAVYDGQRsv3b43+TbA1BzRQRsv3b7o5CbAVkPGQRsv3b4W6SzA1d/QQRsv3b6m1BzAVwbGQRsv3b7u2CLA1qLQQRsv3b6fxBLAWMnFQRsv3b64yBjA3WXQQRsv3b4ztQjAX4zFQRsv3b58uA7A5yjQQRsv3b5CS/2/Zk/FQRsv3b5OqATA7uvPQRsv3b7mKum/bRLFQRsv3b4wMPW/+K7PQRsv3b5CC9W/dtXEQRsv3b6lD+G/ltvOQRsv3b4qtMK/hJjEQRsv3b4W78y/NPfNQRsv3b7oj7C/k1vEQRsv3b6Zzri/zxLNQRsv3b7kap6/oh7EQRsv3b7oraS/cC7MQRsv3b46R4y/uuHDQRsv3b4gjZC/GUrLQRsv3b7oRXS/06TDQRsv3b602Hi/wGXKQRsv3b7I/E+/82fDQRsv3b6fllC/c4HJQRsv3b6vtCu/GyvDQRsv3b5CVCi/K53IQRsv3b7Kawe/Te7CQRsv3b5JEQC/8LjHQRsv3b4MRsa+jLHCQRsv3b4Sma++x9TGQRsv3b7Uc3u+YHTCQRsv3b7jgDy+U/LFQRsv3b5lNN29ND3CQRsv3b7gxC06bx3FQRsv3b5s1Je81ZzCQRsv3b5opzo+qALGQRsv3b4+S2c9dwLDQRsv3b5ErKw+kQTHQRsv3b4BwjQ+u2bDQRsv3b4wt/o+5wrIQRsv3b4+Pps+GsvDQRsv3b75XSQ/ZRHJQRsv3b6BH9w+hy/EQRsv3b7GXks/+RfKQRsv3b5ngQ4/AJTEQRsv3b7SXnI/lx7LQRsv3b4h8i4/gvjEQRsv3b6brow/UyXMQRsv3b4vaU8/6VzFQRsv3b6NK6A/YizNQRsv3b66BnA/6MDFQRsv3b6fqLM/cTPOQRsv3b57Zog/iiTGQRsv3b4wJ8c/UDrPQRsv3b4m1Jg/t4fGQRsv3b4tpto/OUHQQRsv3b4pW6k/LerGQRsv3b6VJO4/JTjRQRsv3b78Z7o/a0vHQRsv3b5D0ABAVp3RQRsv3b4Sr84/HqrHQRsv3b7kggpAsgbSQRsv3b5sSuQ/zgDIQRsv3b5KFBRAiHnSQRsv3b6h3v0/9ETIQRsv3b7Qpx1AYN/SQRsv3b7TPA1AAnjIQRsv3b6JUidAMyzTQRsv3b700RtAVJjIQRsv3b6ZCjFA4V3TQRsv3b6kySpAP6XIQRsv3b6xyTpA7nHTQRsv3b77/DlAIp7IQRsv3b54hkRAnmbTQRsv3b5hWUlAhILIQRsv3b6mNk5AhDrTQRsv3b6lylhA+lHIQRsv3b6F0VdADO3SQRsv3b6nIWhABA3IQRsv3b4DT2FAon/SQRsv3b4UMndALLTHQRsv3b7SpWpA5/PRQRsv3b5j8oJAV0jHQRsv3b5LzXNAukvRQRsv3b5dFopAEcrGQRsv3b4nv3xAO4rQQRsv3b7e8pBA/jrGQRsv3b5cvIJAj7PPQRsv3b5jf5dAWZzFQRsv3b6C+YZAssjOQRsv3b53xp1AduzEQRsv3b4OJItALObNQRsv3b4IK6NAnzXEQRsv3b6eWI9AZCDNQRsv3b73t6dAkXzDQRsv3b6bjZNAxGDMQRsv3b46E6xAdcLCQRsv3b7lwZdA86LLQRsv3b78XLBAwAfCQRsv3b6Y9ZtA8OXKQRsv3b7wnbRAsEzBQRsv3b6rKKBACynKQRsv3b6Q27hATJHAQRsv3b7zWqRA+mvJQRsv3b50F71AmdW/QRsv3b7YjKhAO6/IQRsv3b5YT8FAshy/QRsv3b5ErqxAstTHQRsv3b7iLMZADlm+QRsv3b4fr7BA6uzGQRsv3b4I78pA/JO9QRsv3b5Gs7RAPQ3GQRsv3b4OfM9Amce8QRsv3b5En7hAaCTFQRsv3b6c9dNAFfm7QRsv3b5EjrxAq0bEQRsv3b54LthA0ye7QRsv3b68bsBAqF7DQRsv3b7yetxAglK6QRsv3b5HSsRAmH7CQRsv3b6OiOBAsn25QRsv3b6VI8hAYZnBQRsv3b4YreRAqKS4QRsv3b5r7MtAkq3AQRsv3b5iyuhAjsm3QRsv3b7Suc9ARNC/QRsv3b6VoexAje+2QRsv3b5pgtNAvue+QRsv3b4uqvBA3hG2QRsv3b7PPNdAavq9QRsv3b5tqPRAoTK1QRsv3b7v+9pAMBq9QRsv3b7La/hAHFS0QRsv3b77t95AkTK8QRsv3b7DTvxAqHOzQRsv3b7ZaeJA6US7QRsv3b42HABBYZGyQRsv3b5ZG+ZAk166QRsv3b5z/QFB5a6xQRsv3b63zelAYnq5QRsv3b402gNB1sywQRsv3b7weu1AEo24QRsv3b4kyAVBSuivQRsv3b7CH/FA8J63QRsv3b43rgdB5AKvQRsv3b4SyPRAjLm2QRsv3b5cgglBxB2uQRsv3b5Ib/hAYtG1QRsv3b4pXAtBgTitQRsv3b4vEfxAW+K0QRsv3b7fQA1BXVGsQRsv3b7Xrf9AffSzQRsv3b60HA9BoWmrQRsv3b5zpgFBxAyzQRsv3b427BBBV4KqQRsv3b4YdQNBeSCyQRsv3b7WxBJBA5ypQRsv3b4rPQVBLh2xQRsv3b64xRRBu6+oQRsv3b7K+gZBrRiwQRsv3b6WsRZBTMGnQRsv3b6GvAhBPyqvQRsv3b5QcxhBYNOmQRsv3b5LfQpBjDauQRsv3b7yPhpBhualQRsv3b7/NgxBpimtQRsv3b7NMxxBevOkQRsv3b475Q1BDBysQRsv3b6rER5BEv6jQRsv3b60lw9BpCarQRsv3b4kxB9BswmjQRsv3b5YSBFBmSaqQRsv3b5ViSFBDhWiQRsv3b7H7xJBZw6pQRsv3b7wbSNBkBqhQRsv3b7GjRRB2funQRsv3b4qNCVB7R2gQRsv3b5YLxZBNv+mQRsv3b681SZBciOfQRsv3b5mzRdBheylQRsv3b5YmyhBtSWeQRsv3b7NXRlBOsekQRsv3b50aipB+SKdQRsv3b6Q6hpBTbWjQRsv3b6uDixBCx+cQRsv3b4seRxBl6+iQRsv3b4FoC1BgR6bQRsv3b5fAR5BmIOhQRsv3b5naS9BiRaaQRsv3b4Sdh9BYVGgQRsv3b74GjFB0QqZQRsv3b4v8CBBqkWfQRsv3b4UlTJBnwGYQRsv3b7HZiJBGyCeQRsv3b4zMzRBoPWWQRsv3b6DzSNBoOOcQRsv3b4d2zVB7+OVQRsv3b5aLiVB8L2bQRsv3b75VTdBttGUQRsv3b7pjyZBtp2aQRsv3b54yThB7cCTQRsv3b505idBlFeZQRsv3b4xYjpBNamSQRsv3b4LLClBLhiYQRsv3b7g1jtBPo6RQRsv3b5+dSpBCPqWQRsv3b4HJD1By3eQQRsv3b7ZtytB6qiVQRsv3b6WqD5B2FmPQRsv3b5R4CxBzFKUQRsv3b74DEBB6DaOQRsv3b4dDi5B3S+TQRsv3b7COkFB3hONQRsv3b4DPC9B7g2SQRsv3b6DZ0JB9/CLQRsv3b5xajBBMeyQQRsv3b66lENBIs6KQRsv3b7SmDFBt8mPQRsv3b6+wkRBPquJQRsv3b5yxzJBUqiOQRsv3b7Q70VBhoiIQRsv3b6e9jNBzIaNQRsv3b68HUdBxmWHQRsv3b7SJTVBpWWMQRsv3b5ES0hBLkOGQRsv3b7TVTZBD0WLQRsv3b4seUlBmCCFQRsv3b4QhjdB/CSKQRsv3b7IpkpBOv6DQRsv3b5atzhBnQWJQRsv3b7s1EtBy9uCQRsv3b4/6TlBKeiHQRsv3b6PAU1BhLmBQRsv3b53HTtB5s6GQRsv3b40LE5BEZeAQRsv3b7iVDxBaL6FQRsv3b5LUE9B5N9+QRsv3b7FmT1BvfCEQRsv3b6uL1BBiZ18QRsv3b6VCT9BH16EQRsv3b6r6lBBJXJ6QRsv3b5FmkBBys6DQRsv3b4uuVFB7l54QRsv3b6UTUJBwU2DQRsv3b4hjFJB1Wh2QRsv3b77I0RBytiCQRsv3b5EZ1NBo5J0QRsv3b5NG0ZB+W2CQRsv3b6RS1RBG+ByQRsv3b6LMkhBiw2CQRsv3b4qOVVBqlNxQRsv3b58ZkpBU7WBQRsv3b4nNFZBU+9vQRsv3b40tExBKGWBQRsv3b66PVdBRbRuQRsv3b6+F09BqRuBQRsv3b6kW1hB16FtQRsv3b53jVFBZNmAQRsv3b4CjFlBhbhsQRsv3b75EVRBe56AQRsv3b6n0lpBlPVrQRsv3b6colZBQGyAQRsv3b4yJFxBll1rQRsv3b77M1lB2zmAQRsv3b6g4l1BvNNqQRsv3b5PultBqfZ/QRsv3b7FLWBB6E1qQRsv3b74PV5BSHV/QRsv3b4WnGJB/MlpQRsv3b5nwWBBYfR+QRsv3b7PEGVB4EdpQRsv3b6zRGNBI3R+QRsv3b7kimdBTcZoQRsv3b7Mx2VBvvN9QRsv3b4fCGpBp0VoQRsv3b4IS2hBLHR9QRsv3b74hWxBY8VnQRsv3b46zmpBuvR8QRsv3b4MBW9BwEVnQRsv3b52UW1BunV8QRsv3b4ZhXFBQsZmQRsv3b671G9B3/Z7QRsv3b4kBXRBZkdmQRsv3b4RWHJBiXh7QRsv3b7ThXZBl8hlQRsv3b4s23RBuvl6QRsv3b7uCHlBx0llQRsv3b5FXndB6Hp6QRsv3b4PjHtB9spkQRsv3b5g4XlBF/x5QRsv3b4uD35BJUxkQRsv3b56ZHxBRX15QRsv3b4kSYBBVM1jQRsv3b6U535BdP54QRsv3b6zioFBgk5jQRsv3b5XtYBBoX94QRsv3b5CzIJBsc9iQRsv3b7j9oFBzAB4QRsv3b7WDYRB21BiQRsv3b5vOINB8YF3QRsv3b5vT4VBRtRhQRsv3b6RdIRB7Ot2QRsv3b5zyIZBBVxhQRsv3b7SfYVBjPR0QRsv3b7kCIpB7QpgQRsv3b7DXYZBR4NxQRsv3b6xt4xBcYleQRsv3b7UZodBrQFwQRsv3b7WwI1B8gddQRsv3b7mb4hBJYBuQRsv3b7uyY5BcIZbQRsv3b74eIlBn/5sQRsv3b4C049B7gRaQRsv3b4JgopBGn1rQRsv3b4W3JBBbINYQRsv3b4ai4tBl/tpQRsv3b4o5ZFB6gFXQRsv3b4slIxBEnpoQRsv3b487pJBZ4BVQRsv3b49nY1Bj/hmQRsv3b5N95NB5P5TQRsv3b5Ppo5BCndlQRsv3b5gAJVBYH1SQRsv3b5gr49Bg/VjQRsv3b5zCZZB3ftQQRsv3b5xuJBBAHRiQRsv3b6EEpdBWXpPQRsv3b6CwZFBfPJgQRsv3b6VG5hB1vhNQRsv3b6TypJB+XBfQRsv3b6mJJlBb3xMQRsv3b4w0JNBC7tdQRsv3b4ZUZpBKfJKQRsv3b48zJRBqMdbQRsv3b6hkJtByFRJQRsv3b5QxpVBOftZQRsv3b6Rp5xBM7RHQRsv3b5bwpZBkE9YQRsv3b5Kqp1BNBhGQRsv3b6SuJdBE1JWQRsv3b6H2Z5BvWNEQRsv3b4hpZhBz0RUQRsv3b5o959BYadCQRsv3b4RlplBdYhSQRsv3b5X6KBBfu5AQRsv3b4lhZpBh6hQQRsv3b5f7KFBgzA/QRsv3b4lbZtB+o5OQRsv3b7aA6NBXmI9QRsv3b7fUJxBC4xMQRsv3b7zAaRBiI87QRsv3b7xNp1BNblKQRsv3b4F6KRBfcA5QRsv3b4qG55Bhr9IQRsv3b4H4aVBeus3QRsv3b6M+J5B7ZVGQRsv3b5d5qZBawk2QRsv3b7k0p9B8olEQRsv3b7k06dBoyM0QRsv3b7vrqBBJ6RCQRsv3b7wr6hBKkAyQRsv3b7viaFBrqZAQRsv3b6llqlB0FswQRsv3b7VX6JB2nQ+QRsv3b6MjqpBk2ouQRsv3b60MKNBvU88QRsv3b59datBuHQsQRsv3b6KA6RB4lk6QRsv3b5TSKxB3n4qQRsv3b5g1qRBCGQ4QRsv3b4pG61BvI4oQRsv3b7YpqVBhjM2QRsv3b5CBq5BwpImQRsv3b5yb6ZB9e8zQRsv3b6J665BxI8kQRsv3b6eOadBjOYxQRsv3b46uK9BM4wiQRsv3b4EBKhBAeMvQRsv3b6egrBB6IkgQRsv3b7rzahBbdItQRsv3b4cUrFBhIkeQRsv3b5ilKlBCJErQRsv3b6KMbJBun4cQRsv3b5bVapBJFMpQRsv3b6aBbNBZW8aQRsv3b4HGKtBz0MnQRsv3b5GyLNBEWAYQRsv3b6y2qtBdTQlQRsv3b7zirRBIVIWQRsv3b7anKxB1BYjQRsv3b7gUrVBZkUUQRsv3b66W61Bfs4gQRsv3b5LJ7ZB0y8SQRsv3b7uFa5BwoweQRsv3b4S8bZBUxYQQRsv3b6F0a5BQnMcQRsv3b6prLdB0/wNQRsv3b4bja9BwlkaQRsv3b4/aLhBVOMLQRsv3b6ySLBBOUAYQRsv3b7ZI7lB6skJQRsv3b4+BLFBwiUWQRsv3b7D37lBVLAHQRsv3b6uv7FBMAsUQRsv3b6Lm7pBqJYFQRsv3b4le7JBhPERQRsv3b4CV7tB/HwDQRsv3b6cNrNB2dcPQRsv3b54ErxBX2MBQRsv3b4O8rNBor0NQRsv3b4gzrxBcZP+QBsv3b5orbRBmaILQRsv3b72ib1ByV/6QBsv3b6vaLVB/YcJQRsv3b6CRb5B/Cv2QBsv3b78I7ZBHG4HQRsv3b7NAL9BWvjxQBsv3b5C37ZBX1MFQRsv3b5mvL9BlsTtQBsv3b5kmrdBlTcDQRsv3b4yeMBBVpDpQBsv3b5xVbhBfxwBQRsv3b6UM8FB/lvlQBsv3b6BELlByQP+QBsv3b7L7sFB7SfhQBsv3b5yy7lBFMr5QBsv3b62qsJBAfPcQBsv3b4dhrpBapD1QBsv3b40ZsNBBr7YQBsv3b7MQLtBVVfxQBsv3b6ZIcRBzIjUQBsv3b4p+7tBJBntQBsv3b6C3cRBA1PQQBsv3b4ytbxBv9foQBsv3b6NmcVBmhzMQBsv3b7Abr1BSpDkQBsv3b4JVsZBsu3HQBsv3b4lJr5BNOnfQBsv3b7FIcdBQvPDQBsv3b6xzL5BOWrYQBsv3b6VT8hBSdm/QBsv3b70Pr9Bx7DNQBsv3b7+eclBsYq7QBsv3b4ig79B2PjBQBsv3b4iMcpByvG2QBsv3b4Mk79Br7W3QBsv3b5qX8pBvfmxQBsv3b4DjL9BKQuxQBsv3b4rWMpBxdysQBsv3b7whL9BFNurQBsv3b78UMpB2r+nQBsv3b7CfL9BpaumQBsv3b6ySMpBSaGiQBsv3b6TdL9BFI2hQBsv3b6DQMpBuoKdQBsv3b5jbL9Bc26cQBsv3b5TOMpBamSYQBsv3b4zZL9BTk2XQBsv3b4fMMpBdUaTQBsv3b7ZW79BsSiSQBsv3b66J8pBRiiOQBsv3b5FU79BrwaNQBsv3b4fH8pBwAmJQBsv3b6wSr9BKeiHQBsv3b6KFspBOuuDQBsv3b4bQr9Bo8mCQBsv3b71DcpBYpl9QBsv3b6GOb9BV1Z7QBsv3b5gBcpBVlxzQBsv3b7yML9BSxlxQBsv3b7M/MlBsB9pQBsv3b5dKL9BKthmQBsv3b409MlBQ+NeQBsv3b6oH79BBJVcQBsv3b5568lBd6ZUQBsv3b7gFr9B2VVSQBsv3b6v4slBdWlKQBsv3b4YDr9B1xhIQBsv3b7n2clBdyxAQBsv3b5QBb9Bt9s9QBsv3b4f0clBde81QBsv3b6H/L5BtZ4zQBsv3b5WyMlBcbIrQBsv3b6/875B02EpQBsv3b6Ov8lBb3UhQBsv3b736r5B0SQfQBsv3b7GtslBbTgXQBsv3b4v4r5Bz+cUQBsv3b7+rclBp/sMQBsv3b5n2b5BZqgKQBsv3b40pclBB78CQBsv3b6M0L5BsGcAQBsv3b5UnMlBYQTxPxsv3b6lx75BiFLsPxsv3b5sk8lBa4rcPxsv3b69vr5BktjXPxsv3b6EislBdRDIPxsv3b7Wtb5BnF7DPxsv3b6dgclBf5azPxsv3b7urL5BpuSuPxsv3b61eMlBiRyfPxsv3b4HpL5BsGqaPxsv3b7Ob8lBlKKKPxsv3b4fm75Bu/CFPxsv3b7mZslBL1FsPxsv3b44kr5BBe5iPxsv3b7/XclBT11DPxsv3b5Rib5Bnvk5Pxsv3b4YVclBY2kaPxsv3b5pgL5BsQURPxsv3b4wTMlBs+viPhsv3b6Cd75B4BvQPhsv3b5IQ8lB3wWRPhsv3b6Sbr5Bzj98Phsv3b5WOslBjH38PRsv3b6WZb5B166wPRsv3b5ZMclBe0IWvRsv3b6ZXL5B8++WvRsv3b5cKMlBN2BJvhsv3b6dU75BdkVvvhsv3b5gH8lBtZe2vhsv3b6hSr5BY4vJvhsv3b5kFslBtT8Evxsv3b6kQb5Bi7kNvxsv3b5nDclBmzMtvxsv3b6oOL5B66w2vxsv3b5rBMlBcydWvxsv3b6sL75Bw6Bfvxsv3b5v+8hBQRt/vxsv3b6wJr5BjEqEvxsv3b5z8shBjQeUvxsv3b6zHb5BecSYvxsv3b526chBf4Govxsv3b63FL5BJz6tvxsv3b564MhBZ/u8vxsv3b67C75BU7jBvxsv3b5+18hBU3XRvxsv3b6+Ar5BPzLWvxsv3b6BzshB7e7lvxsv3b7C+b1Biq/qvxsv3b6DxchBeGj6vxsv3b638L1BCS3/vxsv3b53vMhBMHEHwBsv3b6s571BeNMJwBsv3b5ss8hBIK4RwBsv3b6h3r1BihAUwBsv3b5hqshBE+sbwBsv3b6V1b1BfU0ewBsv3b5VochBCSgmwBsv3b6KzL1BUYoowBsv3b5KmMhB+WQwwBsv3b5/w71BY8cywBsv3b4/j8hB7KE6wBsv3b5zur1BVgQ9wBsv3b4zhshB495EwBsv3b5osb1BK0FHwBsv3b4ofchB0htPwBsv3b5dqL1BPH5RwBsv3b4ddMhBxVhZwBsv3b5Rn71BL7tbwBsv3b4Ra8hBuJVjwBsv3b5Glr1BIvhlwBsv3b4GYshBrNJtwBsv3b46jb1BFjVwwBsv3b76WMhBog94wBsv3b4vhL1B6nF6wBsv3b7vT8hBSSaBwBsv3b4ke71BfleCwBsv3b7kRshBvUSGwBsv3b4Ycr1BJXaHwBsv3b7XPchBJ2OLwBsv3b4Lab1BSJWMwBsv3b7INMhBkYGQwBsv3b70X71BSrSRwBsv3b6wK8hBC6CVwBsv3b7dVr1Bs9KWwBsv3b6ZIshBg76awBsv3b7HTb1BK/GbwBsv3b6DGchB/NyfwBsv3b6wRL1BpA+hwBsv3b5sEMhBdPukwBsv3b6aO71BHC6mwBsv3b5WB8hB6hmqwBsv3b6DMr1Bo0yrwBsv3b4//sdBZDivwBsv3b5sKb1BDGuwwBsv3b4o9cdB3Va0wBsv3b5WIL1BhYm1wBsv3b4S7MdBVXW5wBsv3b4/F71B/ae6wBsv3b774sdBzZO+wBsv3b4pDr1Bdca/wBsv3b7l2cdBRLLDwBsv3b4SBb1B/eTEwBsv3b7O0MdBvtDIwBsv3b77+7xBZgPKwBsv3b63x8dBNu/NwBsv3b7l8rxB3iHPwBsv3b6hvsdBrA3TwBsv3b7O6bxBZUDUwBsv3b6KtcdBJyzYwBsv3b634LxBz17ZwBsv3b5zrMdBn0rdwBsv3b6h17xBR33ewBsv3b5do8dBDWniwBsv3b6KzrxBLJzjwBsv3b5GmsdBbIfnwBsv3b5txbxBmbvowBsv3b4nkcdB1qXswBsv3b5GvLxBmtrtwBsv3b7/h8dBTMTxwBsv3b4gs7xBEPnywBsv3b7ZfsdBweL2wBsv3b75qbxBlhf4wBsv3b6ydcdBOQH8wBsv3b7SoLxB/TX9wBsv3b6LbMdB2I8AwRsv3b6sl7xBOioBwRsv3b5lY8dBEx8DwRsv3b6FjrxBdbkDwRsv3b4+WsdBTq4FwRsv3b5fhbxBsEgGwRsv3b4YUcdBij0IwRsv3b44fLxB7NcIwRsv3b7xR8dBxcwKwRsv3b4Sc7xBJ2cLwRsv3b7LPsdBAFwNwRsv3b7rabxBYvYNwRsv3b6kNcdBO+sPwRsv3b7FYLxBnYUQwRsv3b5+LMdBdnoSwRsv3b6eV7xB4RQTwRsv3b5XI8dBsgkVwRsv3b53TrxBFKQVwRsv3b4wGsdB7ZgXwRsv3b5RRbxBTzMYwRsv3b4KEcdBHSgawRsv3b4qPLxBBsMawRsv3b7hB8dBR7ccwRsv3b70MrxB4VIdwRsv3b6p/sZBfUYfwRsv3b64KbxBSeIfwRsv3b5s9cZBt9UhwRsv3b58ILxBg3EiwRsv3b4w7MZB8WQkwRsv3b5AF7xBtgAlwRsv3b704sZBK/QmwRsv3b4FDrxB8I8nwRsv3b652cZBZYMpwRsv3b7JBLxBMR8qwRsv3b590MZBnxIswRsv3b6N+7tBZK4swRsv3b5Bx8ZB2aEuwRsv3b5S8rtBnj0vwRsv3b4GvsZBEzExwRsv3b4W6btB38wxwRsv3b7KtMZBTcAzwRsv3b7a37tBGVw0wRsv3b6Oq8ZBh082wRsv3b6e1rtBTOs2wRsv3b5SosZBwt44wRsv3b5jzbtBh3o5wRsv3b4XmcZB9W07wRsv3b4oxLtBBQo8wRsv3b7aj8ZBGf09wRsv3b7kurtBHpo+wRsv3b6ThsZBQoxAwRsv3b6LsbtB+ClBwRsv3b44fcZBehtDwRsv3b4yqLtBMLlDwRsv3b7fc8ZBs6pFwRsv3b7ZnrtBaUhGwRsv3b6GasZB6zlIwRsv3b6AlbtBoddIwRsv3b4tYcZBI8lKwRsv3b4njLtB2WZLwRsv3b7UV8ZBXFhNwRsv3b7OgrtBEvZNwRsv3b57TsZBlOdPwRsv3b51ebtBSoVQwRsv3b4iRcZBzXZSwRsv3b4ccLtBgxRTwRsv3b7JO8ZBBQZVwRsv3b7DZrtBu6NVwRsv3b5wMsZBPZVXwRsv3b5qXbtB8zJYwRsv3b4XKcZBVSRawRsv3b4SVLtBfsNawRsv3b65H8ZBarNcwRsv3b6NSrtBB1RdwRsv3b4vFsZBoEJfwRsv3b4IQbtBNONfwRsv3b6qDMZB1tFhwRsv3b6EN7tBanJiwRsv3b4mA8ZBDGFkwRsv3b7/LbtBoAFlwRsv3b6h+cVBQvBmwRsv3b57JLtB1pBnwRsv3b4d8MVBeH9pwRsv3b72GrtBDCBqwRsv3b6Y5sVBrg5swRsv3b5yEbtBQq9swRsv3b4U3cVB5J1uwRsv3b7tB7tBeD5vwRsv3b6P08VB6CxxwRsv3b5q/rpBqc9xwRsv3b4EysVB5btzwRsv3b6j9LpB/WB0wRsv3b41wMVBEkt2wRsv3b7Z6rpBVPB2wRsv3b5ptsVBRNp4wRsv3b4N4bpBjn95wRsv3b6drMVBdml7wRsv3b5B17pBwA58wRsv3b7RosVBp/h9wRsv3b51zbpB8Z1+wRsv3b4FmcVB60OAwRsv3b6pw7pBnZaAwRsv3b45j8VBUIuBwRsv3b7bubpBSOCBwRsv3b5ahcVBstKCwRsv3b6Hr7pB3ymDwRsv3b70esVBSBqEwRsv3b4ypbpBcHGEwRsv3b6fcMVB3WGFwRsv3b7dmrpBBrmFwRsv3b5KZsVBQamGwRsv3b6JkLpBfgKHwRsv3b7lW8VBRPCHwRsv3b67hbpBw0+IwRsv3b7iUMVBbTeJwRsv3b7tebpBG5uJwRsv3b7uRMVBKHaKwRsv3b6WbrpBxTyLwRsv3b4+NMVB4qmLwRsv3b5STbpBBjqNwRsv3b4D/cRBTdqMwRsv3b4NFbpBvjKPwRsv3b7dn8RBEQaOwRsv3b7ixrlBGiGRwRsv3b7oHsRB1yqPwRsv3b4wY7lBewmTwRsv3b5reMNBtEaQwRsv3b6d6bhBSuiUwRsv3b5Rq8JBcliRwRsv3b6AWrhBIbWWwRsv3b54usFBvV6SwRsv3b4Dt7dB1WyYwRsv3b5nqMBBa1iTwRsv3b7N/7ZBvgmawRsv3b6+eb9BPEWUwRsv3b7ONrZB7IibwRsv3b6yNL5BuSKVwRsv3b5eX7VBg/ycwRsv3b4EyrxBQ/KVwRsv3b75b7RBWx6ewRsv3b6If7tBVMeWwRsv3b4weLNBYvqewRsv3b6of7pB/5uXwRsv3b5bf7JBEtKfwRsv3b5Ng7lBnHCYwRsv3b5rhrFBY6mgwRsv3b4vh7hBlESZwRsv3b7hjLBBvX+hwRsv3b7airdBxRiawRsv3b4Yk69B61OiwRsv3b4TkbZB4+yawRsv3b5kma5B0SijwRsv3b50lrVBusCbwRsv3b6Sn61BGP6jwRsv3b7xmrRBdJScwRsv3b6EpaxBetKkwRsv3b4coLNBPWidwRsv3b5kq6tBQ6alwRsv3b78pbJBBjyewRsv3b5EsapBDnqmwRsv3b7aq7FBvg+fwRsv3b44t6lBiU6nwRsv3b7nsLBBO+OfwRsv3b4CvahB6yKowRsv3b6jta9BwragwRsv3b6uwqdBkvaowRsv3b4pu65BS4qhwRsv3b5YyKZBGcqpwRsv3b7VwK1B1F2iwRsv3b4CzqVBpJ2qwRsv3b59xqxBWzGjwRsv3b6t06RBPXGrwRsv3b4TzKtB0QSkwRsv3b5j2aNBTEWswRsv3b4U0apBI9ikwRsv3b733qJBKBmtwRsv3b4D1qlBgKulwRsv3b585KFBh+ytwRsv3b6G26hB3X6mwRsv3b4B6qBB4r+uwRsv3b4N4adBO1KnwRsv3b6G759BQJOvwRsv3b6S5qZBmCWowRsv3b4L9Z5Bn2awwRsv3b4V7KVB8/iowRsv3b6S+p1BFjqxwRsv3b588aRBP8ypwRsv3b4dAJ1B0Q2ywRsv3b6C9qNBdZ+qwRsv3b6QBZxBXOGywRsv3b6R+6JBs3KrwRsv3b76CptBmrSzwRsv3b77AKJB8UWswRsv3b5kEJpB2Ie0wRsv3b5kBqFBLhmtwRsv3b7PFZlBFVu1wRsv3b7PC6BBbOytwRsv3b45G5hBUy62wRsv3b46EZ9Bqr+uwRsv3b6jIJdBkQG3wRsv3b6kFp5B5pKvwRsv3b4PJpZB6NS3wRsv3b7wG51BFGawwRsv3b58K5VBa6i4wRsv3b74IJxBNTmxwRsv3b7YMJRBxnu5wRsv3b4QJptBWwyywRsv3b4vNpNB7U66wRsv3b5kK5pBgN+ywRsv3b6FO5JBEiK7wRsv3b66MJlBprKzwRsv3b7aQJFBN/W7wRsv3b4SNphBzIW0wRsv3b4wRpBBXci8wRsv3b5oO5dB8li1wRsv3b6HS49BhJu9wRsv3b68QJZBFyy2wRsv3b7dUI5BqW6+wRsv3b4SRpVBOv+2wRsv3b41Vo1B6EG/wRsv3b5LS5RBT9K3wRsv3b6QW4xBZxXAwRsv3b4nUJNBUKW4wRsv3b7VYItBtejAwRsv3b4QVZJBWHi5wRsv3b4SZopBvbvBwRsv3b5NWpFBYEu6wRsv3b5Pa4lBxY7CwRsv3b6KX5BBaB67wRsv3b6McIhBzmHDwRsv3b7FZI9BcPG7wRsv3b7IdYdB2DTEwRsv3b7/aY5Bd8S8wRsv3b4Fe4ZB3gfFwRsv3b4+b41Be5e9wRsv3b5GgIVBDNvFwRsv3b5OdIxBa2q+wRsv3b6HhYRBiK7GwRsv3b7neItBQj2/wRsv3b6uioNBwoHHwRsv3b6YfYpBIhDAwRsv3b7Jj4JBoFTIwRsv3b62golBA+PAwRsv3b7llIFBgSfJwRsv3b7Sh4hB47XBwRsv3b4AmoBBY/rJwRsv3b7qjIdBw4jCwRsv3b43Pn9BQs3KwRsv3b4HkoZBm1vDwRsv3b6BSH1BdaDLwRsv3b7BloVBUS7EwRsv3b62UntB63PMwRsv3b72moRB8gDFwRsv3b6nXHlB8kbNwRsv3b51n4NBnNPFwRsv3b6DZndBnhnOwRsv3b5hpIJBRabGwRsv3b5ecHVBR+zOwRsv3b5OqYFB73jHwRsv3b46enNB777PwRsv3b4+roBBhkvIwRsv3b5AhHFBVJLQwRsv3b6ZZH9B3R3JwRsv3b73jW9ByGXRwRsv3b6na31BL/DJwRsv3b5dl21BajjSwRsv3b5OdHtBiMLKwRsv3b6yoGtBwQrTwRsv3b6mfXlB35TLwRsv3b4MqmlBON3TwRsv3b61hndBBmfMwRsv3b60s2dBLLHUwRsv3b4QjHVBtzjNwRsv3b6KvGVBh4TVwRsv3b7nkHNBjgrOwRsv3b4FxWNBXlbWwRsv3b5imXFBPtzOwRsv3b7fzWFByynXwRsv3b4Onm9BSa3PwRsv3b5A1l9BN/7XwRsv3b5Lnm1B+H3QwRsv3b6X3V1BDNHYwRsv3b50oGtB7E3RwRsv3b4g5ltBxanZwRsv3b6kk2lBURXSwRsv3b6k+llBQ7/awRsv3b4R4GZBLr/SwRsv3b66CVhBcQzcwRsv3b6CA2NB5UTTwRsv3b5q91VBJi7dwRsv3b4yjF5BMavTwRsv3b5dxlNB8QPewRsv3b6a91lBkO/TwRsv3b70g1FB1pXewRsv3b7ZG1VBCA7UwRsv3b5dLU9B6tXewRsv3b4Zd1BBKBPUwRsv3b56tUxBw9/ewRsv3b7K9kxBWBXUwRsv3b6UKEpBFeLewRsv3b7tTEpBcxfUwRsv3b44mkdBOeTewRsv3b4LskdBKhjUwRsv3b7IC0VB9eTewRsv3b7PF0VB4BjUwRsv3b5efEJBq+XewRsv3b6jh0JBfxnUwRsv3b557T9BTObewRsv3b4N8j9BahnUwRsv3b6EXj1BN+bewRsv3b4qXT1BVhnUwRsv3b4GzzpBI+bewRsv3b61zTpBQhnUwRsv3b6iPzhBD+bewRsv3b4yPThBDBnUwRsv3b6GsDVB2eXewRsv3b7mqTVBehjUwRsv3b5OITNBReXewRsv3b6eFzNB5xfUwRsv3b7SkTBBsuTewRsv3b4iiDBBVBfUwRsv3b5WAi5BH+TewRsv3b6m+C1BwRbUwRsv3b78citBjOPewRsv3b7IZytBABbUwRsv3b7A4yhByuLewRsv3b631ShBFxXUwRsv3b5iVCZB4eHewRsv3b4HRSZBLhTUwRsv3b7mxCNB+ODewRsv3b6LtSNBRRPUwRsv3b5qNSFBD+DewRsv3b4PJiFBXBLUwRsv3b7upR5BJt/ewRsv3b6Tlh5BcxHUwRsv3b6cFhxBPN7ewRsv3b5pBRxBUhDUwRsv3b5PhxlBGt3ewRsv3b4QdBlBKw/UwRsv3b7Z9xZB89vewRsv3b5g5BZBAw7UwRsv3b5eaBRBy9rewRsv3b7cVBRB2wzUwRsv3b7i2BFBo9newRsv3b5gxRFBswvUwRsv3b5nSQ9Be9jewRsv3b7lNQ9BiwrUwRsv3b74uQxBU9fewRsv3b7mpQxBUgnUwRsv3b6fKgpBGdbewRsv3b4BFQpB+wfUwRsv3b46mwdBwtTewRsv3b6fhAdBpAbUwRsv3b6/CwVBa9PewRsv3b4k9QRBTQXUwRsv3b5EfAJBFNLewRsv3b6pZQJB9gPUwRsv3b6S2f9AvdDewRsv3b5crP9AnwLUwRsv3b6buvpAZs/ewRsv3b5ljfpASAHUwRsv3b6lm/VAD87ewRsv3b5vbvVA9v/TwRsv3b5RhfBAiMzewRsv3b709u9A5/jTwRsv3b7ob+tABMXewRsv3b6NeepAZ/HTwRsv3b7hUeZAer3ewRsv3b69VOVA5+nTwRsv3b4/M+FA+rXewRsv3b4bNuBAZuLTwRsv3b6eFNxAea7ewRsv3b56F9tA5trTwRsv3b789dZA+abewRsv3b7Y+NVAZdPTwRsv3b5d19FAeJ/ewRsv3b4o2tBA8svTwRsv3b7cwMxAZ5fewRsv3b45aMtAHb/TwRsv3b7+rMdAjInewRsv3b5X48VA77DTwRsv3b4skcJAInvewRsv3b7pscBAu6LTwRsv3b5sc71A72zewRsv3b46lLtAiJTTwRsv3b6uVbhAvF7ewRsv3b58drZAVIbTwRsv3b7yN7NAh1DewRsv3b6vWLFAIHjTwRsv3b40Gq5AU0LewRsv3b7xOqxADWrTwRsv3b47B6lAxjLewRsv3b7MrqZA1VTTwRsv3b4C9qNAtRvewRsv3b5eIqFAVD/TwRsv3b4K2p5AKwbewRsv3b5cBJxA0ynTwRsv3b7ivZlAq/DdwRsv3b5E6JZAUhTTwRsv3b69oZRAKdvdwRsv3b4PzJFA0P7SwRsv3b6XhY9Ap8XdwRsv3b7pr4xAZ+nSwRsv3b7fbopAMq/dwRsv3b4eXIdAgtDSwRsv3b7SX4VAspPdwRsv3b5qxoFAK7PSwRsv3b6zTIBAwXTdwRsv3b6W03hAr5XSwRsv3b4XZnZARVfdwRsv3b4moG5AMnjSwRsv3b7GMmxAyDndwRsv3b7VbGRAtlrSwRsv3b51/2FATBzdwRsv3b6EOVpAST3SwRsv3b7N0VdAJf7cwRsv3b5BzE9APx7SwRsv3b5Buk1Aa9vcwRsv3b7cjURAUPjRwRsv3b6/okNAP7LcwRsv3b43jzlAF9LRwRsv3b6wdjlABozcwRsv3b4oYy9A3qvRwRsv3b6iSi9AzWXcwRsv3b4aNyVApYXRwRsv3b6UHiVAlD/cwRsv3b4MCxtAiV/RwRsv3b4r+hpALxjcwRsv3b6QkBBAOzfRwRsv3b6U7RBAqurbwRsv3b5aQAVAywfRwRsv3b7H4AZABbfbwRsv3b5gjPQ//NfQwRsv3b7Iffk/NIfbwRsv3b5YSOA/K6jQwRsv3b72OeU/ZVfbwRsv3b7IBMw/XHjQwRsv3b4q9tA/lifbwRsv3b79wLc/6UjQwRsv3b5T2Lw/EfTawRsv3b4W+KE/cRPQwRsv3b5L5Kg/O7fawRsv3b47PYs/X9nPwRsv3b5x1ZQ/AnrawRsv3b4QJGw/B5/PwRsv3b5XrYA/qD/awRsv3b5a00M/rWTPwRsv3b5uClk/TgXawRsv3b4agxs/fyrPwRsv3b6Q1zA/PMnZwRsv3b5gC+Q+jO7OwRsv3b44Igk/x4PZwRsv3b6WYog+U6nOwRsv3b4+E8M+bTbZwRsv3b5MQL49YWPOwRsv3b7SDWY+e/DYwRsv3b4I8YG9bx3OwRsv3b5Q6os9iarYwRsv3b4wEWG+YtfNwRsv3b6TwrS9q2XYwRsv3b5FWL++rJHNwRsv3b7dL32+4SvYwRsv3b6qGwG/qljNwRsv3b5HftC+mfzXwRsv3b62ciO/hSDNwRsv3b7bmxC/dMTXwRsv3b7vz0u/YOjMwRsv3b6f+Di/T4zXwRsv3b6zLHS/O7DMwRsv3b5iVWG/KlTXwRsv3b68RI6/bnfMwRsv3b7bGIW/xyLXwRsv3b5O5Z+/OEnMwRsv3b7Dr5m/p/zWwRsv3b4LCrG/Ax7MwRsv3b6XDK6/0NLWwRsv3b5UxMS/7PLLwRsv3b75WsK/uafWwRsv3b62Etm/1sfLwRsv3b5aqda/o3zWwRsv3b4XYe2/h5zLwRsv3b7MEuu/yVPWwRsv3b4LTQDAbXXLwRsv3b45s/+/tDLWwRsv3b7l/QjAWlbLwRsv3b5fIwrA8BbWwRsv3b5xQBLAkzfLwRsv3b64VRTAKPjVwRsv3b7schzAyxjLwRsv3b4UiB7AYNnVwRsv3b5IpSbABPrKwRsv3b5zuijAmrrVwRsv3b6F1zDA9drKwRsv3b58BjPAtZ7VwRsv3b69AjrAb8TKwRsv3b7VYD3AtovVwRsv3b5C1kLAK7HKwRsv3b5Oo0fAOHnVwRsv3b4is0zA953KwRsv3b693FHAA2bVwRsv3b6y7FbAw4rKwRsv3b4yFlzA0FLVwRsv3b4GJmHAkHfKwRsv3b6jT2bAnT/VwRsv3b53X2vAKmTKwRsv3b5Gp3DAYS7VwRsv3b5sY3TA5VrKwRsv3b65BHvAtibVwRsv3b7uUX3AjlLKwRsv3b4booLAdh7VwRsv3b5Su4PAOErKwRsv3b6nwIfAIBbVwRsv3b7e2YjA40HKwRsv3b4034zAyw3VwRsv3b5r+I3AjTnKwRsv3b7B/ZHAdQXVwRsv3b74FpPAJzHKwRsv3b5eKpfAyP3UwRsv3b5cpZfALzLKwRsv3b6SWJzA9f7UwRsv3b6rJ5zACjTKwRsv3b6+eKHAzADVwRsv3b4iOqHA5TXKwRsv3b6xl6bApwLVwRsv3b4VWabAwDfKwRsv3b6mtqvAggTVwRsv3b75d6vAnDnKwRsv3b6a1bDAXgbVwRsv3b7tlrDAfzvKwRsv3b7I/rXA8AfVwRsv3b4UTbXAQUTKwRsv3b6AK7vAwg/VwRsv3b672LnAsU/KwRsv3b7DTcDA0RrVwRsv3b4Tzb7AFlvKwRsv3b7wa8XANybVwRsv3b5R68PAfWbKwRsv3b4gisrAnTHVwRsv3b5vCcnA5HHKwRsv3b5OqM/ABD3VwRsv3b6dJ87AU33KwRsv3b6QytTAB0jVwRsv3b77G9PAmYvKwRsv3b6g9dnAlFTVwRsv3b47sNfAEqDKwRsv3b5kG9/AimfVwRsv3b4fbdzAabTKwRsv3b7ZN+TA4XvVwRsv3b6DieHAwMjKwRsv3b5LVOnAOJDVwRsv3b71pebAF93KwRsv3b68cO7Aj6TVwRsv3b53wuvAbfHKwRsv3b4ujfPA5bjVwRsv3b7p3vDAwwXLwRsv3b6EqfjAQc3VwRsv3b5//PXABhrLwRsv3b7Qxf3Ai+HVwRsv3b61GvvAPy7LwRsv3b4fcQHBx/XVwRsv3b7VGwDBekLLwRsv3b5c/wPBAgrWwRsv3b4SqgLBtFbLwRsv3b6YjQbBPB7WwRsv3b5WOAXB7mrLwRsv3b7UGwnBdjLWwRsv3b6TxgfBKH/LwRsv3b76qQvBt0bWwRsv3b6+VQrBQpPLwRsv3b4fOA7B21rWwRsv3b4j5QzBVqfLwRsv3b5bxhDB8W7WwRsv3b6Scw/Ba7vLwRsv3b6dVBPBBoPWwRsv3b7MARLBgM/LwRsv3b7f4hXBG5fWwRsv3b4OkBTBlOPLwRsv3b4BcRjBOavWwRsv3b6RHxfBfvfLwRsv3b4h/xrBML/WwRsv3b5grxnBXwvMwRsv3b5ijR3BFNPWwRsv3b7sPRzBQR/MwRsv3b6qGyDB9ubWwRsv3b40zB7BIjPMwRsv3b7SqSLB4vrWwRsv3b62WyHB2kbMwRsv3b7nNyXBrA7XwRsv3b5E7CPBcFrMwRsv3b4exifBSyLXwRsv3b6aeybBB27MwRsv3b5nVCrB5TXXwRsv3b43CinBkYHMwRsv3b5g4izBjEnXwRsv3b4UnCvBsJTMwRsv3b5ucC/BxlzXwRsv3b6xLS7Bz6fMwRsv3b6L/jHB+m/XwRsv3b6svjDBlLrMwRsv3b5SjDTB9ILXwRsv3b6RUzPB1czMwRsv3b6eGTfBkpXXwRsv3b4D7jXB7d3MwRsv3b6NojnBNKjXwRsv3b5ytjjBdujMwRsv3b62HzzBNLXXwRsv3b47/DvBH+LMwRsv3b4zlz7BeqzXwRsv3b6hfz/B3M3MwRsv3b7YDkHBBJDXwRsv3b6Z80LBv6rMwRsv3b5sgkPB2V3XwRsv3b6fckbBFXjMwRsv3b6k8EXBhRTXwRsv3b5i9knBjDXMwRsv3b54V0jBgbLWwRsv3b7Afk3BNOLLwRsv3b7/tErBUjbWwRsv3b7eBFHBOX7LwRsv3b6LB03B0Z/VwRsv3b4rg1TBIgnLwRsv3b6wTE/BGe7UwRsv3b4s9VfBN4PKwRsv3b71glHBgyLUwRsv3b72UVvB2uzJwRsv3b46qFPBTz3TwRsv3b4nl17BREbJwRsv3b74ulXB30DSwRsv3b7Gu2HBopDIwRsv3b4fulfB/C7RwRsv3b53vmTBPMzHwRsv3b4SpFnBMwrQwRsv3b5mmWfBn/rGwRsv3b7+eFvBltXOwRsv3b7NS2rBVxzGwRsv3b56N13B1ZLNwRsv3b6K1GzBuzLFwRsv3b6C4F7BQUbMwRsv3b7UMW/B6T7EwRsv3b6Sc2DBx+/KwRsv3b4saHHBpULDwRsv3b6f72HBjIjJwRsv3b7RhHPB3TrCwRsv3b7BU2PBbSnIwRsv3b6eYHXBvynBwRsv3b4EsWTBofbGwRsv3b5z6XbBeRXAwRsv3b5GD2bBStzFwRsv3b5pT3jBtgC/wRsv3b4ybWfBgsTEwRsv3b4nsXnBl+u9wRsv3b6GymjBzK3DwRsv3b58EHvBcNa8wRsv3b7kJ2rBVZfCwRsv3b6Cb3zBH8G7wRsv3b6XhGvBXIDBwRsv3b5Kzn3BpKu6wRsv3b5I4WzBjGrAwRsv3b5lK3/BKJa5wRsv3b74PW7BulS/wRsv3b5BRIDBsIC4wRsv3b5rmm/BNz6+wRsv3b4i84DBFWu3wRsv3b6T9nDB6Ce9wRsv3b6noYHBalW2wRsv3b7QUnLBPxK8wRsv3b7ET4LBwT+1wRsv3b4Kr3PBi/y6wRsv3b7o/YLBJCq0wRsv3b4tC3XBN+a5wRsv3b5trIPBbRSzwRsv3b4AZ3bB1M+4wRsv3b7CWoTBp/6xwRsv3b7lwnfBELq3wRsv3b6zCIXB4uiwwRsv3b7LHnnBS6S2wRsv3b6mtoXBHdOvwRsv3b6wenrBgo61wRsv3b6aZIbBYr2uwRsv3b6G1nvBQni0wRsv3b7ZEofBlKetwRsv3b4dMn3B8GGzwRsv3b73wIfBupGswRsv3b7EjX7BGEyywRsv3b7KbojB4XurwRsv3b5q6X/BPjaxwRsv3b6dHInBB2aqwRsv3b6IooDBYiCwwRsv3b5yyonBL1CpwRsv3b5aUIHBeQqvwRsv3b5OeIrBXDqowRsv3b4j/oHBQfStwRsv3b5WJovBeiSnwRsv3b7aq4LBCt6swRsv3b5C1IvBkQ6mwRsv3b6VWYPBIcirwRsv3b79gYzBqPikwRsv3b5QB4TBN7KqwRsv3b64L43BwOKjwRsv3b4KtYTBT5ypwRsv3b5y3Y3B18yiwRsv3b7FYoXBZ4aowRsv3b4ti47BxbehwRsv3b76D4bB42enwRsv3b5DPo/B/6GgwRsv3b6HuobBA0GmwRsv3b5S84/BRoqfwRsv3b7KY4fBpCGlwRsv3b47oZDB4HGewRsv3b53DYjBOAmkwRsv3b7rSpHBeFmdwRsv3b4jt4jB0PCiwRsv3b6X9JHBEEGcwRsv3b7QYInBbtihwRsv3b5BnpLBQCmbwRsv3b4iCorB/7mgwRsv3b6RS5PBqRGawRsv3b4ysYrBu46fwRsv3b5Z/pPBpveYwRsv3b6FVYvBnmeewRsv3b5bqpTBedyXwRsv3b6G+ovBcUydwRsv3b5cT5XBTMGWwRsv3b6In4zBRzGcwRsv3b5c9JXBH6aVwRsv3b6KRI3BFxabwRsv3b5gmZbBA4yUwRsv3b7s6I3B9++ZwRsv3b65RJfBPXGTwRsv3b7qiY7BTr6YwRsv3b6/8pfB8FOSwRsv3b7zKI/BJJaXwRsv3b7gl5jBrDWRwRsv3b6IyI/B3XeWwRsv3b52N5nBZxeQwRsv3b4caJDBmFmVwRsv3b4K15nBbPmOwRsv3b6HB5HBVziUwRsv3b5IeJrBHd2NwRsv3b4EpZHBMAGTwRsv3b5+JJvBfb2MwRsv3b4YPZLB48mRwRsv3b48yZvBwZuLwRsv3b5M1pLBJKiQwRsv3b5yYpzBBnqKwRsv3b5/b5PBaYaPwRsv3b6l+5zBoliJwRsv3b6FCJTBK2GOwRsv3b6zlp3BRDmIwRsv3b5Un5TB5yGNwRsv3b4MPp7BKBaHwRsv3b6wL5XBlOKLwRsv3b6a3J7BivCFwRsv3b5OwZXB87yKwRsv3b46bp/B7MqEwRsv3b7sUpbBWJeJwRsv3b7W/5/BFKeDwRsv3b6s45bBh1+IwRsv3b5kmqDBoIKCwRsv3b7lbpfBdxSHwRsv3b4COKHBTFqBwRsv3b6Z9pfBhNmFwRsv3b5TyKHBUTCAwRsv3b4Qf5jBiK+EwRsv3b7KUKLBTw9+wRsv3b7uBpnBC3iDwRsv3b5l36LBqsB7wRsv3b4DipnBeiGCwRsv3b4/d6PBt2h5wRsv3b4LBprB99SAwRsv3b77AKTB/Ap3wRsv3b5Mg5rBM0x/wRsv3b48fqTBfrJ0wRsv3b57/5rBurh8wRsv3b5qBqXB0FlywRsv3b6qc5vB+Ol5wRsv3b5xkaXBgPZvwRsv3b704ZvBi0t3wRsv3b6WCqbB741twRsv3b41UZzB+uJ0wRsv3b7XeabBZCVrwRsv3b51wJzBK3pywRsv3b4k6abB0rxowRsv3b6tL53BXxFwwRsv3b5mWKfBPVRmwRsv3b7nnp3BwqhtwRsv3b6hx6fBrutjwRsv3b4dDp7B1j9rwRsv3b7pNqjBFoNhwRsv3b5LfZ7B+9ZowRsv3b4jpqjBfxpfwRsv3b567J7BIW5mwRsv3b5eFanB57FcwRsv3b6fW5/BCQVkwRsv3b6ahKnBSUlawRsv3b6+yp/B9ZthwRsv3b7O86nBq+BXwRsv3b7VOaDBqDJfwRsv3b4EY6rBEHhVwRsv3b7cqKDB28hcwRsv3b5C0qrBcw9TwRsv3b7JF6HBVV5awRsv3b6HQavBEadQwRsv3b6EhqHBWvBXwRsv3b5EsavB/ZROwRsv3b6S6aHBjwlSwRsv3b7EkqzBx4dMwRsv3b5K4KHB5JpKwRsv3b4VoqzBXiFKwRsv3b44r6HBmMBGwRsv3b7/WazBSppHwRsv3b7Ze6HBLzZEwRsv3b5dJqzBHhNFwRsv3b5ZSKHBI61BwRsv3b638qvB6ItCwRsv3b69FKHB1iQ/wRsv3b4Fv6vBqwRAwRsv3b4a4aDB8Jw8wRsv3b5Ui6vBbn09wRsv3b5praDBLRU6wRsv3b6ZV6vBMPY6wRsv3b62eaDBgY03wRsv3b7dI6vB9W44wRsv3b74RaDB4QU1wRsv3b4W8KrBuOc1wRsv3b44EqDBWH4ywRsv3b5RvKrBf2AzwRsv3b5x3p/ByvYvwRsv3b6CiKrBa9owwRsv3b6/qp/Bf2MtwRsv3b7AU6rByFwuwRsv3b4vdp/B+H8qwRsv3b5rFqrBuOErwRsv3b4UN5/Bd6wnwRsv3b7nzqnBG2MpwRsv3b6r957BQv0kwRsv3b6OiqnBC+wmwRsv3b4Ys57BBB0iwRsv3b6DOqnBmHMkwRsv3b5fZ57BEWwfwRsv3b4u6KjBRP4hwRsv3b4SHJ7BLpscwRsv3b6BkajBCpAfwRsv3b45xp3B+MAZwRsv3b4rLajBeR0dwRsv3b6vbZ3B+h4XwRsv3b7lzafBwrIawRsv3b5rEp3BVkUUwRsv3b76YafBHUsYwRsv3b5LrZzBro0RwRsv3b4M8KbB6OMVwRsv3b5MSJzBjNEOwRsv3b65fKbBOYYTwRsv3b7O2ZvBNwMMwRsv3b4I+qXBFSYRwRsv3b4jZ5vBx2gJwRsv3b5dfKXBys0OwRsv3b728ZrB/J0GwRsv3b578KTB1noMwRsv3b5WcprBJvcDwRsv3b5GX6TBvigKwRsv3b758pnBdkcBwRsv3b5Ty6PBk+IHwRsv3b4faZnBUB39wBsv3b7VJqPBgJoFwRsv3b6825jBcgj4wBsv3b5IiaLBI1wDwRsv3b5JSpjBkqXywBsv3b5+2qHBYyIBwRsv3b6Br5fBtqXtwBsv3b76LKHBRdb9wBsv3b58FZfBsnLowBsv3b6ed6DBPoL5wBsv3b4FcJbBWFnjwBsv3b5dtZ/BcyX1wBsv3b4SyZXBvJ7ewBsv3b49AJ/Bq93wwBsv3b4JHpXBWaLZwBsv3b4EOZ7BRJvswBsv3b5pbJTBBAbVwBsv3b7leJ3BY17owBsv3b68u5PBCDHQwBsv3b7+rpzBxjrkwBsv3b5dApPBJGrLwBsv3b6E2ZvBOw/gwBsv3b6DRpLBBQzHwBsv3b6+FJvB8PLbwBsv3b4PipHBHFrCwBsv3b5BPZrBj+bXwBsv3b5qxpDBst69wBsv3b7sZJnBLdbTwBsv3b4LApDBRIy5wBsv3b78k5jBFNjPwBsv3b4HO4/BkQa1wBsv3b6NspfBEOHLwBsv3b68bo7BEMqwwBsv3b5k2JbBrerHwBsv3b6Zoo3BHIeswBsv3b60/JXBXgfEwBsv3b7a0ozBnCiowBsv3b5VE5XBlybAwBsv3b7o/ovB9BikwBsv3b5vNZTBJ0i8wBsv3b57K4vBUfGfwBsv3b4+UpPBSHy4wBsv3b6KVIrBS7WbwBsv3b6ZYpLBMrK0wBsv3b7VeYnB6cOXwBsv3b4Tf5HB3+mwwBsv3b6Kn4jBe8CTwBsv3b5cl5DBQDKtwBsv3b6vwofBhqKPwBsv3b7Moo/B/X6pwBsv3b4J4obB3sOLwBsv3b7qt47BrselwBsv3b5vAIbBrg6IwBsv3b7Q1o3BmQ+iwBsv3b7iHoXBClyEwBsv3b6O9ozB+FaewBsv3b6VPYTBsqaAwBsv3b4HFozBSZ6awBsv3b5CXIPBAuR5wBsv3b6mNYvBauSWwBsv3b4ce4LBW35ywBsv3b4qVorBJCqTwBsv3b40moHBGRJrwBsv3b48donBIW+PwBsv3b5AuYDBCq9jwBsv3b6Dl4jBVLKLwBsv3b6fsX/BAkdcwBsv3b4juYfBAvWHwBsv3b6Y8H3BbmRXwBsv3b6hhobBQDSEwBsv3b7fMHzBEqlTwBsv3b5cLoXB93GAwBsv3b7ccXrBCuhPwBsv3b4e1oPBEFR5wBsv3b5ss3jBtkFMwBsv3b6AgoLBvZhxwBsv3b7B8nbBb0hJwBsv3b6cRYHBlTxpwBsv3b5KNnXBYgdIwBsv3b5GQ4DBTtxfwBsv3b4NtHPBa81CwBsv3b7nSIDBWt9VwBsv3b5YenLB3R0/wBsv3b73AIDBy2NLwBsv3b4cjXHBzqk6wBsv3b6v7n/BPJRAwBsv3b7k7XDBRAk2wBsv3b5TFYDBT9o1wBsv3b7rnHDBfUYvwBsv3b7YqYDBz3QrwBsv3b65Z3DB7x8mwBsv3b63PYHB7CohwBsv3b4uO3DBbyccwBsv3b760oHB6+cWwBsv3b7PEnDB8vgRwBsv3b60aYLBY6cMwBsv3b4m7W/Bt9QHwBsv3b4Qv4LBkmcCwBsv3b5zyW/B+qr7vxsv3b6nrYLBl1Hwvxsv3b6qp2/BLY7nvxsv3b4TnYLBbNXbvxsv3b7ehm/B2l7Tvxsv3b7qjILBL1bHvxsv3b5cZ2/BMUm/vxsv3b56fYLBB9Kyvxsv3b6oSW/BVF6rvxsv3b4Ob4LBo0Wevxsv3b6kLm/BWL2Xvxsv3b4lYoLBTKmJvxsv3b7YF2/BjrGEvxsv3b6UV4LBLYBpvxsv3b6aCG/BgE1pvxsv3b4aUYLByb4+vxsv3b65F2/Bu+BSvxsv3b73U4LBx7cTvxsv3b4tWW/ByDFBvxsv3b5ZYYLBTBbSvhsv3b7UzW/BoYcuvxsv3b56MILBncZ7vhsv3b6jd3DBEIAZvxsv3b4LyIHBHICuvRsv3b6aWHHBfdoKvxsv3b6zGoLBaX+QPRsv3b5PbnLBC4Puvhsv3b5OC4LBxUNhPhsv3b4luHPBAyDhvhsv3b7/yYLB0H25Phsv3b5mMHXB9HDJvhsv3b74NIPBF1T+Phsv3b7A03bBTRa4vhsv3b5Zw4PBcUIfPxsv3b7jmHjBNDKXvhsv3b6+OITBrY49Pxsv3b7db3rBkIJevhsv3b5z1ITB7sJaPxsv3b41V3zB0PwPvhsv3b7ed4XBcZh2Pxsv3b50U37BMNCMvRsv3b4eIIbBQ5GIPxsv3b5cL4DBAL1FOxsv3b5G1YbBCViVPxsv3b6DP4HB4Gt7PRsv3b7EcofB6B+hPxsv3b43YILBkDHRPRsv3b4E8ofB35WrPxsv3b7kjoPBIMAKPhsv3b5kbYjBMp60Pxsv3b7SyYTB6BFVPhsv3b5pwYjBHha8Pxsv3b5yD4bBUMlgPhsv3b5mS4nBKvPBPxsv3b5NXYfBKDd3Phsv3b69zYnBnirGPxsv3b4lsYjBmDpcPhsv3b4kZYrBesXIPxsv3b50CIrBaLFkPhsv3b6N8YrB887JPxsv3b57YYvBSCtoPhsv3b4Og4vBHU7JPxsv3b7tt4zB2KplPhsv3b7ZMYzBa8bHPxsv3b5jBo7BWCtcPhsv3b7BKo3BSgLGPxsv3b4VT4/BsA9PPhsv3b4tW47B1yTEPxsv3b56lpDBoKdAPhsv3b48l4/BgzfCPxsv3b6B3ZHBMKAxPhsv3b4J1pDBgDvAPxsv3b49JJPBgAkiPhsv3b7ZFpLBXDi+Pxsv3b6wapTBQBkSPhsv3b4OWpPBWDC8Pxsv3b4lsZXBmAcCPhsv3b7fnJTBkh+6Pxsv3b5j95bBQDTjPRsv3b4z4ZXBDhG4Pxsv3b5TPZjB4CDCPRsv3b7PKJfBSAe2Pxsv3b4yg5nBQD6hPRsv3b5rcZjBXwO0Pxsv3b4RyZrBkK+APRsv3b50upnBzQWyPxsv3b7fDpzBYNZAPRsv3b6OBJvBwxKwPxsv3b51VJ3BQAgBPRsv3b6cUZzB2jKuPxsv3b5+mZ7BgKmEPBsv3b5/pZ3BDoKsPxsv3b4K1p/BAAhHuhsv3b7LUp/BrkOsPxsv3b6R/aDBAGCiORsv3b763qHBqFCvPxsv3b7eE6LBUOuHPRsv3b7q5KTBvIy1Pxsv3b64IKPBSDdDPhsv3b6LnqfBIuC+Pxsv3b4ZLqTBjBigPhsv3b6hcqnBg+nIPxsv3b6VSaXBQOrKPhsv3b4SoarBkw7TPxsv3b58ZabBOH30Phsv3b7yw6vB3D7dPxsv3b5qgafBIt0OPxsv3b4/46zB8HPnPxsv3b42najBpn4jPxsv3b4NAq7BorDxPxsv3b7XuKnBOB84Pxsv3b7NH6/BC+/7Pxsv3b591KrB9rVMPxsv3b7ZPLDB6BgDQBsv3b4C8KvBqlFhPxsv3b6RWbHBiToIQBsv3b6GC63BDux1Pxsv3b4odrLBCl4NQBsv3b7qJq7BGEaFPxsv3b6FkrPBh4ESQBsv3b5NQq/Bj5aPPxsv3b7urrTBxaYXQBsv3b6CXbDBne6ZPxsv3b6Yy7XB1swcQBsv3b6neLHBs0ikPxsv3b486LbBvvQhQBsv3b6dk7LBCqquPxsv3b4UBbjB7R0nQBsv3b5nrrPBPRS5Pxsv3b5qIrnBR0osQBsv3b7uyLTBVIfDPxsv3b7CP7rBFngxQBsv3b4t47XB2QrOPxsv3b5AXrvBsKo2QBsv3b68/LbBwLLYPxsv3b7cfrzB/OI7QBsv3b5kFbjBXIzjPxsv3b6Hor3BTxtBQBsv3b5QKrnBbpTvPxsv3b4b4b7BkmxGQBsv3b7QMrrB7FD/Pxsv3b4IZcDBAERMQBsv3b67KLvBNn0JQBsv3b4nA8LBS6pSQBsv3b7rD7zBFEcUQBsv3b6jiMPBypdZQBsv3b7x5bzBICQgQBsv3b7v9sTBYgZhQBsv3b4Tqb3B7QMtQBsv3b7WSMbBHe5oQBsv3b7vV77BDL46QBsv3b6EeMfBKkRxQBsv3b7J8b7BuhNJQBsv3b5FgcjBT/p5QBsv3b6Ddr/Bv8hXQBsv3b6UYcnBfnuBQBsv3b7i5b/BvhdnQBsv3b7fHsrBjiqGQBsv3b5hPsDBpIR1QBsv3b4NqcrBIAuLQBsv3b7/jMDBjaGAQBsv3b5JCMvBCQCQQBsv3b6e2sDBCsmFQBsv3b4DWcvB6veUQBsv3b6TJ8HB09qKQBsv3b6Kp8vBMPGZQBsv3b7Wc8HBW+aPQBsv3b7l9MvBX+ueQBsv3b7Kv8HBReyUQBsv3b6NQczBL+ajQBsv3b5pC8LBdO+ZQBsv3b6qjczBJuGoQBsv3b7jVsLBqPKeQBsv3b6h2czBptytQBsv3b4IosLBBvSjQBsv3b4fJc3BS9iyQBsv3b4u7cLB8/OoQBsv3b6GcM3BAtS3QBsv3b4SOMPBzPWtQBsv3b7Gu83BNdC8QBsv3b7egsPB2POyQBsv3b6uBs7BR8zBQBsv3b6qzcPBRvO3QBsv3b6sUc7BaMjGQBsv3b5AGMTBJfS8QBsv3b6InM7B68TLQBsv3b7GYsTB+vHBQBsv3b4i587BP7zQQBsv3b4ArcTB6STHQBsv3b7MNM/BNa3VQBsv3b4t88TBv7vMQBsv3b4VhM/B7qjaQBsv3b5iM8XB0iHSQBsv3b7Iyc/BHK7fQBsv3b4VdMXBACfXQBsv3b57CtDBsqXkQBsv3b4ftMXBdrfcQBsv3b7vUdDBPKPpQBsv3b4a68XB3lbiQBsv3b4pkNDBw67uQBsv3b4uIsbBHmvnQBsv3b6dx9DBabTzQBsv3b4DWcbBs7vsQBsv3b6TAdHBgLX4QBsv3b4hi8bBKlryQBsv3b7WOdHBS8D9QBsv3b6luMbBaLf3QBsv3b5WatHBNWkBQRsv3b5u5sbBd8n8QBsv3b4fmNHB0+sDQRsv3b7JE8fB0C8BQRsv3b5XytHBRnAGQRsv3b6QOMfBtAAEQRsv3b6689HBS/sIQRsv3b5GXcfBjY8GQRsv3b6nGNLBRoQLQRsv3b7ggcfBOjMJQRsv3b67PtLBrwkOQRsv3b4bo8fBowIMQRsv3b6zY9LBlJIQQRsv3b7hvsfBy7oOQRsv3b6ZgdLBrR8TQRsv3b7Y2sfB5UcRQRsv3b6QndLBRKgVQRsv3b6f9sfBMwMUQRsv3b5lu9LB3y8YQRsv3b5ZDMjBZNIWQRsv3b6f09LBWLwaQRsv3b7FH8jBtXMZQRsv3b6u59LBrUodQRsv3b5AM8jBAgIcQRsv3b4p+9LB69IfQRsv3b6RRsjBtc4eQRsv3b5OENPB3lsiQRsv3b7OUcjBx5whQRsv3b70HNPB6OokQRsv3b4YXcjBeiwkQRsv3b5BKNPBzHgnQRsv3b5caMjB+McmQRsv3b6+M9PBDAIqQRsv3b71ccjB2JMpQRsv3b41PtPBxowsQRsv3b5PdcjBq1MsQRsv3b72QdPBOhwvQRsv3b6xeMjBJ+MuQRsv3b5YRdPBrqsxQRsv3b4TfMjBm3IxQRsv3b66SNPBITs0QRsv3b51f8jBFgI0QRsv3b4cTNPBk8o2QRsv3b7WgsjBkZE2QRsv3b59T9PBB1o5QRsv3b43hsjBBSE5QRsv3b7eUtPBeuk7QRsv3b6YicjBibA7QRsv3b4/VtPB7Hg+QRsv3b73jMjBDEA+QRsv3b6eWdPBXwhBQRsv3b5WkMjBf89AQRsv3b79XNPB0pdDQRsv3b61k8jB+15DQRsv3b5cYNPBRSdGQRsv3b4Tl8jBfu5FQRsv3b66Y9PBt7ZIQRsv3b5wmsjBCX5IQRsv3b4XZ9PBKEZLQRsv3b7LncjBlA1LQRsv3b5yatPBmdVNQRsv3b4locjBL51NQRsv3b7NbdPBB2VQQRsv3b57pMjB4CxQQRsv3b4jcdPBavRSQRsv3b7Np8jBBb1SQRsv3b52dNPBxCxVQRsv3b5+rsjBP8lYQRsv3b5hVNPB/CBXQRsv3b6PUMjBum9fQRsv3b6wSNLBA1tZQRsv3b7CyMfBFaFiQRsv3b7FidHB9qpbQRsv3b4KPMfBZfFkQRsv3b73/NDB6/pdQRsv3b5Nr8bBjUFnQRsv3b4ucNDB3kpgQRsv3b6OIsbBopFpQRsv3b5n48/B0JpiQRsv3b7NlcXBtOFrQRsv3b6eVs/BwupkQRsv3b4JCcXBtzFuQRsv3b7Wyc7BtDpnQRsv3b5FfMTBq4FwQRsv3b4SPc7BpYppQRsv3b6B78PBrdFyQRsv3b5KsM3BlNprQRsv3b68YsPBrCF1QRsv3b6AI83BhSpuQRsv3b721cLBnXF3QRsv3b66lszBdnpwQRsv3b4wScLBlsF5QRsv3b7zCczBZcpyQRsv3b5pvMHBjRF8QRsv3b4qfcvBbxh1QRsv3b4WMMHB9HR+QRsv3b6768rBF1J3QRsv3b7UpcDBy8WAQRsv3b5AKcrBEXV5QRsv3b4BBMDB9ziCQRsv3b5bUMnBaal7QRsv3b5IXb/BI1ODQRsv3b6iqcjB09d9QRsv3b5XuL7BrYuEQRsv3b6u8MfBtPN/QRsv3b52Dr7BXuuFQRsv3b7zEsfBZQOBQRsv3b5JV73B7SSHQRsv3b5mO8bBNhGCQRsv3b47nbzBvjKIQRsv3b5YgcXBrB2DQRsv3b4e5LvBc06JQRsv3b6kvcTBViOEQRsv3b6CKrvBjpKKQRsv3b4M18PBPSKFQRsv3b7eZLrBAsCLQRsv3b4b7sLBRyWGQRsv3b4WnLnBDMOMQRsv3b5TJcLBUyiHQRsv3b5O07jBFcaNQRsv3b6MXMHBwyiIQRsv3b6RDLjBz+OOQRsv3b7MfsDB8iGJQRsv3b5vQLfBSg2QQRsv3b5Gi7/B+RmKQRsv3b6ebbbBfxiRQRsv3b5OqL7BtBOLQRsv3b5dmbXBOhKSQRsv3b4N1L3Bbw2MQRsv3b4dxbTB8wuTQRsv3b7P/7zBkwWNQRsv3b468rPB+hWUQRsv3b6XHbzBMPiNQRsv3b7NHLPBEi+VQRsv3b5EJrvBDeiOQRsv3b4XQbLBeDOWQRsv3b7uN7rBvdmPQRsv3b65Y7HBKCWXQRsv3b6QWrnBbcuQQRsv3b5bhrDB2haYQRsv3b4wfbjBHL2RQRsv3b79qK/BiQiZQRsv3b7Sn7fBhKySQRsv3b69za7BnRGaQRsv3b7CrLbBvpWTQRsv3b737K3B1xmbQRsv3b5orrXB9X+UQRsv3b6zCK3BqQmcQRsv3b6xxLTBq2qVQRsv3b7zI6zBX/ScQRsv3b7x37PBYVWWQRsv3b4zP6vBFd+dQRsv3b4x+7LBF0CXQRsv3b5zWqrBy8meQRsv3b5xFrLBRSmYQRsv3b40d6nBMMSfQRsv3b5FIrHBqQ2ZQRsv3b6xkKjBJcKgQRsv3b4RIrDBivGZQRsv3b6jpqfBfa6hQRsv3b5bL6/BLNaaQRsv3b7Qu6bBH5OiQRsv3b6IRK7Bz7qbQRsv3b790KXBwHejQRsv3b63Wa3Bcp+cQRsv3b4q5qTBY1ykQRsv3b7kbqzBE4SdQRsv3b5X+6PBBkGlQRsv3b4PhKvB/3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+//3///wAA/7//f///AAD/v/9///8AAP+/")
}]
diff --git a/world/interactables/fishing_shop_world.tscn b/world/interactables/fishing_shop_world.tscn
index 0f4ed84..7221005 100644
--- a/world/interactables/fishing_shop_world.tscn
+++ b/world/interactables/fishing_shop_world.tscn
@@ -1,90 +1,28 @@
-[gd_scene load_steps=11 format=3]
+[gd_scene load_steps=5 format=3]
[ext_resource type="Script" path="res://world/fishing_shop_interaction.gd" id="1_shop"]
-[ext_resource type="Script" path="res://world/world_prop.gd" id="2_prop"]
-
-[sub_resource type="BoxMesh" id="CounterMesh"]
-resource_local_to_scene = true
-size = Vector3(4.2, 1.25, 1.8)
-
-[sub_resource type="BoxMesh" id="RoofMesh"]
-resource_local_to_scene = true
-size = Vector3(5.2, 0.35, 3.2)
-
-[sub_resource type="BoxMesh" id="PostMesh"]
-resource_local_to_scene = true
-size = Vector3(0.28, 3.2, 0.28)
-
-[sub_resource type="BoxMesh" id="BackMesh"]
-resource_local_to_scene = true
-size = Vector3(5, 2.8, 0.25)
-
-[sub_resource type="StandardMaterial3D" id="PrimaryMaterial"]
-resource_local_to_scene = true
-albedo_color = Color(0.12, 0.68, 0.62, 1)
-
-[sub_resource type="StandardMaterial3D" id="AccentMaterial"]
-resource_local_to_scene = true
-albedo_color = Color(1, 0.68, 0.18, 1)
-
-[sub_resource type="StandardMaterial3D" id="BackMaterial"]
-resource_local_to_scene = true
-albedo_color = Color(0.13, 0.34, 0.38, 1)
+[ext_resource type="PackedScene" path="res://art/exported/characters/base/netfishing_base_character.glb" id="2_character"]
+[ext_resource type="Script" path="res://world/world_character_display.gd" id="3_display"]
[sub_resource type="SphereShape3D" id="InteractionShape"]
resource_local_to_scene = true
radius = 3.0
-[sub_resource type="BoxShape3D" id="CounterShape"]
-resource_local_to_scene = true
-size = Vector3(4.2, 1.25, 1.8)
-
[node name="FishingShopWorld" type="Node3D"]
-script = ExtResource("2_prop")
-collision_root_path = NodePath("Collision")
-interaction_area_path = NodePath("InteractionArea")
-entrance_marker_path = NodePath("EntranceMarker")
-[node name="Visual" type="Node3D" parent="."]
+[node name="Shopkeeper" parent="." instance=ExtResource("2_character")]
+script = ExtResource("3_display")
+species_id = "pointy"
+fur_color_id = "white"
+ears_id = "pointy_wide"
+tail_id = "fox"
+eyes_id = "punk_purple"
+nose_id = "triangle_small"
+mouth_id = "slanted"
+head_look_enabled = true
-[node name="Counter" type="MeshInstance3D" parent="Visual"]
-position = Vector3(0, 0.625, 0)
-mesh = SubResource("CounterMesh")
-material_override = SubResource("PrimaryMaterial")
-
-[node name="Back" type="MeshInstance3D" parent="Visual"]
-position = Vector3(0, 1.4, 1.25)
-mesh = SubResource("BackMesh")
-material_override = SubResource("BackMaterial")
-
-[node name="Roof" type="MeshInstance3D" parent="Visual"]
-position = Vector3(0, 3.15, 0.35)
-mesh = SubResource("RoofMesh")
-material_override = SubResource("AccentMaterial")
-
-[node name="WestPost" type="MeshInstance3D" parent="Visual"]
-position = Vector3(-2.15, 1.6, -0.8)
-mesh = SubResource("PostMesh")
-material_override = SubResource("PrimaryMaterial")
-
-[node name="EastPost" type="MeshInstance3D" parent="Visual"]
-position = Vector3(2.15, 1.6, -0.8)
-mesh = SubResource("PostMesh")
-material_override = SubResource("PrimaryMaterial")
-
-[node name="ShopName" type="Label3D" parent="Visual"]
-position = Vector3(0, 3.7, 0)
-text = "fishing shop"
-font_size = 42
-outline_size = 9
-billboard = 1
-no_depth_test = true
-
-[node name="Collision" type="StaticBody3D" parent="."]
-
-[node name="CounterShape" type="CollisionShape3D" parent="Collision"]
-position = Vector3(0, 0.625, 0)
-shape = SubResource("CounterShape")
+[node name="AnimationPlayer" parent="Shopkeeper"]
+autoplay = "idle"
[node name="InteractionArea" type="Area3D" parent="."]
unique_name_in_owner = true
@@ -95,6 +33,3 @@ script = ExtResource("1_shop")
[node name="InteractionShape" type="CollisionShape3D" parent="InteractionArea"]
shape = SubResource("InteractionShape")
-
-[node name="EntranceMarker" type="Marker3D" parent="."]
-position = Vector3(0, 0, -2)
diff --git a/world/materials/foliage_wind.gdshader b/world/materials/foliage_wind.gdshader
new file mode 100644
index 0000000..a1220e7
--- /dev/null
+++ b/world/materials/foliage_wind.gdshader
@@ -0,0 +1,44 @@
+shader_type spatial;
+render_mode cull_back, depth_draw_opaque;
+
+uniform vec4 albedo_color : source_color = vec4(1.0);
+uniform float material_roughness = 1.0;
+uniform float material_metallic = 0.0;
+uniform float local_min_y = 0.0;
+uniform float local_height = 1.0;
+uniform float local_wind_strength = 0.08;
+uniform float wind_speed = 0.9;
+uniform float wind_phase = 0.0;
+
+
+void vertex() {
+ float height_ratio = clamp(
+ (VERTEX.y - local_min_y) / max(local_height, 0.001),
+ 0.0,
+ 1.0
+ );
+ float bend_mask = smoothstep(0.08, 1.0, height_ratio);
+ vec3 world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
+ float broad_wave = sin(
+ TIME * wind_speed
+ + dot(world_position.xz, vec2(0.23, 0.17))
+ + wind_phase
+ );
+ float leaf_flutter = sin(
+ TIME * wind_speed * 2.17
+ + dot(world_position.xz, vec2(-0.41, 0.37))
+ + wind_phase * 1.7
+ );
+ float displacement = (
+ broad_wave * 0.72 + leaf_flutter * 0.28
+ ) * local_wind_strength * bend_mask;
+ VERTEX.x += displacement;
+ VERTEX.z += displacement * 0.42;
+}
+
+
+void fragment() {
+ ALBEDO = albedo_color.rgb;
+ ROUGHNESS = material_roughness;
+ METALLIC = material_metallic;
+}
diff --git a/world/materials/foliage_wind.gdshader.uid b/world/materials/foliage_wind.gdshader.uid
new file mode 100644
index 0000000..e5162a5
--- /dev/null
+++ b/world/materials/foliage_wind.gdshader.uid
@@ -0,0 +1 @@
+uid://c3q7l8m9n2v4x
diff --git a/world/materials/shoreline_tide.gdshader b/world/materials/shoreline_tide.gdshader
index b51f794..f8a58e0 100644
--- a/world/materials/shoreline_tide.gdshader
+++ b/world/materials/shoreline_tide.gdshader
@@ -1,16 +1,16 @@
shader_type spatial;
render_mode blend_mix, depth_draw_never, cull_disabled, unshaded;
-uniform vec4 lead_color : source_color = vec4(0.620, 0.875, 0.855, 1.0);
-uniform vec4 trail_color : source_color = vec4(0.430, 0.780, 0.770, 1.0);
-uniform float ribbon_width : hint_range(0.2, 2.0, 0.01) = 0.85;
-uniform float land_inset : hint_range(0.0, 0.4, 0.01) = 0.10;
+uniform vec4 lead_color : source_color = vec4(0.780, 0.960, 0.930, 1.0);
+uniform vec4 trail_color : source_color = vec4(0.500, 0.840, 0.820, 1.0);
+uniform float ribbon_width : hint_range(0.2, 2.0, 0.01) = 1.35;
+uniform float land_inset : hint_range(0.0, 0.4, 0.01) = 0.12;
uniform float tide_speed : hint_range(0.1, 3.0, 0.01) = 1.42;
-uniform float tide_distance : hint_range(0.0, 0.6, 0.01) = 0.30;
-uniform float lead_width : hint_range(0.01, 0.2, 0.005) = 0.065;
-uniform float trail_width : hint_range(0.02, 0.4, 0.005) = 0.18;
-uniform float lead_strength : hint_range(0.0, 1.0, 0.01) = 0.48;
-uniform float trail_strength : hint_range(0.0, 1.0, 0.01) = 0.25;
+uniform float tide_distance : hint_range(0.0, 0.6, 0.01) = 0.42;
+uniform float lead_width : hint_range(0.01, 0.2, 0.005) = 0.14;
+uniform float trail_width : hint_range(0.02, 0.4, 0.005) = 0.32;
+uniform float lead_strength : hint_range(0.0, 1.0, 0.01) = 0.88;
+uniform float trail_strength : hint_range(0.0, 1.0, 0.01) = 0.52;
uniform float phase_scale : hint_range(0.001, 0.2, 0.001) = 0.035;
uniform float phase_strength : hint_range(0.0, 2.0, 0.01) = 0.55;
diff --git a/world/materials/shoreline_tide.tres b/world/materials/shoreline_tide.tres
index dad0a9d..65d2fa8 100644
--- a/world/materials/shoreline_tide.tres
+++ b/world/materials/shoreline_tide.tres
@@ -5,15 +5,15 @@
[resource]
render_priority = 1
shader = ExtResource("1_shader")
-shader_parameter/lead_color = Color(0.619608, 0.87451, 0.854902, 1)
-shader_parameter/trail_color = Color(0.431373, 0.780392, 0.768627, 1)
-shader_parameter/ribbon_width = 0.85
-shader_parameter/land_inset = 0.1
+shader_parameter/lead_color = Color(0.78, 0.96, 0.93, 1)
+shader_parameter/trail_color = Color(0.5, 0.84, 0.82, 1)
+shader_parameter/ribbon_width = 1.35
+shader_parameter/land_inset = 0.12
shader_parameter/tide_speed = 1.42
-shader_parameter/tide_distance = 0.3
-shader_parameter/lead_width = 0.065
-shader_parameter/trail_width = 0.18
-shader_parameter/lead_strength = 0.48
-shader_parameter/trail_strength = 0.25
+shader_parameter/tide_distance = 0.42
+shader_parameter/lead_width = 0.14
+shader_parameter/trail_width = 0.32
+shader_parameter/lead_strength = 0.88
+shader_parameter/trail_strength = 0.52
shader_parameter/phase_scale = 0.035
shader_parameter/phase_strength = 0.55
diff --git a/world/materials/starter_island_grass.tres b/world/materials/starter_island_grass.tres
deleted file mode 100644
index 51ea444..0000000
--- a/world/materials/starter_island_grass.tres
+++ /dev/null
@@ -1,15 +0,0 @@
-[gd_resource type="ShaderMaterial" load_steps=3 format=3]
-
-[ext_resource type="Texture2D" path="res://art/exported/environment/textures/grass_lite.png" id="1_texture"]
-[ext_resource type="Shader" path="res://world/materials/terrain_surface_projection.gdshader" id="2_shader"]
-
-[resource]
-resource_name = "Starter Island Grass"
-shader = ExtResource("2_shader")
-shader_parameter/albedo_texture = ExtResource("1_texture")
-shader_parameter/albedo_tint = Color(1, 1, 1, 1)
-shader_parameter/tile_world_size = 2.5
-shader_parameter/blend_sharpness = 6.0
-shader_parameter/top_projection_bias = 2.0
-shader_parameter/roughness = 1.0
-shader_parameter/specular = 0.5
diff --git a/world/materials/starter_island_sand.tres b/world/materials/starter_island_sand.tres
deleted file mode 100644
index b967425..0000000
--- a/world/materials/starter_island_sand.tres
+++ /dev/null
@@ -1,15 +0,0 @@
-[gd_resource type="ShaderMaterial" load_steps=3 format=3]
-
-[ext_resource type="Texture2D" path="res://art/exported/environment/textures/sand.png" id="1_texture"]
-[ext_resource type="Shader" path="res://world/materials/terrain_surface_projection.gdshader" id="2_shader"]
-
-[resource]
-resource_name = "Starter Island Sand"
-shader = ExtResource("2_shader")
-shader_parameter/albedo_texture = ExtResource("1_texture")
-shader_parameter/albedo_tint = Color(1, 1, 1, 1)
-shader_parameter/tile_world_size = 2.5
-shader_parameter/blend_sharpness = 6.0
-shader_parameter/top_projection_bias = 2.0
-shader_parameter/roughness = 1.0
-shader_parameter/specular = 0.5
diff --git a/world/materials/stylized_water.gdshader b/world/materials/stylized_water.gdshader
index 0bc45e1..fa6c266 100644
--- a/world/materials/stylized_water.gdshader
+++ b/world/materials/stylized_water.gdshader
@@ -29,17 +29,41 @@ uniform float contour_corner_variation : hint_range(0.0, 0.15, 0.005) = 0.045;
uniform float contour_smoothing_pixels : hint_range(0.0, 2.5, 0.05) = 1.0;
uniform float contour_smoothing_strength : hint_range(0.0, 1.0, 0.01) = 0.72;
uniform float contour_depth_reject : hint_range(0.05, 2.0, 0.01) = 0.60;
+uniform float shoreline_horizontal_reach : hint_range(0.05, 1.5, 0.01) = 0.32;
+uniform float contact_fade_depth : hint_range(0.0, 0.1, 0.001) = 0.018;
uniform float open_water_drift_scale : hint_range(0.001, 0.3, 0.001) = 0.018;
uniform vec2 open_water_drift_speed = vec2(0.010, -0.007);
uniform float open_water_drift_strength : hint_range(0.0, 0.08, 0.001) = 0.045;
+uniform vec4 surface_mark_color : source_color = vec4(0.580, 0.850, 0.860, 1.0);
+uniform vec2 surface_mark_density = vec2(1.30, 0.90);
+uniform vec2 surface_mark_drift = vec2(0.045, -0.032);
+uniform float surface_mark_strength : hint_range(0.0, 0.3, 0.005) = 0.12;
+uniform float surface_mottle_scale : hint_range(0.01, 1.0, 0.01) = 0.11;
+uniform vec2 surface_mottle_speed = vec2(-0.018, 0.013);
+uniform float surface_mottle_strength : hint_range(0.0, 0.2, 0.005) = 0.07;
+uniform vec2 shoreline_mark_density = vec2(4.60, 3.20);
+uniform vec2 shoreline_mark_drift = vec2(0.085, -0.060);
+uniform float shoreline_mark_depth : hint_range(0.1, 2.0, 0.01) = 0.95;
+uniform float shoreline_mark_strength : hint_range(0.0, 1.0, 0.01) = 0.82;
+uniform float shoreline_base_fill : hint_range(0.0, 1.0, 0.01) = 0.32;
+uniform float shoreline_opacity_boost : hint_range(0.0, 0.5, 0.01) = 0.26;
+uniform float surface_highlight_night_floor : hint_range(0.0, 1.0, 0.01) = 0.72;
+uniform float shoreline_minimum_reach : hint_range(0.1, 1.0, 0.01) = 0.48;
uniform float distant_alpha_start : hint_range(10.0, 2000.0, 1.0) = 260.0;
uniform float distant_alpha_end : hint_range(20.0, 5000.0, 1.0) = 1400.0;
uniform vec4 environment_tint : source_color = vec4(1.0);
uniform float environment_brightness : hint_range(0.1, 1.2, 0.01) = 1.0;
+uniform vec4 weather_fog_color : source_color = vec4(0.025, 0.038, 0.045, 1.0);
+uniform float weather_fog_amount : hint_range(0.0, 1.0, 0.01) = 0.0;
+uniform float weather_fog_near_amount : hint_range(0.0, 1.0, 0.01) = 0.0;
+uniform float weather_fog_begin : hint_range(0.0, 500.0, 0.5) = 20.0;
+uniform float weather_fog_end : hint_range(1.0, 1000.0, 0.5) = 95.0;
+uniform float weather_fog_curve : hint_range(0.1, 4.0, 0.01) = 1.4;
varying vec3 world_position;
varying float surface_view_depth;
+varying vec3 surface_view_position;
float hash_21(vec2 point) {
@@ -61,7 +85,63 @@ float value_noise(vec2 point) {
}
-float reconstruct_view_depth(
+float block_mark(vec2 point, vec2 half_size) {
+ return (
+ step(abs(point.x), half_size.x)
+ * step(abs(point.y), half_size.y)
+ );
+}
+
+
+float blocky_mark_layer(
+ vec2 flowing_grid,
+ float seed,
+ float occupancy_threshold
+) {
+ float row = floor(flowing_grid.y);
+ flowing_grid.x += mod(row, 2.0) * 0.43;
+ vec2 cell = floor(flowing_grid);
+ vec2 local = fract(flowing_grid) - vec2(0.5);
+ vec2 jitter = vec2(
+ hash_21(cell + vec2(3.7 + seed, 9.1)),
+ hash_21(cell + vec2(7.3, 2.9 + seed))
+ ) - vec2(0.5);
+ local -= jitter * vec2(0.52, 0.46);
+ local = floor((local + vec2(0.5)) * 8.0) / 8.0 - vec2(0.5);
+ float shape_key = hash_21(cell + vec2(13.1 + seed, 5.7));
+ float size_key = hash_21(cell + vec2(1.9, 17.3 + seed));
+ vec2 half_size = mix(vec2(0.10, 0.07), vec2(0.18, 0.12), size_key);
+ float mark = block_mark(local, half_size);
+ if (shape_key < 0.34) {
+ mark = max(
+ mark,
+ block_mark(
+ local - vec2(half_size.x * 0.8, -0.11),
+ vec2(half_size.x * 0.52, 0.045)
+ )
+ );
+ } else if (shape_key < 0.67) {
+ mark *= 1.0 - block_mark(
+ local - vec2(half_size.x * 0.7, 0.0),
+ vec2(0.045)
+ );
+ } else {
+ mark = max(
+ mark,
+ block_mark(
+ local + vec2(half_size.x * 0.75, 0.10),
+ vec2(0.055, 0.04)
+ )
+ );
+ }
+ return mark * step(
+ occupancy_threshold,
+ hash_21(cell + vec2(19.7 + seed, 23.3))
+ );
+}
+
+
+vec3 reconstruct_view_position(
vec2 screen_uv,
float raw_depth,
mat4 inverse_projection
@@ -72,22 +152,39 @@ float reconstruct_view_depth(
vec3 ndc = vec3(screen_uv * 2.0 - 1.0, raw_depth);
#endif
vec4 view_position = inverse_projection * vec4(ndc, 1.0);
- return -view_position.z / max(abs(view_position.w), 0.00001);
+ return view_position.xyz / max(abs(view_position.w), 0.00001);
+}
+
+
+vec3 reconstruct_world_position(
+ vec2 screen_uv,
+ float raw_depth,
+ mat4 inverse_projection,
+ mat4 inverse_view
+) {
+ vec3 view_position = reconstruct_view_position(
+ screen_uv,
+ raw_depth,
+ inverse_projection
+ );
+ return (inverse_view * vec4(view_position, 1.0)).xyz;
}
float sample_water_depth(
vec2 screen_uv,
- float water_surface_depth,
- mat4 inverse_projection
+ float water_surface_height,
+ mat4 inverse_projection,
+ mat4 inverse_view
) {
float raw_depth = texture(depth_texture, screen_uv).r;
- float scene_depth = reconstruct_view_depth(
+ vec3 scene_world_position = reconstruct_world_position(
screen_uv,
raw_depth,
- inverse_projection
+ inverse_projection,
+ inverse_view
);
- return scene_depth - water_surface_depth;
+ return water_surface_height - scene_world_position.y;
}
@@ -113,17 +210,24 @@ void vertex() {
vec4 view_vertex = VIEW_MATRIX * world_vertex;
world_position = world_vertex.xyz;
surface_view_depth = -view_vertex.z;
+ // Godot's depth fog measures radial view-space distance. Keep the existing
+ // forward depth for distant-water presentation, but pass the linear view
+ // position so weather fog can derive the same per-fragment radial metric as
+ // opaque world geometry. Calculating length here would interpolate four
+ // corner distances across the oversized ocean plane and over-fog its center.
+ surface_view_position = view_vertex.xyz;
}
void fragment() {
float raw_depth = texture(depth_texture, SCREEN_UV).r;
- float scene_view_depth = reconstruct_view_depth(
+ vec3 scene_world_position = reconstruct_world_position(
SCREEN_UV,
raw_depth,
- INV_PROJECTION_MATRIX
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
);
- float water_depth = max(scene_view_depth - surface_view_depth, 0.0);
+ float water_depth = max(world_position.y - scene_world_position.y, 0.0);
water_depth = min(water_depth, deep_depth * 4.0);
float contour_depth = water_depth;
@@ -137,23 +241,51 @@ void fragment() {
float contour_weight_sum = 1.0;
float left_depth = sample_water_depth(
SCREEN_UV - vec2(contour_texel.x, 0.0),
- surface_view_depth,
- INV_PROJECTION_MATRIX
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
);
float right_depth = sample_water_depth(
SCREEN_UV + vec2(contour_texel.x, 0.0),
- surface_view_depth,
- INV_PROJECTION_MATRIX
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
);
float upper_depth = sample_water_depth(
SCREEN_UV - vec2(0.0, contour_texel.y),
- surface_view_depth,
- INV_PROJECTION_MATRIX
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
);
float lower_depth = sample_water_depth(
SCREEN_UV + vec2(0.0, contour_texel.y),
- surface_view_depth,
- INV_PROJECTION_MATRIX
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
+ );
+ float upper_left_depth = sample_water_depth(
+ SCREEN_UV - contour_texel,
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
+ );
+ float upper_right_depth = sample_water_depth(
+ SCREEN_UV + vec2(contour_texel.x, -contour_texel.y),
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
+ );
+ float lower_left_depth = sample_water_depth(
+ SCREEN_UV + vec2(-contour_texel.x, contour_texel.y),
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
+ );
+ float lower_right_depth = sample_water_depth(
+ SCREEN_UV + contour_texel,
+ world_position.y,
+ INV_PROJECTION_MATRIX,
+ INV_VIEW_MATRIX
);
float left_weight = contour_neighbor_weight(
water_depth, left_depth, contour_depth_reject
@@ -167,11 +299,37 @@ void fragment() {
float lower_weight = contour_neighbor_weight(
water_depth, lower_depth, contour_depth_reject
);
+ float diagonal_scale = 0.70710678;
+ float upper_left_weight = contour_neighbor_weight(
+ water_depth, upper_left_depth, contour_depth_reject
+ ) * diagonal_scale;
+ float upper_right_weight = contour_neighbor_weight(
+ water_depth, upper_right_depth, contour_depth_reject
+ ) * diagonal_scale;
+ float lower_left_weight = contour_neighbor_weight(
+ water_depth, lower_left_depth, contour_depth_reject
+ ) * diagonal_scale;
+ float lower_right_weight = contour_neighbor_weight(
+ water_depth, lower_right_depth, contour_depth_reject
+ ) * diagonal_scale;
contour_depth_sum += left_depth * left_weight;
contour_depth_sum += right_depth * right_weight;
contour_depth_sum += upper_depth * upper_weight;
contour_depth_sum += lower_depth * lower_weight;
- float neighbor_support = left_weight + right_weight + upper_weight + lower_weight;
+ contour_depth_sum += upper_left_depth * upper_left_weight;
+ contour_depth_sum += upper_right_depth * upper_right_weight;
+ contour_depth_sum += lower_left_depth * lower_left_weight;
+ contour_depth_sum += lower_right_depth * lower_right_weight;
+ float neighbor_support = (
+ left_weight
+ + right_weight
+ + upper_weight
+ + lower_weight
+ + upper_left_weight
+ + upper_right_weight
+ + lower_left_weight
+ + lower_right_weight
+ );
contour_weight_sum += neighbor_support;
float smoothed_contour_depth = contour_depth_sum / contour_weight_sum;
contour_depth = mix(
@@ -182,6 +340,35 @@ void fragment() {
contour_feature_support = smoothstep(0.75, 1.75, neighbor_support);
}
+ vec2 scene_world_dx = dFdx(scene_world_position.xz);
+ vec2 scene_world_dy = dFdy(scene_world_position.xz);
+ float horizontal_dx = max(length(scene_world_dx), 0.0001);
+ float horizontal_dy = max(length(scene_world_dy), 0.0001);
+ float depth_gradient = length(vec2(
+ dFdx(water_depth) / horizontal_dx,
+ dFdy(water_depth) / horizontal_dy
+ ));
+ float estimated_shore_distance = min(
+ water_depth / max(depth_gradient, 0.001),
+ shoreline_horizontal_reach * 4.0
+ );
+ float proximity_center = shoreline_horizontal_reach * 0.86;
+ float proximity_filter_width = max(
+ fwidth(estimated_shore_distance) * 1.5,
+ shoreline_horizontal_reach * 0.12
+ );
+ float shoreline_proximity = 1.0 - smoothstep(
+ max(proximity_center - proximity_filter_width, 0.0),
+ proximity_center + proximity_filter_width,
+ estimated_shore_distance
+ );
+ float contact_filter_width = max(fwidth(water_depth) * 1.5, 0.004);
+ float contact_stability = smoothstep(
+ max(contact_fade_depth - contact_filter_width, 0.0),
+ contact_fade_depth + contact_filter_width,
+ water_depth
+ );
+
float shallow_mix = smoothstep(0.0, shallow_depth, water_depth);
float deep_mix = smoothstep(shallow_depth, deep_depth, water_depth);
vec3 water_color = mix(shore_color.rgb, shallow_color.rgb, shallow_mix);
@@ -207,6 +394,7 @@ void fragment() {
contour_depth
);
tide_wash *= contour_feature_support;
+ tide_wash *= shoreline_proximity;
tide_wash *= 1.0 - smoothstep(shallow_depth, deep_depth, water_depth);
water_color = mix(
water_color,
@@ -220,6 +408,126 @@ void fragment() {
);
}
+ vec2 flowing_grid = (
+ world_position.xz * surface_mark_density
+ + TIME * surface_mark_drift
+ );
+ float surface_row = floor(flowing_grid.y);
+ flowing_grid.x += mod(surface_row, 2.0) * 0.43;
+ vec2 surface_cell = floor(flowing_grid);
+ vec2 surface_local = fract(flowing_grid) - vec2(0.5);
+ vec2 surface_jitter = vec2(
+ hash_21(surface_cell + vec2(3.7, 9.1)),
+ hash_21(surface_cell + vec2(7.3, 2.9))
+ ) - vec2(0.5);
+ surface_local -= surface_jitter * vec2(0.52, 0.46);
+ surface_local = (
+ floor((surface_local + vec2(0.5)) * 8.0) / 8.0
+ - vec2(0.5)
+ );
+ float surface_shape = hash_21(surface_cell + vec2(13.1, 5.7));
+ float surface_size = hash_21(surface_cell + vec2(1.9, 17.3));
+ vec2 surface_half_size = mix(
+ vec2(0.10, 0.07),
+ vec2(0.18, 0.12),
+ surface_size
+ );
+ float surface_mark = block_mark(surface_local, surface_half_size);
+ if (surface_shape < 0.34) {
+ surface_mark = max(
+ surface_mark,
+ block_mark(
+ surface_local - vec2(surface_half_size.x * 0.8, -0.11),
+ vec2(surface_half_size.x * 0.52, 0.045)
+ )
+ );
+ } else if (surface_shape < 0.67) {
+ surface_mark *= 1.0 - block_mark(
+ surface_local - vec2(surface_half_size.x * 0.7, 0.0),
+ vec2(0.045)
+ );
+ } else {
+ surface_mark = max(
+ surface_mark,
+ block_mark(
+ surface_local + vec2(surface_half_size.x * 0.75, 0.10),
+ vec2(0.055, 0.04)
+ )
+ );
+ }
+ surface_mark *= step(
+ 0.22,
+ hash_21(surface_cell + vec2(19.7, 23.3))
+ );
+ float mark_visibility = mix(1.0, 0.68, deep_mix);
+ float surface_highlight = (
+ surface_mark * surface_mark_strength * mark_visibility
+ );
+
+ vec2 shoreline_phase_coordinates = world_position.xz * phase_noise_scale;
+ float shoreline_phase = (
+ value_noise(shoreline_phase_coordinates)
+ + value_noise(
+ shoreline_phase_coordinates * 0.47 + vec2(9.7, 3.1)
+ ) * 0.5
+ - 0.75
+ ) * phase_noise_strength;
+ float shoreline_cycle = (
+ sin(TIME * tide_speed + shoreline_phase) * 0.5 + 0.5
+ );
+ float animated_shoreline_depth = shoreline_mark_depth * mix(
+ shoreline_minimum_reach,
+ 1.0,
+ shoreline_cycle
+ );
+ float shoreline_mask = 1.0 - smoothstep(
+ max(animated_shoreline_depth * 0.08, 0.01),
+ max(animated_shoreline_depth, 0.02),
+ contour_depth
+ );
+ float shoreline_depth_visibility = 1.0 - smoothstep(
+ shallow_depth,
+ deep_depth,
+ water_depth
+ );
+ shoreline_mask *= shoreline_depth_visibility;
+ float shoreline_marks = max(
+ blocky_mark_layer(
+ world_position.xz * shoreline_mark_density
+ + TIME * shoreline_mark_drift,
+ 17.0,
+ 0.04
+ ),
+ blocky_mark_layer(
+ world_position.xz * shoreline_mark_density * 1.37
+ - TIME * shoreline_mark_drift.yx * 0.73,
+ 41.0,
+ 0.08
+ )
+ );
+ float shoreline_foam = shoreline_mask * mix(
+ shoreline_base_fill,
+ 1.0,
+ shoreline_marks
+ );
+ shoreline_foam *= shoreline_proximity;
+ water_alpha = min(
+ water_alpha + shoreline_foam * shoreline_opacity_boost,
+ 0.98
+ );
+ // Preserve most of the water layer at exact terrain contact. Fully fading
+ // it exposed the sand texture as a broken tan seam along the water plane.
+ water_alpha *= mix(0.82, 1.0, contact_stability);
+
+ float surface_mottle = value_noise(
+ world_position.xz * surface_mottle_scale
+ + TIME * surface_mottle_speed
+ );
+ surface_mottle = floor(surface_mottle * 6.0) / 5.0;
+ water_color *= 1.0 + (
+ surface_mottle * 2.0 - 1.0
+ ) * surface_mottle_strength;
+
vec2 drift_coordinates = (
world_position.xz * open_water_drift_scale
+ TIME * open_water_drift_speed
@@ -236,9 +544,48 @@ void fragment() {
water_alpha = mix(water_alpha, 0.96, distant_mix);
water_color *= environment_tint.rgb * environment_brightness;
+ vec3 visible_highlight_color = surface_mark_color.rgb * max(
+ environment_tint.rgb * environment_brightness,
+ vec3(surface_highlight_night_floor)
+ );
+ float visible_highlight = max(
+ surface_highlight,
+ shoreline_foam * shoreline_mark_strength
+ );
+ water_color = mix(
+ water_color,
+ visible_highlight_color,
+ clamp(visible_highlight, 0.0, 1.0)
+ );
+ float surface_view_distance = length(surface_view_position);
+ float weather_fog_distance = smoothstep(
+ weather_fog_begin,
+ max(weather_fog_end, weather_fog_begin + 1.0),
+ surface_view_distance
+ );
+ weather_fog_distance = pow(
+ clamp(weather_fog_distance, 0.0, 1.0),
+ weather_fog_curve
+ );
+ float distance_fog_mix = weather_fog_amount * weather_fog_distance;
+ float weather_fog_mix = 1.0 - (
+ (1.0 - weather_fog_near_amount)
+ * (1.0 - distance_fog_mix)
+ );
+ water_color = mix(
+ water_color,
+ weather_fog_color.rgb,
+ weather_fog_mix
+ );
+ float weather_fog_alpha = mix(
+ 0.96,
+ 1.0,
+ weather_fog_near_amount
+ );
+ water_alpha = mix(water_alpha, weather_fog_alpha, weather_fog_mix);
ALBEDO = water_color;
- ALPHA = clamp(water_alpha, 0.1, 0.96);
+ ALPHA = clamp(water_alpha, 0.1, weather_fog_alpha);
METALLIC = 0.0;
SPECULAR = 0.0;
ROUGHNESS = 1.0;
diff --git a/world/materials/stylized_water.tres b/world/materials/stylized_water.tres
index 100c598..7f4671a 100644
--- a/world/materials/stylized_water.tres
+++ b/world/materials/stylized_water.tres
@@ -1,6 +1,6 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://6lafg0ac2qul"]
-[ext_resource type="Shader" path="res://world/materials/stylized_water.gdshader" id="1_water_shader"]
+[ext_resource type="Shader" uid="uid://lvo7xyr3c1k3" path="res://world/materials/stylized_water.gdshader" id="1_water_shader"]
[resource]
render_priority = 0
@@ -11,25 +11,42 @@ shader_parameter/deep_color = Color(0.109804, 0.345098, 0.435294, 1)
shader_parameter/tide_wash_color = Color(0.360784, 0.721569, 0.733333, 1)
shader_parameter/shallow_depth = 0.7
shader_parameter/deep_depth = 3.6
-shader_parameter/shore_depth_width = 0.16
-shader_parameter/shore_alpha = 0.44
-shader_parameter/shallow_alpha = 0.6
-shader_parameter/deep_alpha = 0.82
+shader_parameter/shore_depth_width = 0.1
+shader_parameter/shore_alpha = 0.68
+shader_parameter/shallow_alpha = 0.78
+shader_parameter/deep_alpha = 0.9
shader_parameter/tide_effect_enabled = true
shader_parameter/tide_speed = 1.42
-shader_parameter/tide_distance = 0.3
-shader_parameter/tide_wash_width = 0.38
+shader_parameter/tide_distance = 0.11
+shader_parameter/tide_wash_width = 0.16
shader_parameter/tide_wash_strength = 0.11
shader_parameter/tide_wash_alpha_shift = 0.045
shader_parameter/phase_noise_scale = 0.055
shader_parameter/phase_noise_strength = 0.68
-shader_parameter/contour_corner_variation = 0.045
-shader_parameter/contour_smoothing_pixels = 1.0
-shader_parameter/contour_smoothing_strength = 0.72
+shader_parameter/contour_corner_variation = 0.025
+shader_parameter/contour_smoothing_pixels = 1.35
+shader_parameter/contour_smoothing_strength = 0.88
shader_parameter/contour_depth_reject = 0.6
+shader_parameter/shoreline_horizontal_reach = 0.32
+shader_parameter/contact_fade_depth = 0.018
shader_parameter/open_water_drift_scale = 0.018
shader_parameter/open_water_drift_speed = Vector2(0.01, -0.007)
shader_parameter/open_water_drift_strength = 0.045
+shader_parameter/surface_mark_color = Color(0.58, 0.85, 0.86, 1)
+shader_parameter/surface_mark_density = Vector2(1.5, 1.05)
+shader_parameter/surface_mark_drift = Vector2(0.045, -0.032)
+shader_parameter/surface_mark_strength = 0.12
+shader_parameter/surface_mottle_scale = 0.11
+shader_parameter/surface_mottle_speed = Vector2(-0.018, 0.013)
+shader_parameter/surface_mottle_strength = 0.07
+shader_parameter/shoreline_mark_density = Vector2(4.6, 3.2)
+shader_parameter/shoreline_mark_drift = Vector2(0.085, -0.06)
+shader_parameter/shoreline_mark_depth = 0.55
+shader_parameter/shoreline_mark_strength = 0.95
+shader_parameter/shoreline_base_fill = 0.58
+shader_parameter/shoreline_opacity_boost = 0.38
+shader_parameter/surface_highlight_night_floor = 0.72
+shader_parameter/shoreline_minimum_reach = 0.22
shader_parameter/distant_alpha_start = 260.0
shader_parameter/distant_alpha_end = 1400.0
shader_parameter/environment_tint = Color(1, 1, 1, 1)
diff --git a/world/materials/stylized_water_fresh.tres b/world/materials/stylized_water_fresh.tres
index 6634e2a..5fe4c8f 100644
--- a/world/materials/stylized_water_fresh.tres
+++ b/world/materials/stylized_water_fresh.tres
@@ -1,6 +1,6 @@
-[gd_resource type="ShaderMaterial" load_steps=2 format=3]
+[gd_resource type="ShaderMaterial" format=3 uid="uid://d27er7sx5bcqw"]
-[ext_resource type="Shader" path="res://world/materials/stylized_water.gdshader" id="1_water_shader"]
+[ext_resource type="Shader" uid="uid://lvo7xyr3c1k3" path="res://world/materials/stylized_water.gdshader" id="1_water_shader"]
[resource]
render_priority = 0
@@ -11,14 +11,42 @@ shader_parameter/deep_color = Color(0.109804, 0.345098, 0.435294, 1)
shader_parameter/tide_wash_color = Color(0.360784, 0.721569, 0.733333, 1)
shader_parameter/shallow_depth = 0.7
shader_parameter/deep_depth = 3.6
-shader_parameter/shore_depth_width = 0.16
-shader_parameter/shore_alpha = 0.44
-shader_parameter/shallow_alpha = 0.6
-shader_parameter/deep_alpha = 0.82
+shader_parameter/shore_depth_width = 0.1
+shader_parameter/shore_alpha = 0.68
+shader_parameter/shallow_alpha = 0.78
+shader_parameter/deep_alpha = 0.9
shader_parameter/tide_effect_enabled = false
+shader_parameter/tide_speed = 1.42
+shader_parameter/tide_distance = 0.3
+shader_parameter/tide_wash_width = 0.38
+shader_parameter/tide_wash_strength = 0.11
+shader_parameter/tide_wash_alpha_shift = 0.045
+shader_parameter/phase_noise_scale = 0.055
+shader_parameter/phase_noise_strength = 0.68
+shader_parameter/contour_corner_variation = 0.045
+shader_parameter/contour_smoothing_pixels = 1.35
+shader_parameter/contour_smoothing_strength = 0.88
+shader_parameter/contour_depth_reject = 0.6
+shader_parameter/shoreline_horizontal_reach = 0.32
+shader_parameter/contact_fade_depth = 0.018
shader_parameter/open_water_drift_scale = 0.018
shader_parameter/open_water_drift_speed = Vector2(0.01, -0.007)
shader_parameter/open_water_drift_strength = 0.045
+shader_parameter/surface_mark_color = Color(0.58, 0.85, 0.86, 1)
+shader_parameter/surface_mark_density = Vector2(1.5, 1.05)
+shader_parameter/surface_mark_drift = Vector2(0.045, -0.032)
+shader_parameter/surface_mark_strength = 0.12
+shader_parameter/surface_mottle_scale = 0.11
+shader_parameter/surface_mottle_speed = Vector2(-0.018, 0.013)
+shader_parameter/surface_mottle_strength = 0.07
+shader_parameter/shoreline_mark_density = Vector2(4.6, 3.2)
+shader_parameter/shoreline_mark_drift = Vector2(0.085, -0.06)
+shader_parameter/shoreline_mark_depth = 0.55
+shader_parameter/shoreline_mark_strength = 0.95
+shader_parameter/shoreline_base_fill = 0.58
+shader_parameter/shoreline_opacity_boost = 0.38
+shader_parameter/surface_highlight_night_floor = 0.72
+shader_parameter/shoreline_minimum_reach = 0.22
shader_parameter/distant_alpha_start = 260.0
shader_parameter/distant_alpha_end = 1400.0
shader_parameter/environment_tint = Color(1, 1, 1, 1)
diff --git a/world/rain_ambience.gd b/world/rain_ambience.gd
new file mode 100644
index 0000000..acea9fd
--- /dev/null
+++ b/world/rain_ambience.gd
@@ -0,0 +1,121 @@
+class_name RainAmbience
+extends AudioStreamPlayer
+
+const RAIN_STREAM_PATH: String = (
+ "res://audio/ambience/rain_loop_ontario.ogg"
+)
+const SILENT_VOLUME_DB: float = -60.0
+
+@export_range(-40.0, 0.0, 0.5) var rain_volume_db: float = -8.0
+@export_range(0.0, 10.0, 0.1) var fade_seconds: float = 2.5
+
+var _weather_service: WorldWeatherService
+var _fade_tween: Tween
+var _is_active: bool = false
+
+
+func _ready() -> void:
+ bus = &"Environment"
+ var rain_stream := load(RAIN_STREAM_PATH) as AudioStreamOggVorbis
+ var runtime_stream := (
+ rain_stream.duplicate() as AudioStreamOggVorbis
+ if rain_stream != null
+ else null
+ )
+ if runtime_stream != null:
+ runtime_stream.loop = true
+ stream = runtime_stream
+ volume_db = SILENT_VOLUME_DB
+
+
+func configure(weather_service: WorldWeatherService) -> void:
+ if (
+ _weather_service != null
+ and _weather_service.weather_changed.is_connected(
+ _on_weather_changed
+ )
+ ):
+ _weather_service.weather_changed.disconnect(_on_weather_changed)
+ _weather_service = weather_service
+ if (
+ _weather_service != null
+ and not _weather_service.weather_changed.is_connected(
+ _on_weather_changed
+ )
+ ):
+ _weather_service.weather_changed.connect(_on_weather_changed)
+
+
+func set_active(active: bool) -> void:
+ if _is_active == active:
+ return
+ _is_active = active
+ if not active:
+ _silence_immediately()
+ return
+ _transition_to_rain(
+ _weather_service != null and _weather_service.is_raining()
+ )
+
+
+func _on_weather_changed(
+ weather: WorldWeatherService.Weather,
+ _seconds_remaining: float,
+) -> void:
+ _transition_to_rain(weather == WorldWeatherService.Weather.RAINY)
+
+
+func _transition_to_rain(is_raining: bool) -> void:
+ if not _is_active:
+ return
+ _stop_fade()
+ if is_raining:
+ if stream == null:
+ return
+ if not playing:
+ volume_db = SILENT_VOLUME_DB
+ play()
+ _fade_volume_to(rain_volume_db, false)
+ return
+ if playing:
+ _fade_volume_to(SILENT_VOLUME_DB, true)
+
+
+func _fade_volume_to(target_volume_db: float, stop_after_fade: bool) -> void:
+ if fade_seconds <= 0.0:
+ volume_db = target_volume_db
+ if stop_after_fade:
+ _finish_fade_out()
+ return
+ _fade_tween = create_tween()
+ _fade_tween.set_trans(Tween.TRANS_SINE)
+ _fade_tween.set_ease(Tween.EASE_IN_OUT)
+ _fade_tween.tween_property(
+ self,
+ "volume_db",
+ target_volume_db,
+ fade_seconds,
+ )
+ if stop_after_fade:
+ _fade_tween.tween_callback(_finish_fade_out)
+
+
+func _finish_fade_out() -> void:
+ if _weather_service != null and _weather_service.is_raining():
+ return
+ stop()
+ volume_db = SILENT_VOLUME_DB
+ _fade_tween = null
+
+
+func _silence_immediately() -> void:
+ _stop_fade()
+ stop()
+ volume_db = SILENT_VOLUME_DB
+
+
+func _stop_fade() -> void:
+ if _fade_tween == null:
+ return
+ _fade_tween.kill()
+ _fade_tween = null
diff --git a/world/rain_ambience.gd.uid b/world/rain_ambience.gd.uid
new file mode 100644
index 0000000..0eccbff
--- /dev/null
+++ b/world/rain_ambience.gd.uid
@@ -0,0 +1 @@
+uid://dbpt2uqm82kmn
diff --git a/world/regions/starter_island_region.gd b/world/regions/starter_island_region.gd
index c03243f..4c8880c 100644
--- a/world/regions/starter_island_region.gd
+++ b/world/regions/starter_island_region.gd
@@ -5,14 +5,22 @@ extends WorldRegion
const FishingShopInteractionType = preload(
"res://world/fishing_shop_interaction.gd"
)
-const GRASS_SURFACE_NAME: String = "grass_lite"
-const SAND_SURFACE_NAME: String = "sand"
+const FOLIAGE_WIND_SHADER: Shader = preload(
+ "res://world/materials/foliage_wind.gdshader"
+)
+const FOLIAGE_MATERIAL_NAMES: Array[StringName] = [
+ &"leaf",
+ &"leaf_light",
+ &"leaf_dark",
+]
@export_group("Owned Nodes")
@export_node_path("MeshInstance3D")
var visual_mesh_path: NodePath = (
^"Terrain/Visual/starter_island"
)
+@export_node_path("Node3D")
+var terrain_visual_root_path: NodePath = ^"Terrain/Visual"
@export_node_path("CollisionShape3D")
var terrain_collision_shape_path: NodePath = (
^"Terrain/Collision/Shape"
@@ -23,24 +31,18 @@ var player_spawn_path: NodePath = ^"PlayerSpawn"
var fishing_shop_path: NodePath = (
^"Interactables/FishingShopWorld/InteractionArea"
)
-@export_node_path("Node3D")
-var pelican_landmark_path: NodePath = (
- ^"Interactables/PelicanCoolerPerch"
-)
-
-@export_group("Grass Surface")
-@export var grass_material: Material
-@export_range(0, 16, 1) var grass_surface_index: int = 0
-
-@export_group("Sand Surface")
-@export var sand_material: Material
-@export_range(0, 16, 1) var sand_surface_index: int = 2
-
+@export_group("Terrain Collision")
+# The imported GLB is the collision authority. Rebuild once per region load so
+# newly authored terrain and props cannot retain a stale saved fallback shape.
+@export var rebuild_terrain_collision_on_ready: bool = true
+@export_group("Foliage Wind")
+@export_range(0.0, 0.4, 0.005) var foliage_wind_strength: float = 0.36
+@export_range(0.0, 4.0, 0.05) var foliage_wind_speed: float = 0.9
func _ready() -> void:
- _apply_grass_material()
- _apply_sand_material()
- _build_terrain_collision()
+ if rebuild_terrain_collision_on_ready or not has_terrain_collision():
+ _build_terrain_collision()
+ _apply_foliage_wind()
if Engine.is_editor_hint():
update_configuration_warnings()
@@ -54,10 +56,6 @@ func get_fishing_shop() -> FishingShopInteractionType:
return get_node_or_null(fishing_shop_path) as FishingShopInteractionType
-func get_pelican_landmark() -> Node3D:
- return get_node_or_null(pelican_landmark_path) as Node3D
-
-
func get_saltwater_shoreline_mesh() -> MeshInstance3D:
return get_node_or_null(^"ShorelineRibbons/Ocean") as MeshInstance3D
@@ -69,108 +67,143 @@ func has_terrain_collision() -> bool:
return collision_shape != null and collision_shape.shape != null
-func _apply_grass_material() -> void:
- var visual_mesh: MeshInstance3D = (
- get_node_or_null(visual_mesh_path) as MeshInstance3D
- )
- if visual_mesh == null or visual_mesh.mesh == null:
- push_error("Starter island visual mesh is unavailable.")
- return
- if grass_material == null:
- push_error("Starter island grass material is unavailable.")
- return
- if grass_surface_index >= visual_mesh.mesh.get_surface_count():
- push_error("Starter island grass surface index is invalid.")
- return
- if (
- visual_mesh.mesh.surface_get_name(grass_surface_index)
- != GRASS_SURFACE_NAME
- ):
- push_error("Starter island grass surface name does not match.")
- return
- visual_mesh.set_surface_override_material(
- grass_surface_index,
- grass_material
- )
-
-
-func _apply_sand_material() -> void:
- var visual_mesh: MeshInstance3D = (
- get_node_or_null(visual_mesh_path) as MeshInstance3D
- )
- if visual_mesh == null or visual_mesh.mesh == null:
- push_error("Starter island visual mesh is unavailable.")
- return
- if sand_material == null:
- push_error("Starter island sand material is unavailable.")
- return
- if sand_surface_index >= visual_mesh.mesh.get_surface_count():
- push_error("Starter island sand surface index is invalid.")
- return
- if (
- visual_mesh.mesh.surface_get_name(sand_surface_index)
- != SAND_SURFACE_NAME
- ):
- push_error("Starter island sand surface name does not match.")
- return
- visual_mesh.set_surface_override_material(
- sand_surface_index,
- sand_material
- )
-
-
func _build_terrain_collision() -> void:
- var visual_mesh: MeshInstance3D = (
- get_node_or_null(visual_mesh_path) as MeshInstance3D
- )
+ var terrain_root: Node = get_node_or_null(terrain_visual_root_path)
+ if terrain_root == null:
+ terrain_root = get_node_or_null(visual_mesh_path)
var collision_shape: CollisionShape3D = (
get_node_or_null(terrain_collision_shape_path) as CollisionShape3D
)
- if visual_mesh == null or visual_mesh.mesh == null:
- push_error("Starter island visual mesh is unavailable.")
+ if terrain_root == null:
+ push_error("Starter island visual terrain root is unavailable.")
return
if collision_shape == null:
push_error("Starter island collision owner is unavailable.")
return
- var terrain_shape: ConcavePolygonShape3D = (
- visual_mesh.mesh.create_trimesh_shape()
- )
- if terrain_shape == null or terrain_shape.get_faces().is_empty():
+ var mesh_instances := _collect_terrain_mesh_instances(terrain_root)
+ if mesh_instances.is_empty():
+ var visual_mesh: MeshInstance3D = terrain_root as MeshInstance3D
+ if visual_mesh == null or visual_mesh.mesh == null:
+ push_error("Starter island visual mesh is unavailable.")
+ return
+ var fallback_shape: ConcavePolygonShape3D = (
+ visual_mesh.mesh.create_trimesh_shape()
+ )
+ if fallback_shape == null or fallback_shape.get_faces().is_empty():
+ push_error("Starter island terrain collision could not be created.")
+ return
+ collision_shape.shape = fallback_shape
+ return
+ var terrain_shape := ConcavePolygonShape3D.new()
+ var faces := PackedVector3Array()
+ for mesh_instance: MeshInstance3D in mesh_instances:
+ var mesh: Mesh = mesh_instance.mesh
+ if mesh == null:
+ continue
+ var mesh_shape := mesh.create_trimesh_shape()
+ if mesh_shape == null:
+ continue
+ for face_vertex: Vector3 in mesh_shape.get_faces():
+ faces.append(to_local(mesh_instance.to_global(face_vertex)))
+ if faces.is_empty():
push_error("Starter island terrain collision could not be created.")
return
+ terrain_shape.set_faces(faces)
collision_shape.shape = terrain_shape
+func _collect_terrain_mesh_instances(root: Node) -> Array[MeshInstance3D]:
+ var mesh_instances: Array[MeshInstance3D] = []
+ if root is MeshInstance3D:
+ mesh_instances.append(root as MeshInstance3D)
+ for child: Node in root.get_children():
+ mesh_instances.append_array(_collect_terrain_mesh_instances(child))
+ return mesh_instances
+
+
+func _apply_foliage_wind() -> void:
+ var terrain_root: Node = get_node_or_null(terrain_visual_root_path)
+ if terrain_root == null:
+ return
+ for mesh_instance: MeshInstance3D in _collect_terrain_mesh_instances(
+ terrain_root
+ ):
+ _apply_foliage_wind_to_mesh(mesh_instance)
+
+
+func _apply_foliage_wind_to_mesh(mesh_instance: MeshInstance3D) -> void:
+ if mesh_instance.mesh == null:
+ return
+ var bounds: AABB = mesh_instance.get_aabb()
+ var mesh_global_scale: Vector3 = mesh_instance.global_basis.get_scale().abs()
+ var horizontal_scale: float = maxf(
+ (mesh_global_scale.x + mesh_global_scale.z) * 0.5,
+ 0.001,
+ )
+ var local_strength: float = foliage_wind_strength / horizontal_scale
+ var phase: float = fposmod(
+ mesh_instance.global_position.x * 0.73
+ + mesh_instance.global_position.z * 0.41,
+ TAU,
+ )
+ for surface_index: int in mesh_instance.mesh.get_surface_count():
+ var source_material: Material = mesh_instance.get_active_material(
+ surface_index
+ )
+ if not source_material is StandardMaterial3D:
+ continue
+ if not FOLIAGE_MATERIAL_NAMES.has(
+ StringName(source_material.resource_name)
+ ):
+ continue
+ var source_standard := source_material as StandardMaterial3D
+ var wind_material := ShaderMaterial.new()
+ wind_material.shader = FOLIAGE_WIND_SHADER
+ wind_material.set_shader_parameter(
+ "albedo_color",
+ source_standard.albedo_color,
+ )
+ wind_material.set_shader_parameter(
+ "material_roughness",
+ source_standard.roughness,
+ )
+ wind_material.set_shader_parameter(
+ "material_metallic",
+ source_standard.metallic,
+ )
+ wind_material.set_shader_parameter("local_min_y", bounds.position.y)
+ wind_material.set_shader_parameter(
+ "local_height",
+ maxf(bounds.size.y, 0.001),
+ )
+ wind_material.set_shader_parameter(
+ "local_wind_strength",
+ local_strength,
+ )
+ wind_material.set_shader_parameter("wind_speed", foliage_wind_speed)
+ wind_material.set_shader_parameter("wind_phase", phase)
+ mesh_instance.set_surface_override_material(
+ surface_index,
+ wind_material,
+ )
+
+
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
var visual_mesh := get_node_or_null(visual_mesh_path) as MeshInstance3D
+ if visual_mesh == null:
+ warnings.append("Terrain/Visual terrain mesh node is unavailable.")
+ return warnings
if visual_mesh == null or visual_mesh.mesh == null:
warnings.append("Terrain/Visual must provide the island mesh.")
- elif grass_surface_index >= visual_mesh.mesh.get_surface_count():
- warnings.append("Grass surface index is outside the terrain mesh.")
- elif (
- visual_mesh.mesh.surface_get_name(grass_surface_index)
- != GRASS_SURFACE_NAME
- ):
- warnings.append("Grass surface index must identify the grass surface.")
- if grass_material == null:
- warnings.append("Assign the starter-island grass material.")
- if visual_mesh != null and visual_mesh.mesh != null:
- if sand_surface_index >= visual_mesh.mesh.get_surface_count():
- warnings.append("Sand surface index is outside the terrain mesh.")
- elif (
- visual_mesh.mesh.surface_get_name(sand_surface_index)
- != SAND_SURFACE_NAME
- ):
- warnings.append("Sand surface index must identify the sand surface.")
- if sand_material == null:
- warnings.append("Assign the starter-island sand material.")
+ return warnings
+
if get_node_or_null(terrain_collision_shape_path) == null:
warnings.append("Terrain/Collision must provide a collision shape.")
+ if get_node_or_null(terrain_visual_root_path) == null:
+ warnings.append("Terrain/Visual root is missing for terrain collision generation.")
if get_node_or_null(player_spawn_path) == null:
warnings.append("PlayerSpawn marker is missing.")
if get_node_or_null(fishing_shop_path) == null:
warnings.append("Fishing Shop placement is missing.")
- if get_node_or_null(pelican_landmark_path) == null:
- warnings.append("Pelican placement is missing.")
return warnings
diff --git a/world/regions/starter_island_region.tscn b/world/regions/starter_island_region.tscn
index 8345704..d956feb 100644
--- a/world/regions/starter_island_region.tscn
+++ b/world/regions/starter_island_region.tscn
@@ -8,16 +8,13 @@
[ext_resource type="Script" uid="uid://dnlbnlimgxoc2" path="res://world/player_water_trigger.gd" id="5_trigger"]
[ext_resource type="Script" uid="uid://df2lsduguegxh" path="res://world/safe_respawn_point.gd" id="6_safe"]
[ext_resource type="PackedScene" path="res://world/interactables/fishing_shop_world.tscn" id="7_shop"]
-[ext_resource type="PackedScene" path="res://world/interactables/pelican_buyer_world.tscn" id="8_pelican"]
-[ext_resource type="Material" path="res://world/materials/starter_island_grass.tres" id="9_grass"]
[ext_resource type="Script" uid="uid://dtcgnxl1kmdu1" path="res://world/water_body_authoring.gd" id="10_water_body"]
-[ext_resource type="Material" path="res://world/materials/starter_island_sand.tres" id="11_sand"]
[ext_resource type="Material" path="res://world/materials/stylized_water.tres" id="13_water"]
-[ext_resource type="Script" path="res://world/water/shoreline_ribbon_baker.gd" id="14_shoreline_baker"]
-[ext_resource type="Script" path="res://world/water/shoreline_ribbon_config.gd" id="15_shoreline_config"]
[ext_resource type="ArrayMesh" path="res://world/generated/shorelines/starter_ocean_shoreline.tres" id="17_ocean_shoreline"]
-[ext_resource type="Material" path="res://world/materials/shoreline_tide.tres" id="18_shoreline_material"]
[ext_resource type="Material" path="res://world/materials/stylized_water_fresh.tres" id="19_fresh_water"]
+[ext_resource type="Script" path="res://world/water_surface_motion.gd" id="20_surface_motion"]
+[ext_resource type="Script" path="res://world/water/shoreline_ribbon_baker.gd" id="21_shoreline_baker"]
+[ext_resource type="Script" path="res://world/water/shoreline_ribbon_config.gd" id="22_shoreline_config"]
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_4e4k5"]
data = PackedVector3Array(10.033899, 3.3913999, 3.3446, 13.3786, 3.3913999, 0, 13.3786, 3.3913999, 3.3446, 10.033899, 3.3913999, 3.3446, 10.033899, 3.3913999, 0, 13.3786, 3.3913999, 0, 6.6893, 3.3913999, 3.3446, 10.033899, 3.3913999, 0, 10.033899, 3.3913999, 3.3446, 6.6893, 3.3913999, 3.3446, 6.6893, 3.3913999, 0, 10.033899, 3.3913999, 0, 6.6893, 3.3913999, 0, 10.033899, 3.3913999, -3.3446, 10.033899, 3.3913999, 0, 6.6893, 3.3913999, 6.6893, 6.6893, 3.3913999, 3.3446, 10.033899, 3.3913999, 3.3446, 6.6893, 3.3913999, 6.6893, 10.033899, 3.3913999, 3.3446, 10.033899, 3.3913999, 6.6893, 3.3446, 3.3913999, 3.3446, 6.6893, 3.3913999, 0, 6.6893, 3.3913999, 3.3446, 6.6893, 3.3913999, 10.033899, 6.6893, 3.3913999, 6.6893, 10.033899, 3.3913999, 6.6893, 6.6893, 3.3913999, 10.033899, 10.033899, 3.3913999, 6.6893, 10.033899, 3.3913999, 10.033899, 3.3446, 3.3913999, 6.6893, 6.6893, 3.3913999, 3.3446, 6.6893, 3.3913999, 6.6893, 3.3446, 3.3913999, 6.6893, 3.3446, 3.3913999, 3.3446, 6.6893, 3.3913999, 3.3446, 3.3446, 3.3913999, 10.033899, 6.6893, 3.3913999, 6.6893, 6.6893, 3.3913999, 10.033899, 3.3446, 3.3913999, 10.033899, 3.3446, 3.3913999, 6.6893, 6.6893, 3.3913999, 6.6893, 0, 3.3913999, 6.6893, 3.3446, 3.3913999, 3.3446, 3.3446, 3.3913999, 6.6893, 0, 3.3913999, 6.6893, 0, 3.3913999, 3.3446, 3.3446, 3.3913999, 3.3446, 0, 3.3913999, 10.033899, 0, 3.3913999, 6.6893, 3.3446, 3.3913999, 6.6893, 0, 3.3913999, 10.033899, 3.3446, 3.3913999, 6.6893, 3.3446, 3.3913999, 10.033899, -3.3446, 3.3913999, 13.3786, -3.3446, 3.3913999, 10.033899, 0, 3.3913999, 10.033899, -3.3446, 3.3913999, 13.3786, 0, 3.3913999, 10.033899, 0, 3.3913999, 13.3786, 0, 3.3913999, 13.3786, 0, 3.3913999, 10.033899, 3.3446, 3.3913999, 10.033899, 0, 3.3913999, 13.3786, 3.3446, 3.3913999, 10.033899, 3.3446, 3.3913999, 13.3786, 3.3446, 3.3913999, 13.3786, 3.3446, 3.3913999, 10.033899, 6.6893, 3.3913999, 10.033899, 3.3446, 3.3913999, 13.3786, 6.6893, 3.3913999, 10.033899, 6.6893, 3.3913999, 13.3786, 3.9148, 3.3913999, 16.514599, 3.3446, 3.3913999, 13.3786, 6.6893, 3.3913999, 13.3786, 3.3446, 3.3913999, 13.3786, 3.9148, 3.3913999, 16.514599, 3.6399, 3.3913999, 16.2405, 3.9148, 3.3913999, 16.514599, 6.6893, 3.3913999, 13.3786, 6.6893, 3.3913999, 16.7232, 6.6893, 3.3913999, 16.7232, 6.6949, 3.3913999, 18.9914, 6.6893, 3.3913999, 18.9861, 6.6949, 3.3913999, 18.9914, 6.6893, 3.3913999, 16.7232, 10.3743, 3.3913999, 16.7232, 6.6949, 3.3913999, 18.9914, 10.3743, 3.3913999, 16.7232, 9.1275, 3.3913999, 18.830599, 10.033899, 3.3913999, -10.033899, 13.3786, 3.3913999, -13.3786, 13.3786, 3.3913999, -10.033899, 13.3786, 3.3913999, -13.3786, 16.7232, 3.3913999, -10.033899, 13.3786, 3.3913999, -10.033899, 16.7232, 3.3913999, -10.033899, 19.798899, 3.3913999, -13.1096, 19.798899, 3.3913999, -10.033899, 16.7232, 3.3913999, -10.033899, 16.7232, 3.3913999, -13.1096, 19.798899, 3.3913999, -13.1096, 16.7232, 3.3913999, -10.033899, 16.4543, 3.3913999, -13.3786, 16.7232, 3.3913999, -13.1096, 16.7232, 3.3913999, -10.033899, 13.3786, 3.3913999, -13.3786, 16.4543, 3.3913999, -13.3786, 13.3786, 3.3913999, -6.6893, 13.3786, 3.3913999, -10.033899, 16.7232, 3.3913999, -10.033899, 13.3786, 3.3913999, -6.6893, 16.7232, 3.3913999, -10.033899, 16.7232, 3.3913999, -6.6893, 10.033899, 3.3913999, -6.6893, 13.3786, 3.3913999, -10.033899, 13.3786, 3.3913999, -6.6893, 10.033899, 3.3913999, -6.6893, 10.033899, 3.3913999, -10.033899, 13.3786, 3.3913999, -10.033899, 16.4543, 3.3913999, -13.3786, 16.495699, 3.3913999, -16.459, 16.495699, 3.3913999, -13.42, 16.4543, 3.3913999, -13.3786, 12.738999, 3.3913999, -15.894899, 16.495699, 3.3913999, -16.459, 12.738999, 3.3913999, -15.894899, 16.4543, 3.3913999, -13.3786, 13.3786, 3.3913999, -13.3786, 13.3786, 3.3913999, -13.3786, 12.460899, 3.3913999, -16.1674, 12.738999, 3.3913999, -15.894899, 13.3786, 3.3913999, -13.3786, 10.033899, 3.3913999, -16.7232, 12.460899, 3.3913999, -16.1674, 10.033899, 3.3913999, -10.033899, 10.033899, 3.3913999, -13.3786, 13.3786, 3.3913999, -13.3786, 10.033899, 3.3913999, -16.7232, 13.3786, 3.3913999, -13.3786, 10.033899, 3.3913999, -13.3786, 6.6893, 3.3913999, -13.3786, 10.033899, 3.3913999, -16.7232, 10.033899, 3.3913999, -13.3786, 6.6893, 3.3913999, -13.3786, 6.6893, 3.3913999, -16.7232, 10.033899, 3.3913999, -16.7232, 6.6893, 3.3913999, -10.033899, 10.033899, 3.3913999, -13.3786, 10.033899, 3.3913999, -10.033899, 6.6893, 3.3913999, -10.033899, 6.6893, 3.3913999, -13.3786, 10.033899, 3.3913999, -13.3786, 6.6893, 3.3913999, -6.6893, 6.6893, 3.3913999, -10.033899, 10.033899, 3.3913999, -10.033899, 6.6893, 3.3913999, -6.6893, 10.033899, 3.3913999, -10.033899, 10.033899, 3.3913999, -6.6893, 4.0225, 3.3913999, -8.7143, 6.6893, 3.3913999, -13.3786, 6.6893, 3.3913999, -10.033899, 4.6821, 3.3913999, -13.3786, 6.6893, 3.3913999, -16.7232, 6.6893, 3.3913999, -13.3786, 4.0225, 3.3913999, -8.7143, 4.6821, 3.3913999, -13.3786, 6.6893, 3.3913999, -13.3786, 4.6821, 3.3913999, -13.3786, 3.8388, 3.3913999, -16.7232, 6.6893, 3.3913999, -16.7232, 4.6821, 3.3913999, -13.3786, 4.0225, 3.3913999, -8.7143, 4.6821, 3.3913999, -13.3786, 4.6821, 3.3913999, -13.3786, 4.6821, 3.3913999, -13.3786, 4.4131, 3.2091, -13.357699, 4.6821, 3.3913999, -13.3786, 4.4131, 3.2091, -13.357699, 4.4131, 3.2091, -13.357699, 3.3446, 3.3913999, -6.6893, 4.0225, 3.3913999, -8.7143, 6.6893, 3.3913999, -10.033899, 3.3446, 3.3913999, -6.6893, 6.6893, 3.3913999, -10.033899, 6.6893, 3.3913999, -6.6893, 0, 3.3913999, -6.6893, 4.0225, 3.3913999, -8.7143, 3.3446, 3.3913999, -6.6893, 0, 3.3913999, -6.6893, 0, 3.3913999, -8.7143, 4.0225, 3.3913999, -8.7143, 3.3446, 3.3913999, -3.3446, 3.3446, 3.3913999, -6.6893, 6.6893, 3.3913999, -6.6893, 0, 3.3913999, -6.6893, -3.9101999, 3.3913999, -9.8592, 0, 3.3913999, -8.7143, 0, 3.3913999, -8.7143, -3.9101999, 3.3913999, -9.8592, 0, 3.3913999, -8.7143, 0, 3.3913999, -3.3446, 0, 3.3913999, -6.6893, 3.3446, 3.3913999, -6.6893, 0, 3.3913999, -3.3446, 3.3446, 3.3913999, -6.6893, 3.3446, 3.3913999, -3.3446, -3.6378, 3.3913999, -2.0792, 0, 3.3913999, -6.6893, 0, 3.3913999, -3.3446, -2.9566998, 3.3913999, 0, -3.6378, 3.3913999, -2.0792, 0, 3.3913999, -3.3446, -3.6378, 3.3913999, -2.0792, -3.3446, 3.3913999, -6.6893, 0, 3.3913999, -6.6893, -3.9101999, 3.3913999, -9.8592, 0, 3.3913999, -6.6893, -3.3446, 3.3913999, -6.6893, -6.6893, 3.3913999, -3.7326, -3.3446, 3.3913999, -6.6893, -3.6378, 3.3913999, -2.0792, -2.9566998, 3.3913999, 0, 0, 3.3913999, -3.3446, 0, 3.3913999, 0, 0, 3.3913999, 0, 0, 3.3913999, -3.3446, 3.3446, 3.3913999, -3.3446, -2.9566998, 3.3913999, 3.3446, -2.9566998, 3.3913999, 0, 0, 3.3913999, 0, -2.9566998, 3.3913999, 3.3446, 0, 3.3913999, 0, 0, 3.3913999, 3.3446, -6.6893, 3.3913999, -3.7326, -6.6893, 3.3913999, -6.6893, -3.3446, 3.3913999, -6.6893, -6.6893, 3.3913999, -6.6893, -3.9101999, 3.3913999, -9.8592, -3.3446, 3.3913999, -6.6893, -10.033899, 3.3913999, -3.7326, -6.6893, 3.3913999, -6.6893, -6.6893, 3.3913999, -3.7326, 0, 3.3913999, 3.3446, 0, 3.3913999, 0, 3.3446, 3.3913999, 0, 0, 3.3913999, 0, 3.3446, 3.3913999, -3.3446, 3.3446, 3.3913999, 0, 0, 3.3913999, 3.3446, 3.3446, 3.3913999, 0, 3.3446, 3.3913999, 3.3446, 3.3446, 3.3913999, 3.3446, 3.3446, 3.3913999, 0, 6.6893, 3.3913999, 0, 3.3446, 3.3913999, 0, 3.3446, 3.3913999, -3.3446, 6.6893, 3.3913999, -3.3446, 3.3446, 3.3913999, 0, 6.6893, 3.3913999, -3.3446, 6.6893, 3.3913999, 0, 3.3446, 3.3913999, -3.3446, 6.6893, 3.3913999, -6.6893, 6.6893, 3.3913999, -3.3446, 6.6893, 3.3913999, 0, 6.6893, 3.3913999, -3.3446, 10.033899, 3.3913999, -3.3446, 6.6893, 3.3913999, -3.3446, 6.6893, 3.3913999, -6.6893, 10.033899, 3.3913999, -6.6893, 6.6893, 3.3913999, -3.3446, 10.033899, 3.3913999, -6.6893, 10.033899, 3.3913999, -3.3446, -6.6893, 3.3913999, -6.6893, -6.6893, 3.3913999, -10.033899, -3.9101999, 3.3913999, -9.8592, -6.6893, 3.3913999, -10.033899, -3.9101999, 3.3913999, -12.538199, -3.9101999, 3.3913999, -9.8592, -10.033899, 3.3913999, -3.7326, -10.033899, 3.3913999, -6.6893, -6.6893, 3.3913999, -6.6893, -10.033899, 3.3913999, -6.6893, -6.6893, 3.3913999, -10.033899, -6.6893, 3.3913999, -6.6893, -13.3786, 3.3913999, -3.7326, -10.033899, 3.3913999, -6.6893, -10.033899, 3.3913999, -3.7326, -6.6893, 3.3913999, -10.033899, -6.6893, 3.3913999, -12.538199, -3.9101999, 3.3913999, -12.538199, -13.3786, 3.3913999, -3.7326, -13.3786, 3.3913999, -6.6893, -10.033899, 3.3913999, -6.6893, -16.191599, 3.3913999, -3.0971, -13.3786, 3.3913999, -6.6893, -13.3786, 3.3913999, -3.7326, -10.033899, 3.3913999, -6.6893, -10.033899, 3.3913999, -10.033899, -6.6893, 3.3913999, -10.033899, -13.3786, 3.3913999, -6.6893, -10.033899, 3.3913999, -10.033899, -10.033899, 3.3913999, -6.6893, -16.191599, 3.3913999, -3.0971, -16.7232, 3.3913999, -6.6893, -13.3786, 3.3913999, -6.6893, -13.3786, 3.3913999, -6.6893, -13.3786, 3.3913999, -10.033899, -10.033899, 3.3913999, -10.033899, -19.7545, 3.3913999, -2.7851999, -16.7232, 3.3913999, -6.6893, -16.191599, 3.3913999, -3.0971, -19.7545, 3.3913999, -2.7851999, -19.280699, 3.3913999, -6.6893, -16.7232, 3.3913999, -6.6893, -17.1112, 3.3913999, 0, -19.7545, 3.3913999, -2.7851999, -16.191599, 3.3913999, -3.0971, -17.1112, 3.3913999, 0, -19.9511, 3.3913999, -2.5834, -19.7545, 3.3913999, -2.7851999, -19.9511, 3.3913999, -2.5834, -17.1112, 3.3913999, 0, -20.0679, 3.3913999, 0, -20.0679, 3.3913999, 3.3446, -20.0679, 3.3913999, 0, -17.1112, 3.3913999, 0, -20.0679, 3.3913999, 3.3446, -17.1112, 3.3913999, 0, -17.1112, 3.3913999, 3.3044999, -13.3786, 3.3913999, -10.033899, -10.699599, 3.3913999, -13.175799, -10.033899, 3.3913999, -10.033899, -10.699599, 3.3913999, -13.175799, -6.6893, 3.3913999, -10.033899, -10.033899, 3.3913999, -10.033899, -13.3786, 3.3913999, -10.033899, -13.3786, 3.3913999, -13.3786, -10.699599, 3.3913999, -13.175799, -6.6893, 3.3913999, -10.033899, -10.699599, 3.3913999, -13.175799, -6.6893, 3.3913999, -12.538199, -13.3786, 3.3913999, -13.3786, -10.699599, 3.3913999, -15.835, -10.699599, 3.3913999, -13.175799, -13.3786, 3.3913999, -13.3786, -13.3786, 3.3913999, -15.4154, -10.699599, 3.3913999, -15.835, -6.6893, 3.3913999, -12.538199, -10.699599, 3.3913999, -13.175799, -6.6893, 3.3913999, -12.538199, -6.6893, 3.3913999, -12.538199, -6.6893, 3.3913999, -12.538199, -6.6893, 3.175, -12.867, -6.6893, 3.3913999, -12.538199, -6.6893, 3.175, -12.867, -6.6893, 3.175, -12.867, -20.0679, 3.3913999, 6.6893, -20.0679, 3.3913999, 3.3446, -17.1112, 3.3913999, 3.3044999, -22.5541, 3.3913999, 9.2058, -22.3151, 3.3913999, 6.6893, -20.0679, 3.3913999, 6.6893, -22.5541, 3.3913999, 9.2058, -20.0679, 3.3913999, 6.6893, -20.0679, 3.3913999, 9.167399, -20.0679, 3.3913999, 9.167399, -20.0679, 3.3913999, 6.6893, -16.7232, 3.3913999, 6.6893, -20.0679, 3.3913999, 6.6893, -17.1112, 3.3913999, 3.3044999, -16.7232, 3.3913999, 6.6893, -20.0679, 3.3913999, 9.167399, -16.7232, 3.3913999, 6.6893, -16.285099, 3.3913999, 9.5865, -16.7232, 3.3913999, 6.6893, -16.053999, 3.3913999, 9.8082, -16.285099, 3.3913999, 9.5865, -16.053999, 3.3913999, 9.8082, -16.7232, 3.3913999, 6.6893, -13.1355, 3.3913999, 6.7549996, -17.1112, 3.3913999, 3.3044999, -13.1355, 3.3913999, 6.7549996, -16.7232, 3.3913999, 6.6893, -16.053999, 3.3913999, 9.8082, -13.1355, 3.3913999, 6.7549996, -13.3786, 3.3913999, 10.033899, -13.1355, 3.3913999, 6.7549996, -17.1112, 3.3913999, 3.3044999, -14.877199, 3.3913999, 4.6657, -14.877199, 3.3913999, 4.6657, -17.1112, 3.3913999, 3.3044999, -15.582299, 3.3913999, 4.0366, -13.1355, 3.3913999, 6.7549996, -14.877199, 3.3913999, 4.6657, -14.0948, 3.3913999, 5.5073, -13.3786, 3.3913999, 10.033899, -13.1355, 3.3913999, 6.7549996, -10.033899, 3.3913999, 7.0772, -13.3786, 3.3913999, 10.033899, -10.033899, 3.3913999, 7.0772, -10.033899, 3.3913999, 10.033899, -10.033899, 3.3913999, 10.033899, -10.033899, 3.3913999, 7.0772, -6.6893, 3.3913999, 7.0772, -10.033899, 3.3913999, 10.033899, -6.6893, 3.3913999, 7.0772, -6.6893, 3.3913999, 10.033899, -10.033899, 3.0033998, 6.6893, -13.1355, 3.3913999, 6.7549996, -12.747499, 3.0033998, 6.3671, -10.033899, 3.0033998, 6.6893, -10.033899, 3.3913999, 7.0772, -13.1355, 3.3913999, 6.7549996, -2.5674999, 2.4164, 7.6215, -6.6893, 3.3913999, 7.0772, -6.6893, 3.0033998, 6.6893, -2.5674999, 2.4164, 7.6215, -2.1794999, 2.8042998, 8.009399, -6.6893, 3.3913999, 7.0772, -12.747499, 3.0033998, 6.3671, -14.0948, 3.3913999, 5.5073, -13.6942, 3.0033998, 5.1798, -12.747499, 3.0033998, 6.3671, -13.1355, 3.3913999, 6.7549996, -14.0948, 3.3913999, 5.5073, -6.6893, 3.0033998, 6.6893, -10.033899, 3.3913999, 7.0772, -10.033899, 3.0033998, 6.6893, -6.6893, 3.0033998, 6.6893, -6.6893, 3.3913999, 7.0772, -10.033899, 3.3913999, 7.0772, -16.7232, 3.0033998, 0, -16.191599, 3.3913999, -3.0971, -15.8036995, 3.0033998, -2.7091, -16.7232, 3.0033998, 0, -17.1112, 3.3913999, 0, -16.191599, 3.3913999, -3.0971, -13.3786, 3.3913999, -3.7326, -15.8036995, 3.0033998, -2.7091, -16.191599, 3.3913999, -3.0971, -13.3786, 3.3913999, -3.7326, -13.3786, 3.0033998, -3.3446, -15.8036995, 3.0033998, -2.7091, -2.9566998, 3.3913999, 0, -4.0257998, 3.0033998, -1.6911999, -3.6378, 3.3913999, -2.0792, -2.9566998, 3.3913999, 0, -3.3446, 3.0033998, 0, -4.0257998, 3.0033998, -1.6911999, -3.6378, 3.3913999, -2.0792, -6.6893, 3.0033998, -3.3446, -6.6893, 3.3913999, -3.7326, -3.6378, 3.3913999, -2.0792, -4.0257998, 3.0033998, -1.6911999, -6.6893, 3.0033998, -3.3446, -10.033899, 3.3913999, -3.7326, -13.3786, 3.0033998, -3.3446, -13.3786, 3.3913999, -3.7326, -10.033899, 3.3913999, -3.7326, -10.033899, 3.0033998, -3.3446, -13.3786, 3.0033998, -3.3446, -6.6893, 3.3913999, -3.7326, -10.033899, 3.0033998, -3.3446, -10.033899, 3.3913999, -3.7326, -6.6893, 3.3913999, -3.7326, -6.6893, 3.0033998, -3.3446, -10.033899, 3.0033998, -3.3446, -16.7232, 3.0033998, 2.9166, -17.1112, 3.3913999, 0, -16.7232, 3.0033998, 0, -16.7232, 3.0033998, 2.9166, -17.1112, 3.3913999, 3.3044999, -17.1112, 3.3913999, 0, -14.4892, 3.0033998, 4.2778, -15.582299, 3.3913999, 4.0366, -15.372, 3.0033998, 3.6132998, -14.4892, 3.0033998, 4.2778, -14.877199, 3.3913999, 4.6657, -15.582299, 3.3913999, 4.0366, -2.9566998, 3.3913999, 3.3446, -3.3446, 3.0033998, 0, -2.9566998, 3.3913999, 0, -2.9566998, 3.3913999, 3.3446, -3.3446, 3.0033998, 3.3446, -3.3446, 3.0033998, 0, -2.1794999, 2.8042998, 8.009399, -2.1397, 3.0033998, 5.1795, -1.7832999, 3.3913999, 5.2162, -2.1794999, 2.8042998, 8.009399, -2.5674999, 2.4164, 7.6215, -2.1397, 3.0033998, 5.1795, -6.6893, 3.3913999, 10.033899, -2.1794999, 2.8042998, 8.009399, -3.3446, 3.3913999, 10.033899, -6.6893, 3.3913999, 10.033899, -6.6893, 3.3913999, 7.0772, -2.1794999, 2.8042998, 8.009399, -1.7832999, 3.3913999, 5.2162, 0, 3.3913999, 6.6893, -2.1794999, 2.8042998, 8.009399, 0, 3.3913999, 6.6893, -1.7832999, 3.3913999, 5.2162, -2.9566998, 3.3913999, 3.3446, 0, 3.3913999, 6.6893, -2.9566998, 3.3913999, 3.3446, 0, 3.3913999, 3.3446, -3.3446, 3.3913999, 10.033899, 0, 3.3913999, 6.6893, 0, 3.3913999, 10.033899, -3.3446, 3.3913999, 10.033899, -2.1794999, 2.8042998, 8.009399, 0, 3.3913999, 6.6893, -2.1397, 3.0033998, 5.1795, -2.9566998, 3.3913999, 3.3446, -1.7832999, 3.3913999, 5.2162, -2.1397, 3.0033998, 5.1795, -3.3446, 3.0033998, 3.3446, -2.9566998, 3.3913999, 3.3446, -14.0948, 3.3913999, 5.5073, -14.4892, 3.0033998, 4.2778, -13.6942, 3.0033998, 5.1798, -14.0948, 3.3913999, 5.5073, -14.877199, 3.3913999, 4.6657, -14.4892, 3.0033998, 4.2778, -15.582299, 3.3913999, 4.0366, -16.7232, 3.0033998, 2.9166, -15.372, 3.0033998, 3.6132998, -15.582299, 3.3913999, 4.0366, -17.1112, 3.3913999, 3.3044999, -16.7232, 3.0033998, 2.9166, 20.198, 3.1490998, -10.033899, 19.798899, 3.3913999, -13.1096, 20.1539, 3.1299, -13.399799, 20.198, 3.1490998, -10.033899, 19.798899, 3.3913999, -10.033899, 19.798899, 3.3913999, -13.1096, 20.1539, 3.1299, -13.399799, 16.7232, 3.3913999, -13.1096, 16.8204, 3.138, -13.447599, 20.1539, 3.1299, -13.399799, 19.798899, 3.3913999, -13.1096, 16.7232, 3.3913999, -13.1096, 16.756899, 3.1650999, -16.7286, 12.738999, 3.3913999, -15.894899, 12.7471, 3.1766999, -16.1988, 16.756899, 3.1650999, -16.7286, 16.495699, 3.3913999, -16.459, 12.738999, 3.3913999, -15.894899, 16.8051, 3.1778, -13.479, 16.495699, 3.3913999, -16.459, 16.756899, 3.1650999, -16.7286, 16.8051, 3.1778, -13.479, 16.495699, 3.3913999, -13.42, 16.495699, 3.3913999, -16.459, 16.4543, 3.3913999, -13.3786, 16.8204, 3.138, -13.447599, 16.7232, 3.3913999, -13.1096, 16.8204, 3.138, -13.447599, 16.4543, 3.3913999, -13.3786, 16.495699, 3.3913999, -13.42, 16.8204, 3.138, -13.447599, 16.495699, 3.3913999, -13.42, 16.8051, 3.1778, -13.479, 10.033899, 3.0523999, -19.0294, 6.6893, 3.2782998, -18.727999, 6.6893, 3.0440998, -19.036999, 10.033899, 3.0523999, -19.0294, 10.033899, 3.2784998, -18.6997, 6.6893, 3.2782998, -18.727999, 12.723599, 2.9213, -19.2902, 10.033899, 3.2784998, -18.6997, 10.033899, 3.0523999, -19.0294, 12.723599, 2.9213, -19.2902, 12.446099, 3.1699998, -18.9401, 10.033899, 3.2784998, -18.6997, 12.446099, 3.1699998, -18.9401, 12.747, 3.1771, -16.1991, 12.460899, 3.3913999, -16.1674, 12.446099, 3.1699998, -18.9401, 12.723599, 2.9213, -19.2902, 12.747, 3.1771, -16.1991, 12.460899, 3.3913999, -16.1674, 10.033899, 3.2784998, -18.6997, 12.446099, 3.1699998, -18.9401, 10.033899, 3.3913999, -16.7232, 10.033899, 3.2784998, -18.6997, 12.460899, 3.3913999, -16.1674, 10.033899, 3.3913999, -16.7232, 12.460899, 3.3913999, -16.1674, 12.460899, 3.3913999, -16.1674, 6.6893, 3.3913999, -16.7232, 10.033899, 3.2784998, -18.6997, 10.033899, 3.3913999, -16.7232, 6.6893, 3.3913999, -16.7232, 6.6893, 3.2782998, -18.727999, 10.033899, 3.2784998, -18.6997, 12.738999, 3.3913999, -15.894899, 12.747, 3.1771, -16.1991, 12.7471, 3.1766999, -16.1988, 12.738999, 3.3913999, -15.894899, 12.460899, 3.3913999, -16.1674, 12.747, 3.1771, -16.1991, 12.460899, 3.3913999, -16.1674, 12.738999, 3.3913999, -15.894899, 12.460899, 3.3913999, -16.1674, 3.8388, 3.3913999, -16.7232, 4.4783998, 3.1067, -18.2665, 4.6443, 3.2897, -17.9799, 3.8388, 3.3913999, -16.7232, 3.5895, 3.2033, -16.7232, 4.4783998, 3.1067, -18.2665, 4.6821, 3.3913999, -13.3786, 3.5895, 3.2033, -16.7232, 3.8388, 3.3913999, -16.7232, 4.6821, 3.3913999, -13.3786, 4.4131, 3.2091, -13.357699, 3.5895, 3.2033, -16.7232, 6.6640997, 3.0702, -19.018099, 4.6443, 3.2897, -17.9799, 4.4783998, 3.1067, -18.2665, 6.6640997, 3.0702, -19.018099, 6.6705, 3.2772, -18.741, 4.6443, 3.2897, -17.9799, 4.6443, 3.2897, -17.9799, 6.6893, 3.3913999, -16.7232, 3.8388, 3.3913999, -16.7232, 6.6893, 3.3913999, -16.7232, 4.6443, 3.2897, -17.9799, 6.6705, 3.2772, -18.741, 6.6893, 3.3913999, -16.7232, 6.6705, 3.2772, -18.741, 6.6893, 3.2782998, -18.727999, 6.6893, 3.2782998, -18.727999, 6.6640997, 3.0702, -19.018099, 6.6893, 3.0440998, -19.036999, 6.6893, 3.2782998, -18.727999, 6.6705, 3.2772, -18.741, 6.6640997, 3.0702, -19.018099, 3.7529, 3.1712, -9.0494995, 0, 3.3913999, -8.7143, 0, 3.179, -9.0652, 3.7529, 3.1712, -9.0494995, 4.0225, 3.3913999, -8.7143, 0, 3.3913999, -8.7143, 4.0225, 3.3913999, -8.7143, 4.4131, 3.2091, -13.357699, 4.6821, 3.3913999, -13.3786, 4.0225, 3.3913999, -8.7143, 3.7529, 3.1712, -9.0494995, 4.4131, 3.2091, -13.357699, -3.6538, 3.1585999, -12.813399, -6.6893, 3.3913999, -12.538199, -6.6893, 3.175, -12.867, -3.6538, 3.1585999, -12.813399, -3.9101999, 3.3913999, -12.538199, -6.6893, 3.3913999, -12.538199, -3.6076, 3.1676, -10.0696, -3.9101999, 3.3913999, -12.538199, -3.6538, 3.1585999, -12.813399, -3.6076, 3.1676, -10.0696, -3.9101999, 3.3913999, -9.8592, -3.9101999, 3.3913999, -12.538199, -0.0081, 3.1864998, -9.063499, -3.9101999, 3.3913999, -9.8592, -3.6076, 3.1676, -10.0696, -0.0081, 3.1864998, -9.063499, 0, 3.3913999, -8.7143, -3.9101999, 3.3913999, -9.8592, 0, 3.3913999, -8.7143, -0.0081, 3.1864998, -9.063499, 0, 3.179, -9.0652, 0, 3.3913999, -8.7143, 0, 3.3913999, -8.7143, -0.0081, 3.1864998, -9.063499, -10.4043, 3.1608999, -13.4295, -10.699599, 3.3913999, -15.835, -10.4319, 3.1557999, -16.1556, -10.4043, 3.1608999, -13.4295, -10.699599, 3.3913999, -13.175799, -10.699599, 3.3913999, -15.835, -10.4319, 3.1557999, -16.1556, -13.3786, 3.3913999, -15.4154, -13.3786, 3.1771998, -15.7625, -10.4319, 3.1557999, -16.1556, -10.699599, 3.3913999, -15.835, -13.3786, 3.3913999, -15.4154, -10.699599, 3.3913999, -13.175799, -6.6893, 3.175, -12.867, -6.6893, 3.3913999, -12.538199, -10.699599, 3.3913999, -13.175799, -10.4043, 3.1608999, -13.4295, -6.6893, 3.175, -12.867, -16.130499, 3.6227, -13.623799, -16.0243, 3.3509998, -15.752, -15.7941, 3.5591, -15.4641, -16.130499, 3.6227, -13.623799, -16.3753, 3.4225, -13.6277, -16.0243, 3.3509998, -15.752, -13.3911, 3.1892, -15.757, -15.7941, 3.5591, -15.4641, -16.0243, 3.3509998, -15.752, -13.3911, 3.1892, -15.757, -13.396, 3.3925, -15.4333, -15.7941, 3.5591, -15.4641, -15.7941, 3.5591, -15.4641, -13.3786, 3.3913999, -13.3786, -16.130499, 3.6227, -13.623799, -13.3786, 3.3913999, -13.3786, -15.7941, 3.5591, -15.4641, -13.396, 3.3925, -15.4333, -13.3786, 3.3913999, -13.3786, -13.396, 3.3925, -15.4333, -13.3786, 3.3913999, -15.4154, -13.3786, 3.3913999, -15.4154, -13.3911, 3.1892, -15.757, -13.3786, 3.1771998, -15.7625, -13.3786, 3.3913999, -15.4154, -13.396, 3.3925, -15.4333, -13.3911, 3.1892, -15.757, -16.3753, 3.4225, -13.6277, -16.1241, 3.3832998, -9.5097, -16.4131, 3.1706, -9.788899, -16.3753, 3.4225, -13.6277, -16.130499, 3.6227, -13.623799, -16.1241, 3.3832998, -9.5097, -16.7232, 3.3913999, -6.6893, -13.3786, 3.3913999, -10.033899, -13.3786, 3.3913999, -6.6893, -16.7232, 3.3913999, -6.6893, -16.1241, 3.3832998, -9.5097, -13.3786, 3.3913999, -10.033899, -16.1241, 3.3832998, -9.5097, -13.3786, 3.3913999, -13.3786, -13.3786, 3.3913999, -10.033899, -16.1241, 3.3832998, -9.5097, -16.130499, 3.6227, -13.623799, -13.3786, 3.3913999, -13.3786, -16.130499, 3.6227, -13.623799, -16.1241, 3.3832998, -9.5097, -16.130499, 3.6227, -13.623799, -16.130499, 3.6227, -13.623799, -16.3753, 3.4225, -13.6277, -16.3753, 3.4225, -13.6277, -16.130499, 3.6227, -13.623799, -16.130499, 3.6227, -13.623799, -16.3753, 3.4225, -13.6277, -19.7545, 3.3913999, -2.7851999, -19.515, 3.2122, -6.6893, -19.280699, 3.3913999, -6.6893, -19.7545, 3.3913999, -2.7851999, -19.9489, 3.2063, -2.8082, -19.515, 3.2122, -6.6893, -19.280699, 3.3913999, -6.6893, -19.6161, 3.2075999, -9.7116995, -19.3965, 3.3909, -9.5092, -19.280699, 3.3913999, -6.6893, -19.515, 3.2122, -6.6893, -19.6161, 3.2075999, -9.7116995, -19.280699, 3.3913999, -6.6893, -16.1241, 3.3832998, -9.5097, -16.7232, 3.3913999, -6.6893, -19.280699, 3.3913999, -6.6893, -19.3965, 3.3909, -9.5092, -16.1241, 3.3832998, -9.5097, -16.1241, 3.3832998, -9.5097, -19.6237, 3.1655998, -9.757899, -16.4131, 3.1706, -9.788899, -19.6237, 3.1655998, -9.757899, -16.1241, 3.3832998, -9.5097, -19.3965, 3.3909, -9.5092, -19.6237, 3.1655998, -9.757899, -19.3965, 3.3909, -9.5092, -19.6161, 3.2075999, -9.7116995, -22.8657, 3.4937, 3.3613, -23.3676, 3.4459999, 0.1372, -23.170399, 3.6251, 0.122999996, -22.8657, 3.4937, 3.3613, -23.0809, 3.3083, 3.3615, -23.3676, 3.4459999, 0.1372, -23.170399, 3.6251, 0.122999996, -23.390299, 3.3349998, -2.6938999, -23.192099, 3.5300999, -2.4668999, -23.170399, 3.6251, 0.122999996, -23.3676, 3.4459999, 0.1372, -23.390299, 3.3349998, -2.6938999, -23.192099, 3.5300999, -2.4668999, -19.9489, 3.2063, -2.8082, -19.9511, 3.3913999, -2.5834, -23.192099, 3.5300999, -2.4668999, -23.390299, 3.3349998, -2.6938999, -19.9489, 3.2063, -2.8082, -23.192099, 3.5300999, -2.4668999, -20.0679, 3.3913999, 0, -23.170399, 3.6251, 0.122999996, -20.0679, 3.3913999, 0, -23.192099, 3.5300999, -2.4668999, -19.9511, 3.3913999, -2.5834, -19.9511, 3.3913999, -2.5834, -23.192099, 3.5300999, -2.4668999, -19.9511, 3.3913999, -2.5834, -22.8657, 3.4937, 3.3613, -20.0679, 3.3913999, 0, -20.0679, 3.3913999, 3.3446, -22.8657, 3.4937, 3.3613, -23.170399, 3.6251, 0.122999996, -20.0679, 3.3913999, 0, -19.7545, 3.3913999, -2.7851999, -19.9489, 3.2063, -2.8082, -19.9489, 3.2063, -2.8082, -19.7545, 3.3913999, -2.7851999, -19.9511, 3.3913999, -2.5834, -19.9489, 3.2063, -2.8082, -19.9511, 3.3913999, -2.5834, -19.7545, 3.3913999, -2.7851999, -19.9511, 3.3913999, -2.5834, -23.0777, 3.3197, 3.3734, -22.3151, 3.3913999, 6.6893, -22.563799, 3.2219, 6.6893, -23.0777, 3.3197, 3.3734, -22.8764, 3.4937, 3.3741, -22.3151, 3.3913999, 6.6893, -22.8764, 3.4937, 3.3741, -20.0679, 3.3913999, 6.6893, -22.3151, 3.3913999, 6.6893, -20.0679, 3.3913999, 6.6893, -22.8764, 3.4937, 3.3741, -22.8657, 3.4937, 3.3613, -20.0679, 3.3913999, 6.6893, -22.8657, 3.4937, 3.3613, -20.0679, 3.3913999, 3.3446, -22.8657, 3.4937, 3.3613, -23.0777, 3.3197, 3.3734, -23.0809, 3.3083, 3.3615, -22.8657, 3.4937, 3.3613, -22.8764, 3.4937, 3.3741, -23.0777, 3.3197, 3.3734, -16.285099, 3.3913999, 9.5865, -20.0679, 3.1943, 9.407499, -20.0679, 3.3913999, 9.167399, -16.285099, 3.3913999, 9.5865, -16.2818, 3.1913998, 9.8056, -20.0679, 3.1943, 9.407499, -22.791399, 3.2124999, 9.4432, -20.0679, 3.3913999, 9.167399, -20.0679, 3.1943, 9.407499, -22.791399, 3.2124999, 9.4432, -22.5541, 3.3913999, 9.2058, -20.0679, 3.3913999, 9.167399, -22.5541, 3.3913999, 9.2058, -22.563799, 3.2219, 6.6893, -22.3151, 3.3913999, 6.6893, -22.5541, 3.3913999, 9.2058, -22.791399, 3.2124999, 9.4432, -22.563799, 3.2219, 6.6893, -22.791399, 3.2124999, 9.4432, -22.5541, 3.3913999, 9.2058, -22.791399, 3.2124999, 9.4432, -13.3786, 3.3922, 12.571899, -16.076399, 3.04, 12.735, -15.847199, 3.2614, 12.4973, -13.3786, 3.3922, 12.571899, -13.3786, 3.194, 12.8089, -16.076399, 3.04, 12.735, -15.847199, 3.2614, 12.4973, -16.2818, 3.1913998, 9.8056, -16.053999, 3.3913999, 9.8082, -15.847199, 3.2614, 12.4973, -16.076399, 3.04, 12.735, -16.2818, 3.1913998, 9.8056, -15.847199, 3.2614, 12.4973, -13.3786, 3.3913999, 10.033899, -13.3786, 3.3922, 12.571899, -15.847199, 3.2614, 12.4973, -16.053999, 3.3913999, 9.8082, -13.3786, 3.3913999, 10.033899, -16.053999, 3.3913999, 9.8082, -15.847199, 3.2614, 12.4973, -16.053999, 3.3913999, 9.8082, -16.285099, 3.3913999, 9.5865, -16.2818, 3.1913998, 9.8056, -16.2818, 3.1913998, 9.8056, -16.285099, 3.3913999, 9.5865, -16.053999, 3.3913999, 9.8082, -16.2818, 3.1913998, 9.8056, -16.053999, 3.3913999, 9.8082, -16.285099, 3.3913999, 9.5865, -16.053999, 3.3913999, 9.8082, -5.9742, 3.3994, 12.8817, -10.033899, 2.9384, 12.4537, -10.033899, 3.2142, 12.1061, -5.9742, 3.3994, 12.8817, -6.2748, 3.126, 13.122, -10.033899, 2.9384, 12.4537, -10.033899, 3.2142, 12.1061, -13.3786, 3.194, 12.8089, -13.3786, 3.3922, 12.571899, -10.033899, 3.2142, 12.1061, -10.033899, 2.9384, 12.4537, -13.3786, 3.194, 12.8089, -10.033899, 3.2142, 12.1061, -6.6893, 3.3913999, 10.033899, -5.9742, 3.3994, 12.8817, -10.033899, 3.2142, 12.1061, -10.033899, 3.3913999, 10.033899, -6.6893, 3.3913999, 10.033899, -13.3786, 3.3922, 12.571899, -10.033899, 3.3913999, 10.033899, -10.033899, 3.2142, 12.1061, -13.3786, 3.3922, 12.571899, -13.3786, 3.3913999, 10.033899, -10.033899, 3.3913999, 10.033899, -13.3786, 3.3913999, 10.033899, -13.3786, 3.3922, 12.571899, -13.3786, 3.3922, 12.571899, -5.9742, 3.3994, 12.8817, -3.3446, 3.3913999, 10.033899, -3.3446, 3.3913999, 13.3786, -5.9742, 3.3994, 12.8817, -6.6893, 3.3913999, 10.033899, -3.3446, 3.3913999, 10.033899, -13.3786, 3.3922, 12.571899, -13.3786, 3.194, 12.8089, -13.3786, 3.194, 12.8089, -13.3786, 3.3922, 12.571899, -13.3786, 3.3922, 12.571899, -13.3786, 3.194, 12.8089, 3.6399, 3.3913999, 16.2405, 0, 2.9636998, 16.0179, 0, 3.2243998, 15.7093, 3.6399, 3.3913999, 16.2405, 3.6425998, 3.1413999, 16.5127, 0, 2.9636998, 16.0179, 0, 3.2243998, 15.7093, -3.3446, 3.1497998, 15.914599, -3.3446, 3.3913999, 15.6011, 0, 3.2243998, 15.7093, 0, 2.9636998, 16.0179, -3.3446, 3.1497998, 15.914599, -6.2558, 3.1427999, 16.4098, -3.3446, 3.3913999, 15.6011, -3.3446, 3.1497998, 15.914599, -6.2558, 3.1427999, 16.4098, -5.9737997, 3.392, 16.087599, -3.3446, 3.3913999, 15.6011, -3.3446, 3.3913999, 15.6011, 0, 3.3913999, 13.3786, 0, 3.2243998, 15.7093, -3.3446, 3.3913999, 15.6011, -3.3446, 3.3913999, 13.3786, 0, 3.3913999, 13.3786, 0, 3.2243998, 15.7093, 3.3446, 3.3913999, 13.3786, 3.6399, 3.3913999, 16.2405, 0, 3.2243998, 15.7093, 0, 3.3913999, 13.3786, 3.3446, 3.3913999, 13.3786, -5.9737997, 3.392, 16.087599, -3.3446, 3.3913999, 13.3786, -3.3446, 3.3913999, 15.6011, -5.9737997, 3.392, 16.087599, -5.9742, 3.3994, 12.8817, -3.3446, 3.3913999, 13.3786, -6.2748, 3.1260998, 16.4145, -5.9737997, 3.392, 16.087599, -6.2558, 3.1427999, 16.4098, -5.9737997, 3.392, 16.087599, -6.2748, 3.1260998, 16.4145, -6.2748, 3.126, 13.122, -5.9737997, 3.392, 16.087599, -6.2748, 3.126, 13.122, -5.9742, 3.3994, 12.8817, 6.6893, 3.3913999, 18.9861, 3.9266999, 3.5967, 19.6223, 4.1273, 3.7335, 19.3804, 6.6893, 3.3913999, 18.9861, 6.6893, 3.2050998, 19.228699, 3.9266999, 3.5967, 19.6223, 4.1273, 3.7335, 19.3804, 3.6536, 3.2078998, 16.5669, 3.8651, 3.3981998, 16.5647, 4.1273, 3.7335, 19.3804, 3.9266999, 3.5967, 19.6223, 3.6536, 3.2078998, 16.5669, 3.8651, 3.3981998, 16.5647, 6.6893, 3.3913999, 18.9861, 4.1273, 3.7335, 19.3804, 6.6893, 3.3913999, 18.9861, 3.8651, 3.3981998, 16.5647, 3.9148, 3.3913999, 16.514599, 6.6893, 3.3913999, 18.9861, 3.9148, 3.3913999, 16.514599, 6.6893, 3.3913999, 16.7232, 3.9148, 3.3913999, 16.514599, 3.6425998, 3.1413999, 16.5127, 3.6399, 3.3913999, 16.2405, 3.6425998, 3.1413999, 16.5127, 3.9148, 3.3913999, 16.514599, 3.8651, 3.3981998, 16.5647, 3.6425998, 3.1413999, 16.5127, 3.8651, 3.3981998, 16.5647, 3.6536, 3.2078998, 16.5669, 9.3066, 3.2186, 19.0653, 10.3743, 3.3913999, 16.7232, 10.5913, 3.1985998, 16.7232, 9.3066, 3.2186, 19.0653, 9.1275, 3.3913999, 18.830599, 10.3743, 3.3913999, 16.7232, 9.1275, 3.3913999, 18.830599, 6.6991997, 3.2148, 19.2255, 6.6949, 3.3913999, 18.9914, 9.1275, 3.3913999, 18.830599, 9.3066, 3.2186, 19.0653, 6.6991997, 3.2148, 19.2255, 6.6893, 3.3913999, 18.9861, 6.6991997, 3.2148, 19.2255, 6.6893, 3.2050998, 19.228699, 6.6893, 3.3913999, 18.9861, 6.6949, 3.3913999, 18.9914, 6.6991997, 3.2148, 19.2255, 9.8131, 3.3546, 13.1979, 10.5893, 3.2117, 16.7106, 10.403999, 3.3911998, 16.6938, 9.8131, 3.3546, 13.1979, 10.0546, 3.1885, 13.4071, 10.5893, 3.2117, 16.7106, 6.6893, 3.3913999, 13.3786, 10.3743, 3.3913999, 16.7232, 6.6893, 3.3913999, 16.7232, 10.3743, 3.3913999, 16.7232, 6.6893, 3.3913999, 13.3786, 9.8131, 3.3546, 13.1979, 10.3743, 3.3913999, 16.7232, 9.8131, 3.3546, 13.1979, 10.403999, 3.3911998, 16.6938, 6.6893, 3.3913999, 13.3786, 10.033899, 3.3913999, 10.033899, 9.8131, 3.3546, 13.1979, 6.6893, 3.3913999, 13.3786, 6.6893, 3.3913999, 10.033899, 10.033899, 3.3913999, 10.033899, 10.3743, 3.3913999, 16.7232, 10.5893, 3.2117, 16.7106, 10.5913, 3.1985998, 16.7232, 10.3743, 3.3913999, 16.7232, 10.403999, 3.3911998, 16.6938, 10.5893, 3.2117, 16.7106, 13.1839, 3.2744, 6.6893, 13.5511, 3.1797, 6.6893, 13.4036, 3.0749998, 6.6893, 13.1839, 3.2744, 6.6893, 13.3786, 3.2744, 6.496, 13.5511, 3.1797, 6.6893, 12.9758, 3.2036, 10.033899, 13.1839, 3.2744, 6.6893, 13.4036, 3.0749998, 6.6893, 12.9758, 3.2036, 10.033899, 12.7325, 3.3913999, 10.033899, 13.1839, 3.2744, 6.6893, 13.2631, 3.5611, 13.4043, 12.7325, 3.3913999, 10.033899, 12.9758, 3.2036, 10.033899, 13.2631, 3.5611, 13.4043, 13.025499, 3.6999, 13.1985, 12.7325, 3.3913999, 10.033899, 10.033899, 3.3913999, 10.033899, 13.1839, 3.2744, 6.6893, 12.7325, 3.3913999, 10.033899, 10.033899, 3.3913999, 10.033899, 10.033899, 3.3913999, 6.6893, 13.1839, 3.2744, 6.6893, 9.8131, 3.3546, 13.1979, 12.7325, 3.3913999, 10.033899, 13.025499, 3.6999, 13.1985, 9.8131, 3.3546, 13.1979, 10.033899, 3.3913999, 10.033899, 12.7325, 3.3913999, 10.033899, 10.033899, 3.3913999, 3.3446, 13.1839, 3.2744, 6.6893, 10.033899, 3.3913999, 6.6893, 13.1839, 3.2744, 6.6893, 10.033899, 3.3913999, 3.3446, 13.3786, 3.3913999, 3.3446, 13.1839, 3.2744, 6.6893, 13.3786, 3.3913999, 3.3446, 13.3786, 3.2744, 6.496, 13.025499, 3.6999, 13.1985, 10.0546, 3.1885, 13.4071, 9.8131, 3.3546, 13.1979, 13.025499, 3.6999, 13.1985, 13.2631, 3.5611, 13.4043, 10.0546, 3.1885, 13.4071, 13.2631, 3.5611, 13.4043, 13.2631, 3.5611, 13.4043, 13.025499, 3.6999, 13.1985, 14.0489, 3.0042, -3.3446, 13.1206, 3.3028998, -3.3446, 13.3786, 3.3028998, -3.6027, 14.0489, 3.0042, -3.3446, 13.3786, 3.3028998, -3.0865998, 13.1206, 3.3028998, -3.3446, 16.7232, 3.1513, -3.602, 14.0489, 3.0042, -3.3446, 13.3786, 3.3028998, -3.6027, 16.7232, 3.1513, -3.602, 16.7127, 2.8734, -3.3446, 14.0489, 3.0042, -3.3446, 13.3786, 3.3028998, -3.6027, 16.7232, 3.3913999, -6.6893, 16.7232, 3.1513, -3.602, 13.3786, 3.3028998, -3.6027, 13.3786, 3.3913999, -6.6893, 16.7232, 3.3913999, -6.6893, 10.033899, 3.3913999, -6.6893, 13.1206, 3.3028998, -3.3446, 10.033899, 3.3913999, -3.3446, 13.1206, 3.3028998, -3.3446, 10.033899, 3.3913999, -6.6893, 13.3786, 3.3913999, -6.6893, 13.1206, 3.3028998, -3.3446, 13.3786, 3.3913999, -6.6893, 13.3786, 3.3028998, -3.6027, 20.0679, 0, 0, 14.0489, 3.0042, -3.3446, 20.961199, 0, -3.3446, 20.0679, 0, 3.3446, 14.0489, 3.0042, -3.3446, 20.0679, 0, 0, 14.0489, 3.0042, -3.3446, 13.3786, 3.3913999, 0, 13.3786, 3.3028998, -3.0865998, 14.0489, 3.0042, -3.3446, 13.3786, 3.2744, 6.496, 13.3786, 3.3913999, 0, 14.0489, 3.0042, -3.3446, 20.0679, 0, 3.3446, 13.3786, 3.2744, 6.496, 13.3786, 3.3913999, 0, 13.3786, 3.2744, 6.496, 13.3786, 3.3913999, 3.3446, 13.3786, 3.2744, 6.496, 20.0679, 0, 3.3446, 16.7232, 1.5715, 6.6893, 16.7232, 1.5715, 6.6893, 20.0679, 0, 3.3446, 20.0679, -0.124199994, 6.6893, 13.3786, 3.2744, 6.496, 16.7232, 1.5715, 6.6893, 13.5511, 3.1797, 6.6893, 10.033899, 3.3913999, -3.3446, 13.3786, 3.3913999, 0, 10.033899, 3.3913999, 0, 13.3786, 3.3913999, 0, 10.033899, 3.3913999, -3.3446, 13.1206, 3.3028998, -3.3446, 13.3786, 3.3913999, 0, 13.1206, 3.3028998, -3.3446, 13.3786, 3.3028998, -3.0865998, 19.831999, 3.3902998, -10.0008, 20.147, 3.0588999, -6.6893, 19.8322, 3.2891998, -6.6893, 19.831999, 3.3902998, -10.0008, 20.1796, 3.182, -9.995999, 20.147, 3.0588999, -6.6893, 19.8322, 3.2891998, -6.6893, 20.1349, 2.7974, -3.3783998, 19.8322, 3.0491, -3.602, 19.8322, 3.2891998, -6.6893, 20.147, 3.0588999, -6.6893, 20.1349, 2.7974, -3.3783998, 16.7232, 3.1513, -3.602, 19.8322, 3.2891998, -6.6893, 19.8322, 3.0491, -3.602, 16.7232, 3.1513, -3.602, 16.7232, 3.3913999, -6.6893, 19.8322, 3.2891998, -6.6893, 16.7232, 3.3913999, -10.033899, 19.8322, 3.2891998, -6.6893, 16.7232, 3.3913999, -6.6893, 19.8322, 3.2891998, -6.6893, 16.7232, 3.3913999, -10.033899, 19.798899, 3.3913999, -10.033899, 19.8322, 3.2891998, -6.6893, 19.798899, 3.3913999, -10.033899, 19.831999, 3.3902998, -10.0008, 20.198, 3.1490998, -10.033899, 19.831999, 3.3902998, -10.0008, 19.798899, 3.3913999, -10.033899, 20.198, 3.1490998, -10.033899, 20.1796, 3.182, -9.995999, 19.831999, 3.3902998, -10.0008, 20.144999, 2.7605999, -3.3446, 19.8322, 3.0491, -3.602, 20.1349, 2.7974, -3.3783998, 19.8322, 3.0491, -3.602, 20.144999, 2.7605999, -3.3446, 16.7127, 2.8734, -3.3446, 19.8322, 3.0491, -3.602, 16.7127, 2.8734, -3.3446, 16.7232, 3.1513, -3.602, 15.0508995, 0, 6.6893, 16.7232, 1.5715, 6.6893, 16.7232, 0, 6.6893, 16.7232, 0, 6.6893, 16.7232, 1.5715, 6.6893, 20.0679, -0.124199994, 6.6893, 15.0508995, 0, 6.6893, 13.5511, 3.1797, 6.6893, 16.7232, 1.5715, 6.6893, 15.0508995, 0, 6.6893, 13.4036, 3.0749998, 6.6893, 13.5511, 3.1797, 6.6893, 13.4036, 3.0749998, 6.6893, 15.0508995, 0, 6.6893, 13.8046, 0, 6.6893, -16.7232, 0.6137, 0, -15.7546, 0.6137, 3.5372, -16.7232, 0.6137, 2.9166, -15.7546, 0.6137, 3.5372, -16.7232, 0.6137, 0, -13.3786, 0.6137, 0, -16.7232, 0.6137, 0, -15.8036995, 0.6137, -2.7091, -13.3786, 0.6137, -3.3446, -16.7232, 0.6137, 0, -13.3786, 0.6137, -3.3446, -13.3786, 0.6137, 0, -13.3786, 0.6137, 0, -13.3786, 0.6137, -3.3446, -10.033899, 0.6137, -3.3446, -15.7546, 0.6137, 3.5372, -13.3786, 0.6137, 0, -14.4892, 0.6137, 4.2778, -13.3786, 0.6137, 0, -10.033899, 0.6137, -3.3446, -10.033899, 0.6137, 0, -14.4892, 0.6137, 4.2778, -13.3786, 0.6137, 0, -10.033899, 0.6137, 0, -10.033899, 0.6137, 0, -10.033899, 0.6137, -3.3446, -6.6893, 0.6137, -3.3446, -10.033899, 0.6137, 0, -6.6893, 0.6137, -3.3446, -6.6893, 0.6137, 0, -6.6893, 0.6137, 0, -6.6893, 0.6137, -3.3446, -4.0257998, 0.6137, -1.6911999, -6.6893, 0.6137, 0, -4.0257998, 0.6137, -1.6911999, -3.3446, 0.6137, 0, -10.033899, 0.6137, 3.3446, -10.033899, 0.6137, 0, -6.6893, 0.6137, 0, -14.4892, 0.6137, 4.2778, -10.033899, 0.6137, 0, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 0, -3.3446, 0.6137, 0, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 0, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -3.3446, 0.6137, 0, -3.3446, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -14.4892, 0.6137, 4.2778, -10.033899, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -10.033899, 0.6137, 3.3446, -6.6893, 0.6137, 3.3446, -10.033899, 0.6137, 6.6893, -6.6893, 0.6137, 3.3446, -6.6893, 0.6137, 6.6893, -10.033899, 0.6137, 6.6893, -13.677099, 0.6137, 5.2616, -14.4892, 0.6137, 4.2778, -13.677099, 0.6137, 5.2616, -10.033899, 0.6137, 6.6893, -12.747499, 0.6137, 6.3671, -6.6893, 0.6137, 3.3446, -2.5674999, 0.0266, 7.6215, -6.6893, 0.6137, 6.6893, -2.5674999, 0.0266, 7.6215, -6.6893, 0.6137, 3.3446, -3.3446, 0.6137, 3.3446, -2.5674999, 0.0266, 7.6215, -3.3446, 0.6137, 3.3446, -2.1193, 0.6137, 5.2736998, -16.7232, 3.0033998, 2.9166, -15.7546, 0.6137, 3.5372, -15.372, 3.0033998, 3.6132998, -16.7232, 3.0033998, 2.9166, -16.7232, 0.6137, 2.9166, -15.7546, 0.6137, 3.5372, -14.4892, 3.0033998, 4.2778, -13.677099, 0.6137, 5.2616, -13.6942, 3.0033998, 5.1798, -14.4892, 3.0033998, 4.2778, -14.4892, 0.6137, 4.2778, -13.677099, 0.6137, 5.2616, -15.8036995, 3.0033998, -2.7091, -16.7232, 0.6137, 0, -16.7232, 3.0033998, 0, -15.8036995, 3.0033998, -2.7091, -15.8036995, 0.6137, -2.7091, -16.7232, 0.6137, 0, -16.7232, 3.0033998, 0, -16.7232, 0.6137, 2.9166, -16.7232, 3.0033998, 2.9166, -16.7232, 3.0033998, 0, -16.7232, 0.6137, 0, -16.7232, 0.6137, 2.9166, -3.3446, 3.0033998, 0, -4.0257998, 0.6137, -1.6911999, -4.0257998, 3.0033998, -1.6911999, -3.3446, 3.0033998, 0, -3.3446, 0.6137, 0, -4.0257998, 0.6137, -1.6911999, -3.3446, 3.0033998, 3.3446, -3.3446, 0.6137, 0, -3.3446, 3.0033998, 0, -3.3446, 3.0033998, 3.3446, -3.3446, 0.6137, 3.3446, -3.3446, 0.6137, 0, -12.747499, 3.0033998, 6.3671, -10.033899, 0.6137, 6.6893, -10.033899, 3.0033998, 6.6893, -12.747499, 3.0033998, 6.3671, -12.747499, 0.6137, 6.3671, -10.033899, 0.6137, 6.6893, -10.033899, 3.0033998, -3.3446, -13.3786, 0.6137, -3.3446, -13.3786, 3.0033998, -3.3446, -10.033899, 3.0033998, -3.3446, -10.033899, 0.6137, -3.3446, -13.3786, 0.6137, -3.3446, -6.6893, 3.0033998, -3.3446, -10.033899, 0.6137, -3.3446, -10.033899, 3.0033998, -3.3446, -6.6893, 3.0033998, -3.3446, -6.6893, 0.6137, -3.3446, -10.033899, 0.6137, -3.3446, -13.3786, 3.0033998, -3.3446, -15.8036995, 0.6137, -2.7091, -15.8036995, 3.0033998, -2.7091, -13.3786, 3.0033998, -3.3446, -13.3786, 0.6137, -3.3446, -15.8036995, 0.6137, -2.7091, -4.0257998, 3.0033998, -1.6911999, -6.6893, 0.6137, -3.3446, -6.6893, 3.0033998, -3.3446, -4.0257998, 3.0033998, -1.6911999, -4.0257998, 0.6137, -1.6911999, -6.6893, 0.6137, -3.3446, -6.6893, 3.0033998, 6.6893, -2.5674999, 0.0266, 7.6215, -2.5674999, 2.4164, 7.6215, -6.6893, 3.0033998, 6.6893, -6.6893, 0.6137, 6.6893, -2.5674999, 0.0266, 7.6215, -10.033899, 3.0033998, 6.6893, -6.6893, 0.6137, 6.6893, -6.6893, 3.0033998, 6.6893, -10.033899, 3.0033998, 6.6893, -10.033899, 0.6137, 6.6893, -6.6893, 0.6137, 6.6893, -2.5674999, 2.4164, 7.6215, -2.1193, 0.6137, 5.2736998, -2.1397, 3.0033998, 5.1795, -2.5674999, 2.4164, 7.6215, -2.5674999, 0.0266, 7.6215, -2.1193, 0.6137, 5.2736998, -2.1193, 0.6137, 5.2736998, -3.3446, 3.0033998, 3.3446, -2.1397, 3.0033998, 5.1795, -2.1193, 0.6137, 5.2736998, -3.3446, 0.6137, 3.3446, -3.3446, 3.0033998, 3.3446, -13.677099, 0.6137, 5.2616, -12.747499, 3.0033998, 6.3671, -13.6942, 3.0033998, 5.1798, -13.677099, 0.6137, 5.2616, -12.747499, 0.6137, 6.3671, -12.747499, 3.0033998, 6.3671, -15.7546, 0.6137, 3.5372, -14.4892, 3.0033998, 4.2778, -15.372, 3.0033998, 3.6132998, -15.7546, 0.6137, 3.5372, -14.4892, 0.6137, 4.2778, -14.4892, 3.0033998, 4.2778, 21.1831, 0, -13.6544, 16.8204, 3.138, -13.447599, 18.0241, 0, -14.3019, 21.1831, 0, -13.6544, 20.1539, 3.1299, -13.399799, 16.8204, 3.138, -13.447599, 21.8888, 0, -10.033899, 20.1539, 3.1299, -13.399799, 21.1831, 0, -13.6544, 21.8888, 0, -10.033899, 20.198, 3.1490998, -10.033899, 20.1539, 3.1299, -13.399799, 17.2285, 0, -16.8036, 12.7471, 3.1766999, -16.1988, 13.7014, 0, -17.416399, 17.2285, 0, -16.8036, 16.756899, 3.1650999, -16.7286, 12.7471, 3.1766999, -16.1988, 16.8204, 3.138, -13.447599, 17.2285, 0, -16.8036, 18.0241, 0, -14.3019, 17.2285, 0, -16.8036, 16.8204, 3.138, -13.447599, 16.8051, 3.1778, -13.479, 17.2285, 0, -16.8036, 16.8051, 3.1778, -13.479, 16.756899, 3.1650999, -16.7286, 12.7471, 3.1766999, -16.1988, 13.3786, 0, -20.5992, 13.7014, 0, -17.416399, 13.3786, 0, -20.5992, 12.7471, 3.1766999, -16.1988, 12.747, 3.1771, -16.1991, 13.3786, 0, -20.5992, 12.747, 3.1771, -16.1991, 12.723599, 2.9213, -19.2902, 13.3786, 0, -20.5992, 10.033899, 3.0523999, -19.0294, 10.033899, 0, -20.467, 13.3786, 0, -20.5992, 12.723599, 2.9213, -19.2902, 10.033899, 3.0523999, -19.0294, 10.033899, 0, -20.467, 6.6893, 3.0440998, -19.036999, 6.6893, 0, -20.1318, 10.033899, 0, -20.467, 10.033899, 3.0523999, -19.0294, 6.6893, 3.0440998, -19.036999, 3.0140998, 0, -16.7232, 4.4131, 3.2091, -13.357699, 3.3446, -0.3989, -12.9443, 3.0140998, 0, -16.7232, 3.5895, 3.2033, -16.7232, 4.4131, 3.2091, -13.357699, 6.6893, 3.0440998, -19.036999, 3.3446, 0, -20.5992, 6.6893, 0, -20.1318, 3.3446, 0, -20.5992, 6.6893, 3.0440998, -19.036999, 6.6640997, 3.0702, -19.018099, 3.3446, 0, -20.5992, 6.6640997, 3.0702, -19.018099, 4.4783998, 3.1067, -18.2665, 3.3446, 0, -20.5992, 3.5895, 3.2033, -16.7232, 3.0140998, 0, -16.7232, 3.3446, 0, -20.5992, 4.4783998, 3.1067, -18.2665, 3.5895, 3.2033, -16.7232, 2.8241, 0, -10.4594, 0, 3.179, -9.0652, 0, 0, -10.7654, 2.8241, 0, -10.4594, 3.7529, 3.1712, -9.0494995, 0, 3.179, -9.0652, 3.3446, -0.3989, -12.9443, 3.7529, 3.1712, -9.0494995, 2.8241, 0, -10.4594, 3.3446, -0.3989, -12.9443, 4.4131, 3.2091, -13.357699, 3.7529, 3.1712, -9.0494995, 4.4131, 3.2091, -13.357699, 3.3446, -0.3989, -12.9443, 4.4131, 3.2091, -13.357699, -2.6297, 0, -10.5745, -3.6538, 3.1585999, -12.813399, -3.3446, 0, -13.3786, -2.6297, 0, -10.5745, -3.6076, 3.1676, -10.0696, -3.6538, 3.1585999, -12.813399, -3.3446, 0, -13.3786, -6.6893, 3.175, -12.867, -6.6893, 0, -14.2637, -3.3446, 0, -13.3786, -3.6538, 3.1585999, -12.813399, -6.6893, 3.175, -12.867, 0, 3.179, -9.0652, -2.6297, 0, -10.5745, 0, 0, -10.7654, -2.6297, 0, -10.5745, 0, 3.179, -9.0652, -0.0081, 3.1864998, -9.063499, -2.6297, 0, -10.5745, -0.0081, 3.1864998, -9.063499, -3.6076, 3.1676, -10.0696, -6.6893, 0, -14.2637, -10.4043, 3.1608999, -13.4295, -9.6168995, 0, -14.127899, -6.6893, 0, -14.2637, -6.6893, 3.175, -12.867, -10.4043, 3.1608999, -13.4295, -6.6893, 3.175, -12.867, -6.6893, 0, -14.2637, -6.6893, 3.175, -12.867, -9.6168995, 0, -14.127899, -10.4319, 3.1557999, -16.1556, -10.033899, 0, -16.7232, -9.6168995, 0, -14.127899, -10.4043, 3.1608999, -13.4295, -10.4319, 3.1557999, -16.1556, -10.033899, 0, -16.7232, -13.3786, 3.1771998, -15.7625, -13.3786, 0, -17.3364, -10.033899, 0, -16.7232, -10.4319, 3.1557999, -16.1556, -13.3786, 3.1771998, -15.7625, -16.7232, 0, -16.7232, -16.3753, 3.4225, -13.6277, -16.7232, 0, -13.3786, -16.7232, 0, -16.7232, -16.0243, 3.3509998, -15.752, -16.3753, 3.4225, -13.6277, -13.3786, 3.1771998, -15.7625, -16.7232, 0, -16.7232, -13.3786, 0, -17.3364, -16.7232, 0, -16.7232, -13.3786, 3.1771998, -15.7625, -13.3911, 3.1892, -15.757, -16.7232, 0, -16.7232, -13.3911, 3.1892, -15.757, -16.0243, 3.3509998, -15.752, -17.275, 0, -10.5169, -19.6237, 3.1655998, -9.757899, -20.0679, 0, -10.033899, -17.275, 0, -10.5169, -16.4131, 3.1706, -9.788899, -19.6237, 3.1655998, -9.757899, -16.7232, 0, -13.3786, -16.4131, 3.1706, -9.788899, -17.275, 0, -10.5169, -16.7232, 0, -13.3786, -16.3753, 3.4225, -13.6277, -16.4131, 3.1706, -9.788899, -16.3753, 3.4225, -13.6277, -16.7232, 0, -13.3786, -16.3753, 3.4225, -13.6277, -20.3764, 0, -6.6893, -19.9489, 3.2063, -2.8082, -20.0679, -0.3484, -3.5669, -20.3764, 0, -6.6893, -19.515, 3.2122, -6.6893, -19.9489, 3.2063, -2.8082, -19.6237, 3.1655998, -9.757899, -20.3764, 0, -6.6893, -20.0679, 0, -10.033899, -20.3764, 0, -6.6893, -19.6237, 3.1655998, -9.757899, -19.6161, 3.2075999, -9.7116995, -20.3764, 0, -6.6893, -19.6161, 3.2075999, -9.7116995, -19.515, 3.2122, -6.6893, -23.412498, -0.2913, 0.26119998, -23.0809, 3.3083, 3.3615, -23.412498, 0, 3.3446, -23.412498, -0.2913, 0.26119998, -23.3676, 3.4459999, 0.1372, -23.0809, 3.3083, 3.3615, -23.412498, 0, -3.3446, -23.3676, 3.4459999, 0.1372, -23.412498, -0.2913, 0.26119998, -23.412498, 0, -3.3446, -23.390299, 3.3349998, -2.6938999, -23.3676, 3.4459999, 0.1372, -20.0679, -0.3484, -3.5669, -23.390299, 3.3349998, -2.6938999, -23.412498, 0, -3.3446, -20.0679, -0.3484, -3.5669, -19.9489, 3.2063, -2.8082, -23.390299, 3.3349998, -2.6938999, -19.9489, 3.2063, -2.8082, -20.0679, -0.3484, -3.5669, -19.9489, 3.2063, -2.8082, -23.0809, 3.3083, 3.3615, -23.8078, 0, 6.6893, -23.412498, 0, 3.3446, -23.8078, 0, 6.6893, -23.0809, 3.3083, 3.3615, -23.0777, 3.3197, 3.3734, -23.8078, 0, 6.6893, -23.0777, 3.3197, 3.3734, -22.563799, 3.2219, 6.6893, -23.8078, 0, 6.6893, -22.791399, 3.2124999, 9.4432, -23.412498, 0, 10.033899, -23.8078, 0, 6.6893, -22.563799, 3.2219, 6.6893, -22.791399, 3.2124999, 9.4432, -23.412498, 0, 10.033899, -20.0679, 3.1943, 9.407499, -20.0679, 0, 10.033899, -23.412498, 0, 10.033899, -22.791399, 3.2124999, 9.4432, -20.0679, 3.1943, 9.407499, -22.791399, 3.2124999, 9.4432, -23.412498, 0, 10.033899, -22.791399, 3.2124999, 9.4432, -20.0679, 0, 10.033899, -16.2818, 3.1913998, 9.8056, -16.7232, 0, 10.033899, -20.0679, 0, 10.033899, -20.0679, 3.1943, 9.407499, -16.2818, 3.1913998, 9.8056, -16.7232, 0, 13.3786, -13.3786, 3.194, 12.8089, -13.3786, 0, 13.3786, -16.7232, 0, 13.3786, -16.076399, 3.04, 12.735, -13.3786, 3.194, 12.8089, -16.7232, 0, 10.033899, -16.076399, 3.04, 12.735, -16.7232, 0, 13.3786, -16.7232, 0, 10.033899, -16.2818, 3.1913998, 9.8056, -16.076399, 3.04, 12.735, -16.2818, 3.1913998, 9.8056, -16.7232, 0, 10.033899, -16.2818, 3.1913998, 9.8056, -13.3786, 0, 13.3786, -10.033899, 2.9384, 12.4537, -10.033899, 0, 13.3786, -13.3786, 0, 13.3786, -13.3786, 3.194, 12.8089, -10.033899, 2.9384, 12.4537, -13.3786, 3.194, 12.8089, -13.3786, 0, 13.3786, -13.3786, 3.194, 12.8089, -10.033899, 0, 13.3786, -6.2748, 3.126, 13.122, -6.6893, 0, 13.3786, -10.033899, 0, 13.3786, -10.033899, 2.9384, 12.4537, -6.2748, 3.126, 13.122, -6.6893, 0, 13.3786, -6.2748, 3.1260998, 16.4145, -6.6893, 0, 16.7232, -6.6893, 0, 13.3786, -6.2748, 3.126, 13.122, -6.2748, 3.1260998, 16.4145, -3.3446, 0, 16.7232, 0, 2.9636998, 16.0179, 0, 0, 16.7232, -3.3446, 0, 16.7232, -3.3446, 3.1497998, 15.914599, 0, 2.9636998, 16.0179, 0, 0, 16.7232, 3.6425998, 3.1413999, 16.5127, 3.3446, 0, 16.7232, 0, 0, 16.7232, 0, 2.9636998, 16.0179, 3.6425998, 3.1413999, 16.5127, -6.2748, 3.1260998, 16.4145, -3.3446, 0, 16.7232, -6.6893, 0, 16.7232, -3.3446, 0, 16.7232, -6.2748, 3.1260998, 16.4145, -6.2558, 3.1427999, 16.4098, -3.3446, 0, 16.7232, -6.2558, 3.1427999, 16.4098, -3.3446, 3.1497998, 15.914599, 3.3446, 0, 20.0679, 6.6893, 3.2050998, 19.228699, 6.6893, 0, 20.0679, 3.3446, 0, 20.0679, 3.9266999, 3.5967, 19.6223, 6.6893, 3.2050998, 19.228699, 3.6425998, 3.1413999, 16.5127, 3.3446, 0, 20.0679, 3.3446, 0, 16.7232, 3.3446, 0, 20.0679, 3.6425998, 3.1413999, 16.5127, 3.6536, 3.2078998, 16.5669, 3.3446, 0, 20.0679, 3.6536, 3.2078998, 16.5669, 3.9266999, 3.5967, 19.6223, 6.6893, 3.2050998, 19.228699, 10.572599, 0, 20.0679, 6.6893, 0, 20.0679, 10.572599, 0, 20.0679, 6.6893, 3.2050998, 19.228699, 6.6991997, 3.2148, 19.2255, 10.572599, 0, 20.0679, 6.6991997, 3.2148, 19.2255, 9.3066, 3.2186, 19.0653, 10.572599, 0, 20.0679, 10.5913, 3.1985998, 16.7232, 10.572599, 0, 16.7232, 10.572599, 0, 20.0679, 9.3066, 3.2186, 19.0653, 10.5913, 3.1985998, 16.7232, 10.5913, 3.1985998, 16.7232, 10.572599, 0, 13.918799, 10.572599, 0, 16.7232, 10.572599, 0, 13.918799, 10.5913, 3.1985998, 16.7232, 10.5893, 3.2117, 16.7106, 10.572599, 0, 13.918799, 10.5893, 3.2117, 16.7106, 10.0546, 3.1885, 13.4071, 10.572599, 0, 13.918799, 13.2631, 3.5611, 13.4043, 13.8046, 0, 13.918799, 10.572599, 0, 13.918799, 10.0546, 3.1885, 13.4071, 13.2631, 3.5611, 13.4043, 13.8046, 0, 13.918799, 12.9758, 3.2036, 10.033899, 13.8046, 0, 10.033899, 13.8046, 0, 13.918799, 13.2631, 3.5611, 13.4043, 12.9758, 3.2036, 10.033899, 13.8046, 0, 13.918799, 13.2631, 3.5611, 13.4043, 13.2631, 3.5611, 13.4043, 13.8046, 0, 10.033899, 13.4036, 3.0749998, 6.6893, 13.8046, 0, 6.6893, 13.8046, 0, 10.033899, 12.9758, 3.2036, 10.033899, 13.4036, 3.0749998, 6.6893, 20.961199, 0, -3.3446, 16.7127, 2.8734, -3.3446, 20.144999, 2.7605999, -3.3446, 20.961199, 0, -3.3446, 14.0489, 3.0042, -3.3446, 16.7127, 2.8734, -3.3446, 20.144999, 2.7605999, -3.3446, 21.2349, 0, -6.6893, 20.961199, 0, -3.3446, 21.2349, 0, -6.6893, 20.144999, 2.7605999, -3.3446, 20.1349, 2.7974, -3.3783998, 21.2349, 0, -6.6893, 20.1349, 2.7974, -3.3783998, 20.147, 3.0588999, -6.6893, 20.147, 3.0588999, -6.6893, 21.8888, 0, -10.033899, 21.2349, 0, -6.6893, 21.8888, 0, -10.033899, 20.147, 3.0588999, -6.6893, 20.1796, 3.182, -9.995999, 21.8888, 0, -10.033899, 20.1796, 3.182, -9.995999, 20.198, 3.1490998, -10.033899, 23.412498, 0, -26.7572, 26.7572, -0.2593, -23.412498, 23.412498, 0, -23.412498, 26.7572, -0.2593, -23.412498, 23.412498, 0, -26.7572, 26.7572, -0.2593, -25.084799, 26.7572, -0.2593, -25.084799, 23.412498, 0, -26.7572, 26.7572, -0.2593, -26.7572, 26.7572, -0.2593, -21.7402, 23.412498, 0, -23.412498, 26.7572, -0.2593, -23.412498, 26.7572, -0.2593, -20.0679, 23.412498, 0, -23.412498, 26.7572, -0.2593, -21.7402, 23.412498, 0, -23.412498, 26.7572, -0.2593, -20.0679, 23.412498, 0, -20.0679, 26.7572, -0.2593, -18.3955, 23.412498, 0, -20.0679, 26.7572, -0.2593, -20.0679, 26.7572, -0.2593, -16.7232, 23.412498, 0, -20.0679, 26.7572, -0.2593, -18.3955, 23.412498, 0, -20.0679, 26.7572, -0.2593, -16.7232, 23.412498, 0, -16.7232, 26.7572, -0.2593, -15.0508995, 23.412498, 0, -16.7232, 26.7572, -0.2593, -16.7232, 26.7572, -0.2593, -13.3786, 23.412498, 0, -16.7232, 26.7572, -0.2593, -15.0508995, 23.412498, 0, -16.7232, 26.7572, -0.2593, -13.3786, 23.412498, 0, -13.3786, 26.7572, -0.2593, -11.7063, 23.412498, 0, -13.3786, 26.7572, -0.2593, -13.3786, 26.7572, -0.2593, -10.033899, 23.412498, 0, -13.3786, 26.7572, -0.2593, -11.7063, 23.412498, 0, -13.3786, 26.7572, -0.2593, -10.033899, 23.412498, 0, -10.033899, 26.7572, -0.2593, -8.3616, 23.412498, 0, -10.033899, 26.7572, -0.2593, -10.033899, 26.7572, -0.2593, -6.6893, 23.412498, 0, -10.033899, 26.7572, -0.2593, -8.3616, 23.412498, 0, -10.033899, 26.7572, -0.2593, -6.6893, 23.412498, 0, -6.6893, 26.7572, -0.2593, -5.0169997, 23.412498, 0, -6.6893, 26.7572, -0.2593, -6.6893, 26.7572, -0.2593, -3.3446, 23.412498, 0, -6.6893, 26.7572, -0.2593, -5.0169997, 23.412498, 0, -6.6893, 26.7572, -0.2593, -3.3446, 23.412498, 0, -3.3446, 26.7572, -0.2593, -1.6723, 23.412498, 0, -3.3446, 26.7572, -0.2593, -3.3446, 26.7572, -0.2593, 0, 23.412498, 0, -3.3446, 26.7572, -0.2593, -1.6723, 23.412498, 0, -3.3446, 26.7572, -0.2593, 0, 23.412498, 0, 0, 26.7572, -0.2593, 1.6723, 23.412498, 0, 0, 26.7572, -0.2593, 0, 26.7572, -0.2593, 3.3446, 23.412498, 0, 0, 26.7572, -0.2593, 1.6723, 23.412498, 0, 0, 26.7572, -0.2593, 3.3446, 23.412498, 0, 3.3446, 26.7572, -0.2593, 5.0169997, 23.412498, 0, 3.3446, 26.7572, -0.2593, 3.3446, 26.7572, -0.2593, 6.6893, 23.412498, 0, 3.3446, 26.7572, -0.2593, 5.0169997, 23.412498, 0, 3.3446, 26.7572, -0.2593, 6.6893, 23.412498, 0, 6.6893, 26.7572, -0.2593, 8.3616, 23.412498, 0, 6.6893, 26.7572, -0.2593, 6.6893, 26.7572, -0.2593, 10.033899, 23.412498, 0, 6.6893, 26.7572, -0.2593, 8.3616, 23.412498, 0, 6.6893, 26.7572, -0.2593, 10.033899, 23.412498, 0, 10.033899, 26.7572, -0.2593, 11.7063, 23.412498, 0, 10.033899, 26.7572, -0.2593, 10.033899, 26.7572, -0.2593, 13.3786, 23.412498, 0, 10.033899, 26.7572, -0.2593, 11.7063, 23.412498, 0, 10.033899, 26.7572, -0.2593, 13.3786, 23.412498, 0, 13.3786, 26.7572, -0.2593, 15.0508995, 23.412498, 0, 13.3786, 26.7572, -0.2593, 13.3786, 26.7572, -0.2593, 16.7232, 23.412498, 0, 13.3786, 26.7572, -0.2593, 15.0508995, 23.412498, 0, 13.3786, 26.7572, -0.2593, 16.7232, 23.412498, 0, 16.7232, 26.7572, -0.2593, 18.3955, 23.412498, 0, 16.7232, 26.7572, -0.2593, 16.7232, 26.7572, -0.2593, 20.0679, 23.412498, 0, 16.7232, 26.7572, -0.2593, 18.3955, 23.412498, 0, 16.7232, 26.7572, -0.2593, 20.0679, 23.412498, 0, 20.0679, 26.7572, -0.2593, 21.7402, 23.412498, 0, 20.0679, 26.7572, -0.2593, 20.0679, 26.7572, -0.2593, 23.412498, 23.412498, 0, 20.0679, 26.7572, -0.2593, 21.7402, 23.412498, 0, 20.0679, 26.7572, -0.2593, 23.412498, 23.412498, 0, 23.412498, 26.7572, -0.2593, 25.084799, 23.412498, 0, 23.412498, 26.7572, -0.2593, 23.412498, 26.7572, -0.2593, 26.7572, 23.412498, 0, 23.412498, 26.7572, -0.2593, 25.084799, 23.412498, 0, 23.412498, 26.7572, -0.2593, 26.7572, 23.412498, 0, 26.7572, -3.3446, 0, -23.412498, 0, 0, -26.7572, 0, 0, -23.412498, 0, 0, -23.412498, 0, 0, -26.7572, 3.3446, 0, -26.7572, -3.3446, 0, -23.412498, -3.3446, 0, -26.7572, 0, 0, -26.7572, 0, 0, -23.412498, 3.3446, 0, -26.7572, 3.3446, 0, -23.412498, 3.3446, 0, -23.412498, 3.3446, 0, -26.7572, 6.6893, 0, -26.7572, -3.3446, 0, -20.0679, -3.3446, 0, -23.412498, 0, 0, -23.412498, 3.3446, 0, -23.412498, 6.6893, 0, -26.7572, 6.6893, 0, -23.412498, 6.6893, 0, -23.412498, 6.6893, 0, -26.7572, 10.033899, 0, -26.7572, 0, 0, -20.0679, 0, 0, -23.412498, 3.3446, 0, -23.412498, -3.3446, 0, -20.0679, 0, 0, -23.412498, 0, 0, -20.0679, 3.3446, 0, -20.5992, 3.3446, 0, -23.412498, 6.6893, 0, -23.412498, 0, 0, -20.0679, 3.3446, 0, -23.412498, 3.3446, 0, -20.5992, 3.3446, 0, -20.5992, 6.6893, 0, -23.412498, 6.6893, 0, -20.1318, 6.6893, 0, -23.412498, 10.033899, 0, -26.7572, 10.033899, 0, -23.412498, 6.6893, 0, -20.1318, 6.6893, 0, -23.412498, 10.033899, 0, -23.412498, 10.033899, 0, -23.412498, 10.033899, 0, -26.7572, 13.3786, 0, -26.7572, 6.6893, 0, -20.1318, 10.033899, 0, -23.412498, 10.033899, 0, -20.467, 10.033899, 0, -23.412498, 13.3786, 0, -26.7572, 13.3786, 0, -23.412498, 10.033899, 0, -20.467, 10.033899, 0, -23.412498, 13.3786, 0, -23.412498, 13.3786, 0, -23.412498, 13.3786, 0, -26.7572, 16.7232, 0, -26.7572, 10.033899, 0, -20.467, 13.3786, 0, -23.412498, 13.3786, 0, -20.5992, 13.3786, 0, -23.412498, 16.7232, 0, -26.7572, 16.7232, 0, -23.412498, 13.3786, 0, -20.5992, 13.3786, 0, -23.412498, 16.7232, 0, -23.412498, 16.7232, 0, -23.412498, 16.7232, 0, -26.7572, 20.0679, 0, -26.7572, 13.3786, 0, -20.5992, 16.7232, 0, -23.412498, 16.7232, 0, -20.0679, 13.7014, 0, -17.416399, 13.3786, 0, -20.5992, 16.7232, 0, -20.0679, 13.7014, 0, -17.416399, 16.7232, 0, -20.0679, 17.2285, 0, -16.8036, 16.7232, 0, -23.412498, 20.0679, 0, -26.7572, 20.0679, 0, -23.412498, 16.7232, 0, -20.0679, 16.7232, 0, -23.412498, 20.0679, 0, -23.412498, 20.0679, 0, -23.412498, 20.0679, 0, -26.7572, 23.412498, 0, -26.7572, 20.0679, 0, -23.412498, 23.412498, 0, -26.7572, 23.412498, 0, -23.412498, 16.7232, 0, -20.0679, 20.0679, 0, -23.412498, 20.0679, 0, -20.0679, 20.0679, 0, -20.0679, 20.0679, 0, -23.412498, 23.412498, 0, -23.412498, 17.2285, 0, -16.8036, 16.7232, 0, -20.0679, 20.0679, 0, -20.0679, 20.0679, 0, -20.0679, 23.412498, 0, -23.412498, 23.412498, 0, -20.0679, 17.2285, 0, -16.8036, 20.0679, 0, -20.0679, 20.0679, 0, -16.7232, 20.0679, 0, -16.7232, 20.0679, 0, -20.0679, 23.412498, 0, -20.0679, 18.0241, 0, -14.3019, 17.2285, 0, -16.8036, 20.0679, 0, -16.7232, 20.0679, 0, -16.7232, 23.412498, 0, -20.0679, 23.412498, 0, -16.7232, 18.0241, 0, -14.3019, 20.0679, 0, -16.7232, 21.1831, 0, -13.6544, 21.1831, 0, -13.6544, 20.0679, 0, -16.7232, 23.412498, 0, -16.7232, 21.1831, 0, -13.6544, 23.412498, 0, -16.7232, 23.412498, 0, -13.3786, 21.8888, 0, -10.033899, 21.1831, 0, -13.6544, 23.412498, 0, -13.3786, 21.8888, 0, -10.033899, 23.412498, 0, -13.3786, 23.412498, 0, -10.033899, 21.2349, 0, -6.6893, 21.8888, 0, -10.033899, 23.412498, 0, -10.033899, 21.2349, 0, -6.6893, 23.412498, 0, -10.033899, 23.412498, 0, -6.6893, 20.961199, 0, -3.3446, 21.2349, 0, -6.6893, 23.412498, 0, -6.6893, 20.961199, 0, -3.3446, 23.412498, 0, -6.6893, 23.412498, 0, -3.3446, 20.0679, 0, 0, 20.961199, 0, -3.3446, 23.412498, 0, -3.3446, 20.0679, 0, 0, 23.412498, 0, -3.3446, 23.412498, 0, 0, 20.0679, 0, 3.3446, 20.0679, 0, 0, 23.412498, 0, 0, 20.0679, 0, 3.3446, 23.412498, 0, 0, 23.412498, 0, 3.3446, 10.572599, 0, 16.7232, 13.8046, 0, 13.918799, 13.3786, 0, 16.7232, 10.572599, 0, 16.7232, 10.572599, 0, 13.918799, 13.8046, 0, 13.918799, 10.572599, 0, 20.0679, 10.572599, 0, 16.7232, 13.3786, 0, 16.7232, 13.3786, 0, 16.7232, 13.8046, 0, 13.918799, 15.0508995, 0, 13.3786, 10.572599, 0, 20.0679, 13.3786, 0, 16.7232, 13.3786, 0, 20.0679, 13.8046, 0, 13.918799, 15.0508995, 0, 10.033899, 15.0508995, 0, 13.3786, 13.8046, 0, 13.918799, 13.8046, 0, 10.033899, 15.0508995, 0, 10.033899, 13.8046, 0, 10.033899, 15.0508995, 0, 6.6893, 15.0508995, 0, 10.033899, 13.8046, 0, 10.033899, 13.8046, 0, 6.6893, 15.0508995, 0, 6.6893, 15.0508995, 0, 10.033899, 15.0508995, 0, 6.6893, 16.7232, 0, 6.6893, 15.0508995, 0, 10.033899, 16.7232, 0, 6.6893, 16.7232, 0, 10.033899, 15.0508995, 0, 13.3786, 15.0508995, 0, 10.033899, 16.7232, 0, 10.033899, 13.3786, 0, 16.7232, 15.0508995, 0, 13.3786, 15.0508995, 0, 16.7232, 13.3786, 0, 20.0679, 13.3786, 0, 16.7232, 15.0508995, 0, 16.7232, 15.0508995, 0, 13.3786, 16.7232, 0, 10.033899, 16.7232, 0, 13.3786, 15.0508995, 0, 16.7232, 15.0508995, 0, 13.3786, 16.7232, 0, 13.3786, 16.7232, 0, 13.3786, 16.7232, 0, 10.033899, 20.0679, 0, 10.033899, 16.7232, 0, 13.3786, 20.0679, 0, 10.033899, 20.0679, 0, 13.3786, 20.0679, 0, 13.3786, 20.0679, 0, 10.033899, 23.412498, 0, 10.033899, 20.0679, 0, 13.3786, 23.412498, 0, 10.033899, 23.412498, 0, 13.3786, 16.7232, 0, 16.7232, 16.7232, 0, 13.3786, 20.0679, 0, 13.3786, 15.0508995, 0, 16.7232, 16.7232, 0, 13.3786, 16.7232, 0, 16.7232, 20.0679, 0, 16.7232, 20.0679, 0, 13.3786, 23.412498, 0, 13.3786, 16.7232, 0, 16.7232, 20.0679, 0, 13.3786, 20.0679, 0, 16.7232, 20.0679, 0, 16.7232, 23.412498, 0, 13.3786, 23.412498, 0, 16.7232, 15.0508995, 0, 20.0679, 15.0508995, 0, 16.7232, 16.7232, 0, 16.7232, 13.3786, 0, 20.0679, 15.0508995, 0, 16.7232, 15.0508995, 0, 20.0679, 16.7232, 0, 20.0679, 16.7232, 0, 16.7232, 20.0679, 0, 16.7232, 15.0508995, 0, 20.0679, 16.7232, 0, 16.7232, 16.7232, 0, 20.0679, 20.0679, 0, 20.0679, 20.0679, 0, 16.7232, 23.412498, 0, 16.7232, 16.7232, 0, 20.0679, 20.0679, 0, 16.7232, 20.0679, 0, 20.0679, 20.0679, 0, 20.0679, 23.412498, 0, 16.7232, 23.412498, 0, 20.0679, 20.0679, 0, 23.412498, 20.0679, 0, 20.0679, 23.412498, 0, 20.0679, 20.0679, 0, 23.412498, 23.412498, 0, 20.0679, 23.412498, 0, 23.412498, 20.0679, 0, 26.7572, 20.0679, 0, 23.412498, 23.412498, 0, 23.412498, 20.0679, 0, 26.7572, 23.412498, 0, 23.412498, 23.412498, 0, 26.7572, 16.7232, 0, 26.7572, 20.0679, 0, 23.412498, 20.0679, 0, 26.7572, 16.7232, 0, 23.412498, 20.0679, 0, 20.0679, 20.0679, 0, 23.412498, 16.7232, 0, 26.7572, 16.7232, 0, 23.412498, 20.0679, 0, 23.412498, 16.7232, 0, 23.412498, 16.7232, 0, 20.0679, 20.0679, 0, 20.0679, 15.0508995, 0, 26.7572, 16.7232, 0, 23.412498, 16.7232, 0, 26.7572, 15.0508995, 0, 23.412498, 16.7232, 0, 20.0679, 16.7232, 0, 23.412498, 15.0508995, 0, 26.7572, 15.0508995, 0, 23.412498, 16.7232, 0, 23.412498, 15.0508995, 0, 23.412498, 15.0508995, 0, 20.0679, 16.7232, 0, 20.0679, 13.3786, 0, 26.7572, 15.0508995, 0, 23.412498, 15.0508995, 0, 26.7572, 13.3786, 0, 23.412498, 15.0508995, 0, 20.0679, 15.0508995, 0, 23.412498, 13.3786, 0, 26.7572, 13.3786, 0, 23.412498, 15.0508995, 0, 23.412498, 13.3786, 0, 23.412498, 13.3786, 0, 20.0679, 15.0508995, 0, 20.0679, 10.033899, 0, 26.7572, 13.3786, 0, 23.412498, 13.3786, 0, 26.7572, 10.033899, 0, 23.412498, 13.3786, 0, 20.0679, 13.3786, 0, 23.412498, 10.033899, 0, 26.7572, 10.033899, 0, 23.412498, 13.3786, 0, 23.412498, 10.033899, 0, 23.412498, 10.572599, 0, 20.0679, 13.3786, 0, 20.0679, 6.6893, 0, 26.7572, 10.033899, 0, 23.412498, 10.033899, 0, 26.7572, 6.6893, 0, 23.412498, 10.572599, 0, 20.0679, 10.033899, 0, 23.412498, 6.6893, 0, 26.7572, 6.6893, 0, 23.412498, 10.033899, 0, 23.412498, 6.6893, 0, 23.412498, 6.6893, 0, 20.0679, 10.572599, 0, 20.0679, 3.3446, 0, 26.7572, 6.6893, 0, 23.412498, 6.6893, 0, 26.7572, 3.3446, 0, 23.412498, 6.6893, 0, 20.0679, 6.6893, 0, 23.412498, 3.3446, 0, 26.7572, 3.3446, 0, 23.412498, 6.6893, 0, 23.412498, 3.3446, 0, 23.412498, 3.3446, 0, 20.0679, 6.6893, 0, 20.0679, 0, 0, 26.7572, 3.3446, 0, 23.412498, 3.3446, 0, 26.7572, 0, 0, 26.7572, 0, 0, 23.412498, 3.3446, 0, 23.412498, 0, 0, 23.412498, 3.3446, 0, 20.0679, 3.3446, 0, 23.412498, -3.3446, 0, 26.7572, 0, 0, 23.412498, 0, 0, 26.7572, 0, 0, 23.412498, 0, 0, 20.0679, 3.3446, 0, 20.0679, 0, 0, 20.0679, 3.3446, 0, 16.7232, 3.3446, 0, 20.0679, 0, 0, 20.0679, 0, 0, 16.7232, 3.3446, 0, 16.7232, -3.3446, 0, 26.7572, -3.3446, 0, 23.412498, 0, 0, 23.412498, -3.3446, 0, 23.412498, 0, 0, 20.0679, 0, 0, 23.412498, -6.6893, 0, 26.7572, -3.3446, 0, 23.412498, -3.3446, 0, 26.7572, -3.3446, 0, 20.0679, 0, 0, 16.7232, 0, 0, 20.0679, -3.3446, 0, 23.412498, -3.3446, 0, 20.0679, 0, 0, 20.0679, -3.3446, 0, 20.0679, -3.3446, 0, 16.7232, 0, 0, 16.7232, -6.6893, 0, 26.7572, -6.6893, 0, 23.412498, -3.3446, 0, 23.412498, -6.6893, 0, 23.412498, -3.3446, 0, 20.0679, -3.3446, 0, 23.412498, -10.033899, 0, 26.7572, -6.6893, 0, 23.412498, -6.6893, 0, 26.7572, -6.6893, 0, 20.0679, -3.3446, 0, 16.7232, -3.3446, 0, 20.0679, -6.6893, 0, 23.412498, -6.6893, 0, 20.0679, -3.3446, 0, 20.0679, -6.6893, 0, 20.0679, -6.6893, 0, 16.7232, -3.3446, 0, 16.7232, -10.033899, 0, 26.7572, -10.033899, 0, 23.412498, -6.6893, 0, 23.412498, -10.033899, 0, 23.412498, -6.6893, 0, 20.0679, -6.6893, 0, 23.412498, -13.3786, 0, 26.7572, -10.033899, 0, 23.412498, -10.033899, 0, 26.7572, -10.033899, 0, 20.0679, -6.6893, 0, 16.7232, -6.6893, 0, 20.0679, -10.033899, 0, 23.412498, -10.033899, 0, 20.0679, -6.6893, 0, 20.0679, -13.3786, 0, 26.7572, -13.3786, 0, 23.412498, -10.033899, 0, 23.412498, -13.3786, 0, 23.412498, -10.033899, 0, 20.0679, -10.033899, 0, 23.412498, -16.7232, 0, 26.7572, -13.3786, 0, 23.412498, -13.3786, 0, 26.7572, -10.033899, 0, 20.0679, -10.033899, 0, 16.7232, -6.6893, 0, 16.7232, -10.033899, 0, 16.7232, -6.6893, 0, 13.3786, -6.6893, 0, 16.7232, -10.033899, 0, 16.7232, -10.033899, 0, 13.3786, -6.6893, 0, 13.3786, -13.3786, 0, 20.0679, -10.033899, 0, 16.7232, -10.033899, 0, 20.0679, -13.3786, 0, 23.412498, -13.3786, 0, 20.0679, -10.033899, 0, 20.0679, -13.3786, 0, 16.7232, -10.033899, 0, 13.3786, -10.033899, 0, 16.7232, -13.3786, 0, 20.0679, -13.3786, 0, 16.7232, -10.033899, 0, 16.7232, -13.3786, 0, 16.7232, -13.3786, 0, 13.3786, -10.033899, 0, 13.3786, -16.7232, 0, 26.7572, -16.7232, 0, 23.412498, -13.3786, 0, 23.412498, -16.7232, 0, 23.412498, -13.3786, 0, 20.0679, -13.3786, 0, 23.412498, -20.0679, 0, 26.7572, -16.7232, 0, 23.412498, -16.7232, 0, 26.7572, -16.7232, 0, 20.0679, -13.3786, 0, 16.7232, -13.3786, 0, 20.0679, -16.7232, 0, 23.412498, -16.7232, 0, 20.0679, -13.3786, 0, 20.0679, -16.7232, 0, 16.7232, -13.3786, 0, 13.3786, -13.3786, 0, 16.7232, -16.7232, 0, 20.0679, -16.7232, 0, 16.7232, -13.3786, 0, 16.7232, -16.7232, 0, 16.7232, -16.7232, 0, 13.3786, -13.3786, 0, 13.3786, -20.0679, 0, 26.7572, -20.0679, 0, 23.412498, -16.7232, 0, 23.412498, -20.0679, 0, 23.412498, -16.7232, 0, 20.0679, -16.7232, 0, 23.412498, -23.412498, 0, 26.7572, -20.0679, 0, 23.412498, -20.0679, 0, 26.7572, -20.0679, 0, 20.0679, -16.7232, 0, 16.7232, -16.7232, 0, 20.0679, -20.0679, 0, 23.412498, -20.0679, 0, 20.0679, -16.7232, 0, 20.0679, -23.412498, 0, 26.7572, -23.412498, 0, 23.412498, -20.0679, 0, 23.412498, -23.412498, 0, 23.412498, -20.0679, 0, 20.0679, -20.0679, 0, 23.412498, -26.7572, 0, 26.7572, -23.412498, 0, 23.412498, -23.412498, 0, 26.7572, -26.7572, 0, 26.7572, -26.7572, 0, 23.412498, -23.412498, 0, 23.412498, -26.7572, 0, 23.412498, -23.412498, 0, 20.0679, -23.412498, 0, 23.412498, -23.412498, 0, 23.412498, -23.412498, 0, 20.0679, -20.0679, 0, 20.0679, -26.7572, 0, 23.412498, -26.7572, 0, 20.0679, -23.412498, 0, 20.0679, -20.0679, 0, 20.0679, -20.0679, 0, 16.7232, -16.7232, 0, 16.7232, -23.412498, 0, 20.0679, -20.0679, 0, 16.7232, -20.0679, 0, 20.0679, -20.0679, 0, 16.7232, -16.7232, 0, 13.3786, -16.7232, 0, 16.7232, -26.7572, 0, 20.0679, -23.412498, 0, 16.7232, -23.412498, 0, 20.0679, -23.412498, 0, 20.0679, -23.412498, 0, 16.7232, -20.0679, 0, 16.7232, -26.7572, 0, 20.0679, -26.7572, 0, 16.7232, -23.412498, 0, 16.7232, -20.0679, 0, 16.7232, -20.0679, 0, 13.3786, -16.7232, 0, 13.3786, -23.412498, 0, 16.7232, -20.0679, 0, 13.3786, -20.0679, 0, 16.7232, -20.0679, 0, 13.3786, -16.7232, 0, 10.033899, -16.7232, 0, 13.3786, -20.0679, 0, 13.3786, -20.0679, 0, 10.033899, -16.7232, 0, 10.033899, -23.412498, 0, 16.7232, -23.412498, 0, 13.3786, -20.0679, 0, 13.3786, -23.412498, 0, 13.3786, -20.0679, 0, 10.033899, -20.0679, 0, 13.3786, -26.7572, 0, 16.7232, -23.412498, 0, 13.3786, -23.412498, 0, 16.7232, -23.412498, 0, 13.3786, -23.412498, 0, 10.033899, -20.0679, 0, 10.033899, -26.7572, 0, 16.7232, -26.7572, 0, 13.3786, -23.412498, 0, 13.3786, -26.7572, 0, 13.3786, -23.412498, 0, 10.033899, -23.412498, 0, 13.3786, -26.7572, 0, 13.3786, -26.7572, 0, 10.033899, -23.412498, 0, 10.033899, -26.7572, 0, 10.033899, -23.8078, 0, 6.6893, -23.412498, 0, 10.033899, -26.7572, 0, 10.033899, -26.7572, 0, 6.6893, -23.8078, 0, 6.6893, -26.7572, 0, 6.6893, -23.412498, 0, 3.3446, -23.8078, 0, 6.6893, -26.7572, 0, 6.6893, -26.7572, 0, 3.3446, -23.412498, 0, 3.3446, -16.7232, 0, -23.412498, -13.3786, 0, -26.7572, -13.3786, 0, -23.412498, -13.3786, 0, -23.412498, -13.3786, 0, -26.7572, -10.033899, 0, -26.7572, -16.7232, 0, -23.412498, -16.7232, 0, -26.7572, -13.3786, 0, -26.7572, -13.3786, 0, -23.412498, -10.033899, 0, -26.7572, -10.033899, 0, -23.412498, -10.033899, 0, -23.412498, -10.033899, 0, -26.7572, -6.6893, 0, -26.7572, -16.7232, 0, -20.0679, -16.7232, 0, -23.412498, -13.3786, 0, -23.412498, -10.033899, 0, -23.412498, -6.6893, 0, -26.7572, -6.6893, 0, -23.412498, -6.6893, 0, -23.412498, -6.6893, 0, -26.7572, -3.3446, 0, -26.7572, -6.6893, 0, -23.412498, -3.3446, 0, -26.7572, -3.3446, 0, -23.412498, -13.3786, 0, -20.0679, -13.3786, 0, -23.412498, -10.033899, 0, -23.412498, -16.7232, 0, -20.0679, -13.3786, 0, -23.412498, -13.3786, 0, -20.0679, -10.033899, 0, -20.0679, -10.033899, 0, -23.412498, -6.6893, 0, -23.412498, -13.3786, 0, -20.0679, -10.033899, 0, -23.412498, -10.033899, 0, -20.0679, -6.6893, 0, -20.0679, -6.6893, 0, -23.412498, -3.3446, 0, -23.412498, -10.033899, 0, -20.0679, -6.6893, 0, -23.412498, -6.6893, 0, -20.0679, -6.6893, 0, -20.0679, -3.3446, 0, -23.412498, -3.3446, 0, -20.0679, -13.3786, 0, -17.3364, -13.3786, 0, -20.0679, -10.033899, 0, -20.0679, -13.3786, 0, -17.3364, -10.033899, 0, -20.0679, -10.033899, 0, -16.7232, -10.033899, 0, -16.7232, -10.033899, 0, -20.0679, -6.6893, 0, -20.0679, -16.7232, 0, -16.7232, -13.3786, 0, -20.0679, -13.3786, 0, -17.3364, -16.7232, 0, -16.7232, -16.7232, 0, -20.0679, -13.3786, 0, -20.0679, -10.033899, 0, -16.7232, -6.6893, 0, -20.0679, -6.6893, 0, -16.7232, -6.6893, 0, -16.7232, -6.6893, 0, -20.0679, -3.3446, 0, -20.0679, -9.6168995, 0, -14.127899, -10.033899, 0, -16.7232, -6.6893, 0, -16.7232, -9.6168995, 0, -14.127899, -6.6893, 0, -16.7232, -6.6893, 0, -14.2637, -6.6893, 0, -16.7232, -3.3446, 0, -20.0679, -3.3446, 0, -16.7232, -6.6893, 0, -14.2637, -6.6893, 0, -16.7232, -3.3446, 0, -16.7232, -3.3446, 0, -16.7232, -3.3446, 0, -20.0679, 0, 0, -20.0679, -6.6893, 0, -14.2637, -3.3446, 0, -16.7232, -3.3446, 0, -13.3786, -3.3446, 0, -16.7232, 0, 0, -20.0679, 0, 0, -16.7232, -3.3446, 0, -13.3786, -3.3446, 0, -16.7232, 0, 0, -16.7232, 0, 0, -16.7232, 0, 0, -20.0679, 3.3446, 0, -20.5992, 0, 0, -16.7232, 3.3446, 0, -20.5992, 3.0140998, 0, -16.7232, -3.3446, 0, -13.3786, 0, 0, -16.7232, 0, 0, -13.3786, -2.6297, 0, -10.5745, -3.3446, 0, -13.3786, 0, 0, -13.3786, -2.6297, 0, -10.5745, 0, 0, -13.3786, 0, 0, -10.7654, -20.0679, 0, -16.7232, -16.7232, 0, -20.0679, -16.7232, 0, -16.7232, -20.0679, 0, -16.7232, -20.0679, 0, -20.0679, -16.7232, 0, -20.0679, -20.0679, 0, -20.0679, -16.7232, 0, -23.412498, -16.7232, 0, -20.0679, -20.0679, 0, -13.3786, -20.0679, 0, -16.7232, -16.7232, 0, -16.7232, -20.0679, 0, -13.3786, -16.7232, 0, -16.7232, -16.7232, 0, -13.3786, -23.412498, 0, -16.7232, -20.0679, 0, -20.0679, -20.0679, 0, -16.7232, -20.0679, 0, -10.033899, -20.0679, 0, -13.3786, -16.7232, 0, -13.3786, -20.0679, 0, -10.033899, -16.7232, 0, -13.3786, -17.275, 0, -10.5169, -23.412498, 0, -13.3786, -20.0679, 0, -16.7232, -20.0679, 0, -13.3786, -23.412498, 0, -13.3786, -23.412498, 0, -16.7232, -20.0679, 0, -16.7232, -23.412498, 0, -10.033899, -20.0679, 0, -13.3786, -20.0679, 0, -10.033899, -23.412498, 0, -10.033899, -23.412498, 0, -13.3786, -20.0679, 0, -13.3786, -26.7572, 0, -10.033899, -23.412498, 0, -13.3786, -23.412498, 0, -10.033899, -26.7572, 0, -10.033899, -26.7572, 0, -13.3786, -23.412498, 0, -13.3786, -26.7572, 0, -13.3786, -23.412498, 0, -16.7232, -23.412498, 0, -13.3786, -26.7572, 0, -6.6893, -26.7572, 0, -10.033899, -23.412498, 0, -10.033899, -26.7572, 0, -13.3786, -26.7572, 0, -16.7232, -23.412498, 0, -16.7232, -26.7572, 0, -6.6893, -23.412498, 0, -10.033899, -23.412498, 0, -6.6893, -23.412498, 0, -6.6893, -23.412498, 0, -10.033899, -20.0679, 0, -10.033899, -23.412498, 0, -6.6893, -20.0679, 0, -10.033899, -20.3764, 0, -6.6893, -26.7572, 0, -3.3446, -26.7572, 0, -6.6893, -23.412498, 0, -6.6893, -26.7572, 0, -3.3446, -23.412498, 0, -6.6893, -23.412498, 0, -3.3446, -26.7572, 0, -16.7232, -23.412498, 0, -20.0679, -23.412498, 0, -16.7232, -23.412498, 0, -16.7232, -23.412498, 0, -20.0679, -20.0679, 0, -20.0679, -26.7572, 0, -16.7232, -26.7572, 0, -20.0679, -23.412498, 0, -20.0679, -23.412498, 0, -20.0679, -20.0679, 0, -23.412498, -20.0679, 0, -20.0679, -20.0679, 0, -20.0679, -20.0679, 0, -23.412498, -16.7232, 0, -23.412498, -20.0679, 0, -23.412498, -16.7232, 0, -26.7572, -16.7232, 0, -23.412498, -20.0679, 0, -23.412498, -20.0679, 0, -26.7572, -16.7232, 0, -26.7572, -23.412498, 0, -20.0679, -23.412498, 0, -23.412498, -20.0679, 0, -23.412498, -23.412498, 0, -23.412498, -20.0679, 0, -26.7572, -20.0679, 0, -23.412498, -26.7572, 0, -20.0679, -23.412498, 0, -23.412498, -23.412498, 0, -20.0679, -23.412498, 0, -23.412498, -23.412498, 0, -26.7572, -20.0679, 0, -26.7572, -26.7572, 0, -20.0679, -26.7572, 0, -23.412498, -23.412498, 0, -23.412498, -26.7572, 0, -23.412498, -23.412498, 0, -26.7572, -23.412498, 0, -23.412498, -26.7572, 0, -23.412498, -26.7572, 0, -26.7572, -23.412498, 0, -26.7572, -23.412498, 0, -3.3446, -20.3764, 0, -6.6893, -20.0679, -0.3484, -3.5669, -23.412498, 0, -3.3446, -23.412498, 0, -6.6893, -20.3764, 0, -6.6893, 16.7232, 0, 10.033899, 20.0679, -0.124199994, 6.6893, 20.0679, 0, 10.033899, 16.7232, 0, 10.033899, 16.7232, 0, 6.6893, 20.0679, -0.124199994, 6.6893, 20.0679, 0, 10.033899, 23.412498, 0, 6.6893, 23.412498, 0, 10.033899, 20.0679, 0, 10.033899, 20.0679, -0.124199994, 6.6893, 23.412498, 0, 6.6893, -26.7572, 0, 3.3446, -23.412498, -0.2913, 0.26119998, -23.412498, 0, 3.3446, -26.7572, 0, 3.3446, -26.7572, 0, 0, -23.412498, -0.2913, 0.26119998, -26.7572, 0, 0, -23.412498, 0, -3.3446, -23.412498, -0.2913, 0.26119998, -26.7572, 0, 0, -26.7572, 0, -3.3446, -23.412498, 0, -3.3446, 0, 0, -13.3786, 3.0140998, 0, -16.7232, 3.3446, -0.3989, -12.9443, 0, 0, -13.3786, 0, 0, -16.7232, 3.0140998, 0, -16.7232, 0, 0, -10.7654, 3.3446, -0.3989, -12.9443, 2.8241, 0, -10.4594, 0, 0, -10.7654, 0, 0, -13.3786, 3.3446, -0.3989, -12.9443, 20.0679, -0.124199994, 6.6893, 23.412498, 0, 3.3446, 23.412498, 0, 6.6893, 20.0679, -0.124199994, 6.6893, 20.0679, 0, 3.3446, 23.412498, 0, 3.3446, 51.2184, -3.9413, -15.0508995, 54.072197, -3.9413, -13.3786, 51.2184, -3.9413, -13.3786, 51.2184, -3.9413, -13.3786, 54.072197, -3.9413, -13.3786, 54.072197, -3.9413, -11.7063, 51.2184, -3.9413, -15.0508995, 54.072197, -3.9413, -15.0508995, 54.072197, -3.9413, -13.3786, 51.2184, -3.9413, -13.3786, 54.072197, -3.9413, -11.7063, 51.2184, -3.9413, -11.7063, 51.2184, -3.9413, -11.7063, 54.072197, -3.9413, -11.7063, 54.072197, -3.9413, -10.033899, 48.3645, -3.9413, -15.0508995, 51.2184, -3.9413, -15.0508995, 51.2184, -3.9413, -13.3786, 51.2184, -3.9413, -11.7063, 54.072197, -3.9413, -10.033899, 51.2184, -3.9413, -10.033899, 51.2184, -3.9413, -10.033899, 54.072197, -3.9413, -10.033899, 54.072197, -3.9413, -8.3616, 48.3645, -3.9413, -13.3786, 51.2184, -3.9413, -13.3786, 51.2184, -3.9413, -11.7063, 48.3645, -3.9413, -15.0508995, 51.2184, -3.9413, -13.3786, 48.3645, -3.9413, -13.3786, 48.3645, -3.9413, -11.7063, 51.2184, -3.9413, -11.7063, 51.2184, -3.9413, -10.033899, 48.3645, -3.9413, -13.3786, 51.2184, -3.9413, -11.7063, 48.3645, -3.9413, -11.7063, 51.2184, -3.9413, -10.033899, 54.072197, -3.9413, -8.3616, 51.2184, -3.9413, -8.3616, 51.2184, -3.9413, -8.3616, 54.072197, -3.9413, -8.3616, 54.072197, -3.9413, -6.6893, 48.3645, -3.9413, -11.7063, 51.2184, -3.9413, -10.033899, 48.3645, -3.9413, -10.033899, 48.3645, -3.9413, -10.033899, 51.2184, -3.9413, -10.033899, 51.2184, -3.9413, -8.3616, 45.5107, -3.9413, -13.3786, 48.3645, -3.9413, -13.3786, 48.3645, -3.9413, -11.7063, 45.5107, -3.9413, -11.7063, 48.3645, -3.9413, -11.7063, 48.3645, -3.9413, -10.033899, 45.5107, -3.9413, -13.3786, 48.3645, -3.9413, -11.7063, 45.5107, -3.9413, -11.7063, 51.2184, -3.9413, -8.3616, 54.072197, -3.9413, -6.6893, 51.2184, -3.9413, -6.6893, 51.2184, -3.9413, -6.6893, 54.072197, -3.9413, -6.6893, 54.072197, -3.9413, -5.0169997, 48.3645, -3.9413, -10.033899, 51.2184, -3.9413, -8.3616, 48.3645, -3.9413, -8.3616, 48.3645, -3.9413, -8.3616, 51.2184, -3.9413, -8.3616, 51.2184, -3.9413, -6.6893, 45.5107, -3.9413, -11.7063, 48.3645, -3.9413, -10.033899, 45.5107, -3.9413, -10.033899, 45.5107, -3.9413, -10.033899, 48.3645, -3.9413, -10.033899, 48.3645, -3.9413, -8.3616, 51.2184, -3.9413, -6.6893, 54.072197, -3.9413, -5.0169997, 51.2184, -3.9413, -5.0169997, 51.2184, -3.9413, -5.0169997, 54.072197, -3.9413, -5.0169997, 54.072197, -3.9413, -3.3446, 48.3645, -3.9413, -8.3616, 51.2184, -3.9413, -6.6893, 48.3645, -3.9413, -6.6893, 48.3645, -3.9413, -6.6893, 51.2184, -3.9413, -6.6893, 51.2184, -3.9413, -5.0169997, 45.5107, -3.9413, -10.033899, 48.3645, -3.9413, -8.3616, 45.5107, -3.9413, -8.3616, 45.5107, -3.9413, -8.3616, 48.3645, -3.9413, -8.3616, 48.3645, -3.9413, -6.6893, 51.2184, -3.9413, -5.0169997, 54.072197, -3.9413, -3.3446, 51.2184, -3.9413, -3.3446, 51.2184, -3.9413, -3.3446, 54.072197, -3.9413, -3.3446, 54.072197, -3.9413, -1.6723, 48.3645, -3.9413, -6.6893, 51.2184, -3.9413, -5.0169997, 48.3645, -3.9413, -5.0169997, 48.3645, -3.9413, -5.0169997, 51.2184, -3.9413, -5.0169997, 51.2184, -3.9413, -3.3446, 45.5107, -3.9413, -8.3616, 48.3645, -3.9413, -6.6893, 45.5107, -3.9413, -6.6893, 45.5107, -3.9413, -6.6893, 48.3645, -3.9413, -6.6893, 48.3645, -3.9413, -5.0169997, 51.2184, -3.9413, -3.3446, 54.072197, -3.9413, -1.6723, 51.2184, -3.9413, -1.6723, 51.2184, -3.9413, -1.6723, 54.072197, -3.9413, -1.6723, 54.072197, -3.9413, 0, 48.3645, -3.9413, -5.0169997, 51.2184, -3.9413, -3.3446, 48.3645, -3.9413, -3.3446, 48.3645, -3.9413, -3.3446, 51.2184, -3.9413, -3.3446, 51.2184, -3.9413, -1.6723, 45.5107, -3.9413, -6.6893, 48.3645, -3.9413, -5.0169997, 45.5107, -3.9413, -5.0169997, 45.5107, -3.9413, -5.0169997, 48.3645, -3.9413, -5.0169997, 48.3645, -3.9413, -3.3446, 51.2184, -3.9413, -1.6723, 54.072197, -3.9413, 0, 51.2184, -3.9413, 0, 51.2184, -3.9413, 0, 54.072197, -3.9413, 0, 54.072197, -3.9413, 1.6723, 48.3645, -3.9413, -3.3446, 51.2184, -3.9413, -1.6723, 48.3645, -3.9413, -1.6723, 48.3645, -3.9413, -1.6723, 51.2184, -3.9413, -1.6723, 51.2184, -3.9413, 0, 45.5107, -3.9413, -5.0169997, 48.3645, -3.9413, -3.3446, 45.5107, -3.9413, -3.3446, 45.5107, -3.9413, -3.3446, 48.3645, -3.9413, -3.3446, 48.3645, -3.9413, -1.6723, 51.2184, -3.9413, 0, 54.072197, -3.9413, 1.6723, 51.2184, -3.9413, 1.6723, 51.2184, -3.9413, 1.6723, 54.072197, -3.9413, 1.6723, 54.072197, -3.9413, 3.3446, 48.3645, -3.9413, -1.6723, 51.2184, -3.9413, 0, 48.3645, -3.9413, 0, 48.3645, -3.9413, 0, 51.2184, -3.9413, 0, 51.2184, -3.9413, 1.6723, 45.5107, -3.9413, -3.3446, 48.3645, -3.9413, -1.6723, 45.5107, -3.9413, -1.6723, 45.5107, -3.9413, -1.6723, 48.3645, -3.9413, -1.6723, 48.3645, -3.9413, 0, 51.2184, -3.9413, 1.6723, 54.072197, -3.9413, 3.3446, 51.2184, -3.9413, 3.3446, 51.2184, -3.9413, 3.3446, 54.072197, -3.9413, 3.3446, 54.072197, -3.9413, 5.0169997, 48.3645, -3.9413, 0, 51.2184, -3.9413, 1.6723, 48.3645, -3.9413, 1.6723, 48.3645, -3.9413, 1.6723, 51.2184, -3.9413, 1.6723, 51.2184, -3.9413, 3.3446, 45.5107, -3.9413, -1.6723, 48.3645, -3.9413, 0, 45.5107, -3.9413, 0, 45.5107, -3.9413, 0, 48.3645, -3.9413, 0, 48.3645, -3.9413, 1.6723, 51.2184, -3.9413, 3.3446, 54.072197, -3.9413, 5.0169997, 51.2184, -3.9413, 5.0169997, 51.2184, -3.9413, 5.0169997, 54.072197, -3.9413, 5.0169997, 54.072197, -3.9413, 6.6893, 48.3645, -3.9413, 1.6723, 51.2184, -3.9413, 3.3446, 48.3645, -3.9413, 3.3446, 48.3645, -3.9413, 3.3446, 51.2184, -3.9413, 3.3446, 51.2184, -3.9413, 5.0169997, 45.5107, -3.9413, 0, 48.3645, -3.9413, 1.6723, 45.5107, -3.9413, 1.6723, 45.5107, -3.9413, 1.6723, 48.3645, -3.9413, 1.6723, 48.3645, -3.9413, 3.3446, 51.2184, -3.9413, 5.0169997, 54.072197, -3.9413, 6.6893, 51.2184, -3.9413, 6.6893, 51.2184, -3.9413, 6.6893, 54.072197, -3.9413, 6.6893, 54.072197, -3.9413, 8.3616, 48.3645, -3.9413, 3.3446, 51.2184, -3.9413, 5.0169997, 48.3645, -3.9413, 5.0169997, 48.3645, -3.9413, 5.0169997, 51.2184, -3.9413, 5.0169997, 51.2184, -3.9413, 6.6893, 45.5107, -3.9413, 1.6723, 48.3645, -3.9413, 3.3446, 45.5107, -3.9413, 3.3446, 45.5107, -3.9413, 3.3446, 48.3645, -3.9413, 3.3446, 48.3645, -3.9413, 5.0169997, 51.2184, -3.9413, 6.6893, 54.072197, -3.9413, 8.3616, 51.2184, -3.9413, 8.3616, 51.2184, -3.9413, 8.3616, 54.072197, -3.9413, 8.3616, 54.072197, -3.9413, 10.033899, 48.3645, -3.9413, 5.0169997, 51.2184, -3.9413, 6.6893, 48.3645, -3.9413, 6.6893, 48.3645, -3.9413, 6.6893, 51.2184, -3.9413, 6.6893, 51.2184, -3.9413, 8.3616, 45.5107, -3.9413, 3.3446, 48.3645, -3.9413, 5.0169997, 45.5107, -3.9413, 5.0169997, 45.5107, -3.9413, 5.0169997, 48.3645, -3.9413, 5.0169997, 48.3645, -3.9413, 6.6893, 51.2184, -3.9413, 8.3616, 54.072197, -3.9413, 10.033899, 51.2184, -3.9413, 10.033899, 51.2184, -3.9413, 10.033899, 54.072197, -3.9413, 10.033899, 54.072197, -3.9413, 11.7063, 48.3645, -3.9413, 6.6893, 51.2184, -3.9413, 8.3616, 48.3645, -3.9413, 8.3616, 48.3645, -3.9413, 8.3616, 51.2184, -3.9413, 8.3616, 51.2184, -3.9413, 10.033899, 45.5107, -3.9413, 5.0169997, 48.3645, -3.9413, 6.6893, 45.5107, -3.9413, 6.6893, 45.5107, -3.9413, 6.6893, 48.3645, -3.9413, 6.6893, 48.3645, -3.9413, 8.3616, 51.2184, -3.9413, 10.033899, 54.072197, -3.9413, 11.7063, 51.2184, -3.9413, 11.7063, 51.2184, -3.9413, 11.7063, 54.072197, -3.9413, 11.7063, 54.072197, -3.9413, 13.3786, 48.3645, -3.9413, 8.3616, 51.2184, -3.9413, 10.033899, 48.3645, -3.9413, 10.033899, 48.3645, -3.9413, 10.033899, 51.2184, -3.9413, 10.033899, 51.2184, -3.9413, 11.7063, 45.5107, -3.9413, 6.6893, 48.3645, -3.9413, 8.3616, 45.5107, -3.9413, 8.3616, 45.5107, -3.9413, 8.3616, 48.3645, -3.9413, 8.3616, 48.3645, -3.9413, 10.033899, 51.2184, -3.9413, 11.7063, 54.072197, -3.9413, 13.3786, 51.2184, -3.9413, 13.3786, 51.2184, -3.9413, 13.3786, 54.072197, -3.9413, 13.3786, 54.072197, -3.9413, 15.0508995, 48.3645, -3.9413, 10.033899, 51.2184, -3.9413, 11.7063, 48.3645, -3.9413, 11.7063, 48.3645, -3.9413, 11.7063, 51.2184, -3.9413, 11.7063, 51.2184, -3.9413, 13.3786, 45.5107, -3.9413, 8.3616, 48.3645, -3.9413, 10.033899, 45.5107, -3.9413, 10.033899, 45.5107, -3.9413, 10.033899, 48.3645, -3.9413, 10.033899, 48.3645, -3.9413, 11.7063, 51.2184, -3.9413, 13.3786, 54.072197, -3.9413, 15.0508995, 51.2184, -3.9413, 15.0508995, 51.2184, -3.9413, 15.0508995, 54.072197, -3.9413, 15.0508995, 54.072197, -3.9413, 16.7232, 48.3645, -3.9413, 11.7063, 51.2184, -3.9413, 13.3786, 48.3645, -3.9413, 13.3786, 48.3645, -3.9413, 13.3786, 51.2184, -3.9413, 13.3786, 51.2184, -3.9413, 15.0508995, 45.5107, -3.9413, 10.033899, 48.3645, -3.9413, 11.7063, 45.5107, -3.9413, 11.7063, 45.5107, -3.9413, 11.7063, 48.3645, -3.9413, 11.7063, 48.3645, -3.9413, 13.3786, 51.2184, -3.9413, 15.0508995, 54.072197, -3.9413, 16.7232, 51.2184, -3.9413, 16.7232, 51.2184, -3.9413, 16.7232, 54.072197, -3.9413, 16.7232, 54.072197, -3.9413, 18.3955, 48.3645, -3.9413, 13.3786, 51.2184, -3.9413, 15.0508995, 48.3645, -3.9413, 15.0508995, 48.3645, -3.9413, 15.0508995, 51.2184, -3.9413, 15.0508995, 51.2184, -3.9413, 16.7232, 45.5107, -3.9413, 11.7063, 48.3645, -3.9413, 13.3786, 45.5107, -3.9413, 13.3786, 45.5107, -3.9413, 13.3786, 48.3645, -3.9413, 13.3786, 48.3645, -3.9413, 15.0508995, 51.2184, -3.9413, 16.7232, 54.072197, -3.9413, 18.3955, 51.2184, -3.9413, 18.3955, 51.2184, -3.9413, 18.3955, 54.072197, -3.9413, 18.3955, 54.072197, -3.9413, 20.0679, 48.3645, -3.9413, 15.0508995, 51.2184, -3.9413, 16.7232, 48.3645, -3.9413, 16.7232, 48.3645, -3.9413, 16.7232, 51.2184, -3.9413, 16.7232, 51.2184, -3.9413, 18.3955, 45.5107, -3.9413, 13.3786, 48.3645, -3.9413, 15.0508995, 45.5107, -3.9413, 15.0508995, 45.5107, -3.9413, 15.0508995, 48.3645, -3.9413, 15.0508995, 48.3645, -3.9413, 16.7232, 51.2184, -3.9413, 18.3955, 54.072197, -3.9413, 20.0679, 51.2184, -3.9413, 20.0679, 51.2184, -3.9413, 20.0679, 54.072197, -3.9413, 20.0679, 54.072197, -3.9413, 21.7402, 48.3645, -3.9413, 16.7232, 51.2184, -3.9413, 18.3955, 48.3645, -3.9413, 18.3955, 48.3645, -3.9413, 18.3955, 51.2184, -3.9413, 18.3955, 51.2184, -3.9413, 20.0679, 45.5107, -3.9413, 15.0508995, 48.3645, -3.9413, 16.7232, 45.5107, -3.9413, 16.7232, 45.5107, -3.9413, 16.7232, 48.3645, -3.9413, 16.7232, 48.3645, -3.9413, 18.3955, 51.2184, -3.9413, 20.0679, 54.072197, -3.9413, 21.7402, 51.2184, -3.9413, 21.7402, 51.2184, -3.9413, 21.7402, 54.072197, -3.9413, 21.7402, 54.072197, -3.9413, 23.412498, 48.3645, -3.9413, 18.3955, 51.2184, -3.9413, 20.0679, 48.3645, -3.9413, 20.0679, 48.3645, -3.9413, 20.0679, 51.2184, -3.9413, 20.0679, 51.2184, -3.9413, 21.7402, 45.5107, -3.9413, 16.7232, 48.3645, -3.9413, 18.3955, 45.5107, -3.9413, 18.3955, 45.5107, -3.9413, 18.3955, 48.3645, -3.9413, 18.3955, 48.3645, -3.9413, 20.0679, 51.2184, -3.9413, 21.7402, 54.072197, -3.9413, 23.412498, 51.2184, -3.9413, 23.412498, 51.2184, -3.9413, 23.412498, 54.072197, -3.9413, 23.412498, 54.072197, -3.9413, 25.084799, 48.3645, -3.9413, 20.0679, 51.2184, -3.9413, 21.7402, 48.3645, -3.9413, 21.7402, 48.3645, -3.9413, 21.7402, 51.2184, -3.9413, 21.7402, 51.2184, -3.9413, 23.412498, 45.5107, -3.9413, 18.3955, 48.3645, -3.9413, 20.0679, 45.5107, -3.9413, 20.0679, 45.5107, -3.9413, 20.0679, 48.3645, -3.9413, 20.0679, 48.3645, -3.9413, 21.7402, 51.2184, -3.9413, 23.412498, 54.072197, -3.9413, 25.084799, 51.2184, -3.9413, 25.084799, 51.2184, -3.9413, 25.084799, 54.072197, -3.9413, 25.084799, 54.072197, -3.9413, 26.7572, 51.2184, -3.9413, 25.084799, 54.072197, -3.9413, 26.7572, 51.2184, -3.9413, 26.7572, 48.3645, -3.9413, 23.412498, 51.2184, -3.9413, 23.412498, 51.2184, -3.9413, 25.084799, 48.3645, -3.9413, 21.7402, 51.2184, -3.9413, 23.412498, 48.3645, -3.9413, 23.412498, 48.3645, -3.9413, 25.084799, 51.2184, -3.9413, 25.084799, 51.2184, -3.9413, 26.7572, 48.3645, -3.9413, 23.412498, 51.2184, -3.9413, 25.084799, 48.3645, -3.9413, 25.084799, 48.3645, -3.9413, 25.084799, 51.2184, -3.9413, 26.7572, 48.3645, -3.9413, 26.7572, 45.5107, -3.9413, 21.7402, 48.3645, -3.9413, 21.7402, 48.3645, -3.9413, 23.412498, 45.5107, -3.9413, 20.0679, 48.3645, -3.9413, 21.7402, 45.5107, -3.9413, 21.7402, 45.5107, -3.9413, 23.412498, 48.3645, -3.9413, 23.412498, 48.3645, -3.9413, 25.084799, 45.5107, -3.9413, 21.7402, 48.3645, -3.9413, 23.412498, 45.5107, -3.9413, 23.412498, 45.5107, -3.9413, 25.084799, 48.3645, -3.9413, 25.084799, 48.3645, -3.9413, 26.7572, 45.5107, -3.9413, 23.412498, 48.3645, -3.9413, 25.084799, 45.5107, -3.9413, 25.084799, 45.5107, -3.9413, 25.084799, 48.3645, -3.9413, 26.7572, 45.5107, -3.9413, 26.7572, 42.6568, -3.9413, 25.084799, 45.5107, -3.9413, 25.084799, 45.5107, -3.9413, 26.7572, 42.6568, -3.9413, 25.084799, 45.5107, -3.9413, 26.7572, 42.6568, -3.9413, 26.7572, 39.7973, -3.9413, 25.084799, 42.6568, -3.9413, 25.084799, 42.6568, -3.9413, 26.7572, 39.7973, -3.9413, 25.084799, 42.6568, -3.9413, 26.7572, 39.7973, -3.9413, 26.7572, 39.7973, -3.9413, 23.412498, 42.6568, -3.9413, 25.084799, 39.7973, -3.9413, 25.084799, 42.6568, -3.9413, 23.412498, 45.5107, -3.9413, 25.084799, 42.6568, -3.9413, 25.084799, 39.7973, -3.9413, 23.412498, 42.6568, -3.9413, 23.412498, 42.6568, -3.9413, 25.084799, 42.6568, -3.9413, 23.412498, 45.5107, -3.9413, 23.412498, 45.5107, -3.9413, 25.084799, 39.7973, -3.9413, 21.7402, 42.6568, -3.9413, 23.412498, 39.7973, -3.9413, 23.412498, 42.6568, -3.9413, 21.7402, 45.5107, -3.9413, 23.412498, 42.6568, -3.9413, 23.412498, 39.7973, -3.9413, 21.7402, 42.6568, -3.9413, 21.7402, 42.6568, -3.9413, 23.412498, 42.6568, -3.9413, 21.7402, 45.5107, -3.9413, 21.7402, 45.5107, -3.9413, 23.412498, 39.7973, -3.9413, 20.0679, 42.6568, -3.9413, 21.7402, 39.7973, -3.9413, 21.7402, 42.6568, -3.9413, 20.0679, 45.5107, -3.9413, 21.7402, 42.6568, -3.9413, 21.7402, 39.7973, -3.9413, 20.0679, 42.6568, -3.9413, 20.0679, 42.6568, -3.9413, 21.7402, 42.6568, -3.9413, 20.0679, 45.5107, -3.9413, 20.0679, 45.5107, -3.9413, 21.7402, 39.7973, -3.9413, 18.3955, 42.6568, -3.9413, 20.0679, 39.7973, -3.9413, 20.0679, 42.6568, -3.9413, 18.3955, 45.5107, -3.9413, 20.0679, 42.6568, -3.9413, 20.0679, 39.7973, -3.9413, 18.3955, 42.6568, -3.9413, 18.3955, 42.6568, -3.9413, 20.0679, 42.6568, -3.9413, 18.3955, 45.5107, -3.9413, 18.3955, 45.5107, -3.9413, 20.0679, 39.7973, -3.9413, 16.7232, 42.6568, -3.9413, 18.3955, 39.7973, -3.9413, 18.3955, 42.6568, -3.9413, 16.7232, 45.5107, -3.9413, 18.3955, 42.6568, -3.9413, 18.3955, 39.7973, -3.9413, 16.7232, 42.6568, -3.9413, 16.7232, 42.6568, -3.9413, 18.3955, 42.6568, -3.9413, 16.7232, 45.5107, -3.9413, 16.7232, 45.5107, -3.9413, 18.3955, 39.7973, -3.9413, 15.0508995, 42.6568, -3.9413, 16.7232, 39.7973, -3.9413, 16.7232, 42.6568, -3.9413, 15.0508995, 45.5107, -3.9413, 16.7232, 42.6568, -3.9413, 16.7232, 39.7973, -3.9413, 15.0508995, 42.6568, -3.9413, 15.0508995, 42.6568, -3.9413, 16.7232, 42.6568, -3.9413, 15.0508995, 45.5107, -3.9413, 15.0508995, 45.5107, -3.9413, 16.7232, 39.7973, -3.9413, 13.3786, 42.6568, -3.9413, 15.0508995, 39.7973, -3.9413, 15.0508995, 42.6568, -3.9413, 13.3786, 45.5107, -3.9413, 15.0508995, 42.6568, -3.9413, 15.0508995, 39.7973, -3.9413, 13.3786, 42.6568, -3.9413, 13.3786, 42.6568, -3.9413, 15.0508995, 42.6568, -3.9413, 13.3786, 45.5107, -3.9413, 13.3786, 45.5107, -3.9413, 15.0508995, 39.7973, -3.9413, 11.7063, 42.6568, -3.9413, 13.3786, 39.7973, -3.9413, 13.3786, 42.6568, -3.9413, 11.7063, 45.5107, -3.9413, 13.3786, 42.6568, -3.9413, 13.3786, 39.7973, -3.9413, 11.7063, 42.6568, -3.9413, 11.7063, 42.6568, -3.9413, 13.3786, 42.6568, -3.9413, 11.7063, 45.5107, -3.9413, 11.7063, 45.5107, -3.9413, 13.3786, 39.7973, -3.9413, 10.033899, 42.6568, -3.9413, 11.7063, 39.7973, -3.9413, 11.7063, 42.6568, -3.9413, 10.033899, 45.5107, -3.9413, 11.7063, 42.6568, -3.9413, 11.7063, 39.7973, -3.9413, 10.033899, 42.6568, -3.9413, 10.033899, 42.6568, -3.9413, 11.7063, 42.6568, -3.9413, 10.033899, 45.5107, -3.9413, 10.033899, 45.5107, -3.9413, 11.7063, 39.7973, -3.9413, 8.3616, 42.6568, -3.9413, 10.033899, 39.7973, -3.9413, 10.033899, 42.6568, -3.9413, 8.3616, 45.5107, -3.9413, 10.033899, 42.6568, -3.9413, 10.033899, 39.7973, -3.9413, 8.3616, 42.6568, -3.9413, 8.3616, 42.6568, -3.9413, 10.033899, 42.6568, -3.9413, 8.3616, 45.5107, -3.9413, 8.3616, 45.5107, -3.9413, 10.033899, 39.7973, -3.9413, 6.6893, 42.6568, -3.9413, 8.3616, 39.7973, -3.9413, 8.3616, 42.6568, -3.9413, 6.6893, 45.5107, -3.9413, 8.3616, 42.6568, -3.9413, 8.3616, 39.7973, -3.9413, 6.6893, 42.6568, -3.9413, 6.6893, 42.6568, -3.9413, 8.3616, 42.6568, -3.9413, 6.6893, 45.5107, -3.9413, 6.6893, 45.5107, -3.9413, 8.3616, 39.7973, -3.9413, 5.0169997, 42.6568, -3.9413, 6.6893, 39.7973, -3.9413, 6.6893, 42.6568, -3.9413, 5.0169997, 45.5107, -3.9413, 6.6893, 42.6568, -3.9413, 6.6893, 39.7973, -3.9413, 5.0169997, 42.6568, -3.9413, 5.0169997, 42.6568, -3.9413, 6.6893, 42.6568, -3.9413, 5.0169997, 45.5107, -3.9413, 5.0169997, 45.5107, -3.9413, 6.6893, 39.7973, -3.9413, 3.3446, 42.6568, -3.9413, 5.0169997, 39.7973, -3.9413, 5.0169997, 42.6568, -3.9413, 3.3446, 45.5107, -3.9413, 5.0169997, 42.6568, -3.9413, 5.0169997, 39.7973, -3.9413, 3.3446, 42.6568, -3.9413, 3.3446, 42.6568, -3.9413, 5.0169997, 42.6568, -3.9413, 3.3446, 45.5107, -3.9413, 3.3446, 45.5107, -3.9413, 5.0169997, 39.7973, -3.9413, 1.6723, 42.6568, -3.9413, 3.3446, 39.7973, -3.9413, 3.3446, 42.6568, -3.9413, 1.6723, 45.5107, -3.9413, 3.3446, 42.6568, -3.9413, 3.3446, 39.7973, -3.9413, 1.6723, 42.6568, -3.9413, 1.6723, 42.6568, -3.9413, 3.3446, 42.6568, -3.9413, 1.6723, 45.5107, -3.9413, 1.6723, 45.5107, -3.9413, 3.3446, 39.7973, -3.9413, 0, 42.6568, -3.9413, 1.6723, 39.7973, -3.9413, 1.6723, 42.6568, -3.9413, 0, 45.5107, -3.9413, 1.6723, 42.6568, -3.9413, 1.6723, 39.7973, -3.9413, 0, 42.6568, -3.9413, 0, 42.6568, -3.9413, 1.6723, 42.6568, -3.9413, 0, 45.5107, -3.9413, 0, 45.5107, -3.9413, 1.6723, 39.7973, -3.9413, -1.6723, 42.6568, -3.9413, 0, 39.7973, -3.9413, 0, 42.6568, -3.9413, -1.6723, 45.5107, -3.9413, 0, 42.6568, -3.9413, 0, 39.7973, -3.9413, -1.6723, 42.6568, -3.9413, -1.6723, 42.6568, -3.9413, 0, 42.6568, -3.9413, -1.6723, 45.5107, -3.9413, -1.6723, 45.5107, -3.9413, 0, 39.7973, -3.9413, -3.3446, 42.6568, -3.9413, -1.6723, 39.7973, -3.9413, -1.6723, 42.6568, -3.9413, -3.3446, 45.5107, -3.9413, -1.6723, 42.6568, -3.9413, -1.6723, 39.7973, -3.9413, -3.3446, 42.6568, -3.9413, -3.3446, 42.6568, -3.9413, -1.6723, 42.6568, -3.9413, -3.3446, 45.5107, -3.9413, -3.3446, 45.5107, -3.9413, -1.6723, 39.7973, -3.9413, -5.0169997, 42.6568, -3.9413, -3.3446, 39.7973, -3.9413, -3.3446, 42.6568, -3.9413, -5.0169997, 45.5107, -3.9413, -3.3446, 42.6568, -3.9413, -3.3446, 39.7973, -3.9413, -5.0169997, 42.6568, -3.9413, -5.0169997, 42.6568, -3.9413, -3.3446, 42.6568, -3.9413, -5.0169997, 45.5107, -3.9413, -5.0169997, 45.5107, -3.9413, -3.3446, 39.7973, -3.9413, -6.6893, 42.6568, -3.9413, -5.0169997, 39.7973, -3.9413, -5.0169997, 42.6568, -3.9413, -6.6893, 45.5107, -3.9413, -5.0169997, 42.6568, -3.9413, -5.0169997, 39.7973, -3.9413, -6.6893, 42.6568, -3.9413, -6.6893, 42.6568, -3.9413, -5.0169997, 42.6568, -3.9413, -6.6893, 45.5107, -3.9413, -6.6893, 45.5107, -3.9413, -5.0169997, 39.7973, -3.9413, -8.3616, 42.6568, -3.9413, -6.6893, 39.7973, -3.9413, -6.6893, 42.6568, -3.9413, -8.3616, 45.5107, -3.9413, -6.6893, 42.6568, -3.9413, -6.6893, 39.7973, -3.9413, -8.3616, 42.6568, -3.9413, -8.3616, 42.6568, -3.9413, -6.6893, 42.6568, -3.9413, -8.3616, 45.5107, -3.9413, -8.3616, 45.5107, -3.9413, -6.6893, 39.7973, -3.9413, -10.033899, 42.6568, -3.9413, -8.3616, 39.7973, -3.9413, -8.3616, 42.6568, -3.9413, -10.033899, 45.5107, -3.9413, -8.3616, 42.6568, -3.9413, -8.3616, 39.7973, -3.9413, -10.033899, 42.6568, -3.9413, -10.033899, 42.6568, -3.9413, -8.3616, 42.6568, -3.9413, -10.033899, 45.5107, -3.9413, -10.033899, 45.5107, -3.9413, -8.3616, 39.7973, -3.9413, -11.7063, 42.6568, -3.9413, -10.033899, 39.7973, -3.9413, -10.033899, 42.6568, -3.9413, -11.7063, 45.5107, -3.9413, -10.033899, 42.6568, -3.9413, -10.033899, 39.7973, -3.9413, -11.7063, 42.6568, -3.9413, -11.7063, 42.6568, -3.9413, -10.033899, 42.6568, -3.9413, -11.7063, 45.5107, -3.9413, -11.7063, 45.5107, -3.9413, -10.033899, 39.7973, -3.9413, -13.3786, 42.6568, -3.9413, -11.7063, 39.7973, -3.9413, -11.7063, 42.6568, -3.9413, -13.3786, 45.5107, -3.9413, -11.7063, 42.6568, -3.9413, -11.7063, 39.7973, -3.9413, -13.3786, 42.6568, -3.9413, -13.3786, 42.6568, -3.9413, -11.7063, 42.6568, -3.9413, -13.3786, 45.5107, -3.9413, -13.3786, 45.5107, -3.9413, -11.7063, 39.7973, -3.9413, -15.0508995, 42.6568, -3.9413, -13.3786, 39.7973, -3.9413, -13.3786, 39.7973, -3.9413, -15.0508995, 42.6568, -3.9413, -15.0508995, 42.6568, -3.9413, -13.3786, 42.6568, -3.9413, -15.0508995, 45.5107, -3.9413, -13.3786, 42.6568, -3.9413, -13.3786, 39.7973, -3.9413, -16.7232, 42.6568, -3.9413, -15.0508995, 39.7973, -3.9413, -15.0508995, 42.6568, -3.9413, -15.0508995, 45.5107, -3.9413, -15.0508995, 45.5107, -3.9413, -13.3786, 45.5107, -3.9413, -15.0508995, 48.3645, -3.9413, -13.3786, 45.5107, -3.9413, -13.3786, 39.7973, -3.9413, -16.7232, 42.6568, -3.9413, -16.7232, 42.6568, -3.9413, -15.0508995, 42.6568, -3.9413, -16.7232, 45.5107, -3.9413, -15.0508995, 42.6568, -3.9413, -15.0508995, 39.7973, -3.9413, -18.3955, 42.6568, -3.9413, -16.7232, 39.7973, -3.9413, -16.7232, 45.5107, -3.9413, -15.0508995, 48.3645, -3.9413, -15.0508995, 48.3645, -3.9413, -13.3786, 39.7973, -3.9413, -18.3955, 42.6568, -3.9413, -18.3955, 42.6568, -3.9413, -16.7232, 42.6568, -3.9413, -16.7232, 45.5107, -3.9413, -16.7232, 45.5107, -3.9413, -15.0508995, 45.5107, -3.9413, -16.7232, 48.3645, -3.9413, -15.0508995, 45.5107, -3.9413, -15.0508995, 42.6568, -3.9413, -18.3955, 45.5107, -3.9413, -16.7232, 42.6568, -3.9413, -16.7232, 39.7973, -3.9413, -20.0679, 42.6568, -3.9413, -18.3955, 39.7973, -3.9413, -18.3955, 45.5107, -3.9413, -16.7232, 48.3645, -3.9413, -16.7232, 48.3645, -3.9413, -15.0508995, 48.3645, -3.9413, -16.7232, 51.2184, -3.9413, -15.0508995, 48.3645, -3.9413, -15.0508995, 42.6568, -3.9413, -18.3955, 45.5107, -3.9413, -18.3955, 45.5107, -3.9413, -16.7232, 45.5107, -3.9413, -18.3955, 48.3645, -3.9413, -16.7232, 45.5107, -3.9413, -16.7232, 39.7973, -3.9413, -20.0679, 42.6568, -3.9413, -20.0679, 42.6568, -3.9413, -18.3955, 42.6568, -3.9413, -20.0679, 45.5107, -3.9413, -18.3955, 42.6568, -3.9413, -18.3955, 39.7973, -3.9413, -21.7402, 42.6568, -3.9413, -20.0679, 39.7973, -3.9413, -20.0679, 48.3645, -3.9413, -16.7232, 51.2184, -3.9413, -16.7232, 51.2184, -3.9413, -15.0508995, 51.2184, -3.9413, -16.7232, 54.072197, -3.9413, -15.0508995, 51.2184, -3.9413, -15.0508995, 51.2184, -3.9413, -16.7232, 54.072197, -3.9413, -16.7232, 54.072197, -3.9413, -15.0508995, 48.3645, -3.9413, -18.3955, 51.2184, -3.9413, -16.7232, 48.3645, -3.9413, -16.7232, 45.5107, -3.9413, -18.3955, 48.3645, -3.9413, -18.3955, 48.3645, -3.9413, -16.7232, 51.2184, -3.9413, -18.3955, 54.072197, -3.9413, -16.7232, 51.2184, -3.9413, -16.7232, 48.3645, -3.9413, -18.3955, 51.2184, -3.9413, -18.3955, 51.2184, -3.9413, -16.7232, 51.2184, -3.9413, -18.3955, 54.072197, -3.9413, -18.3955, 54.072197, -3.9413, -16.7232, 45.5107, -3.9413, -20.0679, 48.3645, -3.9413, -18.3955, 45.5107, -3.9413, -18.3955, 42.6568, -3.9413, -20.0679, 45.5107, -3.9413, -20.0679, 45.5107, -3.9413, -18.3955, 48.3645, -3.9413, -20.0679, 51.2184, -3.9413, -18.3955, 48.3645, -3.9413, -18.3955, 45.5107, -3.9413, -20.0679, 48.3645, -3.9413, -20.0679, 48.3645, -3.9413, -18.3955, 51.2184, -3.9413, -20.0679, 54.072197, -3.9413, -18.3955, 51.2184, -3.9413, -18.3955, 48.3645, -3.9413, -20.0679, 51.2184, -3.9413, -20.0679, 51.2184, -3.9413, -18.3955, 51.2184, -3.9413, -20.0679, 54.072197, -3.9413, -20.0679, 54.072197, -3.9413, -18.3955, 39.7973, -3.9413, -21.7402, 42.6568, -3.9413, -21.7402, 42.6568, -3.9413, -20.0679, 42.6568, -3.9413, -21.7402, 45.5107, -3.9413, -20.0679, 42.6568, -3.9413, -20.0679, 39.7973, -3.9413, -23.412498, 42.6568, -3.9413, -21.7402, 39.7973, -3.9413, -21.7402, 45.5107, -3.9413, -21.7402, 48.3645, -3.9413, -20.0679, 45.5107, -3.9413, -20.0679, 42.6568, -3.9413, -21.7402, 45.5107, -3.9413, -21.7402, 45.5107, -3.9413, -20.0679, 39.7973, -3.9413, -23.412498, 42.6568, -3.9413, -23.412498, 42.6568, -3.9413, -21.7402, 42.6568, -3.9413, -23.412498, 45.5107, -3.9413, -21.7402, 42.6568, -3.9413, -21.7402, 39.7973, -3.9413, -25.084799, 42.6568, -3.9413, -23.412498, 39.7973, -3.9413, -23.412498, 45.5107, -3.9413, -21.7402, 48.3645, -3.9413, -21.7402, 48.3645, -3.9413, -20.0679, 48.3645, -3.9413, -21.7402, 51.2184, -3.9413, -20.0679, 48.3645, -3.9413, -20.0679, 42.6568, -3.9413, -23.412498, 45.5107, -3.9413, -23.412498, 45.5107, -3.9413, -21.7402, 45.5107, -3.9413, -23.412498, 48.3645, -3.9413, -21.7402, 45.5107, -3.9413, -21.7402, 39.7973, -3.9413, -25.084799, 42.6568, -3.9413, -25.084799, 42.6568, -3.9413, -23.412498, 42.6568, -3.9413, -25.084799, 45.5107, -3.9413, -23.412498, 42.6568, -3.9413, -23.412498, 39.7973, -3.9413, -26.7572, 42.6568, -3.9413, -25.084799, 39.7973, -3.9413, -25.084799, 39.7973, -3.9413, -26.7572, 42.6568, -3.9413, -26.7572, 42.6568, -3.9413, -25.084799, 42.6568, -3.9413, -26.7572, 45.5107, -3.9413, -25.084799, 42.6568, -3.9413, -25.084799, 42.6568, -3.9413, -25.084799, 45.5107, -3.9413, -25.084799, 45.5107, -3.9413, -23.412498, 42.6568, -3.9413, -26.7572, 45.5107, -3.9413, -26.7572, 45.5107, -3.9413, -25.084799, 45.5107, -3.9413, -23.412498, 48.3645, -3.9413, -23.412498, 48.3645, -3.9413, -21.7402, 45.5107, -3.9413, -25.084799, 48.3645, -3.9413, -23.412498, 45.5107, -3.9413, -23.412498, 45.5107, -3.9413, -26.7572, 48.3645, -3.9413, -25.084799, 45.5107, -3.9413, -25.084799, 45.5107, -3.9413, -25.084799, 48.3645, -3.9413, -25.084799, 48.3645, -3.9413, -23.412498, 45.5107, -3.9413, -26.7572, 48.3645, -3.9413, -26.7572, 48.3645, -3.9413, -25.084799, 48.3645, -3.9413, -21.7402, 51.2184, -3.9413, -21.7402, 51.2184, -3.9413, -20.0679, 48.3645, -3.9413, -23.412498, 51.2184, -3.9413, -21.7402, 48.3645, -3.9413, -21.7402, 51.2184, -3.9413, -21.7402, 54.072197, -3.9413, -20.0679, 51.2184, -3.9413, -20.0679, 51.2184, -3.9413, -21.7402, 54.072197, -3.9413, -21.7402, 54.072197, -3.9413, -20.0679, 48.3645, -3.9413, -23.412498, 51.2184, -3.9413, -23.412498, 51.2184, -3.9413, -21.7402, 51.2184, -3.9413, -23.412498, 54.072197, -3.9413, -21.7402, 51.2184, -3.9413, -21.7402, 48.3645, -3.9413, -25.084799, 51.2184, -3.9413, -23.412498, 48.3645, -3.9413, -23.412498, 51.2184, -3.9413, -23.412498, 54.072197, -3.9413, -23.412498, 54.072197, -3.9413, -21.7402, 48.3645, -3.9413, -26.7572, 51.2184, -3.9413, -25.084799, 48.3645, -3.9413, -25.084799, 48.3645, -3.9413, -25.084799, 51.2184, -3.9413, -25.084799, 51.2184, -3.9413, -23.412498, 51.2184, -3.9413, -25.084799, 54.072197, -3.9413, -23.412498, 51.2184, -3.9413, -23.412498, 48.3645, -3.9413, -26.7572, 51.2184, -3.9413, -26.7572, 51.2184, -3.9413, -25.084799, 51.2184, -3.9413, -25.084799, 54.072197, -3.9413, -25.084799, 54.072197, -3.9413, -23.412498, 51.2184, -3.9413, -26.7572, 54.072197, -3.9413, -25.084799, 51.2184, -3.9413, -25.084799, 51.2184, -3.9413, -26.7572, 54.072197, -3.9413, -26.7572, 54.072197, -3.9413, -25.084799, 29.679499, -0.6044, -15.0508995, 32.4649, -1.1213, -13.3786, 29.679499, -0.6044, -13.3786, 29.679499, -0.6044, -13.3786, 32.4649, -1.1213, -13.3786, 32.4649, -1.1213, -11.7063, 29.679499, -0.6044, -15.0508995, 32.4649, -1.1213, -15.0508995, 32.4649, -1.1213, -13.3786, 29.679499, -0.6044, -13.3786, 32.4649, -1.1213, -11.7063, 29.679499, -0.6044, -11.7063, 29.679499, -0.6044, -16.7232, 32.4649, -1.1213, -15.0508995, 29.679499, -0.6044, -15.0508995, 29.679499, -0.6044, -11.7063, 32.4649, -1.1213, -11.7063, 32.4649, -1.1213, -10.033899, 29.679499, -0.6044, -16.7232, 32.4649, -1.1213, -16.7232, 32.4649, -1.1213, -15.0508995, 29.679499, -0.6044, -11.7063, 32.4649, -1.1213, -10.033899, 29.679499, -0.6044, -10.033899, 29.679499, -0.6044, -18.3955, 32.4649, -1.1213, -16.7232, 29.679499, -0.6044, -16.7232, 29.679499, -0.6044, -10.033899, 32.4649, -1.1213, -10.033899, 32.4649, -1.1213, -8.3616, 29.679499, -0.6044, -18.3955, 32.4649, -1.1213, -18.3955, 32.4649, -1.1213, -16.7232, 29.679499, -0.6044, -10.033899, 32.4649, -1.1213, -8.3616, 29.679499, -0.6044, -8.3616, 29.679499, -0.6044, -20.0679, 32.4649, -1.1213, -18.3955, 29.679499, -0.6044, -18.3955, 29.679499, -0.6044, -8.3616, 32.4649, -1.1213, -8.3616, 32.4649, -1.1213, -6.6893, 29.679499, -0.6044, -20.0679, 32.4649, -1.1213, -20.0679, 32.4649, -1.1213, -18.3955, 29.679499, -0.6044, -8.3616, 32.4649, -1.1213, -6.6893, 29.679499, -0.6044, -6.6893, 29.679499, -0.6044, -21.7402, 32.4649, -1.1213, -20.0679, 29.679499, -0.6044, -20.0679, 29.679499, -0.6044, -6.6893, 32.4649, -1.1213, -6.6893, 32.4649, -1.1213, -5.0169997, 29.679499, -0.6044, -21.7402, 32.4649, -1.1213, -21.7402, 32.4649, -1.1213, -20.0679, 29.679499, -0.6044, -6.6893, 32.4649, -1.1213, -5.0169997, 29.679499, -0.6044, -5.0169997, 29.679499, -0.6044, -23.412498, 32.4649, -1.1213, -21.7402, 29.679499, -0.6044, -21.7402, 29.679499, -0.6044, -5.0169997, 32.4649, -1.1213, -5.0169997, 32.4649, -1.1213, -3.3446, 29.679499, -0.6044, -23.412498, 32.4649, -1.1213, -23.412498, 32.4649, -1.1213, -21.7402, 29.679499, -0.6044, -5.0169997, 32.4649, -1.1213, -3.3446, 29.679499, -0.6044, -3.3446, 29.679499, -0.6044, -25.084799, 32.4649, -1.1213, -23.412498, 29.679499, -0.6044, -23.412498, 29.679499, -0.6044, -3.3446, 32.4649, -1.1213, -3.3446, 32.4649, -1.1213, -1.6723, 29.679499, -0.6044, -25.084799, 32.4649, -1.1213, -25.084799, 32.4649, -1.1213, -23.412498, 29.679499, -0.6044, -26.7572, 32.4649, -1.1213, -25.084799, 29.679499, -0.6044, -25.084799, 29.679499, -0.6044, -26.7572, 32.4649, -1.1213, -26.7572, 32.4649, -1.1213, -25.084799, 29.679499, -0.6044, -3.3446, 32.4649, -1.1213, -1.6723, 29.679499, -0.6044, -1.6723, 29.679499, -0.6044, -1.6723, 32.4649, -1.1213, -1.6723, 32.4649, -1.1213, 0, 29.679499, -0.6044, -1.6723, 32.4649, -1.1213, 0, 29.679499, -0.6044, 0, 29.679499, -0.6044, 0, 32.4649, -1.1213, 0, 32.4649, -1.1213, 1.6723, 29.679499, -0.6044, 0, 32.4649, -1.1213, 1.6723, 29.679499, -0.6044, 1.6723, 29.679499, -0.6044, 1.6723, 32.4649, -1.1213, 1.6723, 32.4649, -1.1213, 3.3446, 29.679499, -0.6044, 1.6723, 32.4649, -1.1213, 3.3446, 29.679499, -0.6044, 3.3446, 29.679499, -0.6044, 3.3446, 32.4649, -1.1213, 3.3446, 32.4649, -1.1213, 5.0169997, 29.679499, -0.6044, 3.3446, 32.4649, -1.1213, 5.0169997, 29.679499, -0.6044, 5.0169997, 29.679499, -0.6044, 5.0169997, 32.4649, -1.1213, 5.0169997, 32.4649, -1.1213, 6.6893, 29.679499, -0.6044, 5.0169997, 32.4649, -1.1213, 6.6893, 29.679499, -0.6044, 6.6893, 29.679499, -0.6044, 6.6893, 32.4649, -1.1213, 6.6893, 32.4649, -1.1213, 8.3616, 29.679499, -0.6044, 6.6893, 32.4649, -1.1213, 8.3616, 29.679499, -0.6044, 8.3616, 29.679499, -0.6044, 8.3616, 32.4649, -1.1213, 8.3616, 32.4649, -1.1213, 10.033899, 29.679499, -0.6044, 8.3616, 32.4649, -1.1213, 10.033899, 29.679499, -0.6044, 10.033899, 29.679499, -0.6044, 10.033899, 32.4649, -1.1213, 10.033899, 32.4649, -1.1213, 11.7063, 29.679499, -0.6044, 10.033899, 32.4649, -1.1213, 11.7063, 29.679499, -0.6044, 11.7063, 29.679499, -0.6044, 11.7063, 32.4649, -1.1213, 11.7063, 32.4649, -1.1213, 13.3786, 29.679499, -0.6044, 11.7063, 32.4649, -1.1213, 13.3786, 29.679499, -0.6044, 13.3786, 29.679499, -0.6044, 13.3786, 32.4649, -1.1213, 13.3786, 32.4649, -1.1213, 15.0508995, 29.679499, -0.6044, 13.3786, 32.4649, -1.1213, 15.0508995, 29.679499, -0.6044, 15.0508995, 29.679499, -0.6044, 15.0508995, 32.4649, -1.1213, 15.0508995, 32.4649, -1.1213, 16.7232, 29.679499, -0.6044, 15.0508995, 32.4649, -1.1213, 16.7232, 29.679499, -0.6044, 16.7232, 29.679499, -0.6044, 16.7232, 32.4649, -1.1213, 16.7232, 32.4649, -1.1213, 18.3955, 29.679499, -0.6044, 16.7232, 32.4649, -1.1213, 18.3955, 29.679499, -0.6044, 18.3955, 29.679499, -0.6044, 18.3955, 32.4649, -1.1213, 18.3955, 32.4649, -1.1213, 20.0679, 29.679499, -0.6044, 18.3955, 32.4649, -1.1213, 20.0679, 29.679499, -0.6044, 20.0679, 29.679499, -0.6044, 20.0679, 32.4649, -1.1213, 20.0679, 32.4649, -1.1213, 21.7402, 29.679499, -0.6044, 20.0679, 32.4649, -1.1213, 21.7402, 29.679499, -0.6044, 21.7402, 29.679499, -0.6044, 21.7402, 32.4649, -1.1213, 21.7402, 32.4649, -1.1213, 23.412498, 29.679499, -0.6044, 21.7402, 32.4649, -1.1213, 23.412498, 29.679499, -0.6044, 23.412498, 29.679499, -0.6044, 23.412498, 32.4649, -1.1213, 23.412498, 32.4649, -1.1213, 25.084799, 29.679499, -0.6044, 23.412498, 32.4649, -1.1213, 25.084799, 29.679499, -0.6044, 25.084799, 29.679499, -0.6044, 25.084799, 32.4649, -1.1213, 25.084799, 32.4649, -1.1213, 26.7572, 29.679499, -0.6044, 25.084799, 32.4649, -1.1213, 26.7572, 29.679499, -0.6044, 26.7572, 32.4649, -1.1213, -15.0508995, 39.7973, -3.9413, -13.3786, 32.4649, -1.1213, -13.3786, 32.4649, -1.1213, -13.3786, 39.7973, -3.9413, -13.3786, 39.7973, -3.9413, -11.7063, 32.4649, -1.1213, -15.0508995, 39.7973, -3.9413, -15.0508995, 39.7973, -3.9413, -13.3786, 32.4649, -1.1213, -13.3786, 39.7973, -3.9413, -11.7063, 32.4649, -1.1213, -11.7063, 32.4649, -1.1213, -16.7232, 39.7973, -3.9413, -15.0508995, 32.4649, -1.1213, -15.0508995, 32.4649, -1.1213, -11.7063, 39.7973, -3.9413, -11.7063, 39.7973, -3.9413, -10.033899, 32.4649, -1.1213, -16.7232, 39.7973, -3.9413, -16.7232, 39.7973, -3.9413, -15.0508995, 32.4649, -1.1213, -11.7063, 39.7973, -3.9413, -10.033899, 32.4649, -1.1213, -10.033899, 32.4649, -1.1213, -18.3955, 39.7973, -3.9413, -16.7232, 32.4649, -1.1213, -16.7232, 32.4649, -1.1213, -10.033899, 39.7973, -3.9413, -10.033899, 39.7973, -3.9413, -8.3616, 32.4649, -1.1213, -18.3955, 39.7973, -3.9413, -18.3955, 39.7973, -3.9413, -16.7232, 32.4649, -1.1213, -10.033899, 39.7973, -3.9413, -8.3616, 32.4649, -1.1213, -8.3616, 32.4649, -1.1213, -20.0679, 39.7973, -3.9413, -18.3955, 32.4649, -1.1213, -18.3955, 32.4649, -1.1213, -8.3616, 39.7973, -3.9413, -8.3616, 39.7973, -3.9413, -6.6893, 32.4649, -1.1213, -20.0679, 39.7973, -3.9413, -20.0679, 39.7973, -3.9413, -18.3955, 32.4649, -1.1213, -8.3616, 39.7973, -3.9413, -6.6893, 32.4649, -1.1213, -6.6893, 32.4649, -1.1213, -21.7402, 39.7973, -3.9413, -20.0679, 32.4649, -1.1213, -20.0679, 32.4649, -1.1213, -6.6893, 39.7973, -3.9413, -6.6893, 39.7973, -3.9413, -5.0169997, 32.4649, -1.1213, -21.7402, 39.7973, -3.9413, -21.7402, 39.7973, -3.9413, -20.0679, 32.4649, -1.1213, -6.6893, 39.7973, -3.9413, -5.0169997, 32.4649, -1.1213, -5.0169997, 32.4649, -1.1213, -23.412498, 39.7973, -3.9413, -21.7402, 32.4649, -1.1213, -21.7402, 32.4649, -1.1213, -5.0169997, 39.7973, -3.9413, -5.0169997, 39.7973, -3.9413, -3.3446, 32.4649, -1.1213, -23.412498, 39.7973, -3.9413, -23.412498, 39.7973, -3.9413, -21.7402, 32.4649, -1.1213, -5.0169997, 39.7973, -3.9413, -3.3446, 32.4649, -1.1213, -3.3446, 32.4649, -1.1213, -25.084799, 39.7973, -3.9413, -23.412498, 32.4649, -1.1213, -23.412498, 32.4649, -1.1213, -3.3446, 39.7973, -3.9413, -3.3446, 39.7973, -3.9413, -1.6723, 32.4649, -1.1213, -25.084799, 39.7973, -3.9413, -25.084799, 39.7973, -3.9413, -23.412498, 32.4649, -1.1213, -26.7572, 39.7973, -3.9413, -25.084799, 32.4649, -1.1213, -25.084799, 32.4649, -1.1213, -26.7572, 39.7973, -3.9413, -26.7572, 39.7973, -3.9413, -25.084799, 32.4649, -1.1213, -3.3446, 39.7973, -3.9413, -1.6723, 32.4649, -1.1213, -1.6723, 32.4649, -1.1213, -1.6723, 39.7973, -3.9413, -1.6723, 39.7973, -3.9413, 0, 32.4649, -1.1213, -1.6723, 39.7973, -3.9413, 0, 32.4649, -1.1213, 0, 32.4649, -1.1213, 0, 39.7973, -3.9413, 0, 39.7973, -3.9413, 1.6723, 32.4649, -1.1213, 0, 39.7973, -3.9413, 1.6723, 32.4649, -1.1213, 1.6723, 32.4649, -1.1213, 1.6723, 39.7973, -3.9413, 1.6723, 39.7973, -3.9413, 3.3446, 32.4649, -1.1213, 1.6723, 39.7973, -3.9413, 3.3446, 32.4649, -1.1213, 3.3446, 32.4649, -1.1213, 3.3446, 39.7973, -3.9413, 3.3446, 39.7973, -3.9413, 5.0169997, 32.4649, -1.1213, 3.3446, 39.7973, -3.9413, 5.0169997, 32.4649, -1.1213, 5.0169997, 32.4649, -1.1213, 5.0169997, 39.7973, -3.9413, 5.0169997, 39.7973, -3.9413, 6.6893, 32.4649, -1.1213, 5.0169997, 39.7973, -3.9413, 6.6893, 32.4649, -1.1213, 6.6893, 32.4649, -1.1213, 6.6893, 39.7973, -3.9413, 6.6893, 39.7973, -3.9413, 8.3616, 32.4649, -1.1213, 6.6893, 39.7973, -3.9413, 8.3616, 32.4649, -1.1213, 8.3616, 32.4649, -1.1213, 8.3616, 39.7973, -3.9413, 8.3616, 39.7973, -3.9413, 10.033899, 32.4649, -1.1213, 8.3616, 39.7973, -3.9413, 10.033899, 32.4649, -1.1213, 10.033899, 32.4649, -1.1213, 10.033899, 39.7973, -3.9413, 10.033899, 39.7973, -3.9413, 11.7063, 32.4649, -1.1213, 10.033899, 39.7973, -3.9413, 11.7063, 32.4649, -1.1213, 11.7063, 32.4649, -1.1213, 11.7063, 39.7973, -3.9413, 11.7063, 39.7973, -3.9413, 13.3786, 32.4649, -1.1213, 11.7063, 39.7973, -3.9413, 13.3786, 32.4649, -1.1213, 13.3786, 32.4649, -1.1213, 13.3786, 39.7973, -3.9413, 13.3786, 39.7973, -3.9413, 15.0508995, 32.4649, -1.1213, 13.3786, 39.7973, -3.9413, 15.0508995, 32.4649, -1.1213, 15.0508995, 32.4649, -1.1213, 15.0508995, 39.7973, -3.9413, 15.0508995, 39.7973, -3.9413, 16.7232, 32.4649, -1.1213, 15.0508995, 39.7973, -3.9413, 16.7232, 32.4649, -1.1213, 16.7232, 32.4649, -1.1213, 16.7232, 39.7973, -3.9413, 16.7232, 39.7973, -3.9413, 18.3955, 32.4649, -1.1213, 16.7232, 39.7973, -3.9413, 18.3955, 32.4649, -1.1213, 18.3955, 32.4649, -1.1213, 18.3955, 39.7973, -3.9413, 18.3955, 39.7973, -3.9413, 20.0679, 32.4649, -1.1213, 18.3955, 39.7973, -3.9413, 20.0679, 32.4649, -1.1213, 20.0679, 32.4649, -1.1213, 20.0679, 39.7973, -3.9413, 20.0679, 39.7973, -3.9413, 21.7402, 32.4649, -1.1213, 20.0679, 39.7973, -3.9413, 21.7402, 32.4649, -1.1213, 21.7402, 32.4649, -1.1213, 21.7402, 39.7973, -3.9413, 21.7402, 39.7973, -3.9413, 23.412498, 32.4649, -1.1213, 21.7402, 39.7973, -3.9413, 23.412498, 32.4649, -1.1213, 23.412498, 32.4649, -1.1213, 23.412498, 39.7973, -3.9413, 23.412498, 39.7973, -3.9413, 25.084799, 32.4649, -1.1213, 23.412498, 39.7973, -3.9413, 25.084799, 32.4649, -1.1213, 25.084799, 32.4649, -1.1213, 25.084799, 39.7973, -3.9413, 25.084799, 39.7973, -3.9413, 26.7572, 32.4649, -1.1213, 25.084799, 39.7973, -3.9413, 26.7572, 32.4649, -1.1213, 26.7572, 26.7572, -0.2593, 16.7232, 29.679499, -0.6044, 18.3955, 26.7572, -0.2593, 18.3955, 26.7572, -0.2593, 18.3955, 29.679499, -0.6044, 18.3955, 29.679499, -0.6044, 20.0679, 26.7572, -0.2593, 16.7232, 29.679499, -0.6044, 16.7232, 29.679499, -0.6044, 18.3955, 26.7572, -0.2593, 18.3955, 29.679499, -0.6044, 20.0679, 26.7572, -0.2593, 20.0679, 26.7572, -0.2593, 15.0508995, 29.679499, -0.6044, 16.7232, 26.7572, -0.2593, 16.7232, 26.7572, -0.2593, 20.0679, 29.679499, -0.6044, 20.0679, 29.679499, -0.6044, 21.7402, 26.7572, -0.2593, 15.0508995, 29.679499, -0.6044, 15.0508995, 29.679499, -0.6044, 16.7232, 26.7572, -0.2593, 20.0679, 29.679499, -0.6044, 21.7402, 26.7572, -0.2593, 21.7402, 26.7572, -0.2593, 13.3786, 29.679499, -0.6044, 15.0508995, 26.7572, -0.2593, 15.0508995, 26.7572, -0.2593, 21.7402, 29.679499, -0.6044, 21.7402, 29.679499, -0.6044, 23.412498, 26.7572, -0.2593, 13.3786, 29.679499, -0.6044, 13.3786, 29.679499, -0.6044, 15.0508995, 26.7572, -0.2593, 21.7402, 29.679499, -0.6044, 23.412498, 26.7572, -0.2593, 23.412498, 26.7572, -0.2593, 11.7063, 29.679499, -0.6044, 13.3786, 26.7572, -0.2593, 13.3786, 26.7572, -0.2593, 23.412498, 29.679499, -0.6044, 23.412498, 29.679499, -0.6044, 25.084799, 26.7572, -0.2593, 11.7063, 29.679499, -0.6044, 11.7063, 29.679499, -0.6044, 13.3786, 26.7572, -0.2593, 23.412498, 29.679499, -0.6044, 25.084799, 26.7572, -0.2593, 25.084799, 26.7572, -0.2593, 25.084799, 29.679499, -0.6044, 25.084799, 29.679499, -0.6044, 26.7572, 26.7572, -0.2593, 25.084799, 29.679499, -0.6044, 26.7572, 26.7572, -0.2593, 26.7572, 26.7572, -0.2593, 10.033899, 29.679499, -0.6044, 11.7063, 26.7572, -0.2593, 11.7063, 26.7572, -0.2593, 10.033899, 29.679499, -0.6044, 10.033899, 29.679499, -0.6044, 11.7063, 26.7572, -0.2593, 8.3616, 29.679499, -0.6044, 10.033899, 26.7572, -0.2593, 10.033899, 26.7572, -0.2593, 8.3616, 29.679499, -0.6044, 8.3616, 29.679499, -0.6044, 10.033899, 26.7572, -0.2593, 6.6893, 29.679499, -0.6044, 8.3616, 26.7572, -0.2593, 8.3616, 26.7572, -0.2593, 6.6893, 29.679499, -0.6044, 6.6893, 29.679499, -0.6044, 8.3616, 26.7572, -0.2593, 5.0169997, 29.679499, -0.6044, 6.6893, 26.7572, -0.2593, 6.6893, 26.7572, -0.2593, 5.0169997, 29.679499, -0.6044, 5.0169997, 29.679499, -0.6044, 6.6893, 26.7572, -0.2593, 3.3446, 29.679499, -0.6044, 5.0169997, 26.7572, -0.2593, 5.0169997, 26.7572, -0.2593, 3.3446, 29.679499, -0.6044, 3.3446, 29.679499, -0.6044, 5.0169997, 26.7572, -0.2593, 1.6723, 29.679499, -0.6044, 3.3446, 26.7572, -0.2593, 3.3446, 26.7572, -0.2593, 1.6723, 29.679499, -0.6044, 1.6723, 29.679499, -0.6044, 3.3446, 26.7572, -0.2593, 0, 29.679499, -0.6044, 1.6723, 26.7572, -0.2593, 1.6723, 26.7572, -0.2593, 0, 29.679499, -0.6044, 0, 29.679499, -0.6044, 1.6723, 26.7572, -0.2593, -1.6723, 29.679499, -0.6044, 0, 26.7572, -0.2593, 0, 26.7572, -0.2593, -1.6723, 29.679499, -0.6044, -1.6723, 29.679499, -0.6044, 0, 26.7572, -0.2593, -3.3446, 29.679499, -0.6044, -1.6723, 26.7572, -0.2593, -1.6723, 26.7572, -0.2593, -3.3446, 29.679499, -0.6044, -3.3446, 29.679499, -0.6044, -1.6723, 26.7572, -0.2593, -5.0169997, 29.679499, -0.6044, -3.3446, 26.7572, -0.2593, -3.3446, 26.7572, -0.2593, -5.0169997, 29.679499, -0.6044, -5.0169997, 29.679499, -0.6044, -3.3446, 26.7572, -0.2593, -6.6893, 29.679499, -0.6044, -5.0169997, 26.7572, -0.2593, -5.0169997, 26.7572, -0.2593, -6.6893, 29.679499, -0.6044, -6.6893, 29.679499, -0.6044, -5.0169997, 26.7572, -0.2593, -8.3616, 29.679499, -0.6044, -6.6893, 26.7572, -0.2593, -6.6893, 26.7572, -0.2593, -8.3616, 29.679499, -0.6044, -8.3616, 29.679499, -0.6044, -6.6893, 26.7572, -0.2593, -10.033899, 29.679499, -0.6044, -8.3616, 26.7572, -0.2593, -8.3616, 26.7572, -0.2593, -10.033899, 29.679499, -0.6044, -10.033899, 29.679499, -0.6044, -8.3616, 26.7572, -0.2593, -11.7063, 29.679499, -0.6044, -10.033899, 26.7572, -0.2593, -10.033899, 26.7572, -0.2593, -11.7063, 29.679499, -0.6044, -11.7063, 29.679499, -0.6044, -10.033899, 26.7572, -0.2593, -13.3786, 29.679499, -0.6044, -11.7063, 26.7572, -0.2593, -11.7063, 26.7572, -0.2593, -13.3786, 29.679499, -0.6044, -13.3786, 29.679499, -0.6044, -11.7063, 26.7572, -0.2593, -15.0508995, 29.679499, -0.6044, -13.3786, 26.7572, -0.2593, -13.3786, 26.7572, -0.2593, -15.0508995, 29.679499, -0.6044, -15.0508995, 29.679499, -0.6044, -13.3786, 26.7572, -0.2593, -16.7232, 29.679499, -0.6044, -15.0508995, 26.7572, -0.2593, -15.0508995, 26.7572, -0.2593, -16.7232, 29.679499, -0.6044, -16.7232, 29.679499, -0.6044, -15.0508995, 26.7572, -0.2593, -18.3955, 29.679499, -0.6044, -16.7232, 26.7572, -0.2593, -16.7232, 26.7572, -0.2593, -18.3955, 29.679499, -0.6044, -18.3955, 29.679499, -0.6044, -16.7232, 26.7572, -0.2593, -20.0679, 29.679499, -0.6044, -18.3955, 26.7572, -0.2593, -18.3955, 26.7572, -0.2593, -20.0679, 29.679499, -0.6044, -20.0679, 29.679499, -0.6044, -18.3955, 26.7572, -0.2593, -21.7402, 29.679499, -0.6044, -20.0679, 26.7572, -0.2593, -20.0679, 26.7572, -0.2593, -21.7402, 29.679499, -0.6044, -21.7402, 29.679499, -0.6044, -20.0679, 26.7572, -0.2593, -23.412498, 29.679499, -0.6044, -21.7402, 26.7572, -0.2593, -21.7402, 26.7572, -0.2593, -23.412498, 29.679499, -0.6044, -23.412498, 29.679499, -0.6044, -21.7402, 26.7572, -0.2593, -25.084799, 29.679499, -0.6044, -23.412498, 26.7572, -0.2593, -23.412498, 26.7572, -0.2593, -25.084799, 29.679499, -0.6044, -25.084799, 29.679499, -0.6044, -23.412498, 26.7572, -0.2593, -26.7572, 29.679499, -0.6044, -25.084799, 26.7572, -0.2593, -25.084799, 26.7572, -0.2593, -26.7572, 29.679499, -0.6044, -26.7572, 29.679499, -0.6044, -25.084799)
@@ -40,19 +37,23 @@ size = Vector2(10000, 10000)
[sub_resource type="BoxShape3D" id="OceanWestShape"]
resource_local_to_scene = true
-size = Vector3(17, 2, 80)
+size = Vector3(20.820662814, 2, 97.979589711)
[sub_resource type="BoxShape3D" id="OceanEastShape"]
resource_local_to_scene = true
-size = Vector3(42, 2, 80)
+size = Vector3(51.439284598, 2, 97.979589711)
[sub_resource type="BoxShape3D" id="OceanNorthShape"]
resource_local_to_scene = true
-size = Vector3(48, 2, 18)
+size = Vector3(58.787753827, 2, 22.045407685)
[sub_resource type="BoxShape3D" id="OceanSouthShape"]
resource_local_to_scene = true
-size = Vector3(48, 2, 18)
+size = Vector3(58.787753827, 2, 22.045407685)
+
+[sub_resource type="BoxShape3D" id="OceanCenterShape"]
+resource_local_to_scene = true
+size = Vector3(58.787753827, 2, 53.888774341)
[sub_resource type="BoxShape3D" id="OceanWestRecoveryShape"]
resource_local_to_scene = true
@@ -70,29 +71,31 @@ size = Vector3(48, 5, 18)
resource_local_to_scene = true
size = Vector3(48, 5, 18)
-[sub_resource type="Resource" id="ShorelineRibbonConfig_pond"]
-script = ExtResource("15_shoreline_config")
-terrain_source = NodePath("../Terrain/Collision/Shape")
+[sub_resource type="Resource" id="ShorelineRibbonConfigPond"]
+script = ExtResource("22_shoreline_config")
+terrain_source = NodePath("../Terrain/Visual/starter_island")
water_height = 2.51
generation_bounds = Rect2(-17.45, -4.08375, 16.1, 12.3675)
water_reference = Vector2(-9.4, 2.1)
water_is_inside = true
output_resource_path = "res://world/generated/shorelines/starter_pond_shoreline.tres"
-[sub_resource type="Resource" id="ShorelineRibbonConfig_ocean"]
-script = ExtResource("15_shoreline_config")
-terrain_source = NodePath("../Terrain/Collision/Shape")
+[sub_resource type="Resource" id="ShorelineRibbonConfigOcean"]
+script = ExtResource("22_shoreline_config")
+terrain_source = NodePath("../Terrain/Visual/starter_island")
water_type = 1
water_height = -0.45
generation_bounds = Rect2(-42, -50, 108, 100)
water_reference = Vector2(0, 0)
water_is_inside = false
output_resource_path = "res://world/generated/shorelines/starter_ocean_shoreline.tres"
+simplification_tolerance = 0.55
+smoothing_iterations = 3
+resample_spacing = 0.16
+corner_rounding_distance = 2.4
[node name="StarterIslandRegion" type="Node3D" unique_id=1830415700]
script = ExtResource("1_region")
-grass_material = ExtResource("9_grass")
-sand_material = ExtResource("11_sand")
region_id = &"starter_island"
fishable_water_root = NodePath("WaterBodies")
water_recovery_root = NodePath("WaterBodies")
@@ -107,14 +110,14 @@ water_recovery_root = NodePath("WaterBodies")
shape = SubResource("ConcavePolygonShape3D_4e4k5")
[node name="ShorelineRibbonBaker" type="Node" parent="."]
-script = ExtResource("14_shoreline_baker")
-water_bodies = Array[ExtResource("15_shoreline_config")]([SubResource("ShorelineRibbonConfig_pond"), SubResource("ShorelineRibbonConfig_ocean")])
+script = ExtResource("21_shoreline_baker")
+water_bodies = Array[ExtResource("22_shoreline_config")]([SubResource("ShorelineRibbonConfigPond"), SubResource("ShorelineRibbonConfigOcean")])
[node name="ShorelineRibbons" type="Node3D" parent="."]
[node name="Ocean" type="MeshInstance3D" parent="ShorelineRibbons"]
+visible = false
cast_shadow = 0
-material_override = ExtResource("18_shoreline_material")
mesh = ExtResource("17_ocean_shoreline")
[node name="WaterBodies" type="Node3D" parent="." unique_id=1417012172]
@@ -162,6 +165,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, -0.45, 0)
[node name="VisualWater" type="MeshInstance3D" parent="WaterBodies/Ocean" unique_id=1176408937]
material_override = ExtResource("13_water")
mesh = SubResource("OceanWaterMesh")
+script = ExtResource("20_surface_motion")
[node name="FishingRegions" type="Node3D" parent="WaterBodies/Ocean" unique_id=205598473]
@@ -176,21 +180,25 @@ fish_pool = ExtResource("4_pool")
surface_height_mode = 1
[node name="WestShape" type="CollisionShape3D" parent="WaterBodies/Ocean/FishingRegions/OceanFishingRegion" unique_id=357406062]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -45.5, -1, 0)
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -55.613519213, -1, 0)
shape = SubResource("OceanWestShape")
[node name="EastShape" type="CollisionShape3D" parent="WaterBodies/Ocean/FishingRegions/OceanFishingRegion" unique_id=772224738]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 32, -1, 0)
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 39.30420832, -1, 0)
shape = SubResource("OceanEastShape")
[node name="NorthShape" type="CollisionShape3D" parent="WaterBodies/Ocean/FishingRegions/OceanFishingRegion" unique_id=646147646]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, -1, 31)
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.809310892, -1, 37.967091013)
shape = SubResource("OceanNorthShape")
[node name="SouthShape" type="CollisionShape3D" parent="WaterBodies/Ocean/FishingRegions/OceanFishingRegion" unique_id=894083854]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13, -1, -31)
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.809310892, -1, -37.967091013)
shape = SubResource("OceanSouthShape")
+[node name="CenterShape" type="CollisionShape3D" parent="WaterBodies/Ocean/FishingRegions/OceanFishingRegion"]
+position = Vector3(-15.809310892, -1, 0)
+shape = SubResource("OceanCenterShape")
+
[node name="RecoveryRegions" type="Node3D" parent="WaterBodies/Ocean" unique_id=463706703]
[node name="OceanRecoveryRegion" type="Area3D" parent="WaterBodies/Ocean/RecoveryRegions" unique_id=922834963]
@@ -248,7 +256,4 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.95, 13)
[node name="Interactables" type="Node3D" parent="." unique_id=26695257]
[node name="FishingShopWorld" parent="Interactables" unique_id=1255373524 instance=ExtResource("7_shop")]
-transform = Transform3D(0.90630776, 0, -0.42261827, 0, 1, 0, 0.42261827, 0, 0.90630776, 8, 3.42, 6)
-
-[node name="PelicanCoolerPerch" parent="Interactables" unique_id=588122038 instance=ExtResource("8_pelican")]
-transform = Transform3D(0.81915206, 0, -0.57357645, 0, 1, 0, 0.57357645, 0, 0.81915206, 18, 0.35, -16)
+transform = Transform3D(-0.9976046, 0, -0.06917416, 0, 1, 0, 0.06917416, 0, -0.9976046, 5.976795, 3.42, 4.299163)
diff --git a/world/shoreline_ambience.gd b/world/shoreline_ambience.gd
index 959cb93..81e9c65 100644
--- a/world/shoreline_ambience.gd
+++ b/world/shoreline_ambience.gd
@@ -18,6 +18,7 @@ var _is_active := false
func _ready() -> void:
+ _waves_audio.bus = &"Environment"
_configure_audio_loop(_waves_audio.stream)
_waves_audio.volume_db = -80.0
set_process(false)
diff --git a/world/test_world.gd b/world/test_world.gd
index 5d6660a..a3ea397 100644
--- a/world/test_world.gd
+++ b/world/test_world.gd
@@ -57,10 +57,6 @@ func get_fishable_water_regions() -> Array[FishableWaterRegion]:
return waters
-func get_pelican_convenience_landmark() -> Node3D:
- return _starter_island.get_pelican_landmark()
-
-
func get_saltwater_shoreline_mesh() -> MeshInstance3D:
return _starter_island.get_saltwater_shoreline_mesh()
diff --git a/world/test_world.tscn b/world/test_world.tscn
index ef19355..b6345fb 100644
--- a/world/test_world.tscn
+++ b/world/test_world.tscn
@@ -6,13 +6,13 @@
[ext_resource type="Environment" path="res://world/environment/netfishing_environment.tres" id="4_environment"]
[sub_resource type="BoxShape3D" id="NorthSouthBoundsShape"]
-size = Vector3(120, 14, 2)
+size = Vector3(168.8772, 14, 2)
[sub_resource type="BoxShape3D" id="EastWestBoundsShape"]
-size = Vector3(2, 14, 90)
+size = Vector3(2, 14, 126.45079)
[sub_resource type="BoxShape3D" id="FailsafeShape"]
-size = Vector3(118, 4, 88)
+size = Vector3(166.8772, 4, 124.45079)
[node name="TestWorld" type="Node3D"]
script = ExtResource("1_world")
@@ -49,25 +49,25 @@ shape = SubResource("FailsafeShape")
[node name="WorldBounds" type="Node3D" parent="."]
[node name="North" type="StaticBody3D" parent="WorldBounds"]
-position = Vector3(12, 5, 45)
+position = Vector3(12, 5, 63.225395)
[node name="Shape" type="CollisionShape3D" parent="WorldBounds/North"]
shape = SubResource("NorthSouthBoundsShape")
[node name="South" type="StaticBody3D" parent="WorldBounds"]
-position = Vector3(12, 5, -45)
+position = Vector3(12, 5, -63.225395)
[node name="Shape" type="CollisionShape3D" parent="WorldBounds/South"]
shape = SubResource("NorthSouthBoundsShape")
[node name="West" type="StaticBody3D" parent="WorldBounds"]
-position = Vector3(-48, 5, 0)
+position = Vector3(-72.4386, 5, 0)
[node name="Shape" type="CollisionShape3D" parent="WorldBounds/West"]
shape = SubResource("EastWestBoundsShape")
[node name="East" type="StaticBody3D" parent="WorldBounds"]
-position = Vector3(72, 5, 0)
+position = Vector3(96.4386, 5, 0)
[node name="Shape" type="CollisionShape3D" parent="WorldBounds/East"]
shape = SubResource("EastWestBoundsShape")
diff --git a/world/water/shoreline_ribbon_baker.gd b/world/water/shoreline_ribbon_baker.gd
index 32c75d6..a88b6e4 100644
--- a/world/water/shoreline_ribbon_baker.gd
+++ b/world/water/shoreline_ribbon_baker.gd
@@ -51,7 +51,8 @@ func _rebuild(configuration: ShorelineRibbonConfig) -> Dictionary:
configuration.water_is_inside,
configuration.simplification_tolerance,
configuration.smoothing_iterations,
- configuration.resample_spacing
+ configuration.resample_spacing,
+ configuration.corner_rounding_distance,
)
var output_directory := configuration.output_resource_path.get_base_dir()
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(output_directory))
diff --git a/world/water/shoreline_ribbon_config.gd b/world/water/shoreline_ribbon_config.gd
index ae58496..682bfed 100644
--- a/world/water/shoreline_ribbon_config.gd
+++ b/world/water/shoreline_ribbon_config.gd
@@ -12,3 +12,4 @@ extends Resource
@export var simplification_tolerance := -1.0
@export_range(-1, 4, 1) var smoothing_iterations := -1
@export var resample_spacing := -1.0
+@export var corner_rounding_distance := -1.0
diff --git a/world/water/shoreline_ribbon_generator.gd b/world/water/shoreline_ribbon_generator.gd
index 5531ab8..9708b06 100644
--- a/world/water/shoreline_ribbon_generator.gd
+++ b/world/water/shoreline_ribbon_generator.gd
@@ -5,11 +5,16 @@ const WATER_PLANE_EPSILON := 0.001
const ENDPOINT_MERGE_TOLERANCE := 0.03
const LOOP_CLOSURE_TOLERANCE := 0.06
const MINIMUM_FRAGMENT_LENGTH := 2.0
-const SIMPLIFICATION_TOLERANCE := 0.20
-const SMOOTHING_ITERATIONS := 2
-const RESAMPLE_SPACING := 0.22
-const RIBBON_WIDTH := 0.85
-const LAND_INSET := 0.10
+const SIMPLIFICATION_TOLERANCE := 0.55
+const SMOOTHING_ITERATIONS := 3
+const RESAMPLE_SPACING := 0.16
+const CORNER_ROUNDING_DISTANCE := 2.4
+const CORNER_ROUNDING_START_DEGREES := 24.0
+const CORNER_ROUNDING_FULL_DEGREES := 78.0
+const MAXIMUM_JOIN_SCALE := 1.0
+const RIBBON_REACH_GROWTH_PER_METER := 0.52
+const RIBBON_WIDTH := 1.35
+const LAND_INSET := 0.12
const SURFACE_OFFSET := 0.018
@@ -21,7 +26,8 @@ static func generate(
water_is_inside: bool,
simplification_override := -1.0,
smoothing_iterations_override := -1,
- resample_spacing_override := -1.0
+ resample_spacing_override := -1.0,
+ corner_rounding_override := -1.0
) -> Dictionary:
var simplification := (
SIMPLIFICATION_TOLERANCE
@@ -38,6 +44,11 @@ static func generate(
if resample_spacing_override < 0.0
else resample_spacing_override
)
+ var corner_rounding := (
+ CORNER_ROUNDING_DISTANCE
+ if corner_rounding_override < 0.0
+ else corner_rounding_override
+ )
var segments := _extract_segments(faces, water_height, bounds)
var raw_paths := _stitch_segments(segments)
var processed_paths: Array[Dictionary] = []
@@ -52,7 +63,12 @@ static func generate(
continue
var simplified := _simplify(raw_points, closed, simplification)
simplified_paths.append({"points": simplified, "closed": closed})
- var smoothed := _chaikin(simplified, closed, smoothing_iterations)
+ var rounded := _round_sharp_corners(
+ simplified,
+ closed,
+ corner_rounding,
+ )
+ var smoothed := _chaikin(rounded, closed, smoothing_iterations)
var resampled := _resample(smoothed, closed, resample_spacing)
if resampled.size() < (3 if closed else 2):
continue
@@ -296,6 +312,65 @@ static func _chaikin(
return result
+static func _round_sharp_corners(
+ points: PackedVector2Array,
+ closed: bool,
+ rounding_distance: float,
+) -> PackedVector2Array:
+ if rounding_distance <= WATER_PLANE_EPSILON or points.size() < 3:
+ return points
+ var result := PackedVector2Array()
+ for index: int in points.size():
+ if not closed and (index == 0 or index == points.size() - 1):
+ result.append(points[index])
+ continue
+ var previous := points[(index - 1 + points.size()) % points.size()]
+ var point := points[index]
+ var following := points[(index + 1) % points.size()]
+ var incoming_vector := point - previous
+ var outgoing_vector := following - point
+ var incoming_length := incoming_vector.length()
+ var outgoing_length := outgoing_vector.length()
+ if (
+ incoming_length <= WATER_PLANE_EPSILON
+ or outgoing_length <= WATER_PLANE_EPSILON
+ ):
+ result.append(point)
+ continue
+ var incoming := incoming_vector / incoming_length
+ var outgoing := outgoing_vector / outgoing_length
+ var turn_degrees := rad_to_deg(
+ acos(clampf(incoming.dot(outgoing), -1.0, 1.0))
+ )
+ var corner_weight := smoothstep(
+ CORNER_ROUNDING_START_DEGREES,
+ CORNER_ROUNDING_FULL_DEGREES,
+ turn_degrees,
+ )
+ var cut_distance := minf(
+ rounding_distance * corner_weight,
+ minf(incoming_length, outgoing_length) * 0.44,
+ )
+ if cut_distance <= WATER_PLANE_EPSILON:
+ result.append(point)
+ continue
+ var entry := point - incoming * cut_distance
+ var exit := point + outgoing * cut_distance
+ var curve_steps := maxi(3, ceili(cut_distance / 0.22))
+ for step: int in curve_steps + 1:
+ var amount := float(step) / float(curve_steps)
+ var first := entry.lerp(point, amount)
+ var second := point.lerp(exit, amount)
+ var rounded_point := first.lerp(second, amount)
+ if (
+ result.is_empty()
+ or result[result.size() - 1].distance_to(rounded_point)
+ > WATER_PLANE_EPSILON
+ ):
+ result.append(rounded_point)
+ return result
+
+
static func _resample(
points: PackedVector2Array,
closed: bool,
@@ -342,26 +417,77 @@ static func _build_mesh(
for path_data: Dictionary in paths:
var points: PackedVector2Array = path_data["points"]
var closed: bool = path_data["closed"]
+ var closed_water_side := (
+ _closed_path_water_side(points, water_is_inside)
+ if closed
+ else 0.0
+ )
var base_index := vertices.size()
- var path_distance := 0.0
+ var water_normals := PackedVector2Array()
+ var join_scales := PackedFloat32Array()
+ var water_reaches := PackedFloat32Array()
for index: int in points.size():
- if index > 0:
- path_distance += points[index - 1].distance_to(points[index])
var previous := points[(index - 1 + points.size()) % points.size()]
var following := points[(index + 1) % points.size()]
if not closed:
previous = points[maxi(index - 1, 0)]
following = points[mini(index + 1, points.size() - 1)]
- var tangent := previous.direction_to(following)
- var water_normal := Vector2(-tangent.y, tangent.x)
- var toward_reference := points[index].direction_to(water_reference)
- if (
- (water_is_inside and water_normal.dot(toward_reference) < 0.0)
- or (not water_is_inside and water_normal.dot(toward_reference) > 0.0)
- ):
- water_normal = -water_normal
- var land_point := points[index] - water_normal * LAND_INSET
- var water_point := points[index] + water_normal * (RIBBON_WIDTH - LAND_INSET)
+ var point := points[index]
+ var incoming := previous.direction_to(point)
+ var outgoing := point.direction_to(following)
+ if incoming.is_zero_approx():
+ incoming = outgoing
+ if outgoing.is_zero_approx():
+ outgoing = incoming
+ var incoming_normal := Vector2(-incoming.y, incoming.x)
+ var outgoing_normal := Vector2(-outgoing.y, outgoing.x)
+ var water_normal := incoming_normal + outgoing_normal
+ if water_normal.is_zero_approx():
+ water_normal = outgoing_normal
+ water_normal = water_normal.normalized()
+ if closed:
+ water_normal *= closed_water_side
+ else:
+ var toward_reference := point.direction_to(water_reference)
+ if (
+ (water_is_inside and water_normal.dot(toward_reference) < 0.0)
+ or (not water_is_inside and water_normal.dot(toward_reference) > 0.0)
+ ):
+ water_normal = -water_normal
+ var join_scale := minf(
+ 1.0 / maxf(absf(water_normal.dot(outgoing_normal)), 0.55),
+ MAXIMUM_JOIN_SCALE,
+ )
+ var water_reach := _safe_water_reach(
+ incoming,
+ outgoing,
+ water_normal,
+ previous.distance_to(point),
+ point.distance_to(following),
+ (RIBBON_WIDTH - LAND_INSET) * join_scale,
+ )
+ water_normals.append(water_normal)
+ join_scales.append(join_scale)
+ water_reaches.append(water_reach)
+ water_reaches = _smooth_water_reaches(
+ points,
+ water_reaches,
+ closed,
+ )
+ var path_distance := 0.0
+ for index: int in points.size():
+ if index > 0:
+ path_distance += points[index - 1].distance_to(points[index])
+ var point := points[index]
+ var water_normal := water_normals[index]
+ var join_scale := join_scales[index]
+ var land_point := (
+ point - water_normal * LAND_INSET * join_scale
+ )
+ var water_point := (
+ point
+ + water_normal * water_reaches[index]
+ )
vertices.append(Vector3(land_point.x, water_height + SURFACE_OFFSET, land_point.y))
vertices.append(Vector3(water_point.x, water_height + SURFACE_OFFSET, water_point.y))
normals.append(Vector3.UP)
@@ -388,6 +514,71 @@ static func _build_mesh(
return mesh
+static func _safe_water_reach(
+ incoming: Vector2,
+ outgoing: Vector2,
+ water_normal: Vector2,
+ incoming_length: float,
+ outgoing_length: float,
+ desired_reach: float,
+) -> float:
+ var turn_cross := incoming.cross(outgoing)
+ var water_side := incoming.cross(water_normal)
+ if turn_cross * water_side <= 0.0:
+ return desired_reach
+ var turn_angle := acos(clampf(incoming.dot(outgoing), -1.0, 1.0))
+ if turn_angle <= WATER_PLANE_EPSILON:
+ return desired_reach
+ var radius := minf(incoming_length, outgoing_length) / maxf(
+ 2.0 * sin(turn_angle * 0.5),
+ WATER_PLANE_EPSILON,
+ )
+ return minf(desired_reach, maxf(radius * 0.58, 0.24))
+
+
+static func _smooth_water_reaches(
+ points: PackedVector2Array,
+ reaches: PackedFloat32Array,
+ closed: bool,
+) -> PackedFloat32Array:
+ var result := reaches.duplicate()
+ if result.size() < 2:
+ return result
+ for _pass: int in 3:
+ var forward_start := 0 if closed else 1
+ for index: int in range(forward_start, result.size()):
+ var previous := (index - 1 + result.size()) % result.size()
+ var allowed := (
+ result[previous]
+ + points[previous].distance_to(points[index])
+ * RIBBON_REACH_GROWTH_PER_METER
+ )
+ result[index] = minf(result[index], allowed)
+ var backward_start := result.size() - 1 if closed else result.size() - 2
+ for index: int in range(backward_start, -1, -1):
+ var following := (index + 1) % result.size()
+ var allowed := (
+ result[following]
+ + points[index].distance_to(points[following])
+ * RIBBON_REACH_GROWTH_PER_METER
+ )
+ result[index] = minf(result[index], allowed)
+ return result
+
+
+static func _closed_path_water_side(
+ points: PackedVector2Array,
+ water_is_inside: bool,
+) -> float:
+ var signed_area_twice := 0.0
+ for index: int in points.size():
+ signed_area_twice += points[index].cross(
+ points[(index + 1) % points.size()]
+ )
+ var interior_side := 1.0 if signed_area_twice >= 0.0 else -1.0
+ return interior_side if water_is_inside else -interior_side
+
+
static func _point_key(point: Vector2) -> Vector2i:
return Vector2i(
roundi(point.x / ENDPOINT_MERGE_TOLERANCE),
@@ -440,4 +631,6 @@ static func _mesh_triangle_count(mesh: ArrayMesh) -> int:
if mesh.get_surface_count() == 0:
return 0
var arrays := mesh.surface_get_arrays(0)
- return (arrays[Mesh.ARRAY_INDEX] as PackedInt32Array).size() / 3
+ return floori(
+ float((arrays[Mesh.ARRAY_INDEX] as PackedInt32Array).size()) / 3.0
+ )
diff --git a/world/water_surface_motion.gd b/world/water_surface_motion.gd
new file mode 100644
index 0000000..992f9cb
--- /dev/null
+++ b/world/water_surface_motion.gd
@@ -0,0 +1,68 @@
+class_name WaterSurfaceMotion
+extends MeshInstance3D
+
+const DEFAULT_AMPLITUDE: float = 0.055
+const DEFAULT_CYCLE_SECONDS: float = 7.0
+const DEFAULT_SECONDARY_SWELL: float = 0.18
+const DEFAULT_PHASE_OFFSET: float = 0.0
+
+@export_range(0.0, 0.2, 0.005, "suffix:m") var amplitude: float = (
+ DEFAULT_AMPLITUDE
+)
+@export_range(1.0, 30.0, 0.1, "suffix:s") var cycle_seconds: float = (
+ DEFAULT_CYCLE_SECONDS
+)
+@export_range(0.0, 0.5, 0.01) var secondary_swell: float = (
+ DEFAULT_SECONDARY_SWELL
+)
+@export_range(0.0, TAU, 0.01, "radians") var phase_offset: float = 0.0
+
+var _base_height: float
+
+
+func _ready() -> void:
+ _base_height = position.y
+ set_process(amplitude > 0.0)
+
+
+func _process(_delta: float) -> void:
+ position.y = _base_height + calculate_height_offset(
+ _current_time_seconds(),
+ amplitude,
+ cycle_seconds,
+ secondary_swell,
+ phase_offset,
+ )
+
+
+static func get_default_height_offset() -> float:
+ return calculate_height_offset(
+ _current_time_seconds(),
+ DEFAULT_AMPLITUDE,
+ DEFAULT_CYCLE_SECONDS,
+ DEFAULT_SECONDARY_SWELL,
+ DEFAULT_PHASE_OFFSET,
+ )
+
+
+static func calculate_height_offset(
+ time_seconds: float,
+ motion_amplitude: float,
+ motion_cycle_seconds: float,
+ motion_secondary_swell: float,
+ motion_phase_offset: float,
+) -> float:
+ var safe_cycle := maxf(motion_cycle_seconds, 0.001)
+ var phase := (
+ fposmod(time_seconds, safe_cycle) / safe_cycle * TAU
+ + motion_phase_offset
+ )
+ var swell := (
+ sin(phase)
+ + sin(phase * 2.0 + 1.1) * motion_secondary_swell
+ ) / (1.0 + motion_secondary_swell)
+ return swell * motion_amplitude
+
+
+static func _current_time_seconds() -> float:
+ return float(Time.get_ticks_msec()) * 0.001
diff --git a/world/water_surface_motion.gd.uid b/world/water_surface_motion.gd.uid
new file mode 100644
index 0000000..65746a9
--- /dev/null
+++ b/world/water_surface_motion.gd.uid
@@ -0,0 +1 @@
+uid://drdjm443o35tc
diff --git a/world/world_character_display.gd b/world/world_character_display.gd
new file mode 100644
index 0000000..a145f3b
--- /dev/null
+++ b/world/world_character_display.gd
@@ -0,0 +1,137 @@
+class_name WorldCharacterDisplay
+extends Node3D
+
+const CharacterCustomizationCatalogType = preload(
+ "res://progression/character_customization_catalog.gd"
+)
+const PlayerVisualPresenterType = preload(
+ "res://player/player_visual_presenter.gd"
+)
+
+@export_enum("round", "pointy") var species_id: String = "round"
+@export_enum(
+ "white",
+ "gray",
+ "charcoal",
+ "brown",
+ "orange",
+ "yellow",
+ "green",
+ "teal",
+) var fur_color_id: String = "white"
+@export_enum(
+ "none",
+ "pointy_long",
+ "pointy_short",
+ "pointy_wide",
+) var ears_id: String = "none"
+@export_enum(
+ "none",
+ "bear",
+ "bunny",
+ "cat",
+ "fox",
+ "gator",
+ "pointy",
+) var tail_id: String = "none"
+@export var eyes_id: String = "simple_shine"
+@export var nose_id: String = "dog_round"
+@export var mouth_id: String = "three"
+@export_category("Head Look")
+@export var head_look_enabled: bool = false
+@export_range(0.5, 10.0, 0.1, "suffix:m") var head_look_distance: float = 4.0
+@export_range(0.5, 3.0, 0.05, "suffix:m") var look_target_height: float = 1.25
+@export_range(0.0, 80.0, 1.0, "degrees") var head_yaw_limit: float = 50.0
+@export_range(0.0, 45.0, 1.0, "degrees") var head_pitch_limit: float = 22.0
+@export_range(0.05, 2.0, 0.05, "suffix:s") var head_blend_seconds: float = 0.3
+
+var _head_look: LookAtModifier3D
+var _skeleton: Skeleton3D
+var _look_target: Node3D
+var _look_target_proxy: Node3D
+var _head_look_requested: bool = false
+
+
+func _ready() -> void:
+ var appearance := CharacterCustomizationCatalogType.default_snapshot()
+ appearance["species"] = species_id
+ appearance["fur_pattern"] = fur_color_id
+ appearance["ears"] = ears_id
+ appearance["tail"] = tail_id
+ appearance["eyes"] = eyes_id
+ appearance["nose"] = nose_id
+ appearance["mouth"] = mouth_id
+ PlayerVisualPresenterType.apply_appearance(self, appearance)
+ _prepare_head_look()
+
+
+func _process(delta: float) -> void:
+ if _head_look == null or _look_target_proxy == null:
+ return
+ var target_is_valid := (
+ _look_target != null and is_instance_valid(_look_target)
+ )
+ if target_is_valid:
+ _look_target_proxy.global_position = (
+ _look_target.global_position + Vector3.UP * look_target_height
+ )
+ var target_influence := (
+ 1.0 if _head_look_requested and target_is_valid else 0.0
+ )
+ _head_look.influence = move_toward(
+ _head_look.influence,
+ target_influence,
+ delta / maxf(head_blend_seconds, 0.001),
+ )
+
+
+func set_head_look_target(target: Node3D) -> void:
+ _look_target = target
+
+
+func set_head_look_active(active: bool) -> void:
+ _head_look_requested = active
+
+
+func get_head_anchor_position() -> Vector3:
+ if _skeleton == null:
+ return global_position + Vector3.UP * 1.8
+ var head_index := _skeleton.find_bone("head")
+ if head_index < 0:
+ return global_position + Vector3.UP * 1.8
+ var head_pose := _skeleton.get_bone_global_pose(head_index)
+ return (
+ (_skeleton.global_transform * head_pose).origin
+ + Vector3.UP * 0.85
+ )
+
+
+func _prepare_head_look() -> void:
+ if not head_look_enabled:
+ set_process(false)
+ return
+ _skeleton = find_child("Skeleton3D", true, false) as Skeleton3D
+ if _skeleton == null or _skeleton.find_bone("head") < 0:
+ push_warning("World character head-look requires a head bone.")
+ set_process(false)
+ return
+ _look_target_proxy = Node3D.new()
+ _look_target_proxy.name = "HeadLookTarget"
+ add_child(_look_target_proxy)
+ _head_look = LookAtModifier3D.new()
+ _head_look.name = "HeadLookModifier"
+ _head_look.bone_name = "head"
+ _head_look.use_secondary_rotation = true
+ _head_look.use_angle_limitation = true
+ _head_look.symmetry_limitation = true
+ _head_look.primary_limit_angle = deg_to_rad(head_yaw_limit)
+ _head_look.secondary_limit_angle = deg_to_rad(head_pitch_limit)
+ _head_look.primary_damp_threshold = 0.65
+ _head_look.secondary_damp_threshold = 0.65
+ _head_look.duration = head_blend_seconds
+ _head_look.influence = 0.0
+ _head_look.set("origin_from", 1)
+ _head_look.set("origin_bone_name", "head")
+ _skeleton.add_child(_head_look)
+ _head_look.target_node = _head_look.get_path_to(_look_target_proxy)
+ set_process(true)
diff --git a/world/world_character_display.gd.uid b/world/world_character_display.gd.uid
new file mode 100644
index 0000000..0873153
--- /dev/null
+++ b/world/world_character_display.gd.uid
@@ -0,0 +1 @@
+uid://dqsehnkidygg7
diff --git a/world/world_time_service.gd b/world/world_time_service.gd
index 1285f3e..c3186b4 100644
--- a/world/world_time_service.gd
+++ b/world/world_time_service.gd
@@ -3,6 +3,8 @@ extends Node
signal time_changed(time_hours: float, phase: Phase)
signal phase_changed(phase: Phase)
+signal authoritative_time_set(time_hours: float)
+signal natural_time_advanced(hours: float)
enum Phase {
DAWN,
@@ -54,10 +56,12 @@ func end_session() -> void:
func advance_time(real_seconds: float) -> void:
if not _running or real_seconds <= 0.0:
return
+ var advanced_hours := real_seconds * HOURS_PER_REAL_SECOND
_set_time_hours(
- _time_hours + real_seconds * HOURS_PER_REAL_SECOND,
+ _time_hours + advanced_hours,
false,
)
+ natural_time_advanced.emit(advanced_hours)
func synchronize_time(authoritative_time_hours: float) -> void:
@@ -66,6 +70,18 @@ func synchronize_time(authoritative_time_hours: float) -> void:
_set_time_hours(authoritative_time_hours, true)
+func set_authoritative_time(time_hours: float) -> bool:
+ if (
+ not is_finite(time_hours)
+ or time_hours < 0.0
+ or time_hours >= HOURS_PER_DAY
+ ):
+ return false
+ _set_time_hours(time_hours, true)
+ authoritative_time_set.emit(_time_hours)
+ return true
+
+
func set_persistence_tracking_enabled(enabled: bool) -> void:
if _persistence_tracking_enabled == enabled:
return
diff --git a/world/world_time_visual_controller.gd b/world/world_time_visual_controller.gd
index c6a9ed4..99b0429 100644
--- a/world/world_time_visual_controller.gd
+++ b/world/world_time_visual_controller.gd
@@ -5,16 +5,35 @@ const UPDATE_INTERVAL_SECONDS: float = 0.1
const SUN_YAW_DEGREES: float = -32.0
const WEATHER_TRANSITION_SECONDS: float = 10.0
const RAIN_EMITTER_OFFSET := Vector3(0.0, 7.0, 0.0)
-const RAIN_PARTICLE_AMOUNT: int = 560
+const RAIN_EMISSION_EXTENTS := Vector3(13.0, 1.0, 13.0)
+const RAIN_VISIBILITY_AABB := AABB(
+ Vector3(-13.5, -9.0, -13.5),
+ Vector3(27.0, 12.0, 27.0),
+)
+const RAIN_PARTICLE_AMOUNT: int = 2240
const RAIN_VELOCITY_MIN: float = 16.0
const RAIN_VELOCITY_MAX: float = 20.0
const RAIN_DROP_SIZE := Vector3(0.014, 0.34, 0.014)
+const FOG_DAYLIGHT_SCENE_BRIGHTNESS: float = 0.42
+const FOG_DAYLIGHT_FOG_LIGHT_BRIGHTNESS: float = 0.42
+const FOG_DAYLIGHT_WATER_BRIGHTNESS: float = 0.42
+const FOG_DAYLIGHT_POST_BRIGHTNESS: float = 0.50
+const RAIN_DAYLIGHT_POST_BRIGHTNESS: float = 0.52
+const DEFAULT_SURFACE_HIGHLIGHT_FLOOR: float = 0.72
+const FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR: float = 0.25
+const FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT: float = 1.0
+const FOGGY_DARK_WATER_FOG_CORRECTION := Color(1.15, 1.025, 1.0, 1.0)
+const FOGGY_BRIGHT_WATER_FOG_CORRECTION := Color(0.99, 1.005, 1.01, 1.0)
+const RAIN_WATER_FOG_COLOR := Color(0.025, 0.038, 0.045)
const SALT_WATER_MATERIAL: ShaderMaterial = preload(
"res://world/materials/stylized_water.tres"
)
const FRESH_WATER_MATERIAL: ShaderMaterial = preload(
"res://world/materials/stylized_water_fresh.tres"
)
+const LocalStormCloudLayerType = preload(
+ "res://world/environment/local_storm_cloud_layer.gd"
+)
const DAY_SKY_TOP := Color(0.204, 0.498, 0.643)
const DAY_SKY_HORIZON := Color(0.663, 0.843, 0.847)
@@ -44,15 +63,27 @@ const WARM_SUN := Color(1.0, 0.58, 0.30)
const WARM_WATER_TINT := Color(0.78, 0.62, 0.58)
const WARM_SUN_DISC := Color(1.0, 0.45, 0.16)
const MOON_DISC := Color(0.78, 0.88, 1.0)
+const DAY_CLOUD_LIGHT := Color(0.70, 0.76, 0.77)
+const DAY_CLOUD_SHADOW := Color(0.31, 0.38, 0.40)
+const NIGHT_CLOUD_LIGHT := Color(0.18, 0.22, 0.30)
+const NIGHT_CLOUD_SHADOW := Color(0.06, 0.09, 0.14)
+const WARM_CLOUD_LIGHT := Color(0.76, 0.55, 0.45)
+const WARM_CLOUD_SHADOW := Color(0.31, 0.23, 0.24)
+const STORM_CLOUD_SHADOW := Color(0.08, 0.12, 0.14)
+const DAY_LOWER_CLOUD := Color(0.22, 0.25, 0.26)
+const NIGHT_LOWER_CLOUD := Color(0.08, 0.10, 0.14)
+const WARM_LOWER_CLOUD := Color(0.22, 0.16, 0.16)
var _time_service: WorldTimeService
var _weather_service: WorldWeatherService
var _world_environment: WorldEnvironment
var _sun: DirectionalLight3D
var _rain_target: Node3D
+var _rain_camera_provider: Callable
var _environment: Environment
var _sky_material: ShaderMaterial
var _rain: GPUParticles3D
+var _storm_clouds: LocalStormCloudLayer
var _elapsed: float = 0.0
var _weather_from: WorldWeatherService.Weather = (
WorldWeatherService.Weather.SUNNY
@@ -69,16 +100,19 @@ func setup(
sun: DirectionalLight3D,
weather_service: WorldWeatherService = null,
rain_target: Node3D = null,
+ rain_camera_provider: Callable = Callable(),
) -> void:
_time_service = time_service
_weather_service = weather_service
_world_environment = world_environment
_sun = sun
_rain_target = rain_target
+ _rain_camera_provider = rain_camera_provider
if not _prepare_runtime_environment():
set_process(false)
return
_prepare_rain()
+ _prepare_storm_clouds()
if _weather_service != null:
_weather_from = _weather_service.get_weather()
_weather_to = _weather_from
@@ -158,14 +192,12 @@ func _prepare_rain() -> void:
_rain.lifetime = 1.25
_rain.fixed_fps = 30
_rain.local_coords = false
- _rain.visibility_aabb = AABB(
- Vector3(-7.0, -9.0, -7.0), Vector3(14.0, 12.0, 14.0)
- )
+ _rain.visibility_aabb = RAIN_VISIBILITY_AABB
var process_material := ParticleProcessMaterial.new()
process_material.emission_shape = (
ParticleProcessMaterial.EMISSION_SHAPE_BOX
)
- process_material.emission_box_extents = Vector3(6.5, 1.0, 6.5)
+ process_material.emission_box_extents = RAIN_EMISSION_EXTENTS
process_material.direction = Vector3.DOWN
process_material.spread = 5.0
process_material.initial_velocity_min = RAIN_VELOCITY_MIN
@@ -184,6 +216,13 @@ func _prepare_rain() -> void:
_update_rain_position()
+func _prepare_storm_clouds() -> void:
+ _storm_clouds = LocalStormCloudLayerType.new()
+ _storm_clouds.name = "LocalStormClouds"
+ add_child(_storm_clouds)
+ _storm_clouds.setup(_rain_target)
+
+
func _apply_time(time_hours: float) -> void:
if _environment == null or _sky_material == null or _sun == null:
return
@@ -220,6 +259,21 @@ func _apply_time(time_hours: float) -> void:
var fog_color: Color = _blended_color(
NIGHT_FOG, DAY_FOG, WARM_FOG, daylight, warmth
)
+ var foggy_fog_amount: float = _weather_value(0.0, 0.0, 0.0, 1.0)
+ var rain_fog_amount: float = _weather_value(0.0, 0.0, 1.0, 0.0)
+ var fog_daylight_amount: float = daylight * foggy_fog_amount
+ var rain_daylight_amount: float = daylight * rain_fog_amount
+ var weather_fog_amount: float = minf(
+ rain_fog_amount + foggy_fog_amount,
+ 1.0,
+ )
+ var foggy_horizon_occlusion := _foggy_horizon_occlusion_amount(hour)
+ _environment.fog_enabled = weather_fog_amount > 0.001
+ var fog_scene_brightness: float = lerpf(
+ 1.0,
+ FOG_DAYLIGHT_SCENE_BRIGHTNESS,
+ fog_daylight_amount,
+ )
_sky_material.set_shader_parameter(
"sky_top_color", sky_top
)
@@ -235,24 +289,40 @@ func _apply_time(time_hours: float) -> void:
"ground_horizon_color",
ground_horizon,
)
+ _sky_material.set_shader_parameter("fog_horizon_color", fog_color)
+ _sky_material.set_shader_parameter(
+ "fog_horizon_occlusion",
+ foggy_fog_amount * foggy_horizon_occlusion,
+ )
+ _apply_sky_clouds(daylight, warmth)
_environment.background_energy_multiplier = (
lerpf(0.52, 0.85, daylight)
* _weather_value(1.0, 0.82, 0.66, 1.0)
+ * fog_scene_brightness
)
_environment.ambient_light_color = ambient
_environment.ambient_light_energy = (
lerpf(0.66, 1.08, daylight)
- * _weather_value(1.0, 0.88, 0.76, 0.82)
+ * _weather_value(1.0, 0.88, 0.76, 1.0)
+ * fog_scene_brightness
)
_environment.fog_light_color = fog_color
- _environment.fog_light_energy = (
+ var fog_light_energy := (
lerpf(0.56, 0.82, daylight)
- * _weather_value(1.0, 0.92, 0.82, 1.05)
+ * _weather_value(1.0, 0.92, 0.82, 1.0)
+ * lerpf(
+ 1.0,
+ FOG_DAYLIGHT_FOG_LIGHT_BRIGHTNESS,
+ fog_daylight_amount,
+ )
)
+ _environment.fog_light_energy = fog_light_energy
_environment.fog_aerial_perspective = _weather_value(
- 0.35, 0.48, 0.62, 0.92
+ 0.35, 0.48, 0.62, 0.0
+ )
+ _environment.fog_sky_affect = _weather_value(
+ 0.35, 0.48, 0.68, 1.0
)
- _environment.fog_sky_affect = 0.0
_environment.fog_depth_curve = _weather_value(
1.6, 1.5, 1.4, 1.18
)
@@ -260,12 +330,29 @@ func _apply_time(time_hours: float) -> void:
42.0, 32.0, 20.0, 3.0
)
_environment.fog_depth_end = _weather_value(
- 170.0, 140.0, 95.0, 28.0
+ 170.0, 140.0, 95.0, 18.0
+ )
+ _apply_water_environment(
+ daylight,
+ warmth,
+ rain_fog_amount,
+ foggy_fog_amount,
+ foggy_horizon_occlusion,
+ _fog_render_color(fog_color, fog_light_energy),
)
- _apply_water_environment(daylight, warmth)
_environment.adjustment_brightness = (
lerpf(0.93, 0.98, daylight)
* _weather_value(1.0, 0.97, 0.92, 1.0)
+ * lerpf(
+ 1.0,
+ FOG_DAYLIGHT_POST_BRIGHTNESS,
+ fog_daylight_amount,
+ )
+ * lerpf(
+ 1.0,
+ RAIN_DAYLIGHT_POST_BRIGHTNESS,
+ rain_daylight_amount,
+ )
)
_environment.adjustment_saturation = (
lerpf(0.82, 0.91, daylight)
@@ -299,7 +386,7 @@ func _apply_time(time_hours: float) -> void:
)
_sun.light_energy = (
lerpf(0.0, 0.10, daylight)
- * _weather_value(1.0, 0.55, 0.25, 0.35)
+ * _weather_value(1.0, 0.55, 0.25, 0.30)
)
_update_rain_amount()
@@ -307,6 +394,10 @@ func _apply_time(time_hours: float) -> void:
func _apply_water_environment(
daylight: float,
warmth: float,
+ rain_fog_amount: float,
+ foggy_fog_amount: float,
+ foggy_horizon_occlusion: float,
+ fog_render_color: Color,
) -> void:
var water_tint := _blended_color(
NIGHT_WATER_TINT,
@@ -318,6 +409,62 @@ func _apply_water_environment(
var water_brightness := (
lerpf(0.34, 1.0, daylight)
* _weather_value(1.0, 0.90, 0.78, 1.0)
+ * lerpf(
+ 1.0,
+ FOG_DAYLIGHT_WATER_BRIGHTNESS,
+ daylight * _weather_value(0.0, 0.0, 0.0, 1.0),
+ )
+ )
+ var weather_fog_amount: float = minf(
+ rain_fog_amount + foggy_fog_amount,
+ 1.0,
+ )
+ var foggy_color_weight: float = (
+ foggy_fog_amount / weather_fog_amount
+ if weather_fog_amount > 0.001
+ else 0.0
+ )
+ var water_fog_color := RAIN_WATER_FOG_COLOR.lerp(
+ fog_render_color,
+ foggy_color_weight,
+ )
+ var fog_correction_amount := (
+ foggy_fog_amount * foggy_horizon_occlusion
+ )
+ var bright_fog_amount := maxf(daylight, warmth)
+ var fog_color_correction := FOGGY_DARK_WATER_FOG_CORRECTION.lerp(
+ FOGGY_BRIGHT_WATER_FOG_CORRECTION,
+ bright_fog_amount,
+ )
+ water_fog_color.r *= lerpf(
+ 1.0,
+ fog_color_correction.r,
+ fog_correction_amount,
+ )
+ water_fog_color.g *= lerpf(
+ 1.0,
+ fog_color_correction.g,
+ fog_correction_amount,
+ )
+ water_fog_color.b *= lerpf(
+ 1.0,
+ fog_color_correction.b,
+ fog_correction_amount,
+ )
+ var foggy_surface_highlight_floor := lerpf(
+ FOGGY_NIGHT_SURFACE_HIGHLIGHT_FLOOR,
+ DEFAULT_SURFACE_HIGHLIGHT_FLOOR,
+ daylight,
+ )
+ var surface_highlight_floor := lerpf(
+ DEFAULT_SURFACE_HIGHLIGHT_FLOOR,
+ foggy_surface_highlight_floor,
+ foggy_fog_amount,
+ )
+ var water_near_fog_amount := (
+ FOGGY_NIGHT_WATER_NEAR_FOG_AMOUNT
+ * foggy_fog_amount
+ * foggy_horizon_occlusion
)
for material: ShaderMaterial in [
SALT_WATER_MATERIAL,
@@ -328,6 +475,107 @@ func _apply_water_environment(
"environment_brightness",
water_brightness,
)
+ material.set_shader_parameter("weather_fog_color", water_fog_color)
+ material.set_shader_parameter(
+ "surface_highlight_night_floor",
+ surface_highlight_floor,
+ )
+ material.set_shader_parameter(
+ "weather_fog_amount",
+ weather_fog_amount,
+ )
+ material.set_shader_parameter(
+ "weather_fog_near_amount",
+ water_near_fog_amount,
+ )
+ material.set_shader_parameter(
+ "weather_fog_begin",
+ _weather_value(42.0, 32.0, 20.0, 3.0),
+ )
+ material.set_shader_parameter(
+ "weather_fog_end",
+ _weather_value(170.0, 140.0, 95.0, 18.0),
+ )
+ material.set_shader_parameter(
+ "weather_fog_curve",
+ _weather_value(1.6, 1.5, 1.4, 1.18),
+ )
+
+
+func _fog_render_color(fog_color: Color, fog_light_energy: float) -> Color:
+ var linear_fog_color := fog_color.srgb_to_linear()
+ linear_fog_color.r *= fog_light_energy
+ linear_fog_color.g *= fog_light_energy
+ linear_fog_color.b *= fog_light_energy
+ linear_fog_color.a = 1.0
+ return linear_fog_color.linear_to_srgb()
+
+
+func _foggy_horizon_occlusion_amount(hour: float) -> float:
+ # Day and dusk already blend cleanly. During night and most of dawn, make
+ # the manually fogged transparent water fully occluding so the dark scene
+ # below it cannot reintroduce a horizon band. Brief edge fades avoid a pop
+ # where the dawn/night phases meet their neighboring phases.
+ if hour >= WorldTimeService.DUSK_END_HOUR - 0.1:
+ return smoothstep(
+ WorldTimeService.DUSK_END_HOUR - 0.1,
+ WorldTimeService.DUSK_END_HOUR,
+ hour,
+ )
+ if hour < WorldTimeService.DAWN_START_HOUR:
+ return 1.0
+ if hour < WorldTimeService.DAWN_END_HOUR:
+ return 1.0 - smoothstep(
+ WorldTimeService.DAWN_END_HOUR - 0.1,
+ WorldTimeService.DAWN_END_HOUR,
+ hour,
+ )
+ return 0.0
+
+
+func _apply_sky_clouds(daylight: float, warmth: float) -> void:
+ var cloud_light := _blended_color(
+ NIGHT_CLOUD_LIGHT,
+ DAY_CLOUD_LIGHT,
+ WARM_CLOUD_LIGHT,
+ daylight,
+ warmth,
+ )
+ var cloud_shadow := _blended_color(
+ NIGHT_CLOUD_SHADOW,
+ DAY_CLOUD_SHADOW,
+ WARM_CLOUD_SHADOW,
+ daylight,
+ warmth,
+ )
+ var storm_amount: float = _weather_value(0.0, 0.18, 0.55, 0.0)
+ cloud_light = cloud_light.lerp(cloud_shadow, storm_amount * 0.35)
+ cloud_shadow = cloud_shadow.lerp(
+ STORM_CLOUD_SHADOW,
+ storm_amount * 0.10,
+ )
+ var lower_cloud_color := _blended_color(
+ NIGHT_LOWER_CLOUD,
+ DAY_LOWER_CLOUD,
+ WARM_LOWER_CLOUD,
+ daylight,
+ warmth,
+ )
+ _sky_material.set_shader_parameter(
+ "cloud_coverage",
+ _weather_value(0.0, 0.58, 0.985, 0.0),
+ )
+ _sky_material.set_shader_parameter(
+ "cloud_opacity",
+ _weather_value(0.0, 0.76, 1.0, 0.0),
+ )
+ _sky_material.set_shader_parameter("cloud_light_color", cloud_light)
+ _sky_material.set_shader_parameter("cloud_shadow_color", cloud_shadow)
+ if _storm_clouds != null:
+ _storm_clouds.set_storm_amount(
+ _weather_value(0.0, 0.0, 1.0, 0.0),
+ lower_cloud_color,
+ )
func _on_weather_changed(
@@ -382,7 +630,14 @@ func _update_rain_amount() -> void:
func _update_rain_position() -> void:
if _rain == null or _rain_target == null:
return
- _rain.global_position = _rain_target.global_position + RAIN_EMITTER_OFFSET
+ var anchor_position: Vector3 = _rain_target.global_position
+ if _rain_camera_provider.is_valid():
+ var camera_candidate: Variant = _rain_camera_provider.call()
+ if camera_candidate is Camera3D:
+ var active_camera := camera_candidate as Camera3D
+ if is_instance_valid(active_camera):
+ anchor_position = active_camera.global_position
+ _rain.global_position = anchor_position + RAIN_EMITTER_OFFSET
func _daylight_amount(hour: float) -> float:
diff --git a/world/world_weather_service.gd b/world/world_weather_service.gd
index fd09d60..4fce78e 100644
--- a/world/world_weather_service.gd
+++ b/world/world_weather_service.gd
@@ -30,6 +30,8 @@ var _rng := RandomNumberGenerator.new()
var _daily_plan_id: String = ""
var _daily_schedule: Array[Dictionary] = []
var _world_time: WorldTimeService
+var _manual_override_weather: Weather = DEFAULT_WEATHER
+var _manual_override_segment_index: int = -1
func _ready() -> void:
@@ -44,6 +46,7 @@ func begin_authoritative_session(seed_value: int) -> void:
_rng.seed = seed_value
_running_authority = true
set_process(true)
+ _clear_manual_override()
if _daily_schedule.is_empty() or _world_time == null:
if _has_persistent_state:
_set_weather(
@@ -64,12 +67,14 @@ func begin_authoritative_session(seed_value: int) -> void:
func begin_remote_session() -> void:
_running_authority = false
set_process(false)
+ _clear_manual_override()
_set_weather(DEFAULT_WEATHER, SUNNY_DURATION_RANGE.x, true)
func end_session() -> void:
_running_authority = false
set_process(false)
+ _clear_manual_override()
_set_weather(DEFAULT_WEATHER, SUNNY_DURATION_RANGE.x, true)
@@ -98,6 +103,22 @@ func apply_authoritative_snapshot(
_set_weather(weather, maxf(seconds_remaining, 0.0), false)
+func set_authoritative_weather(weather: Weather) -> bool:
+ if not _running_authority or not is_valid_weather(int(weather)):
+ return false
+ var duration: float = _roll_duration(weather)
+ if not _daily_schedule.is_empty() and _world_time != null:
+ _manual_override_weather = weather
+ _manual_override_segment_index = _current_daily_segment_index()
+ duration = _current_daily_segment_seconds_remaining(
+ _manual_override_segment_index
+ )
+ else:
+ _clear_manual_override()
+ _set_weather(weather, duration, true)
+ return true
+
+
func set_persistence_tracking_enabled(enabled: bool) -> void:
if _persistence_tracking_enabled == enabled:
return
@@ -181,6 +202,7 @@ func configure_daily_plan(
return false
_daily_plan_id = plan_id
_daily_schedule.clear()
+ _clear_manual_override()
for value: Variant in schedule:
_daily_schedule.append((value as Dictionary).duplicate(true))
_world_time = world_time
@@ -193,6 +215,7 @@ func clear_daily_plan() -> void:
_daily_plan_id = ""
_daily_schedule.clear()
_world_time = null
+ _clear_manual_override()
func get_daily_plan_id() -> String:
@@ -327,21 +350,43 @@ func _duration_range(weather: Weather) -> Vector2:
func _update_scheduled_weather(force_emit: bool) -> void:
if _daily_schedule.is_empty() or _world_time == null:
return
+ var segment_index: int = _current_daily_segment_index()
+ var entry: Dictionary = _daily_schedule[segment_index]
+ var weather: Weather = int(entry.get("weather", DEFAULT_WEATHER)) as Weather
+ if _manual_override_segment_index == segment_index:
+ weather = _manual_override_weather
+ elif _manual_override_segment_index >= 0:
+ _clear_manual_override()
+ var seconds_remaining: float = _current_daily_segment_seconds_remaining(
+ segment_index
+ )
+ _set_weather(weather, seconds_remaining, force_emit)
+
+
+func _current_daily_segment_index() -> int:
var elapsed_hours: float = fposmod(
_world_time.get_time_hours() - WorldTimeService.DAY_START_HOUR,
WorldTimeService.HOURS_PER_DAY,
)
- var segment_hours: float = DAILY_PLAN_SEGMENT_HOURS
- var segment_index: int = clampi(
- floori(elapsed_hours / segment_hours),
+ return clampi(
+ floori(elapsed_hours / DAILY_PLAN_SEGMENT_HOURS),
0,
_daily_schedule.size() - 1,
)
- var entry: Dictionary = _daily_schedule[segment_index]
- var weather: Weather = int(entry.get("weather", DEFAULT_WEATHER)) as Weather
- var next_boundary: float = float(segment_index + 1) * segment_hours
- var hours_remaining: float = maxf(next_boundary - elapsed_hours, 0.0)
- var seconds_remaining: float = (
- hours_remaining / WorldTimeService.HOURS_PER_REAL_SECOND
+
+
+func _current_daily_segment_seconds_remaining(segment_index: int) -> float:
+ var elapsed_hours: float = fposmod(
+ _world_time.get_time_hours() - WorldTimeService.DAY_START_HOUR,
+ WorldTimeService.HOURS_PER_DAY,
)
- _set_weather(weather, seconds_remaining, force_emit)
+ var next_boundary: float = (
+ float(segment_index + 1) * DAILY_PLAN_SEGMENT_HOURS
+ )
+ var hours_remaining: float = maxf(next_boundary - elapsed_hours, 0.0)
+ return hours_remaining / WorldTimeService.HOURS_PER_REAL_SECOND
+
+
+func _clear_manual_override() -> void:
+ _manual_override_weather = DEFAULT_WEATHER
+ _manual_override_segment_index = -1